feat: Add public endpoint to get registration configuration
Some checks failed
ParentFlow CI/CD Pipeline / Backend Tests (push) Has been cancelled
ParentFlow CI/CD Pipeline / Frontend Tests (push) Has been cancelled
ParentFlow CI/CD Pipeline / Security Scanning (push) Has been cancelled
ParentFlow CI/CD Pipeline / Build Docker Images (map[context:maternal-app/maternal-app-backend dockerfile:Dockerfile.production name:backend]) (push) Has been cancelled
ParentFlow CI/CD Pipeline / Build Docker Images (map[context:maternal-web dockerfile:Dockerfile.production name:frontend]) (push) Has been cancelled
ParentFlow CI/CD Pipeline / Deploy to Development (push) Has been cancelled
ParentFlow CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled

Backend Changes:
- Added GET /api/v1/auth/registration/config public endpoint
- Returns registrationMode and requireInviteCode settings
- No authentication required - accessible before registration
- Injected ConfigService into AuthController

This allows the frontend to dynamically show/hide the invite code
field based on the current registration mode setting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andrei
2025-10-08 12:01:14 +00:00
parent 7213075cde
commit 9f72183a36
2 changed files with 65 additions and 20 deletions

View File

@@ -23,6 +23,7 @@ import * as z from 'zod';
import { useAuth } from '@/lib/auth/AuthContext';
import Link from 'next/link';
import { useTheme } from '@mui/material/styles';
import apiClient from '@/lib/api/client';
const registerSchema = z.object({
name: z.string().min(2, 'Name must be at least 2 characters'),
@@ -79,6 +80,8 @@ export default function RegisterPage() {
const [isLoading, setIsLoading] = useState(false);
const [userAge, setUserAge] = useState<number | null>(null);
const [requiresParentalConsent, setRequiresParentalConsent] = useState(false);
const [requireInviteCode, setRequireInviteCode] = useState(false);
const [loadingConfig, setLoadingConfig] = useState(true);
const { register: registerUser } = useAuth();
const {
@@ -95,6 +98,26 @@ export default function RegisterPage() {
},
});
// Fetch registration configuration on mount
useEffect(() => {
const fetchRegistrationConfig = async () => {
try {
const response = await apiClient.get('/api/v1/auth/registration/config');
if (response.data?.success && response.data?.data) {
setRequireInviteCode(response.data.data.requireInviteCode);
}
} catch (error) {
console.error('Failed to fetch registration config:', error);
// Default to not requiring invite code if fetch fails
setRequireInviteCode(false);
} finally {
setLoadingConfig(false);
}
};
fetchRegistrationConfig();
}, []);
// Watch date of birth to calculate age and show parental consent if needed
const dateOfBirth = watch('dateOfBirth');
@@ -244,26 +267,30 @@ export default function RegisterPage() {
}}
/>
<TextField
fullWidth
label="Invite Code (Optional)"
margin="normal"
error={!!errors.inviteCode}
helperText={errors.inviteCode?.message || 'Leave blank if registration is open'}
{...register('inviteCode')}
disabled={isLoading}
inputProps={{
'aria-invalid': !!errors.inviteCode,
'aria-describedby': errors.inviteCode ? 'invite-code-error' : 'invite-code-helper',
}}
InputProps={{
sx: { borderRadius: 3 },
}}
FormHelperTextProps={{
id: errors.inviteCode ? 'invite-code-error' : 'invite-code-helper',
role: errors.inviteCode ? 'alert' : undefined,
}}
/>
{requireInviteCode && (
<TextField
fullWidth
label="Invite Code"
margin="normal"
error={!!errors.inviteCode}
helperText={errors.inviteCode?.message || 'Enter your invite code to register'}
{...register('inviteCode')}
disabled={isLoading}
required
inputProps={{
'aria-required': 'true',
'aria-invalid': !!errors.inviteCode,
'aria-describedby': errors.inviteCode ? 'invite-code-error' : 'invite-code-helper',
}}
InputProps={{
sx: { borderRadius: 3 },
}}
FormHelperTextProps={{
id: errors.inviteCode ? 'invite-code-error' : 'invite-code-helper',
role: errors.inviteCode ? 'alert' : undefined,
}}
/>
)}
<TextField
fullWidth