Added routes
This commit is contained in:
124
apps/web/src/features/groups/detail/QuickAddForm.tsx
Normal file
124
apps/web/src/features/groups/detail/QuickAddForm.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
import { useState } from 'react'
|
||||
import { Check, Loader2 } from 'lucide-react'
|
||||
import { Button, Input, Label, useToast } from '../../../components/ui'
|
||||
import { useGroupDetail } from './GroupDetailProvider'
|
||||
|
||||
export function QuickAddForm() {
|
||||
const { submitQuickAttendee, isSubmittingAttendee, closeAddAttendeeModal } = useGroupDetail()
|
||||
const toast = useToast()
|
||||
const [firstName, setFirstName] = useState('')
|
||||
const [lastName, setLastName] = useState('')
|
||||
const [phone, setPhone] = useState('')
|
||||
const [email, setEmail] = useState('')
|
||||
const [notes, setNotes] = useState('')
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
if (!firstName.trim() || !phone.trim()) {
|
||||
toast.error('Nombre y teléfono son obligatorios.')
|
||||
return
|
||||
}
|
||||
submitQuickAttendee({
|
||||
firstName: firstName.trim(),
|
||||
lastName: lastName.trim(),
|
||||
phone: phone.trim(),
|
||||
email: email.trim() || undefined,
|
||||
notes: notes.trim() || undefined,
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
setFirstName('')
|
||||
setLastName('')
|
||||
setPhone('')
|
||||
setEmail('')
|
||||
setNotes('')
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
<div>
|
||||
<Label htmlFor="quick-first-name" className="mb-1 block text-xs">
|
||||
Nombre <span className="text-danger">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="quick-first-name"
|
||||
placeholder="Ej. Lucas"
|
||||
value={firstName}
|
||||
onChange={(e) => setFirstName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="quick-last-name" className="mb-1 block text-xs">
|
||||
Apellido
|
||||
</Label>
|
||||
<Input
|
||||
id="quick-last-name"
|
||||
placeholder="Ej. González"
|
||||
value={lastName}
|
||||
onChange={(e) => setLastName(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="quick-phone" className="mb-1 block text-xs">
|
||||
Teléfono / WhatsApp <span className="text-danger">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
id="quick-phone"
|
||||
placeholder="Ej. +54 9 11 2345-6789"
|
||||
value={phone}
|
||||
onChange={(e) => setPhone(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<p className="mt-1 text-[11px] text-foreground/50">
|
||||
Usado para contacto y validación de duplicados.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="quick-email" className="mb-1 block text-xs">
|
||||
Email (opcional)
|
||||
</Label>
|
||||
<Input
|
||||
id="quick-email"
|
||||
type="email"
|
||||
placeholder="alumno@ejemplo.com"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="quick-notes" className="mb-1 block text-xs">
|
||||
Notas u Observaciones (opcional)
|
||||
</Label>
|
||||
<Input
|
||||
id="quick-notes"
|
||||
placeholder="Ej. Nivel intermedio, trae materiales propios"
|
||||
value={notes}
|
||||
onChange={(e) => setNotes(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-end gap-2.5 border-t border-border pt-3">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
resetForm()
|
||||
closeAddAttendeeModal()
|
||||
}}
|
||||
>
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button variant="primary" type="submit" disabled={isSubmittingAttendee} className="gap-2">
|
||||
{isSubmittingAttendee ? <Loader2 className="size-4 animate-spin" /> : <Check className="size-4" />}
|
||||
<span>Guardar Miembro</span>
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user