Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7858467
fix: replace Material Symbols icon with MUI ExpandMore icon in naviga…
117Isabell Nov 2, 2025
15a71d1
feat: create reusable RHF CheckboxGroup component with Other option s…
117Isabell Nov 2, 2025
4273e51
feat: create reusable RHF RadioGroup component
117Isabell Nov 2, 2025
55da6be
feat: create Zod schema for mentee registration form validation
117Isabell Nov 2, 2025
34127e4
feat: add mentee registration form background image
117Isabell Nov 2, 2025
3683c65
Merge branch 'Women-Coding-Community:main' into feat/mentee-registrat…
117Isabell Nov 2, 2025
1df93e3
feat: add form libraries
117Isabell Nov 2, 2025
b998f08
Rename RHF form components to remove RHF prefix
117Isabell Nov 9, 2025
1e67a07
Add path aliases for schemas and update component imports
117Isabell Nov 9, 2025
47891ae
Add forms index file and use @components for form imports
117Isabell Nov 9, 2025
37132c7
Merge branch 'main' into feat/mentee-registration-form
117Isabell Nov 30, 2025
3fe6805
fix: replace Material Symbols icon with MUI ExpandMore icon in naviga…
117Isabell Nov 2, 2025
40ce841
feat: create reusable RHF CheckboxGroup component with Other option s…
117Isabell Nov 2, 2025
d7436a5
feat: create reusable RHF RadioGroup component
117Isabell Nov 2, 2025
0eacfa0
feat: create Zod schema for mentee registration form validation
117Isabell Nov 2, 2025
101be14
feat: add mentee registration form background image
117Isabell Nov 2, 2025
45cf5e8
feat: add form libraries
117Isabell Nov 2, 2025
d53a827
Rename RHF form components to remove RHF prefix
117Isabell Nov 9, 2025
9412cc9
Add path aliases for schemas and update component imports
117Isabell Nov 9, 2025
db9f2d8
Add forms index file and use @components for form imports
117Isabell Nov 9, 2025
ed44a30
Merge remote-tracking branch 'origin/feat/mentee-registration-form' i…
117Isabell Jan 4, 2026
174c2b8
Merge branch 'main' into feat/mentee-registration-form
117Isabell Jan 4, 2026
a5bb54d
refactor: reorganize imports in mentorship pages
117Isabell Jan 4, 2026
e77bbd4
chore: update pnpm-lock.yaml to sync with package.json
117Isabell Jan 4, 2026
090125b
Merge branch 'main' into feat/mentee-registration-form
117Isabell Jan 18, 2026
40d1bca
feat: replace placeholder text with mentee registration description
117Isabell Jan 24, 2026
33bcc4e
style: format mentee registration description with paragraphs and links
117Isabell Jan 24, 2026
4384125
feat: update the mentee basic information based on Google form
117Isabell Jan 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@
"settings": {
"react": {
"version": "detect"
},
"import/resolver": {
"typescript": {
"alwaysTryTypes": true,
"project": "./tsconfig.json"
}
}
}
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@hookform/resolvers": "^5.2.2",
"@mui/icons-material": "^5.15.18",
"@mui/material": "^5.15.18",
"@testing-library/dom": "^10.1.0",
Expand All @@ -29,7 +30,9 @@
"next": "14.2.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"ts-jest": "^29.1.2"
"react-hook-form": "^7.66.0",
"ts-jest": "^29.1.2",
"zod": "^4.1.12"
},
"devDependencies": {
"@playwright/test": "^1.57.0",
Expand Down
39 changes: 39 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/mentee-form-bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
105 changes: 105 additions & 0 deletions src/components/forms/CheckboxGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {
FormControl,
FormLabel,
FormGroup,
FormControlLabel,
Checkbox,
FormHelperText,
TextField as MuiTextField,
} from '@mui/material';
import { Controller, Control, FieldPath, FieldValues } from 'react-hook-form';

interface CheckboxGroupProps<T extends FieldValues> {
name: FieldPath<T>;
control: Control<T>;
label: string;
options: Array<{ value: string; label: string }>;
showOtherOption?: boolean;
otherFieldName?: FieldPath<T>;
}

function CheckboxGroup<T extends FieldValues>({
name,
control,
label,
options,
showOtherOption = false,
otherFieldName,
}: CheckboxGroupProps<T>) {
return (
<Controller
name={name}
control={control}
render={({ field: { value, onChange }, fieldState: { error } }) => {
const selectedValues = (value as string[]) || [];

const handleChange = (optionValue: string, checked: boolean) => {
if (checked) {
onChange([...selectedValues, optionValue]);
} else {
onChange(selectedValues.filter((v) => v !== optionValue));
}
};

return (
<FormControl component="fieldset" error={!!error} fullWidth>
<FormLabel component="legend">{label}</FormLabel>
<FormGroup>
{options.map((option) => (
<FormControlLabel
key={option.value}
control={
<Checkbox
checked={selectedValues.includes(option.value)}
onChange={(e) =>
handleChange(option.value, e.target.checked)
}
/>
}
label={option.label}
/>
))}
{showOtherOption && otherFieldName && (
<FormControlLabel
control={
<Checkbox
checked={selectedValues.includes('other')}
onChange={(e) => handleChange('other', e.target.checked)}
/>
}
label={
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
}}
>
<span>Other:</span>
<Controller
name={otherFieldName}
control={control}
render={({ field: otherField }) => (
<MuiTextField
{...otherField}
placeholder="Please specify"
size="small"
sx={{ width: '200px' }}
disabled={!selectedValues.includes('other')}
/>
)}
/>
</div>
}
/>
)}
</FormGroup>
{error && <FormHelperText>{error.message}</FormHelperText>}
</FormControl>
);
}}
/>
);
}

export default CheckboxGroup;
95 changes: 95 additions & 0 deletions src/components/forms/MenteeFormLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Box, Container, Paper, Typography } from '@mui/material';
import React, { ReactNode } from 'react';

interface MenteeFormLayoutProps {
title: string;
description?: ReactNode;
children: ReactNode;
}

const MenteeFormLayout: React.FC<MenteeFormLayoutProps> = ({
title,
description,
children,
}) => {
return (
<Box
sx={{
minHeight: '100vh',
display: 'flex',
backgroundColor: '#C7E7FF',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stepsen89 we don't have variable for colour to make simple the change or maintainability?
Also, we could use css class instead of add all css inside of the command, I am not sure if this is the convention with react, but looks like a but hard to maintain...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use our default colours, if it's either primary or one we set in the theme.

The sx is the props/convention used for MUI components

Copy link
Contributor Author

@117Isabell 117Isabell Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dricazenck @stepsen89 Thanks for the feedback. I understood the feedback now. Now I'm not sure which default color to changge to as the color in the Figma doesn't match any of the primary colors in the theme.ts

position: 'relative',
overflow: 'hidden',
'&::after': {
content: '""',
position: 'absolute',
right: { xs: 16, md: 0 },
top: { xs: 16, md: '-231px' },
width: { xs: '120px', sm: '180px', md: '1055.78px' },
height: { xs: '120px', sm: '180px', md: '970px' },
backgroundImage: 'url(/mentee-form-bg.png)',
backgroundSize: { xs: 'cover', md: 'contain' },
backgroundPosition: { xs: 'center', md: 'center right' },
backgroundRepeat: 'no-repeat',
borderRadius: { xs: '50%', md: 0 },
zIndex: 0,
opacity: 1,
pointerEvents: 'none',
},
}}
>
<Container
maxWidth={false}
sx={{
display: 'flex',
justifyContent: { xs: 'center', md: 'flex-start' },
alignItems: 'flex-start',
py: { xs: 4, md: 6 },
px: { xs: 2, sm: 3, md: '157px' },
position: 'relative',
zIndex: 1,
}}
>
<Paper
elevation={3}
sx={{
width: { xs: '100%', sm: '90%', md: '744px' },
maxWidth: '744px',
p: { xs: 3, md: 4 },
borderRadius: 2,
backgroundColor: 'white',
boxShadow: '0 8px 32px rgba(0, 0, 0, 0.1)',
position: 'relative',
zIndex: 2,
}}
>
<Box sx={{ mb: 3 }}>
<Typography
variant="h4"
component="h1"
gutterBottom
sx={{ fontWeight: 600 }}
>
{title}
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
<Typography
variant="caption"
sx={{ color: 'error.main', mr: 0.5 }}
>
*
</Typography>
<Typography variant="caption" color="text.secondary">
Indicates a required field
</Typography>
</Box>
{description && <Box sx={{ mt: 2 }}>{description}</Box>}
</Box>
{children}
</Paper>
</Container>
</Box>
);
};

export default MenteeFormLayout;
48 changes: 48 additions & 0 deletions src/components/forms/RadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
FormControl,
FormLabel,
RadioGroup as MuiRadioGroup,
FormControlLabel,
Radio,
FormHelperText,
} from '@mui/material';
import { Controller, Control, FieldPath, FieldValues } from 'react-hook-form';

interface RadioGroupProps<T extends FieldValues> {
name: FieldPath<T>;
control: Control<T>;
label: string;
options: Array<{ value: string; label: string }>;
}

function RadioGroup<T extends FieldValues>({
name,
control,
label,
options,
}: RadioGroupProps<T>) {
return (
<Controller
name={name}
control={control}
render={({ field, fieldState: { error } }) => (
<FormControl component="fieldset" error={!!error} fullWidth>
<FormLabel component="legend">{label}</FormLabel>
<MuiRadioGroup {...field}>
{options.map((option) => (
<FormControlLabel
key={option.value}
value={option.value}
control={<Radio />}
label={option.label}
/>
))}
</MuiRadioGroup>
{error && <FormHelperText>{error.message}</FormHelperText>}
</FormControl>
)}
/>
);
}

export default RadioGroup;
Loading