mirror of
https://git.hmsn.ink/kospo/svcm/oa.git
synced 2026-03-20 11:53:38 +09:00
first
This commit is contained in:
120
src/composables/wizard.ts
Normal file
120
src/composables/wizard.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import type { InjectionKey } from 'vue'
|
||||
|
||||
/**
|
||||
* Using typescript types allow better developer experience
|
||||
* with autocompletion and compiler error prechecking
|
||||
*/
|
||||
import type { WizardData } from '/@src/types/wizard'
|
||||
|
||||
interface WizardStepOptions {
|
||||
number: number
|
||||
canNavigate?: boolean
|
||||
previousStepFn?: () => Promise<void>
|
||||
validateStepFn?: () => Promise<void>
|
||||
}
|
||||
|
||||
export type WizardContext = ReturnType<typeof createWizardContext>
|
||||
export const useWizardSymbolContext = Symbol('wizard') as InjectionKey<WizardContext>
|
||||
|
||||
function createWizardContext() {
|
||||
const step = ref(1)
|
||||
const loading = ref(false)
|
||||
const canNavigate = ref(false)
|
||||
const previousStepFn = shallowRef<WizardStepOptions['previousStepFn'] | null>()
|
||||
const validateStepFn = shallowRef<WizardStepOptions['validateStepFn'] | null>()
|
||||
const data = reactive<WizardData>({
|
||||
name: '',
|
||||
description: '',
|
||||
relatedTo: 'UI/UX Design',
|
||||
logo: null,
|
||||
timeFrame: ref({
|
||||
start: new Date(),
|
||||
end: new Date(),
|
||||
}),
|
||||
budget: '< 5K',
|
||||
attachments: [],
|
||||
teammates: [],
|
||||
tools: [],
|
||||
customer: null,
|
||||
})
|
||||
|
||||
const stepTitle = computed(() => {
|
||||
switch (step.value) {
|
||||
case 2:
|
||||
return 'Project Info'
|
||||
case 3:
|
||||
return 'Project Details'
|
||||
case 4:
|
||||
return 'Project Files'
|
||||
case 5:
|
||||
return 'Team Members'
|
||||
case 6:
|
||||
return 'Project Tools'
|
||||
case 7:
|
||||
return 'Preview'
|
||||
case 8:
|
||||
return 'Finish'
|
||||
case 1:
|
||||
default:
|
||||
return 'Project Type'
|
||||
}
|
||||
})
|
||||
|
||||
function setLoading(value: boolean) {
|
||||
loading.value = value
|
||||
}
|
||||
function setStep(options?: WizardStepOptions) {
|
||||
step.value = options?.number || 1
|
||||
canNavigate.value = options?.canNavigate ?? false
|
||||
previousStepFn.value = options?.previousStepFn ?? null
|
||||
validateStepFn.value = options?.validateStepFn ?? null
|
||||
}
|
||||
|
||||
async function save() {
|
||||
loading.value = true
|
||||
|
||||
// simulate saving data
|
||||
await sleep(2000)
|
||||
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
function reset() {
|
||||
data.name = ''
|
||||
data.description = ''
|
||||
data.relatedTo = 'UI/UX Design'
|
||||
data.logo = null
|
||||
data.timeFrame = {
|
||||
start: new Date(),
|
||||
end: new Date(),
|
||||
}
|
||||
data.budget = '< 5K'
|
||||
data.attachments = []
|
||||
data.teammates = []
|
||||
data.tools = []
|
||||
data.customer = null
|
||||
}
|
||||
|
||||
return reactive({
|
||||
canNavigate,
|
||||
previousStepFn,
|
||||
validateStepFn,
|
||||
step,
|
||||
loading,
|
||||
stepTitle,
|
||||
data,
|
||||
setLoading,
|
||||
setStep,
|
||||
save,
|
||||
reset,
|
||||
})
|
||||
}
|
||||
|
||||
export function useWizard() {
|
||||
let context = inject(useWizardSymbolContext, undefined)
|
||||
if (!context) {
|
||||
context = createWizardContext()
|
||||
provide(useWizardSymbolContext, context)
|
||||
}
|
||||
return context
|
||||
}
|
||||
Reference in New Issue
Block a user