elearning/Frontend-Learner/composables/useCategory.ts

106 lines
3.4 KiB
TypeScript
Raw Normal View History

// Interface สำหรับข้อมูลหมวดหมู่ (Category)
export interface Category {
id: number
name: {
th: string
en: string
[key: string]: string
}
slug: string
description: {
th: string
en: string
[key: string]: string
}
icon: string
sort_order: number
is_active: boolean
created_at: string
updated_at: string
}
export interface CategoryData {
total: number
categories: Category[]
}
interface CategoryResponse {
code: number
message: string
data: CategoryData
}
// Composable สำหรับจัดการข้อมูลหมวดหมู่
export const useCategory = () => {
const config = useRuntimeConfig()
const API_BASE_URL = config.public.apiBase as string
const { token } = useAuth()
// ใช้ useState เพื่อเก็บ Cached Data ระดับ Global (แชร์กันทุก Component)
const categoriesState = useState<Category[]>('categories_cache', () => [])
const isLoaded = useState<boolean>('categories_loaded', () => false)
// ฟังก์ชันดึงข้อมูลหมวดหมู่ทั้งหมด
// Endpoint: GET /categories
const fetchCategories = async (forceRefresh = false) => {
// ถ้ามีข้อมูลอยู่แล้วและไม่สั่งบังคับโหลดใหม่ ให้ใช้ข้อมูลเดิมทันที
if (isLoaded.value && !forceRefresh && categoriesState.value.length > 0) {
return {
success: true,
data: categoriesState.value,
total: categoriesState.value.length
}
}
try {
const response = await $fetch<CategoryResponse>(`${API_BASE_URL}/categories`, {
method: 'GET',
headers: token.value ? {
Authorization: `Bearer ${token.value}`
} : {}
})
const categories = response.data?.categories || []
// เก็บข้อมูลลง State
categoriesState.value = categories
isLoaded.value = true
return {
success: true,
data: categories,
total: response.data?.total || 0
}
} catch (err: any) {
console.error('Fetch categories failed:', err)
// Retry logic for 429 Too Many Requests
if (err.statusCode === 429 || err.status === 429) {
await new Promise(resolve => setTimeout(resolve, 1500)); // Wait 1.5s
try {
const retryRes = await $fetch<CategoryResponse>(`${API_BASE_URL}/categories`, {
method: 'GET',
headers: token.value ? { Authorization: `Bearer ${token.value}` } : {}
})
const cats = retryRes.data?.categories || []
categoriesState.value = cats
isLoaded.value = true
return { success: true, data: cats, total: retryRes.data?.total || 0 }
} catch (retryErr) {
console.error('Retry fetch categories failed:', retryErr)
}
}
return {
success: false,
error: err.data?.message || err.message || 'Error fetching categories'
}
}
}
return {
fetchCategories,
categories: computed(() => categoriesState.value) // ส่งข้อมูลออกมาเป็น Computed เพื่อให้ UI อัปเดตตามอัตโนมัติ
}
}