Files
gameyfin/frontend/components/wizard/Wizard.tsx
T
grimsi a61c8eead0 Layout updates
Added more themed components
Refactored Superadmin creation
2024-05-15 19:43:41 +02:00

92 lines
3.5 KiB
TypeScript

import React, {ReactNode, useState} from "react";
import {Form, Formik, FormikBag, FormikHelpers} from "formik";
import {ArrowLeft, ArrowRight, Check} from "@phosphor-icons/react";
import {Button} from "@nextui-org/react";
import {Step, Stepper} from "@material-tailwind/react";
const Wizard = ({children, initialValues, onSubmit}: {
children: ReactNode,
initialValues: any,
onSubmit: (values: any, bag: FormikHelpers<any> | FormikBag<any, any>) => Promise<any>
}) => {
const [stepNumber, setStepNumber] = useState(0);
const steps = React.Children.toArray(children);
const [snapshot, setSnapshot] = useState(initialValues);
const step = steps[stepNumber];
const totalSteps = steps.length;
const isFirstStep = stepNumber === 0;
const isLastStep = stepNumber === totalSteps - 1;
const next = (values: any) => {
setSnapshot(values);
setStepNumber(Math.min(stepNumber + 1, totalSteps - 1));
};
const previous = (values: any) => {
setSnapshot(values);
setStepNumber(Math.max(stepNumber - 1, 0));
};
const handleSubmit = async (values: any, bag: FormikBag<any, any> | FormikHelpers<any>) => {
/*// @ts-ignore*/
if (step.props.onSubmit) {
/*// @ts-ignore*/
await step.props.onSubmit(values, bag);
}
if (isLastStep) {
return onSubmit(values, bag);
} else {
await bag.setTouched({});
next(values);
}
};
return (
<Formik
initialValues={snapshot}
onSubmit={handleSubmit}
/*// @ts-ignore*/
validationSchema={step.props.validationSchema}
>
{formik => (
<Form className="flex flex-col h-full">
<div className="w-full mb-8">
{/*<p>Step {stepNumber + 1} of {steps.length}</p>*/}
<Stepper activeStep={stepNumber} activeLineClassName="bg-primary"
lineClassName="bg-foreground">
{steps.map((child, index) => (
<Step key={index}
className="bg-foreground text-background"
activeClassName="bg-primary"
completedClassName="bg-primary">
{/*@ts-ignore*/}
{child.props.icon}
</Step>
))}
</Stepper>
</div>
<div className="flex grow">
{step}
</div>
<div className="left-8 right-8 absolute bottom-8 -z-1">
<div className="flex justify-between">
<Button color="primary" onClick={() => previous(formik.values)} disabled={isFirstStep}>
<ArrowLeft/>
</Button>
<Button
color="primary"
isLoading={formik.isSubmitting}
type="submit"
>
{formik.isSubmitting ? "" : isLastStep ? <Check/> : <ArrowRight/>}
</Button>
</div>
</div>
</Form>
)}
</Formik>
);
};
export default Wizard;