SPB Git forge

spb/trouve-ka

Public ★ Pinned

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

40commits 1branches 0releases
9.2 MBsize
maindefault branch
23 days agolast push
Python 51.9% TypeScript 32.7% JavaScript 4.8% CSS 4.1% Shell 2.9% HTML 1.8% SQL 1.5%
2.6 KB · 98 lines tsx
Raw Blame History
1/**2 * Trouve-KA — cœur ♥ « Mon univers Ka » d'un résultat de recherche3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 *6 * Toggle du favori au hub Groupe KA (via /api/favorites/toggle). Connecté :7 * cœur plein/contour ; non connecté : le tap envoie au flux « Se connecter8 * avec KA ID » existant (retour sur la page courante). Zone tactile 44 px9 * via ::after (pattern du socle mobile KA).10 */1112"use client";1314import { useEffect, useState } from "react";15import { cn } from "@/lib/utils";16import { ensureLoaded, isFavorite, toggleFav, useFavorites } from "@/components/fav-store";1718interface FavButtonProps {19  url: string;20  title: string;21  subtitle?: string;22  imageUrl?: string | null;23  className?: string;24}2526export function FavButton({ url, title, subtitle, imageUrl, className }: FavButtonProps) {27  const favs = useFavorites();28  const [busy, setBusy] = useState(false);2930  useEffect(() => {31    void ensureLoaded();32  }, []);3334  const fav = isFavorite(favs, url);35  const anon = favs.status === "anon";3637  const onClick = async () => {38    if (busy) return;39    if (anon) {40      const here = window.location.pathname + window.location.search;41      window.location.href = `/api/auth/ka/login?next=${encodeURIComponent(here)}`;42      return;43    }44    setBusy(true);45    await toggleFav({46      url,47      title,48      subtitle,49      image_url: imageUrl || undefined,50    });51    setBusy(false);52  };5354  return (55    <button56      type="button"57      onClick={onClick}58      disabled={busy}59      aria-pressed={fav}60      aria-label={61        anon62          ? "Se connecter avec KA ID pour ajouter aux favoris"63          : fav64            ? "Retirer des favoris"65            : "Ajouter aux favoris"66      }67      title={68        anon69          ? "Se connecter avec KA ID"70          : fav71            ? "Retirer de Mon univers Ka"72            : "Ajouter à Mon univers Ka"73      }74      className={cn(75        "relative inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-[1.5px] transition-colors after:absolute after:-inset-1.5 after:content-['']",76        fav77          ? "border-ink bg-ink text-lime"78          : "border-transparent text-ink-2 hover:border-ink hover:text-ink",79        busy && "opacity-60",80        className,81      )}82    >83      <svg84        width="15"85        height="15"86        viewBox="0 0 24 24"87        fill={fav ? "currentColor" : "none"}88        stroke="currentColor"89        strokeWidth="2"90        strokeLinejoin="round"91        aria-hidden="true"92      >93        <path d="M12 21c-4.8-3.6-9-6.9-9-11a5 5 0 0 1 9-3 5 5 0 0 1 9 3c0 4.1-4.2 7.4-9 11Z" />94      </svg>95    </button>96  );97}98