-
Notifications
You must be signed in to change notification settings - Fork 32
Feat/mentee registration form #157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7858467
15a71d1
4273e51
55da6be
34127e4
3683c65
1df93e3
b998f08
1e67a07
47891ae
37132c7
3fe6805
40ce841
d7436a5
0eacfa0
101be14
45cf5e8
d53a827
9412cc9
db9f2d8
ed44a30
174c2b8
a5bb54d
e77bbd4
090125b
40d1bca
33bcc4e
4384125
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| 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; |
| 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', | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
| 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; |
Uh oh!
There was an error while loading. Please reload this page.