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 51.9%
TypeScript 32.7%
JavaScript 4.8%
CSS 4.1%
Shell 2.9%
HTML 1.8%
SQL 1.5%
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// ka-ui/react/KaFooter.tsx — footer commun Groupe KA (fond encre), vendoré ici3// sous apps/web/ka/. Consomme ecosystem.json : toute modification des infos de4// contact se fait dans ka-ui/ecosystem.json puis se resynchronise sur les 125// sites (voir ka-ui/README.md).6// Extension locale trouve-ka : prop `children` (rendue après l'avertissement)7// pour accueillir le flux temps réel du bot (<LiveCrawl />).8import eco from "./ecosystem.json";910type LocalLink = { label: string; href: string };1112export default function KaFooter({13 siteId,14 localLegal = [],15 children,16}: {17 /** id du site courant dans ecosystem.json (ex. "trouve-ka") */18 siteId: string;19 /** pages légales PROPRES au site (ex. /conditions), affichées avant celles du hub */20 localLegal?: LocalLink[];21 /** contenu propre au site, rendu après l'avertissement (ex. flux du bot) */22 children?: React.ReactNode;23}) {24 const year = new Date().getFullYear();25 const site = eco.sites.find((s) => s.id === siteId);26 const others = eco.sites.filter((s) => s.id !== siteId);27 return (28 <footer className="ka-footer" id="contact">29 <div className="container">30 <a31 className="wordmark"32 href={eco.hub.url}33 target={siteId === "groupe-ka" ? undefined : "_blank"}34 rel="noopener noreferrer"35 aria-label="Groupe KA — le portail de l'écosystème"36 >37 Groupe <span className="ka">KA</span>38 </a>39 <p className="desc">40 {eco.org.tagline} Des centaines de connecteurs lisent les sites à la41 source, normalisent la donnée et se resynchronisent seuls.{" "}42 {site ? (43 <>44 <b style={{ color: "var(--paper)" }}>{site.wordmark}</b> —{" "}45 {site.tagline} — est un service Groupe KA.46 </>47 ) : null}48 </p>49 <p className="notice">50 <b>{eco.org.disclaimer}</b>51 </p>52 {children}53 <ul className="sites">54 {others.map((s) => (55 <li key={s.id}>56 <a href={`https://${s.domain}`} target="_blank" rel="noopener noreferrer">57 {s.wordmark}58 </a>59 </li>60 ))}61 {eco.extraFooterLinks.map((l) => (62 <li key={l.href}>63 <a href={l.href} target="_blank" rel="noopener noreferrer">64 {l.label}65 </a>66 </li>67 ))}68 </ul>69 <div className="contacts">70 {eco.contacts.map((c) => (71 <p key={c.email} style={{ margin: 0 }}>72 <a href={`mailto:${c.email}`}>{c.email}</a>73 <span>{c.role}</span>74 </p>75 ))}76 </div>77 <p className="legal">78 © {year} {eco.org.copyrightHolder}79 {localLegal.map((l) => (80 <span key={l.href}>81 {" · "}82 <a href={l.href}>{l.label}</a>83 </span>84 ))}85 {eco.legal.map((l) => (86 <span key={l.href}>87 {" · "}88 <a href={l.href} target="_blank" rel="noopener noreferrer">89 {l.label}90 </a>91 </span>92 ))}93 </p>94 </div>95 </footer>96 );97}98