Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 35 additions & 0 deletions src/__tests__/pages/MenteeRegistrationPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ jest.mock('next/router', () => ({
useRouter: () => ({ push: jest.fn(), pathname: '/' }),
}));

// Mutable flag so individual tests can override the registration state
let mockIsRegistrationOpen = true;

// Mock the registration toggle
jest.mock('../../utils/mentorshipConstants', () => ({
...jest.requireActual('../../utils/mentorshipConstants'),
get IS_REGISTRATION_OPEN() {
return mockIsRegistrationOpen;
},
}));

const renderPage = () =>
render(
<ThemeProvider theme={theme}>
Expand Down Expand Up @@ -150,3 +161,27 @@ describe('MenteeRegistrationPage', () => {
});
});
});

describe('MenteeRegistrationPage - registration closed', () => {
beforeEach(() => {
mockIsRegistrationOpen = false;
});

afterEach(() => {
mockIsRegistrationOpen = true;
jest.resetAllMocks();
});

it('shows closed message when registration is not open', () => {
render(
<ThemeProvider theme={theme}>
<MenteeRegistrationPage />
</ThemeProvider>,
);
expect(screen.getByText('Application is now closed')).toBeInTheDocument();
expect(
screen.getByText(/Long-Term Mentorship programme/i),
).toBeInTheDocument();
expect(screen.queryByText('Step 1 of 3')).not.toBeInTheDocument();
});
});
22 changes: 22 additions & 0 deletions src/components/mentorship/RegistrationClosed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Box, Button, Typography } from '@mui/material';
import NextLink from 'next/link';
import React from 'react';

/**
* Displayed when the mentee registration window is closed.
*/
const RegistrationClosed = () => (
<Box sx={{ textAlign: 'center', py: 4 }}>
<Typography variant="h5" gutterBottom fontWeight={600}>
Application is now closed
</Typography>
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
Applications for the Long-Term Mentorship programme are currently closed.
</Typography>
<Button variant="contained" component={NextLink} href="/mentorship">
Back to Mentorship
</Button>
</Box>
);

export default RegistrationClosed;
18 changes: 15 additions & 3 deletions src/pages/mentorship/mentee-registration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import MenteeStep2Skills from 'components/mentorship/MenteeStep2Skills';
import MenteeStep3Applications from 'components/mentorship/MenteeStep3Applications';
import { MentorOption } from 'components/mentorship/MentorApplicationCard';
import RegistrationClosed from 'components/mentorship/RegistrationClosed';
import { IS_REGISTRATION_OPEN } from 'utils/mentorshipConstants';

const TOTAL_STEPS = 3;

Expand Down Expand Up @@ -55,6 +57,7 @@
const MenteeRegistrationPage = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const registrationOpen = IS_REGISTRATION_OPEN;

const formMethods = useForm<MenteeFormData>({
resolver: zodResolver(menteeFormSchema),
Expand All @@ -68,6 +71,7 @@
const [submitted, setSubmitted] = useState(false);

useEffect(() => {
if (!registrationOpen) return;
fetch('/api/mentors')
.then((res) => res.json())
.then((data) => {
Expand All @@ -83,7 +87,7 @@
.catch(() => {
// silently fall back to empty list — user can still submit if API is down
});
}, []);
}, [registrationOpen]);

const handleNext = async () => {
let isValid;
Expand Down Expand Up @@ -204,10 +208,16 @@
sx={{
position: 'relative',
zIndex: 1,
pt: { xs: 4, sm: 6, md: 8 },
pt: registrationOpen ? { xs: 4, sm: 6, md: 8 } : 0,
px: { xs: 2, sm: 3 },
maxWidth: isMobile ? '100%' : theme.custom?.innerBox?.maxWidth,
margin: '0 auto',
...(!registrationOpen && {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
minHeight: '70vh',
}),
}}
>
<Box
Expand Down Expand Up @@ -238,137 +248,139 @@
bgcolor: 'white',
}}
>
{submitted ? (
{!registrationOpen ? (

Check warning on line 251 in src/pages/mentorship/mentee-registration.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=Women-Coding-Community_wcc-frontend&issues=AZ1JPX9r3JBpSDiAyIUK&open=AZ1JPX9r3JBpSDiAyIUK&pullRequest=269
<RegistrationClosed />
) : submitted ? (
<Box sx={{ textAlign: 'center', py: 4 }}>
<Typography variant="h5" gutterBottom fontWeight={600}>
Application submitted!
</Typography>
<Typography
variant="body1"
color="text.secondary"
sx={{ mb: 3 }}
>
Thank you for applying to our mentorship programme. We will
review your application and get back to you soon.
</Typography>
<Button
variant="contained"
component={NextLink}
href="/mentorship"
>
Back to Mentorship
</Button>
</Box>
) : (
<>
{/* Progress */}
<Typography
variant="body2"
align="center"
sx={{ mb: 2, color: 'text.secondary' }}
>
Step {activeStep} of {TOTAL_STEPS}
</Typography>
<Box
sx={{
width: '100%',
height: 6,
bgcolor: '#E5E5E5',
borderRadius: 3,
mb: 5,
overflow: 'hidden',
}}
>
<Box
sx={{
width: `${(activeStep / TOTAL_STEPS) * 100}%`,
height: '100%',
bgcolor: 'primary.main',
borderRadius: 3,
transition: 'width 0.3s ease',
}}
/>
</Box>

{/* Step content */}
<Box>
{activeStep === 1 && <MenteeStep1BasicInfo />}
{activeStep === 2 && <MenteeStep2Skills />}
{activeStep === 3 && (
<MenteeStep3Applications mentors={mentors} />
)}
</Box>

{/* Error alert */}
{submitError && (
<Alert
severity="error"
onClose={() => setSubmitError(null)}
sx={{ mt: 3 }}
>
{submitError}
</Alert>
)}

{/* Navigation */}
<Stack
direction="row"
justifyContent="space-between"
mt={3}
spacing={2}
>
<Button
variant="outlined"
disabled={activeStep === 1}
onClick={handleBack}
sx={{ px: { xs: 2.5, md: 3.5 }, py: 1 }}
>
Back
</Button>

{activeStep === TOTAL_STEPS ? (
<Button
variant="contained"
color="success"
disabled={formMethods.formState.isSubmitting}
onClick={formMethods.handleSubmit(onSubmit)}
sx={{ px: { xs: 2.5, md: 3.5 }, py: 1 }}
>
{formMethods.formState.isSubmitting
? 'Submitting…'
: 'Submit Application'}
</Button>
) : (
<Button
variant="contained"
onClick={handleNext}
sx={{ px: { xs: 2.5, md: 3.5 }, py: 1 }}
>
Next
</Button>
)}
</Stack>

{/* Code of conduct note */}
{activeStep === 1 && (
<Box sx={{ mt: 4 }}>
<Typography variant="body2" color="text.secondary">
By submitting, you agree to our{' '}
<NextLink
href="/mentorship/code-of-conduct"
style={{
color: 'inherit',
textDecoration: 'underline',
}}
>
Mentee Code of Conduct
</NextLink>
.
</Typography>
</Box>
)}
</>
)}

Check warning on line 383 in src/pages/mentorship/mentee-registration.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested ternary operation into an independent statement.

See more on https://sonarcloud.io/project/issues?id=Women-Coding-Community_wcc-frontend&issues=AZ1JPX9r3JBpSDiAyIUL&open=AZ1JPX9r3JBpSDiAyIUL&pullRequest=269
</Paper>
</Container>
</Box>
Expand Down
6 changes: 6 additions & 0 deletions src/utils/mentorshipConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,9 @@ export const SKILL_LEVELS = [
'Not Applicable',
];
export const PREFERENCE_LEVELS = ['Low', 'Medium', 'High', 'Not Applicable'];

/**
* Mentee registration toggle.
* Set to `true` to open the registration form, `false` to show the closed page.
*/
export const IS_REGISTRATION_OPEN = false;
Loading