Spaces:
Sleeping
Sleeping
| import { useState } from 'react'; | |
| import { Helmet } from 'react-helmet-async'; | |
| import { motion } from 'framer-motion'; | |
| import { HiCheck, HiArrowRight, HiArrowLeft } from 'react-icons/hi'; | |
| import { CAMPAIGN_CATEGORIES, URGENCY_LEVELS } from '../utils/constants'; | |
| import toast from 'react-hot-toast'; | |
| const steps = ['Type & Urgency', 'Description', 'Location & Contact', 'Review']; | |
| export default function HelpRequest() { | |
| const [step, setStep] = useState(0); | |
| const [submitted, setSubmitted] = useState(false); | |
| const [form, setForm] = useState({ | |
| requestType: '', urgency: '', title: '', description: '', estimatedAmount: '', | |
| address: '', city: '', state: '', pincode: '', contactPerson: '', contactPhone: '', | |
| }); | |
| const updateForm = (key, val) => setForm(f => ({ ...f, [key]: val })); | |
| const nextStep = () => { | |
| if (step === 0 && (!form.requestType || !form.urgency)) return toast.error('Select type and urgency'); | |
| if (step === 1 && (!form.title || !form.description)) return toast.error('Add title and description'); | |
| if (step === 2 && (!form.contactPerson || !form.contactPhone)) return toast.error('Add contact info'); | |
| setStep(s => Math.min(s + 1, 3)); | |
| }; | |
| const handleSubmit = (e) => { | |
| e.preventDefault(); | |
| // TODO: Save to Firestore | |
| setSubmitted(true); | |
| }; | |
| if (submitted) { | |
| return ( | |
| <> | |
| <Helmet><title>Request Submitted</title></Helmet> | |
| <section className="about-hero"> | |
| <div className="about-hero__bg" /> | |
| <div className="container"> | |
| <motion.div className="about-hero__content" initial={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1 }}> | |
| <div style={{ width: 80, height: 80, borderRadius: '50%', background: '#d1fae5', color: '#10B981', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: '1rem' }}> | |
| <HiCheck size={40} /> | |
| </div> | |
| <h1 className="about-hero__title" style={{ fontSize: '2rem' }}>Help Request Submitted</h1> | |
| <p className="about-hero__subtitle">Our team will review your request and reach out within 24-48 hours. Track status in your dashboard.</p> | |
| </motion.div> | |
| </div> | |
| </section> | |
| </> | |
| ); | |
| } | |
| return ( | |
| <> | |
| <Helmet><title>Request Help — Social Share and Care Foundation</title></Helmet> | |
| <section className="about-hero"> | |
| <div className="about-hero__bg" /> | |
| <div className="container"> | |
| <motion.div className="about-hero__content" initial={{ opacity: 0, y: 30 }} animate={{ opacity: 1, y: 0 }}> | |
| <span className="section-header__tag">🆘 Request Help</span> | |
| <h1 className="about-hero__title">We're Here to Help</h1> | |
| <p className="about-hero__subtitle">Submit a help request and our team will prioritize based on urgency.</p> | |
| </motion.div> | |
| </div> | |
| </section> | |
| <section className="section"> | |
| <div className="container" style={{ maxWidth: '680px' }}> | |
| {/* Step Indicator */} | |
| <div style={{ display: 'flex', justifyContent: 'center', gap: '0.5rem', marginBottom: '2rem' }}> | |
| {steps.map((s, i) => ( | |
| <div key={s} style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}> | |
| <div style={{ | |
| width: 32, height: 32, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', | |
| fontSize: '0.8rem', fontWeight: '700', | |
| background: i <= step ? '#2D6A4F' : '#e5e7eb', color: i <= step ? 'white' : '#9ca3af', | |
| }}> | |
| {i < step ? <HiCheck size={16} /> : i + 1} | |
| </div> | |
| <span style={{ fontSize: '0.82rem', color: i <= step ? '#1f2937' : '#9ca3af', fontWeight: '500', display: i === steps.length - 1 ? 'inline' : 'none' }}>{s}</span> | |
| {i < steps.length - 1 && <div style={{ width: 40, height: 2, background: i < step ? '#2D6A4F' : '#e5e7eb', borderRadius: 2 }} />} | |
| </div> | |
| ))} | |
| </div> | |
| <motion.form className="card" style={{ padding: '2.5rem' }} onSubmit={handleSubmit} key={step} initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }}> | |
| {step === 0 && ( | |
| <> | |
| <h2 style={{ marginBottom: '1.5rem' }}>Type & Urgency</h2> | |
| <div className="form-group"> | |
| <label className="form-label">Request Type *</label> | |
| <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0.75rem' }}> | |
| {CAMPAIGN_CATEGORIES.map(cat => ( | |
| <button key={cat.value} type="button" onClick={() => updateForm('requestType', cat.value)} style={{ | |
| padding: '1rem', borderRadius: '12px', border: form.requestType === cat.value ? `2px solid ${cat.color}` : '2px solid #e5e7eb', | |
| background: form.requestType === cat.value ? `${cat.color}10` : 'white', textAlign: 'center', cursor: 'pointer', transition: 'all 0.2s', | |
| }}> | |
| <div style={{ fontSize: '1.5rem', marginBottom: '0.35rem' }}>{cat.icon}</div> | |
| <div style={{ fontSize: '0.88rem', fontWeight: '600' }}>{cat.label}</div> | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| <div className="form-group"> | |
| <label className="form-label">Urgency Level *</label> | |
| <div style={{ display: 'flex', gap: '0.75rem', flexWrap: 'wrap' }}> | |
| {URGENCY_LEVELS.map(level => ( | |
| <button key={level.value} type="button" onClick={() => updateForm('urgency', level.value)} style={{ | |
| padding: '0.5rem 1.25rem', borderRadius: '999px', fontSize: '0.85rem', fontWeight: '600', | |
| background: form.urgency === level.value ? level.color : '#f3f4f6', | |
| color: form.urgency === level.value ? 'white' : '#4b5563', | |
| border: 'none', cursor: 'pointer', transition: 'all 0.2s', | |
| }}> | |
| {level.label} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| </> | |
| )} | |
| {step === 1 && ( | |
| <> | |
| <h2 style={{ marginBottom: '1.5rem' }}>Describe Your Situation</h2> | |
| <div className="form-group"> | |
| <label className="form-label">Title *</label> | |
| <input className="form-input" placeholder="Brief title for your request" value={form.title} onChange={(e) => updateForm('title', e.target.value)} required /> | |
| </div> | |
| <div className="form-group"> | |
| <label className="form-label">Description *</label> | |
| <textarea className="form-input" rows={5} placeholder="Describe your situation in detail..." value={form.description} onChange={(e) => updateForm('description', e.target.value)} required style={{ resize: 'vertical' }} /> | |
| </div> | |
| <div className="form-group"> | |
| <label className="form-label">Estimated Amount Needed (₹)</label> | |
| <input type="number" className="form-input" placeholder="0" value={form.estimatedAmount} onChange={(e) => updateForm('estimatedAmount', e.target.value)} /> | |
| </div> | |
| </> | |
| )} | |
| {step === 2 && ( | |
| <> | |
| <h2 style={{ marginBottom: '1.5rem' }}>Location & Contact</h2> | |
| <div className="form-group"> | |
| <label className="form-label">Address</label> | |
| <input className="form-input" placeholder="Street address" value={form.address} onChange={(e) => updateForm('address', e.target.value)} /> | |
| </div> | |
| <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '1rem' }}> | |
| <div className="form-group"> | |
| <label className="form-label">City</label> | |
| <input className="form-input" placeholder="City" value={form.city} onChange={(e) => updateForm('city', e.target.value)} /> | |
| </div> | |
| <div className="form-group"> | |
| <label className="form-label">State</label> | |
| <input className="form-input" placeholder="State" value={form.state} onChange={(e) => updateForm('state', e.target.value)} /> | |
| </div> | |
| <div className="form-group"> | |
| <label className="form-label">Pincode</label> | |
| <input className="form-input" placeholder="110001" value={form.pincode} onChange={(e) => updateForm('pincode', e.target.value)} /> | |
| </div> | |
| </div> | |
| <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}> | |
| <div className="form-group"> | |
| <label className="form-label">Contact Person *</label> | |
| <input className="form-input" placeholder="Name" value={form.contactPerson} onChange={(e) => updateForm('contactPerson', e.target.value)} required /> | |
| </div> | |
| <div className="form-group"> | |
| <label className="form-label">Contact Phone *</label> | |
| <input className="form-input" placeholder="9876543210" value={form.contactPhone} onChange={(e) => updateForm('contactPhone', e.target.value)} required /> | |
| </div> | |
| </div> | |
| </> | |
| )} | |
| {step === 3 && ( | |
| <> | |
| <h2 style={{ marginBottom: '1.5rem' }}>Review Your Request</h2> | |
| <div style={{ background: '#f9fafb', borderRadius: '12px', padding: '1.5rem', fontSize: '0.9rem', lineHeight: '1.8' }}> | |
| <p><strong>Type:</strong> {CAMPAIGN_CATEGORIES.find(c => c.value === form.requestType)?.label || '—'}</p> | |
| <p><strong>Urgency:</strong> {URGENCY_LEVELS.find(l => l.value === form.urgency)?.label || '—'}</p> | |
| <p><strong>Title:</strong> {form.title}</p> | |
| <p><strong>Description:</strong> {form.description}</p> | |
| {form.estimatedAmount && <p><strong>Amount Needed:</strong> ₹{Number(form.estimatedAmount).toLocaleString()}</p>} | |
| <p><strong>Location:</strong> {[form.address, form.city, form.state, form.pincode].filter(Boolean).join(', ') || '—'}</p> | |
| <p><strong>Contact:</strong> {form.contactPerson} ({form.contactPhone})</p> | |
| </div> | |
| </> | |
| )} | |
| {/* Navigation */} | |
| <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: '2rem' }}> | |
| {step > 0 ? ( | |
| <button type="button" className="btn btn--ghost" onClick={() => setStep(s => s - 1)}> | |
| <HiArrowLeft /> Back | |
| </button> | |
| ) : <div />} | |
| {step < 3 ? ( | |
| <button type="button" className="btn btn--primary" onClick={nextStep}> | |
| Next <HiArrowRight /> | |
| </button> | |
| ) : ( | |
| <button type="submit" className="btn btn--primary btn--lg"> | |
| Submit Request | |
| </button> | |
| )} | |
| </div> | |
| </motion.form> | |
| </div> | |
| </section> | |
| </> | |
| ); | |
| } | |