SPB Git

spb/trouve-ka Public

Trouve-KA — moteur de recherche web indépendant, Québec-first. Crawler distribué, index OpenSearch, ranking bilingue, galerie d'images. En prod : www.trouve-ka.com

Python 76.8% TypeScript 15.7% SQL 3.9% Shell 1.4% CSS 1.3% Dockerfile 0.7%
2.7 KB · 105 lines tsx
Raw Blame History
1/**2 * Trouve-KA — filtres de recherche en pastilles3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 */67"use client";89import { cn } from "@/lib/utils";1011/** Filtres actifs de la page de résultats. */12export interface SearchFilters {13  category?: string;14  language?: string;15  quebecOnly: boolean;16  images?: boolean;17}1819interface FilterPillsProps {20  filters: SearchFilters;21  onChange: (next: SearchFilters) => void;22}2324interface Pill {25  label: string;26  active: boolean;27  next: SearchFilters;28}2930export function FilterPills({ filters, onChange }: FilterPillsProps) {31  const allActive =32    !filters.category && !filters.language && !filters.quebecOnly && !filters.images;3334  const pills: Pill[] = [35    { label: "Tout", active: allActive, next: { quebecOnly: false } },36    {37      label: "Images",38      active: Boolean(filters.images),39      next: { ...filters, images: !filters.images },40    },41    {42      label: "Actualités",43      active: filters.category === "news",44      next: {45        ...filters,46        category: filters.category === "news" ? undefined : "news",47      },48    },49    {50      label: "Gouvernement",51      active: filters.category === "government",52      next: {53        ...filters,54        category: filters.category === "government" ? undefined : "government",55      },56    },57    {58      label: "Français",59      active: filters.language === "fr",60      next: {61        ...filters,62        language: filters.language === "fr" ? undefined : "fr",63      },64    },65    {66      label: "English",67      active: filters.language === "en",68      next: {69        ...filters,70        language: filters.language === "en" ? undefined : "en",71      },72    },73    {74      label: "Québec seulement",75      active: filters.quebecOnly,76      next: { ...filters, quebecOnly: !filters.quebecOnly },77    },78  ];7980  return (81    <div82      role="group"83      aria-label="Filtres de recherche"84      className="flex flex-wrap gap-2"85    >86      {pills.map((pill) => (87        <button88          key={pill.label}89          type="button"90          aria-pressed={pill.active}91          onClick={() => onChange(pill.next)}92          className={cn(93            "gk-mono whitespace-nowrap rounded-full border-[1.5px] border-ink px-3.5 py-1.5 text-[11px] font-bold uppercase tracking-[0.08em] shadow-[2px_2px_0_rgba(20,24,20,0.12)] transition-[background,color,transform,box-shadow] duration-150 hover:-translate-y-px hover:shadow-[3px_3px_0_rgba(20,24,20,0.2)] active:translate-y-0 active:shadow-none",94            pill.active95              ? "bg-ink text-lime"96              : "bg-surface text-ink-2 hover:bg-lime hover:text-ink",97          )}98        >99          {pill.label}100        </button>101      ))}102    </div>103  );104}105