feat: add canvas-confetti integration and AuroraButton component; enhance UI with animations and improve button interactions

This commit is contained in:
2025-08-26 15:58:30 -06:00
parent 56b0dc8a62
commit 196aea5df9
8 changed files with 143 additions and 41 deletions

View File

@@ -291,7 +291,7 @@ function RouteComponent() {
// NEW: acciones carrito
function addToCart(a: Asignatura) {
setCart(prev => prev.find(x => x.id === a.id) ? prev : [...prev, a])
toast.success('Asignatura añadida al carrito')
toast.success('Asignatura añadida al carrito de asignaturas')
}
function removeFromCart(id: string) {
setCart(prev => prev.filter(x => x.id !== id))
@@ -355,7 +355,7 @@ function RouteComponent() {
className="relative"
>
<Icons.ShoppingCart className="w-4 h-4 mr-2" />
Carrito
Carrito de asignaturas
{cart.length > 0 && (
<span className="ml-2 inline-flex h-5 min-w-[1.25rem] items-center justify-center rounded-full bg-white/90 text-[11px] text-neutral-900 px-1">
{cart.length}
@@ -369,36 +369,51 @@ function RouteComponent() {
</div>
{/* Filtros */}
<div className="grid gap-2 sm:grid-cols-[1fr,140px,180px,150px]">
<Input
value={q}
onChange={(e) => setQ(e.target.value)}
placeholder="Buscar por nombre, clave, plan, carrera, facultad…"
className="w-full"
/>
<Select value={sem} onValueChange={setSem}>
<SelectTrigger><SelectValue placeholder="Semestre" /></SelectTrigger>
<SelectContent>
<SelectItem value="todos">Todos</SelectItem>
{semestres.map(s => <SelectItem key={s} value={s}>Semestre {s}</SelectItem>)}
</SelectContent>
</Select>
<Select value={tipo} onValueChange={setTipo}>
<SelectTrigger><SelectValue placeholder="Tipo" /></SelectTrigger>
<SelectContent className="max-h-64">
<SelectItem value="todos">Todos</SelectItem>
{tipos.map(t => <SelectItem key={t} value={t}>{t}</SelectItem>)}
</SelectContent>
</Select>
<Select value={groupBy} onValueChange={(v) => setGroupBy(v as any)}>
<SelectTrigger><SelectValue placeholder="Agrupar por" /></SelectTrigger>
<SelectContent>
<SelectItem value="semestre">Agrupar por semestre</SelectItem>
<SelectItem value="ninguno">Sin agrupación</SelectItem>
</SelectContent>
</Select>
<div className="grid gap-4 sm:grid-cols-4">
<div>
<Label>Búsqueda</Label>
<Input
value={q}
onChange={(e) => setQ(e.target.value)}
placeholder="Nombre, clave, plan, carrera, facultad…"
/>
</div>
<div>
<Label>Semestre</Label>
<Select value={sem} onValueChange={setSem}>
<SelectTrigger><SelectValue placeholder="Todos" /></SelectTrigger>
<SelectContent>
<SelectItem value="todos">Todos</SelectItem>
{semestres.map(s => <SelectItem key={s} value={s}>Semestre {s}</SelectItem>)}
</SelectContent>
</Select>
</div>
<div>
<Label>Tipo</Label>
<Select value={tipo} onValueChange={setTipo}>
<SelectTrigger><SelectValue placeholder="Todos" /></SelectTrigger>
<SelectContent className="max-h-64">
<SelectItem value="todos">Todos</SelectItem>
{tipos.map(t => <SelectItem key={t} value={t}>{t}</SelectItem>)}
</SelectContent>
</Select>
</div>
<div>
<Label>Agrupación</Label>
<Select value={groupBy} onValueChange={(v) => setGroupBy(v as any)}>
<SelectTrigger><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="semestre">Por semestre</SelectItem>
<SelectItem value="ninguno">Sin agrupación</SelectItem>
</SelectContent>
</Select>
</div>
</div>
{/* Chips de salud */}
<div className="flex flex-wrap items-center gap-2">
<HealthChip
@@ -621,7 +636,7 @@ function RouteComponent() {
</div>
<div className="flex items-center justify-between">
<Button variant="ghost" onClick={clearCart}><Icons.Trash2 className="w-4 h-4 mr-1" /> Vaciar carrito</Button>
<Button variant="ghost" onClick={clearCart}><Icons.Trash2 className="w-4 h-4 mr-1" /> Vaciar carrito de Asignaturas</Button>
<div className="space-x-2">
<Button variant="outline" onClick={() => setBulkOpen(false)}>Cerrar</Button>
<Button onClick={cloneBulk}><Icons.CopyPlus className="w-4 h-4 mr-1" /> Clonar en lote</Button>
@@ -686,7 +701,7 @@ function AsignaturaCard({ a, onClone, onAddToCart }: { a: Asignatura; onClone: (
<Icons.Copy className="w-4 h-4" /> Clonar
</DropdownMenuItem>
<DropdownMenuItem className="gap-2" onClick={onAddToCart}>
<Icons.ShoppingCart className="w-4 h-4" /> Añadir al carrito
<Icons.ShoppingCart className="w-4 h-4" /> Añadir al carrito de asignaturas
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>