Een dating-app op basis van brieven, niet van gezichten!

main

Deze repository wordt als momentopname gepubliceerd: een clone bevat de volledige inhoud, maar geen commitgeschiedenis.

2.7 kB Ruw bestand
/*
 * Getallen → Nederlands. Gedeeld door de twee uitvoervormen van `npm run health`: de terminal
 * (scripts/health.js) en de pagina (scripts/health-html.js). Ze staan hier zodat "20 u" en
 * "18% (702 van 3858)" op beide plekken hetzelfde betekenen én er hetzelfde uitzien; twee kopieën
 * van een afrondingsregel is één kopie te veel.
 */
import { GENDER_LABEL } from "../src/constants.js";

export const nl = (x, d = 1) => (x == null ? "—" : x.toFixed(d).replace(".", ","));

/*
 * Elk percentage draagt zijn n mee. Er wordt niets verzwegen bij kleine aantallen — 100% over twee
 * mensen mag er staan, zolang die twee er ook staat. Zonder noemer een streepje, want 0/0 is geen 0%.
 */
export const pct = (n, of) => (of ? `${Math.round((n / of) * 100)}% (${n} van ${of})` : "— (geen)");
export const pctShort = (n, of) => (of ? `${Math.round((n / of) * 100)}%` : "—");
export const share = (n, of) => (of ? n / of : 0);

export const per100 = (n, of) => (of ? `${nl((n / of) * 100)} per 100` : "—");

/* Seconden → iets wat een mens leest */
export const span = (sec) => {
  if (sec == null) return "—";
  const h = sec / 3600;
  if (h < 1) return `${Math.round(sec / 60)} min`;
  if (h < 48) return `${nl(h, 0)} u`;
  const d = h / 24;
  if (d < 21) return `${nl(d, 0)} d`;
  return `${nl(d / 7, 0)} wk`;
};
export const spanH = (h) => span(h == null ? null : h * 3600);

export const genderName = (g) => (g == null ? "iedereen" : GENDER_LABEL[g] ?? g);

export const weekLabel = (d) =>
  new Date(d).toLocaleDateString("nl-NL", { day: "numeric", month: "short", year: "2-digit" });

export const dateLabel = (d) =>
  new Date(d).toLocaleDateString("nl-NL", { day: "numeric", month: "long", year: "numeric" });

/*
 * De wachttijdbakken, afgetopt op de horizon van --settle. Zonder die aftopping staat er "7 tot 30
 * dagen" boven een telling die maar 14 dagen ver kijkt, en dat opschrift liegt dan. Bakken waarvan
 * de ondergrens al voorbij de horizon ligt vallen helemaal weg: die kunnen per definitie leeg zijn.
 */
export const waitBuckets = (row, settleDays) => {
  const horizon = settleDays * 24;
  return [[0, 24, row.b1], [24, 72, row.b2], [72, 168, row.b3], [168, 720, row.b4], [720, Infinity, row.b5]]
    .filter(([low]) => low < horizon)
    .map(([low, high, n]) => {
      const hi = Math.min(high, horizon) / 24;
      const label = low === 0 ? (hi === 1 ? "binnen een dag" : `binnen ${nl(hi, 0)} dagen`) : `${low / 24} tot ${nl(hi, 0)} dagen`;
      return { label, n: n ?? 0 };
    });
};

/* De middelste waarde; bij een even aantal de laagste van de twee — geen half proefprofiel */
export const median = (xs) => (xs.length ? [...xs].sort((a, b) => a - b)[Math.floor((xs.length - 1) / 2)] : null);