import React, { useState, useEffect } from 'react'; import { TextField, Button, Box, Typography, Snackbar, Alert } from '@mui/material'; interface DesireFormProps { onSubmit: (desires: { wants: string[], accepts: string[], noGoes: string[], afraidToAsk: string }) => void; externalError?: string | null; } const DesireForm: React.FC = ({ onSubmit, externalError }) => { const [wants, setWants] = useState(''); const [accepts, setAccepts] = useState(''); const [noGoes, setNoGoes] = useState(''); const [afraidToAsk, setAfraidToAsk] = useState(''); const [alertOpen, setAlertOpen] = useState(false); const [alertMessage, setAlertMessage] = useState(''); const [alertSeverity, setAlertSeverity] = useState<'error' | 'warning' | 'info' | 'success'>('error'); // Effect to handle external errors useEffect(() => { if (externalError) { setAlertMessage(externalError); setAlertSeverity('error'); setAlertOpen(true); } }, [externalError]); const handleCloseAlert = (event?: React.SyntheticEvent | Event, reason?: string) => { if (reason === 'clickaway') { return; } setAlertOpen(false); }; const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); const parsedWants = wants.split('\n').map(s => s.trim()).filter(s => s); const parsedAccepts = accepts.split('\n').map(s => s.trim()).filter(s => s); const parsedNoGoes = noGoes.split('\n').map(s => s.trim()).filter(s => s); // FR-020: The system MUST require a user to enter at least one desire in at least one of the three categories if (parsedWants.length === 0 && parsedAccepts.length === 0 && parsedNoGoes.length === 0 && afraidToAsk.length === 0) { setAlertMessage('Please enter at least one desire in any category.'); setAlertSeverity('error'); setAlertOpen(true); return; } // FR-016: System MUST validate a user's submission to prevent the same item from appearing in conflicting categories const allItems = [...parsedWants, ...parsedAccepts, ...parsedNoGoes]; const uniqueItems = new Set(allItems); if (allItems.length !== uniqueItems.size) { setAlertMessage('You have conflicting desires (same item in different categories). Please resolve.'); setAlertSeverity('error'); setAlertOpen(true); return; } onSubmit({ wants: parsedWants, accepts: parsedAccepts, noGoes: parsedNoGoes, afraidToAsk: afraidToAsk, }); }; return ( What You Want setWants(e.target.value)} margin="normal" inputProps={{ maxLength: 500, 'aria-label': 'Enter items you want' }} helperText={`Enter items you want, one per line. Max 500 characters per item. ${wants.length}/500`} /> Afraid to Ask (Private) setAfraidToAsk(e.target.value)} margin="normal" inputProps={{ maxLength: 500, 'aria-label': 'Enter sensitive ideas privately' }} helperText={`Enter sensitive ideas privately. Max 500 characters. ${afraidToAsk.length}/500`} /> What You Accept setAccepts(e.target.value)} margin="normal" inputProps={{ maxLength: 500, 'aria-label': 'Enter items you accept' }} helperText={`Enter items you accept, one per line. Max 500 characters per item. ${accepts.length}/500`} /> What You Do Not Want setNoGoes(e.target.value)} margin="normal" inputProps={{ maxLength: 500, 'aria-label': 'Enter items you absolutely do not want' }} helperText={`Enter items you absolutely do not want, one per line. Max 500 characters per item. ${noGoes.length}/500`} /> {alertMessage} ); }; export default DesireForm;