Initial commit: fabric-trade-admin panel with responsive layouts and UI refinements.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { ref } from 'vue'
|
||||
import { useToast } from '@/composables/useToast'
|
||||
|
||||
export function mockPersistToggle(delayMs = 480): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
window.setTimeout(resolve, delayMs)
|
||||
})
|
||||
}
|
||||
|
||||
export function useAsyncToggle(options: {
|
||||
onPersist: (value: boolean) => Promise<void>
|
||||
successMessage?: (value: boolean) => string
|
||||
errorMessage?: string
|
||||
confirmOff?: () => Promise<boolean>
|
||||
}) {
|
||||
const loadingId = ref<string | null>(null)
|
||||
const errorId = ref<string | null>(null)
|
||||
const toast = useToast()
|
||||
|
||||
async function toggle(id: string, current: boolean): Promise<boolean> {
|
||||
if (loadingId.value) return current
|
||||
|
||||
const next = !current
|
||||
|
||||
if (!next && options.confirmOff) {
|
||||
const confirmed = await options.confirmOff()
|
||||
if (!confirmed) return current
|
||||
}
|
||||
|
||||
loadingId.value = id
|
||||
errorId.value = null
|
||||
const previous = current
|
||||
|
||||
try {
|
||||
await options.onPersist(next)
|
||||
toast.success(options.successMessage?.(next) ?? (next ? 'وضعیت فعال شد.' : 'وضعیت غیرفعال شد.'))
|
||||
return next
|
||||
} catch {
|
||||
errorId.value = id
|
||||
toast.error(options.errorMessage ?? 'بهروزرسانی وضعیت انجام نشد.')
|
||||
return previous
|
||||
} finally {
|
||||
loadingId.value = null
|
||||
}
|
||||
}
|
||||
|
||||
function isLoading(id: string) {
|
||||
return loadingId.value === id
|
||||
}
|
||||
|
||||
function hasError(id: string) {
|
||||
return errorId.value === id
|
||||
}
|
||||
|
||||
return { toggle, isLoading, hasError }
|
||||
}
|
||||
Reference in New Issue
Block a user