TypeScript 50.6%
JavaScript 46.1%
SQL 2.1%
Shell 0.6%
CSS 0.5%
1"use client";2import Link from "next/link";3import { useRouter } from "next/navigation";4import { Empty, Notice } from "@/components/ui";5type S = { id: string; label: string; query: Record<string, string>; alertEnabled: boolean; alertFrequency: string; lastAlertAt: string | null; createdAt: string };6export function AlertsView({ items }: { items: S[] }) {7 const router = useRouter();8 const patch = async (id: string, b: Record<string, unknown>) => { await fetch(`/api/me/saved-searches/${id}`, { method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify(b) }); router.refresh(); };9 const del = async (id: string) => { await fetch(`/api/me/saved-searches/${id}`, { method: "DELETE" }); router.refresh(); };10 return (11 <div>12 <h1 className="text-2xl md:text-3xl font-extrabold tracking-tight mb-1">Alertes</h1><p className="text-sm text-ink-2 mb-4">Recevez par courriel les nouvelles annonces correspondant à vos recherches sauvegardées (compte requis). Fréquence au choix, désactivable en un clic.</p>13 {items.length === 0 ? <Empty title="Aucune recherche sauvegardée" hint="Sur la page des résultats, cliquez « Sauvegarder » : connecté, la recherche est enregistrée dans votre compte et peut devenir une alerte." action={{ href: "/recherche", label: "Lancer une recherche" }} /> : (14 <ul className="tv-card divide-y divide-line text-sm">{items.map((s) => <li key={s.id} className="p-3 flex flex-wrap items-center gap-3"><div className="min-w-0 flex-1"><Link href={`/recherche?${new URLSearchParams(s.query)}`} className="font-semibold hover:underline">{s.label}</Link><p className="text-xs text-ink-3">{s.lastAlertAt ? `Dernière alerte ${new Date(s.lastAlertAt).toLocaleDateString("fr-CA")}` : "Aucune alerte envoyée encore"}</p></div>15 <label className="flex items-center gap-1 text-xs"><input type="checkbox" checked={s.alertEnabled} onChange={(e) => patch(s.id, { alertEnabled: e.target.checked })} className="accent-[#e0263c]" /> Alerte</label>16 <select value={s.alertFrequency} onChange={(e) => patch(s.id, { alertFrequency: e.target.value })} className="tv-chip appearance-none text-xs"><option value="INSTANT">Dès publication</option><option value="DAILY">Quotidienne</option><option value="WEEKLY">Hebdomadaire</option><option value="OFF">Désactivée</option></select>17 <button type="button" onClick={() => del(s.id)} className="text-xs underline text-ink-3">Supprimer</button></li>)}</ul>18 )}19 <div className="mt-4"><Notice>Les alertes sont envoyées par le service de courriel Toveli à l'adresse vérifiée de votre compte, selon la fréquence choisie, uniquement pour les nouvelles annonces (agrégées ou directes) correspondant à vos critères.</Notice></div>20 </div>21 );22}23