'use client'; // src/components/dashboard/teacher/teacher-create-form.tsx // PURPOSE // T.B.A. // import * as React from 'react'; import RouterLink from 'next/link'; import { useRouter } from 'next/navigation'; import { UpdateBillingAddressById } from '@/db/billingAddress/UpdateById'; import { createTeacher } from '@/db/Teachers/Create'; import { getTeacherById } from '@/db/Teachers/GetById'; import { UpdateTeacherById } from '@/db/Teachers/UpdateById'; import { zodResolver } from '@hookform/resolvers/zod'; import { LoadingButton } from '@mui/lab'; // import Avatar from '@mui/material/Avatar'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Card from '@mui/material/Card'; import CardActions from '@mui/material/CardActions'; import CardContent from '@mui/material/CardContent'; import Checkbox from '@mui/material/Checkbox'; import Divider from '@mui/material/Divider'; import FormControl from '@mui/material/FormControl'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormHelperText from '@mui/material/FormHelperText'; import InputLabel from '@mui/material/InputLabel'; import MenuItem from '@mui/material/MenuItem'; import OutlinedInput from '@mui/material/OutlinedInput'; import Select from '@mui/material/Select'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import Grid from '@mui/material/Unstable_Grid2'; // import { Camera as CameraIcon } from '@phosphor-icons/react/dist/ssr/Camera'; // import { Controller, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { z as zod } from 'zod'; import { paths } from '@/paths'; import isDevelopment from '@/lib/check-is-development'; import { logger } from '@/lib/default-logger'; import { base64ToFile, fileToBase64 } from '@/lib/file-to-base64'; import { pb } from '@/lib/pb'; import { Option } from '@/components/core/option'; import { toast } from '@/components/core/toaster'; import FormLoading from '@/components/loading'; // import ErrorDisplay from '../../error'; import ErrorDisplay from '../error'; import type { CreateFormProps } from './type.d'; // TODO: review schema const schema = zod.object({ name: zod.string().min(1, 'Name is required').max(255), email: zod.string().email('Must be a valid email').min(1, 'Email is required').max(255), phone: zod.string().min(1, 'Phone is required').max(25), company: zod.string().max(255).optional(), billingAddress: zod.object({ country: zod.string().min(1, 'Country is required').max(255), state: zod.string().min(1, 'State is required').max(255), city: zod.string().min(1, 'City is required').max(255), zipCode: zod.string().min(1, 'Zip code is required').max(255), line1: zod.string().min(1, 'Street line 1 is required').max(255), line2: zod.string().max(255).optional(), }), taxId: zod.string().max(255).optional(), timezone: zod.string().min(1, 'Timezone is required').max(255), language: zod.string().min(1, 'Language is required').max(255), currency: zod.string().min(1, 'Currency is required').max(255), avatar: zod.string().optional(), }); type Values = zod.infer; const defaultValues = { name: 'new name', email: '123@123.com', phone: '91234567', company: '', billingAddress: { country: 'US', state: '00000', city: 'NY', zipCode: '00000', line1: 'test line 1', line2: 'test line 2', }, taxId: '12345', timezone: 'new_york', language: 'en', currency: 'USD', avatar: '', } satisfies Values; export function TeacherCreateForm(): React.JSX.Element { const router = useRouter(); const { t } = useTranslation(['students']); // const [isUpdating, setIsUpdating] = React.useState(false); const [showLoading, setShowLoading] = React.useState(false); // const [showError, setShowError] = React.useState({ show: false, detail: '' }); const { control, handleSubmit, formState: { errors }, setValue, watch, } = useForm({ defaultValues, resolver: zodResolver(schema) }); const onSubmit = React.useCallback( async (values: Values): Promise => { // Use standard create method from db/Customers/Create const tempCreate: CreateFormProps = { avatar: values.avatar ? await base64ToFile(values.avatar) : null, // name: values.name, email: values.email, phone: values.phone, company: values.company, timezone: values.timezone, language: values.language, currency: values.currency, taxId: values.taxId, state: 'pending', meta: {}, }; try { const record = await createTeacher(tempCreate); toast.success('teacher-created'); router.push(paths.dashboard.teachers.details(record.id)); } catch (err) { logger.error(err); toast.error('failed-to-create-teacher'); } finally { setIsUpdating(false); } }, [router] ); const avatarInputRef = React.useRef(null); const avatar = watch('avatar'); const handleAvatarChange = React.useCallback( async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { const url = await fileToBase64(file); setValue('avatar', url); } }, [setValue] ); return (
} spacing={4} > {t('create.basic-info')} {t('create.avatar')} {t('create.avatarRequirements')} ( Name {errors.name ? {errors.name.message} : null} )} /> ( {t('create.email-address')} {errors.email ? {errors.email.message} : null} )} /> ( {t('create.phone-number')} {errors.phone ? {errors.phone.message} : null} )} /> ( Company {errors.company ? {errors.company.message} : null} )} /> {/* */} {t('create.billing-information')} ( Country {errors.billingAddress?.country ? ( {errors.billingAddress?.country?.message} ) : null} )} /> ( State {errors.billingAddress?.state ? ( {errors.billingAddress?.state?.message} ) : null} )} /> ( City {errors.billingAddress?.city ? ( {errors.billingAddress?.city?.message} ) : null} )} /> ( {t('create.zip-code')} {errors.billingAddress?.zipCode ? ( {errors.billingAddress?.zipCode?.message} ) : null} )} /> ( {t('create.address-line-1')} {errors.billingAddress?.line1 ? ( {errors.billingAddress?.line1?.message} ) : null} )} /> ( Tax ID {errors.taxId ? {errors.taxId.message} : null} )} /> Shipping information } label="Same as billing address" /> {t('create.additional-information')} ( Timezone {errors.timezone ? {errors.timezone.message} : null} )} /> ( Language {errors.language ? {errors.language.message} : null} )} /> ( {t('create.currency')} {errors.currency ? {errors.currency.message} : null} )} /> {t('create.updateButton')}
{JSON.stringify({ errors }, null, 2)}
); }