From a3d12638d1dd4a6e05ebde13c7c81bd42f793a4c Mon Sep 17 00:00:00 2001 From: Anilkumar3494 Date: Mon, 16 Feb 2026 16:55:31 -0500 Subject: [PATCH 1/3] make feedback from custom and API insert to supbase --- src/components/Pages/Contact.tsx | 222 +++++++++++++++++++++---- src/components/Pages/Pages.module.scss | 4 +- src/services/db.ts | 17 +- src/types/ResourceEntry.ts | 7 + 4 files changed, 217 insertions(+), 33 deletions(-) diff --git a/src/components/Pages/Contact.tsx b/src/components/Pages/Contact.tsx index 98287a52..189a2f21 100644 --- a/src/components/Pages/Contact.tsx +++ b/src/components/Pages/Contact.tsx @@ -1,42 +1,204 @@ -import { useState } from 'react'; -import { Box, CircularProgress } from '@mui/material'; +import { useState, useEffect, useMemo } from 'react'; +import ReplayIcon from '@mui/icons-material/Replay'; +import { + Checkbox, + Stack, + TextField, + Button, + FormControlLabel, + Alert, + Collapse +} from '@mui/material'; +import { addFeedback } from 'services/db'; + +import styles from './Pages.module.scss'; + +const PRIMARY_COLOR = '#10b6ff'; const Contact = () => { - const [loading, setLoading] = useState(true); + const [form, setForm] = useState({ + name: '', + email: '', + feedback: '', + interest: false + }); + + const [loading, setLoading] = useState(false); + const [status, setStatus] = useState<'idle' | 'success' | 'error'>('idle'); + + useEffect(() => { + let timer: NodeJS.Timeout; + if (status === 'success') { + timer = setTimeout(() => { + setStatus('idle'); + }, 5000); + } + return () => clearTimeout(timer); + }, [status]); + + const handleChange = + (field: string) => (event: React.ChangeEvent) => { + const value = + field === 'interest' ? event.target.checked : event.target.value; + setForm(prev => ({ ...prev, [field]: value })); + if (status === 'error') setStatus('idle'); + }; + + const validateEmail = (email: string) => { + return /\S+@\S+\.\S+/.test(email); + }; - const handleLoading = () => { - setLoading(false); + const handleSubmit = async () => { + if (!form.name.trim() || !form.email.trim()) { + setStatus('error'); + return; + } + if (!validateEmail(form.email)) { + alert('Please enter a valid email address'); + return; + } + + try { + setLoading(true); + + await addFeedback({ + name: form.name, + email: form.email, + feedback: form.feedback || null, + interest: form.interest + }); + + setStatus('success'); + + setForm({ + name: '', + email: '', + feedback: '', + interest: false + }); + } catch (error) { + console.error(error); + setStatus('error'); + } finally { + setLoading(false); + } }; + const handleReset = () => { + setForm({ name: '', email: '', feedback: '', interest: false }); + setStatus('idle'); + }; + + const textFieldFocusSX = useMemo( + () => ({ + '& .MuiOutlinedInput-root': { + '&.Mui-focused fieldset': { + borderColor: PRIMARY_COLOR + } + }, + '& .MuiInputLabel-root.Mui-focused': { + color: PRIMARY_COLOR + } + }), + [] + ); + return ( - - {loading && ( - +

Contact Us

+ + + {status === 'success' && ( + setStatus('idle')}> + Thank you! Your feedback has been received! + + )} + {status === 'error' && ( + setStatus('idle')}> + Please check your inputs and try again. + + )} + + + + + + + + + + } + label={ + + I'm interested in helping PHLASK with future research + + } + /> + + + + +