Vrai-Prix — l'évaluation du vrai prix des propriétés résidentielles au Québec.
TypeScript 90.2%
JavaScript 3.5%
Python 3.4%
CSS 1.9%
HTML 0.6%
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// Constantes et aides SEO : URL canonique du site, slugs, libellés de types.34export const SITE_URL =5 process.env.NEXT_PUBLIC_SITE_URL ?? "https://www.vrai-prix.com";67export const SITE_NAME = "Vrai-Prix";89/** Slug URL d'un nom de municipalité (unique sur les 1 097 noms — vérifié). */10export function slugify(name: string): string {11 return name12 .normalize("NFD")13 // retire les diacritiques combinants (é → e)14 .replace(/[\u0300-\u036f]/g, "")15 .toLowerCase()16 .replace(/['’]/g, "-")17 .replace(/[^a-z0-9]+/g, "-")18 .replace(/^-+|-+$/g, "");19}2021/** type_prop (DB) → segment d'URL. */22export const TYPE_SLUGS: Record<string, string> = {23 unifamilial: "maison",24 plex: "plex",25 chalet: "chalet",26 condo_ou_multi: "condo",27 terrain: "terrain",28 maison_mobile: "maison-mobile",29 autre: "autre",30};3132/** segment d'URL → type_prop (DB). */33export const SLUG_TYPES: Record<string, string> = Object.fromEntries(34 Object.entries(TYPE_SLUGS).map(([k, v]) => [v, k])35);3637/** Libellés français des types de propriété. */38export const TYPE_LABELS: Record<string, { singulier: string; pluriel: string }> = {39 unifamilial: { singulier: "maison unifamiliale", pluriel: "maisons unifamiliales" },40 plex: { singulier: "plex", pluriel: "plex (2 à 5 logements)" },41 chalet: { singulier: "chalet", pluriel: "chalets et résidences secondaires" },42 condo_ou_multi: { singulier: "condo ou multirésidentiel", pluriel: "condos et multirésidentiel" },43 terrain: { singulier: "terrain", pluriel: "terrains vacants" },44 maison_mobile: { singulier: "maison mobile", pluriel: "maisons mobiles" },45 autre: { singulier: "autre propriété", pluriel: "autres propriétés" },46};4748/** 425 000 → « 425 000 $ » (fr-CA, sans décimales). */49export function moneyFr(v: number | null | undefined): string {50 if (v == null) return "—";51 return new Intl.NumberFormat("fr-CA", {52 style: "currency",53 currency: "CAD",54 maximumFractionDigits: 0,55 }).format(v);56}5758/** 3747008 → « 3 747 008 » (fr-CA). */59export function numFr(v: number): string {60 return v.toLocaleString("fr-CA");61}6263/** Millésime courant des estimations (dernier millésime du rôle chargé). */64export const EST_YEAR = 2026;65