Add TSX form
This commit is contained in:
114
ui/package-lock.json
generated
114
ui/package-lock.json
generated
@@ -17,9 +17,11 @@
|
|||||||
"@mui/material-nextjs": "^7.1.1",
|
"@mui/material-nextjs": "^7.1.1",
|
||||||
"@mui/system": "^7.1.1",
|
"@mui/system": "^7.1.1",
|
||||||
"axios": "^1.10.0",
|
"axios": "^1.10.0",
|
||||||
|
"formik": "^2.4.6",
|
||||||
"next": "15.3.4",
|
"next": "15.3.4",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0"
|
"react-dom": "^19.0.0",
|
||||||
|
"yup": "^1.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3",
|
"@eslint/eslintrc": "^3",
|
||||||
@@ -1918,6 +1920,16 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/hoist-non-react-statics": {
|
||||||
|
"version": "3.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz",
|
||||||
|
"integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"hoist-non-react-statics": "^3.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
"version": "7.0.15",
|
"version": "7.0.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||||
@@ -3210,6 +3222,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/deepmerge": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/define-data-property": {
|
"node_modules/define-data-property": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||||
@@ -4141,6 +4162,31 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/formik": {
|
||||||
|
"version": "2.4.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz",
|
||||||
|
"integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://opencollective.com/formik"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
|
"deepmerge": "^2.1.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"react-fast-compare": "^2.0.1",
|
||||||
|
"tiny-warning": "^1.0.2",
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
@@ -5319,6 +5365,18 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/lodash-es": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/lodash.merge": {
|
"node_modules/lodash.merge": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
@@ -5936,6 +5994,12 @@
|
|||||||
"react-is": "^16.13.1"
|
"react-is": "^16.13.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/property-expr": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/proxy-from-env": {
|
"node_modules/proxy-from-env": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
@@ -5994,6 +6058,12 @@
|
|||||||
"react": "^19.1.0"
|
"react": "^19.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-fast-compare": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
@@ -6693,6 +6763,18 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tiny-case": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/tiny-warning": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tinyglobby": {
|
"node_modules/tinyglobby": {
|
||||||
"version": "0.2.14",
|
"version": "0.2.14",
|
||||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
|
||||||
@@ -6751,6 +6833,12 @@
|
|||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/toposort": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ts-api-utils": {
|
"node_modules/ts-api-utils": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
||||||
@@ -6796,6 +6884,18 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/type-fest": {
|
||||||
|
"version": "2.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||||
|
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
|
||||||
|
"license": "(MIT OR CC0-1.0)",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typed-array-buffer": {
|
"node_modules/typed-array-buffer": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
||||||
@@ -7114,6 +7214,18 @@
|
|||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yup": {
|
||||||
|
"version": "1.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yup/-/yup-1.6.1.tgz",
|
||||||
|
"integrity": "sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"property-expr": "^2.0.5",
|
||||||
|
"tiny-case": "^1.0.3",
|
||||||
|
"toposort": "^2.0.2",
|
||||||
|
"type-fest": "^2.19.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,11 @@
|
|||||||
"@mui/material-nextjs": "^7.1.1",
|
"@mui/material-nextjs": "^7.1.1",
|
||||||
"@mui/system": "^7.1.1",
|
"@mui/system": "^7.1.1",
|
||||||
"axios": "^1.10.0",
|
"axios": "^1.10.0",
|
||||||
|
"formik": "^2.4.6",
|
||||||
"next": "15.3.4",
|
"next": "15.3.4",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0"
|
"react-dom": "^19.0.0",
|
||||||
|
"yup": "^1.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3",
|
"@eslint/eslintrc": "^3",
|
||||||
|
|||||||
@@ -0,0 +1,392 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
TextField,
|
||||||
|
Button,
|
||||||
|
Typography,
|
||||||
|
Grid,
|
||||||
|
MenuItem,
|
||||||
|
FormControl,
|
||||||
|
InputLabel,
|
||||||
|
Select,
|
||||||
|
FormHelperText,
|
||||||
|
Chip,
|
||||||
|
Avatar,
|
||||||
|
Container,
|
||||||
|
SelectChangeEvent,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { useFormik, FormikHelpers } from 'formik';
|
||||||
|
import * as yup from 'yup';
|
||||||
|
import PersonIcon from '@mui/icons-material/Person';
|
||||||
|
import EmailIcon from '@mui/icons-material/Email';
|
||||||
|
import PhoneIcon from '@mui/icons-material/Phone';
|
||||||
|
import WorkIcon from '@mui/icons-material/Work';
|
||||||
|
import SendIcon from '@mui/icons-material/Send';
|
||||||
|
|
||||||
|
interface FormValues {
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
email: string;
|
||||||
|
phone: string;
|
||||||
|
age: string | number;
|
||||||
|
department: string;
|
||||||
|
skills: string[];
|
||||||
|
bio: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const validationSchema = yup.object<FormValues>({
|
||||||
|
firstName: yup
|
||||||
|
.string()
|
||||||
|
.min(2, 'First name should be at least 2 characters')
|
||||||
|
.required('First name is required'),
|
||||||
|
lastName: yup
|
||||||
|
.string()
|
||||||
|
.min(2, 'Last name should be at least 2 characters')
|
||||||
|
.required('Last name is required'),
|
||||||
|
email: yup
|
||||||
|
.string()
|
||||||
|
.email('Enter a valid email')
|
||||||
|
.required('Email is required'),
|
||||||
|
phone: yup
|
||||||
|
.string()
|
||||||
|
.matches(/^[\+]?[1-9][\d]{0,15}$/, 'Enter a valid phone number')
|
||||||
|
.required('Phone number is required'),
|
||||||
|
age: yup
|
||||||
|
.number()
|
||||||
|
.min(18, 'Must be at least 18 years old')
|
||||||
|
.max(120, 'Must be less than 120 years old')
|
||||||
|
.required('Age is required'),
|
||||||
|
department: yup
|
||||||
|
.string()
|
||||||
|
.required('Department is required'),
|
||||||
|
skills: yup
|
||||||
|
.array()
|
||||||
|
.of(yup.string())
|
||||||
|
.min(1, 'Select at least one skill')
|
||||||
|
.required('Skills are required'),
|
||||||
|
bio: yup
|
||||||
|
.string()
|
||||||
|
.min(10, 'Bio should be at least 10 characters')
|
||||||
|
.max(500, 'Bio should not exceed 500 characters')
|
||||||
|
.required('Bio is required'),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const departments: string[] = [
|
||||||
|
'Engineering',
|
||||||
|
'Marketing',
|
||||||
|
'Sales',
|
||||||
|
'HR',
|
||||||
|
'Finance',
|
||||||
|
'Operations',
|
||||||
|
'Design',
|
||||||
|
];
|
||||||
|
|
||||||
|
const skillOptions: string[] = [
|
||||||
|
'JavaScript',
|
||||||
|
'React',
|
||||||
|
'Node.js',
|
||||||
|
'Python',
|
||||||
|
'UI/UX Design',
|
||||||
|
'Project Management',
|
||||||
|
'Data Analysis',
|
||||||
|
'Marketing',
|
||||||
|
'Sales',
|
||||||
|
'Communication',
|
||||||
|
];
|
||||||
|
|
||||||
|
const FormPage: React.FC = () => {
|
||||||
|
const formik = useFormik<FormValues>({
|
||||||
|
initialValues: {
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
email: '',
|
||||||
|
phone: '',
|
||||||
|
age: '',
|
||||||
|
department: '',
|
||||||
|
skills: [],
|
||||||
|
bio: '',
|
||||||
|
},
|
||||||
|
validationSchema: validationSchema,
|
||||||
|
onSubmit: (values: FormValues, { setSubmitting, resetForm }: FormikHelpers<FormValues>) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('Form submitted:', values);
|
||||||
|
alert('Form submitted successfully!');
|
||||||
|
setSubmitting(false);
|
||||||
|
resetForm();
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSkillChange = (event: SelectChangeEvent<string[]>): void => {
|
||||||
|
const value = event.target.value;
|
||||||
|
formik.setFieldValue('skills', typeof value === 'string' ? value.split(',') : value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
minHeight: '100vh',
|
||||||
|
background: (theme) =>
|
||||||
|
theme.palette.mode === 'dark'
|
||||||
|
? 'linear-gradient(135deg, #0f0f23 0%, #1a1a2e 50%, #16213e 100%)'
|
||||||
|
: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||||||
|
py: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Container maxWidth="sm">
|
||||||
|
<Card
|
||||||
|
elevation={8}
|
||||||
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
background: (theme) =>
|
||||||
|
theme.palette.mode === 'dark'
|
||||||
|
? 'rgba(26, 26, 46, 0.95)'
|
||||||
|
: 'rgba(255, 255, 255, 0.95)',
|
||||||
|
backdropFilter: 'blur(10px)',
|
||||||
|
border: (theme) =>
|
||||||
|
theme.palette.mode === 'dark'
|
||||||
|
? '1px solid rgba(99, 102, 241, 0.2)'
|
||||||
|
: '1px solid rgba(255, 255, 255, 0.3)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent sx={{ p: 4 }}>
|
||||||
|
<Box
|
||||||
|
display="flex"
|
||||||
|
flexDirection="column"
|
||||||
|
alignItems="center"
|
||||||
|
mb={4}
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
sx={{
|
||||||
|
bgcolor: 'primary.main',
|
||||||
|
width: 56,
|
||||||
|
height: 56,
|
||||||
|
mb: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PersonIcon fontSize="large" />
|
||||||
|
</Avatar>
|
||||||
|
<Typography
|
||||||
|
variant="h4"
|
||||||
|
component="h1"
|
||||||
|
fontWeight="bold"
|
||||||
|
color="primary"
|
||||||
|
textAlign="center"
|
||||||
|
>
|
||||||
|
User Registration
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="subtitle1" color="text.secondary" textAlign="center">
|
||||||
|
Please fill out all required fields
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<form onSubmit={formik.handleSubmit}>
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
||||||
|
<Typography variant="h6" color="primary" sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<PersonIcon /> Personal Information
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid size={{ xs: 6 }}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="firstName"
|
||||||
|
name="firstName"
|
||||||
|
label="First Name"
|
||||||
|
value={formik.values.firstName}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.touched.firstName && Boolean(formik.errors.firstName)}
|
||||||
|
helperText={formik.touched.firstName && formik.errors.firstName}
|
||||||
|
variant="outlined"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid size={{ xs: 6 }}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="lastName"
|
||||||
|
name="lastName"
|
||||||
|
label="Last Name"
|
||||||
|
value={formik.values.lastName}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.touched.lastName && Boolean(formik.errors.lastName)}
|
||||||
|
helperText={formik.touched.lastName && formik.errors.lastName}
|
||||||
|
variant="outlined"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="email"
|
||||||
|
name="email"
|
||||||
|
label="Email Address"
|
||||||
|
type="email"
|
||||||
|
value={formik.values.email}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.touched.email && Boolean(formik.errors.email)}
|
||||||
|
helperText={formik.touched.email && formik.errors.email}
|
||||||
|
variant="outlined"
|
||||||
|
InputProps={{
|
||||||
|
startAdornment: <EmailIcon sx={{ color: 'action.active', mr: 1 }} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="phone"
|
||||||
|
name="phone"
|
||||||
|
label="Phone Number"
|
||||||
|
value={formik.values.phone}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.touched.phone && Boolean(formik.errors.phone)}
|
||||||
|
helperText={formik.touched.phone && formik.errors.phone}
|
||||||
|
variant="outlined"
|
||||||
|
InputProps={{
|
||||||
|
startAdornment: <PhoneIcon sx={{ color: 'action.active', mr: 1 }} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="age"
|
||||||
|
name="age"
|
||||||
|
label="Age"
|
||||||
|
type="number"
|
||||||
|
value={formik.values.age}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.touched.age && Boolean(formik.errors.age)}
|
||||||
|
helperText={formik.touched.age && formik.errors.age}
|
||||||
|
variant="outlined"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Typography variant="h6" color="primary" sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: 2 }}>
|
||||||
|
<WorkIcon /> Professional Information
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<FormControl
|
||||||
|
fullWidth
|
||||||
|
error={formik.touched.department && Boolean(formik.errors.department)}
|
||||||
|
>
|
||||||
|
<InputLabel id="department-label">Department</InputLabel>
|
||||||
|
<Select
|
||||||
|
labelId="department-label"
|
||||||
|
id="department"
|
||||||
|
name="department"
|
||||||
|
value={formik.values.department}
|
||||||
|
label="Department"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
>
|
||||||
|
{departments.map((dept: string) => (
|
||||||
|
<MenuItem key={dept} value={dept}>
|
||||||
|
{dept}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
{formik.touched.department && formik.errors.department && (
|
||||||
|
<FormHelperText>{formik.errors.department}</FormHelperText>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormControl
|
||||||
|
fullWidth
|
||||||
|
error={formik.touched.skills && Boolean(formik.errors.skills)}
|
||||||
|
>
|
||||||
|
<InputLabel id="skills-label">Skills</InputLabel>
|
||||||
|
<Select
|
||||||
|
labelId="skills-label"
|
||||||
|
id="skills"
|
||||||
|
multiple
|
||||||
|
value={formik.values.skills}
|
||||||
|
onChange={handleSkillChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
label="Skills"
|
||||||
|
renderValue={(selected: string[]) => (
|
||||||
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
|
||||||
|
{selected.map((value: string) => (
|
||||||
|
<Chip key={value} label={value} size="small" />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{skillOptions.map((skill: string) => (
|
||||||
|
<MenuItem key={skill} value={skill}>
|
||||||
|
{skill}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
{formik.touched.skills && formik.errors.skills && (
|
||||||
|
<FormHelperText>{formik.errors.skills}</FormHelperText>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="bio"
|
||||||
|
name="bio"
|
||||||
|
label="Bio"
|
||||||
|
multiline
|
||||||
|
rows={4}
|
||||||
|
value={formik.values.bio}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.touched.bio && Boolean(formik.errors.bio)}
|
||||||
|
helperText={
|
||||||
|
formik.touched.bio && formik.errors.bio
|
||||||
|
? formik.errors.bio
|
||||||
|
: `${formik.values.bio.length}/500 characters`
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
placeholder="Tell us about yourself..."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
variant="contained"
|
||||||
|
fullWidth
|
||||||
|
size="large"
|
||||||
|
type="submit"
|
||||||
|
disabled={formik.isSubmitting}
|
||||||
|
startIcon={<SendIcon />}
|
||||||
|
sx={{
|
||||||
|
mt: 2,
|
||||||
|
py: 1.5,
|
||||||
|
borderRadius: 3,
|
||||||
|
background: (theme) =>
|
||||||
|
theme.palette.mode === 'dark'
|
||||||
|
? 'linear-gradient(45deg, #6366f1 30%, #8b5cf6 90%)'
|
||||||
|
: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
|
||||||
|
boxShadow: (theme) =>
|
||||||
|
theme.palette.mode === 'dark'
|
||||||
|
? '0 3px 5px 2px rgba(99, 102, 241, .3)'
|
||||||
|
: '0 3px 5px 2px rgba(255, 105, 135, .3)',
|
||||||
|
'&:hover': {
|
||||||
|
background: (theme) =>
|
||||||
|
theme.palette.mode === 'dark'
|
||||||
|
? 'linear-gradient(45deg, #5b21b6 60%, #7c3aed 100%)'
|
||||||
|
: 'linear-gradient(45deg, #FE6B8B 60%, #FF8E53 100%)',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{formik.isSubmitting ? 'Submitting...' : 'Submit Registration'}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</form>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormPage;
|
||||||
Reference in New Issue
Block a user