diff --git a/002_source/cms/src/app/dashboard/lesson_categories/create/page.tsx b/002_source/cms/src/app/dashboard/lesson_categories/create/page.tsx
new file mode 100644
index 0000000..e69b0c4
--- /dev/null
+++ b/002_source/cms/src/app/dashboard/lesson_categories/create/page.tsx
@@ -0,0 +1,49 @@
+'use client';
+
+import * as React from 'react';
+
+import RouterLink from 'next/link';
+import Box from '@mui/material/Box';
+import Link from '@mui/material/Link';
+import Stack from '@mui/material/Stack';
+import Typography from '@mui/material/Typography';
+import { ArrowLeft as ArrowLeftIcon } from '@phosphor-icons/react/dist/ssr/ArrowLeft';
+
+import { config } from '@/config';
+import { paths } from '@/paths';
+import { CustomerCreateForm } from '@/components/dashboard/lesson_category/lesson-category-create-form';
+
+
+export default function Page(): React.JSX.Element {
+ return (
+
+
+
+
+
+
+ Lesson Categories
+
+
+
+ Create customer
+
+
+
+
+
+ );
+}
diff --git a/002_source/cms/src/components/dashboard/lesson_category/lesson-category-create-form.tsx b/002_source/cms/src/components/dashboard/lesson_category/lesson-category-create-form.tsx
new file mode 100644
index 0000000..c8c4f35
--- /dev/null
+++ b/002_source/cms/src/components/dashboard/lesson_category/lesson-category-create-form.tsx
@@ -0,0 +1,398 @@
+'use client';
+
+import * as React from 'react';
+import RouterLink from 'next/link';
+import { useRouter } from 'next/navigation';
+import { zodResolver } from '@hookform/resolvers/zod';
+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 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 { z as zod } from 'zod';
+
+import { paths } from '@/paths';
+import { logger } from '@/lib/default-logger';
+import { Option } from '@/components/core/option';
+import { toast } from '@/components/core/toaster';
+
+function fileToBase64(file: Blob): Promise {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.readAsDataURL(file);
+ reader.onload = () => {
+ resolve(reader.result as string);
+ };
+ reader.onerror = () => {
+ reject(new Error('Error converting file to base64'));
+ };
+ });
+}
+
+const schema = zod.object({
+ avatar: zod.string().optional(),
+ 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(15),
+ company: zod.string().max(255),
+ 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),
+});
+
+type Values = zod.infer;
+
+const defaultValues = {
+ avatar: '',
+ name: '',
+ email: '',
+ phone: '',
+ company: '',
+ billingAddress: { country: '', state: '', city: '', zipCode: '', line1: '', line2: '' },
+ taxId: '',
+ timezone: 'new_york',
+ language: 'en',
+ currency: 'USD',
+} satisfies Values;
+
+export function CustomerCreateForm(): React.JSX.Element {
+ const router = useRouter();
+
+ const {
+ control,
+ handleSubmit,
+ formState: { errors },
+ setValue,
+ watch,
+ } = useForm({ defaultValues, resolver: zodResolver(schema) });
+
+ const onSubmit = React.useCallback(
+ async (_: Values): Promise => {
+ try {
+ // Make API request
+ toast.success('Customer updated');
+ router.push(paths.dashboard.lesson_categories.details('1'));
+ } catch (err) {
+ logger.error(err);
+ toast.error('Something went wrong!');
+ }
+ },
+ [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 (
+
+ );
+}