- Standardize parameter naming with hyphens instead of underscores - Remove page size limit and enable no-limit flag for all region queries - Improve arrow function syntax consistency and formatting
112 lines
3.1 KiB
TypeScript
112 lines
3.1 KiB
TypeScript
import { ref, computed } from 'vue'
|
|
import type { Province } from '~/models/province'
|
|
import type { SelectItem } from '~/components/pub/my-ui/form/select.vue'
|
|
import { toTitleCase } from '~/lib/utils'
|
|
import * as provinceService from '~/services/province.service'
|
|
|
|
// Global state untuk caching
|
|
const provincesCache = ref<Province[]>([])
|
|
const isLoading = ref(false)
|
|
const isInitialized = ref(false)
|
|
const error = ref<string | null>(null)
|
|
|
|
export function useProvinces() {
|
|
// Computed untuk format SelectItem
|
|
const provinceOptions = computed<SelectItem[]>(() => {
|
|
return provincesCache.value.map((province) => ({
|
|
label: toTitleCase(province.name),
|
|
value: province.code,
|
|
// code: province.code,
|
|
searchValue: `${province.code} ${province.name}`.trim(), // Untuk search internal combobox
|
|
}))
|
|
})
|
|
|
|
// Function untuk fetch data provinces
|
|
async function fetchProvinces(forceRefresh = false) {
|
|
// Jika sudah ada data dan tidak force refresh, skip
|
|
if (isInitialized.value && !forceRefresh) {
|
|
return
|
|
}
|
|
|
|
// Jika sedang loading, skip untuk mencegah duplicate calls
|
|
if (isLoading.value) {
|
|
return
|
|
}
|
|
|
|
isLoading.value = true
|
|
error.value = null
|
|
|
|
try {
|
|
const response = await provinceService.getList({
|
|
'page-no-limit': true,
|
|
sort: 'name:asc',
|
|
})
|
|
|
|
if (response.success) {
|
|
provincesCache.value = response.body.data || []
|
|
isInitialized.value = true
|
|
} else {
|
|
error.value = 'Gagal memuat data provinsi'
|
|
console.error('Failed to fetch provinces:', response)
|
|
}
|
|
} catch (err) {
|
|
error.value = 'Terjadi kesalahan saat memuat data provinsi'
|
|
console.error('Error fetching provinces:', err)
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
// Function untuk mencari province berdasarkan code
|
|
function getProvinceByCode(code: string): Province | undefined {
|
|
return provincesCache.value.find((province) => province.code === code)
|
|
}
|
|
|
|
// Function untuk mencari province berdasarkan name
|
|
function getProvinceByName(name: string): Province | undefined {
|
|
return provincesCache.value.find((province) => province.name.toLowerCase() === name.toLowerCase())
|
|
}
|
|
|
|
// Function untuk clear cache (jika diperlukan)
|
|
function clearCache() {
|
|
provincesCache.value = []
|
|
isInitialized.value = false
|
|
error.value = null
|
|
}
|
|
|
|
// Function untuk refresh data
|
|
function refreshProvinces() {
|
|
return fetchProvinces(true)
|
|
}
|
|
|
|
// Auto fetch saat composable pertama kali digunakan
|
|
if (!isInitialized.value && !isLoading.value) {
|
|
fetchProvinces()
|
|
}
|
|
|
|
return {
|
|
// Data
|
|
provinces: readonly(provincesCache),
|
|
provinceOptions,
|
|
|
|
// State
|
|
isLoading: readonly(isLoading),
|
|
isInitialized: readonly(isInitialized),
|
|
error: readonly(error),
|
|
|
|
// Methods
|
|
fetchProvinces,
|
|
refreshProvinces,
|
|
getProvinceByCode,
|
|
getProvinceByName,
|
|
clearCache,
|
|
}
|
|
}
|
|
|
|
// Export untuk direct access ke cached data (jika diperlukan)
|
|
export const useProvincesCache = () => ({
|
|
provinces: readonly(provincesCache),
|
|
isLoading: readonly(isLoading),
|
|
isInitialized: readonly(isInitialized),
|
|
})
|