```
refactor Student and Teacher create/edit forms to implement i18n support, update UI components, and standardize API calls ```
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
'use client';
|
||||
|
||||
// src/components/dashboard/teacher/teacher-edit-form.tsx
|
||||
// PURPOSE:
|
||||
// handle change details for teachers collection
|
||||
//
|
||||
import * as React from 'react';
|
||||
import RouterLink from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
//
|
||||
import { COL_USER_METAS } from '@/constants';
|
||||
import { UpdateBillingAddressById } from '@/db/billingAddress/UpdateById';
|
||||
import { getTeacherById } from '@/db/Teachers/GetById';
|
||||
import { UpdateTeacherById } from '@/db/Teachers/UpdateById';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
//
|
||||
@@ -37,14 +41,15 @@ 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 getImageUrlFromFile from '@/lib/get-image-url-from-file.ts';
|
||||
import { toast } from '@/components/core/toaster';
|
||||
import FormLoading from '@/components/loading';
|
||||
|
||||
// import ErrorDisplay from '../../error';
|
||||
import ErrorDisplay from '../error';
|
||||
import type { Teacher } from './type.d';
|
||||
|
||||
// TODO: review this
|
||||
// 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),
|
||||
@@ -89,7 +94,7 @@ const defaultValues = {
|
||||
|
||||
export function TeacherEditForm(): React.JSX.Element {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation(['lp_categories']);
|
||||
const { t } = useTranslation(['teachers']);
|
||||
|
||||
const { id: teacherId } = useParams<{ id: string }>();
|
||||
//
|
||||
@@ -97,6 +102,7 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
const [showLoading, setShowLoading] = React.useState<boolean>(false);
|
||||
//
|
||||
const [showError, setShowError] = React.useState({ show: false, detail: '' });
|
||||
const [billingAddressId, setBillingAddressId] = React.useState<string | null>(null);
|
||||
|
||||
const {
|
||||
control,
|
||||
@@ -116,7 +122,9 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
email: values.email,
|
||||
phone: values.phone,
|
||||
company: values.company,
|
||||
billingAddress: values.billingAddress,
|
||||
//
|
||||
// billingAddress: values.billingAddress,
|
||||
//
|
||||
taxId: values.taxId,
|
||||
timezone: values.timezone,
|
||||
language: values.language,
|
||||
@@ -125,12 +133,17 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
};
|
||||
|
||||
try {
|
||||
await pb.collection(COL_USER_METAS).update(teacherId, updateData);
|
||||
toast.success('Teacher updated successfully');
|
||||
await UpdateTeacherById(teacherId, updateData);
|
||||
//
|
||||
toast.success(t('teacher-updated-successfully'));
|
||||
router.push(paths.dashboard.teachers.list);
|
||||
|
||||
if (billingAddressId) {
|
||||
await UpdateBillingAddressById(billingAddressId, values.billingAddress);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
toast.error('Failed to update teacher');
|
||||
toast.error(t('failed-to-update-teacher'));
|
||||
} finally {
|
||||
setIsUpdating(false);
|
||||
}
|
||||
@@ -164,21 +177,21 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
setShowLoading(true);
|
||||
|
||||
try {
|
||||
const result = await pb.collection(COL_USER_METAS).getOne(id);
|
||||
const result = (await getTeacherById(id)) as unknown as Teacher;
|
||||
//
|
||||
reset({ ...defaultValues, ...result });
|
||||
console.log({ result });
|
||||
|
||||
setBillingAddressId(result.billingAddress.id);
|
||||
|
||||
if (result.avatar) {
|
||||
const fetchResult = await fetch(
|
||||
`http://127.0.0.1:8090/api/files/${result.collectionId}/${result.id}/${result.avatar}`
|
||||
);
|
||||
const fetchResult = await fetch(getImageUrlFromFile(result.collectionId, result.id, result.avatar));
|
||||
const blob = await fetchResult.blob();
|
||||
const url = await fileToBase64(blob);
|
||||
setValue('avatar', url);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
toast.error('Failed to load teacher data');
|
||||
toast.error(t('failed-to-load-teacher-data'));
|
||||
setShowError({ show: true, detail: JSON.stringify(error, null, 2) });
|
||||
} finally {
|
||||
setShowLoading(false);
|
||||
@@ -301,7 +314,7 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
error={Boolean(errors.email)}
|
||||
fullWidth
|
||||
>
|
||||
<InputLabel required>Email</InputLabel>
|
||||
<InputLabel required>{t('edit.email-address')}</InputLabel>
|
||||
<OutlinedInput
|
||||
{...field}
|
||||
type="email"
|
||||
@@ -323,7 +336,7 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
error={Boolean(errors.phone)}
|
||||
fullWidth
|
||||
>
|
||||
<InputLabel required>Phone</InputLabel>
|
||||
<InputLabel required>{t('edit.phone-number')}</InputLabel>
|
||||
<OutlinedInput {...field} />
|
||||
{errors.phone ? <FormHelperText>{errors.phone.message}</FormHelperText> : null}
|
||||
</FormControl>
|
||||
@@ -352,11 +365,12 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
{/* */}
|
||||
</Grid>
|
||||
</Stack>
|
||||
{/* */}
|
||||
<Stack spacing={3}>
|
||||
<Typography variant="h6">Billing Information</Typography>
|
||||
<Typography variant="h6">{t('edit.billing-information')}</Typography>
|
||||
<Grid
|
||||
container
|
||||
spacing={3}
|
||||
@@ -375,9 +389,12 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
>
|
||||
<InputLabel required>Country</InputLabel>
|
||||
<Select {...field}>
|
||||
<MenuItem value="">No Country selected</MenuItem>
|
||||
<MenuItem value="US">United States</MenuItem>
|
||||
<MenuItem value="UK">United Kingdom</MenuItem>
|
||||
<MenuItem value="CA">Canada</MenuItem>
|
||||
<MenuItem value="DE">Germany</MenuItem>
|
||||
<MenuItem value="ES">Spain</MenuItem>
|
||||
</Select>
|
||||
{errors.billingAddress?.country ? (
|
||||
<FormHelperText>{errors.billingAddress.country.message}</FormHelperText>
|
||||
@@ -440,7 +457,7 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
error={Boolean(errors.billingAddress?.zipCode)}
|
||||
fullWidth
|
||||
>
|
||||
<InputLabel required>Zip Code</InputLabel>
|
||||
<InputLabel required>{t('edit.zip-code')}</InputLabel>
|
||||
<OutlinedInput {...field} />
|
||||
{errors.billingAddress?.zipCode ? (
|
||||
<FormHelperText>{errors.billingAddress.zipCode.message}</FormHelperText>
|
||||
@@ -461,7 +478,7 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
error={Boolean(errors.billingAddress?.line1)}
|
||||
fullWidth
|
||||
>
|
||||
<InputLabel required>Address Line 1</InputLabel>
|
||||
<InputLabel required>{t('edit.address-line-1')}</InputLabel>
|
||||
<OutlinedInput {...field} />
|
||||
{errors.billingAddress?.line1 ? (
|
||||
<FormHelperText>{errors.billingAddress.line1.message}</FormHelperText>
|
||||
@@ -496,7 +513,7 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
</Stack>
|
||||
|
||||
<Stack spacing={3}>
|
||||
<Typography variant="h6">Additional Information</Typography>
|
||||
<Typography variant="h6">{t('edit.additional-information')}</Typography>
|
||||
<Grid
|
||||
container
|
||||
spacing={3}
|
||||
@@ -543,8 +560,10 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
>
|
||||
<InputLabel required>Language</InputLabel>
|
||||
<Select {...field}>
|
||||
<MenuItem value="">no language selected</MenuItem>
|
||||
<MenuItem value="en">English</MenuItem>
|
||||
<MenuItem value="es">Spanish</MenuItem>
|
||||
<MenuItem value="de">German</MenuItem>
|
||||
<MenuItem value="fr">French</MenuItem>
|
||||
</Select>
|
||||
{errors.language ? <FormHelperText>{errors.language.message}</FormHelperText> : null}
|
||||
@@ -564,8 +583,9 @@ export function TeacherEditForm(): React.JSX.Element {
|
||||
error={Boolean(errors.currency)}
|
||||
fullWidth
|
||||
>
|
||||
<InputLabel required>Currency</InputLabel>
|
||||
<InputLabel required>{t('edit.currency')}</InputLabel>
|
||||
<Select {...field}>
|
||||
<MenuItem value="">no currency selected</MenuItem>
|
||||
<MenuItem value="USD">USD</MenuItem>
|
||||
<MenuItem value="EUR">EUR</MenuItem>
|
||||
<MenuItem value="GBP">GBP</MenuItem>
|
||||
|
Reference in New Issue
Block a user