diff --git a/COMPOSITION_API.md b/COMPOSITION_API.md new file mode 100644 index 0000000..a8a599e --- /dev/null +++ b/COMPOSITION_API.md @@ -0,0 +1,289 @@ +1. Organize Your Code into Logical Sections + +Structure your component script into clear sections to improve readability. A common approach is to group related logic together. +Example Structure: + + + +--- + +2. Use script setup Syntax + +The + + + +--- + +3. Use Descriptive Variable and Function Names + +Choose meaningful names for variables, functions, and computed properties to make your code self-documenting. +Example: +// Bad +const x = ref(0) + +// Good +const userCount = ref(0) + +--- + +4. Extract Reusable Logic into Composables + Move reusable logic into composables (custom hooks) to keep your components clean and promote code reuse. + Example Composable: + +// composables/useCounter.js +import { ref } from 'vue' + +export function useCounter(initialValue = 0) { +const count = ref(initialValue) + +function increment() { +count.value++ +} + +function reset() { +count.value = initialValue +} + +return { +count, +increment, +reset, +} +} + +Usage in a Component: + + + + + +--- + +5. Use ref for Primitive Values and reactive for Objects + + - Use ref for primitive values (e.g., numbers, strings, booleans). + - Use reactive for objects or arrays. + +Example: +const count = ref(0) // Primitive value +const user = reactive({ name: 'John', age: 30 }) // Object + +--- + +6. Use Computed Properties for Derived State + +Use computed to create reactive properties that depend on other state. This ensures the derived state is always up-to-date. +Example: +const firstName = ref('John') +const lastName = ref('Doe') + +const fullName = computed(() => `${firstName.value} ${lastName.value}`) + +--- + +7. Use Watchers Sparingly + +Watchers (watch and watchEffect) are powerful but can make your code harder to understand if overused. Prefer computed properties or event-driven updates where possible. +Example: +watch(count, (newValue, oldValue) => { +console.log(`Count changed from ${oldValue} to ${newValue}`) +}) + +--- + +8. Group Related Logic Together + +Keep related reactive state, computed properties, and functions together to make your code easier to follow. +Example: +// User-related logic +const user = reactive({ name: 'John', age: 30 }) +const isAdult = computed(() => user.age >= 18) +function updateUser(newName) { + user.name = newName +} + +----------- + +9. Use Lifecycle Hooks for Side Effects + +Use lifecycle hooks (onMounted, onUnmounted, etc.) for side effects like fetching data or setting up event listeners. +Example: +onMounted(() => { + console.log('Component mounted') + fetchData() +}) + +onUnmounted(() => { + console.log('Component unmounted') + cleanup() +}) + +---------------- + +10. Use TypeScript for Better Type Safety +If your project uses TypeScript, leverage it to add type safety to your components. +Example: + + +-------------- + +11. Keep Templates Clean + +Avoid putting too much logic in your template. Instead, move complex logic into the script or composables. +Example: + + + + +------------ + +12. Use provide and inject for Prop Drilling +Avoid prop drilling by using provide and inject to share state across deeply nested components. +Example: +// Parent component +import { provide, ref } from 'vue' + +const theme = ref('dark') +provide('theme', theme) + +// Child component +import { inject } from 'vue' + +const theme = inject('theme') + +----------------- + +13. Use v-model for Two-Way Binding + +Use v-model to simplify two-way binding between parent and child components. +Example: + + + + + + + + + + +---------- + +14. Use defineProps and defineEmits for TypeScript Support + +When using TypeScript, use defineProps and defineEmits to define props and emits with type safety. +Example: + + +------------- + +15. Use Scoped Styles + +Use scoped styles ( + +------------------ + +16. Use Environment Variables + +Use environment variables for configuration (e.g., API URLs) to keep your code flexible and secure. +Example: +const apiUrl = import.meta.env.VITE_API_URL + +------------- + +17. Write Unit Tests + +Write unit tests for your components and composables to ensure they work as expected. +Example: +import { render } from '@testing-library/vue' +import MyComponent from '@/components/MyComponent.vue' + +test('renders correctly', () => { + const { getByText } = render(MyComponent) + expect(getByText('Hello, Vue 3!')).toBeInTheDocument() +}) \ No newline at end of file diff --git a/composables/useHadithaSearchComposable.ts b/composables/useHadithaSearchComposable.ts index 1500ae5..0eb2aaa 100644 --- a/composables/useHadithaSearchComposable.ts +++ b/composables/useHadithaSearchComposable.ts @@ -1,12 +1,7 @@ // composables/useHadithaSearchComposable.js import { useStorage } from "@vueuse/core"; -export const useHadithaSearchComposable = (url, options = {}) => { - const loading = ref(false); // Track loading state - const data = ref(null); - const error = ref(null); - const status = ref(null); - +export const useHadithaSearchComposable = (url: string, options = {}) => { // Get the authentication token (e.g., from a cookie or local storage) // const token = useCookie('auth-token') // Assuming you store the token in a cookie let token = useStorage("id_token", "GuestAccess"); @@ -25,7 +20,7 @@ export const useHadithaSearchComposable = (url, options = {}) => { // Use useFetch with the headers return useFetch(url, { ...options, - baseURL: baseURL, + baseURL, headers, }); }; diff --git a/plugins/api.ts b/plugins/api.ts index c9895c0..6c62317 100644 --- a/plugins/api.ts +++ b/plugins/api.ts @@ -13,7 +13,7 @@ export default defineNuxtPlugin((nuxtApp) => { onRequest({ request, options, error }) { options.baseURL = import.meta.env.VITE_BASE_URL + - import.meta.env.VITE_API_NAME + + import.meta.env.NUXT_PUBLIC_API_NAME+ options.baseURL; if (token) { diff --git a/plugins/httpService.ts b/plugins/httpService.ts index 704f4f0..d5c15a2 100644 --- a/plugins/httpService.ts +++ b/plugins/httpService.ts @@ -3,12 +3,13 @@ import { useStorage } from "@vueuse/core"; export default defineNuxtPlugin((nuxtApp) => { let token = useStorage("id_token", "GuestAccess").value; + const config = useRuntimeConfig(); const api = $fetch.create({ onRequest({ request, options, error }) { options.baseURL = - import.meta.env.VITE_BASE_URL + - import.meta.env.VITE_API_NAME + + config.public.NUXT_PUBLIC_BASE_URL + + config.public.NUXT_PUBLIC_API_NAME + options.baseURL; if (token) { @@ -40,13 +41,14 @@ export default defineNuxtPlugin((nuxtApp) => { getRequest: (url, options = {}) => api(url, { method: "GET", ...options }), postRequest: (url, body, options = {}) => api(url, { method: "POST", body, ...options }), - deleteRequest: (url, options = {}) => api(url, { method: "DELETE", ...options }), + deleteRequest: (url, options = {}) => + api(url, { method: "DELETE", ...options }), }; // Expose to useNuxtApp().$api and useNuxtApp().$http return { provide: { - http + http, }, }; }); diff --git a/routes/haditha.ts b/routes/haditha.ts index 76abf37..5936935 100644 --- a/routes/haditha.ts +++ b/routes/haditha.ts @@ -12,7 +12,7 @@ export default [ { name: "hadithaSearchShow", path: "/haditha/search/:id/:slug?", - file: "~/systems/hadith_ui/pages/haditha/searchy/[id]/[slug]/index.vue", + file: "~/systems/hadith_ui/pages/haditha/search/[id]/[slug]/index.vue", }, { diff --git a/systems/hadith_ui b/systems/hadith_ui index 832f5db..3800df1 160000 --- a/systems/hadith_ui +++ b/systems/hadith_ui @@ -1 +1 @@ -Subproject commit 832f5dbf525ebddbcfa8873b5b3c88325f446a3c +Subproject commit 3800df1b4005255a315df026e1c7ea9d7f9a71c2 diff --git a/utils/globalMixin.ts b/utils/globalMixin.ts index 220aa09..0c45f43 100644 --- a/utils/globalMixin.ts +++ b/utils/globalMixin.ts @@ -275,7 +275,7 @@ export const userAvatar = (user = undefined) => { if (user?.avatar && user?.avatar?.length) { return ( import.meta.env.VITE_BASE_URL + - import.meta.env.VITE_API_NAME + + import.meta.env.NUXT_PUBLIC_API_NAME+ fileUrl() + user.avatar ); diff --git a/utils/useApi.ts b/utils/useApi.ts index 6d26c99..51ec60b 100644 --- a/utils/useApi.ts +++ b/utils/useApi.ts @@ -4,7 +4,7 @@ export async function useAPI( url: string | (() => string), options?: UseFetchOptions ) { - const prexFixUrlWithApiName = import.meta.env.VITE_API_NAME + url; + const prexFixUrlWithApiName = import.meta.env.NUXT_PUBLIC_API_NAME+ url; return await useFetch(prexFixUrlWithApiName, { ...options,