mirror of
https://git.hmsn.ink/kospo/svcm/oa.git
synced 2026-03-20 07:53:48 +09:00
121 lines
2.7 KiB
TypeScript
121 lines
2.7 KiB
TypeScript
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
|
|
}
|