Spreadsheet-UX op een echte relationele engine

main

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

6.3 kB Ruw bestand
import { formatCount, type Locale } from '@wellformed/shared';
import type { MessageCatalog } from './entry';

/** The billing dialog and the plan banner: plans, meters, trials, payments. */
export const billing = {
  'billing.planFor': {
    en: (name: string) => `Plan for ${name}`,
    nl: (name: string) => `Abonnement voor ${name}`,
  },
  'billing.usageIn': {
    en: (name: string) => `Usage in ${name}`,
    nl: (name: string) => `Gebruik in ${name}`,
  },
  'billing.thisWorkspace': { en: 'this workspace', nl: 'deze werkruimte' },
  'billing.manageOrCancel': { en: 'Manage or cancel', nl: 'Beheren of opzeggen' },
  'billing.loadFailed': {
    en: 'Could not read the plan for this workspace.',
    nl: 'Het abonnement voor deze werkruimte kon niet worden gelezen.',
  },

  'billing.licensedToBefore': { en: 'Licensed to ', nl: 'Gelicentieerd aan ' },
  'billing.licensedToAfter': {
    en: ', so nothing here is capped',
    nl: ', dus niets hier is begrensd',
  },
  'billing.ownLicence': {
    en: 'This installation runs under its own licence, so nothing here is capped',
    nl: 'Deze installatie draait onder een eigen licentie, dus niets hier is begrensd',
  },
  'billing.onPlanBefore': { en: 'On ', nl: 'Op ' },
  'billing.trialClause': {
    en: (plan: string, remaining: string) => ` — trial of ${plan}, ${remaining}`,
    nl: (plan: string, remaining: string) => ` — proefperiode van ${plan}, ${remaining}`,
  },
  'billing.pastDueClause': {
    en: ' — the last payment did not go through',
    nl: ' — de laatste betaling is niet gelukt',
  },
  'billing.endsClause': {
    en: (date: string) => ` — ends ${date}, nothing is deleted`,
    nl: (date: string) => ` — eindigt ${date}, er wordt niets verwijderd`,
  },

  /* The meters and the plan cards count in the reader's locale. */
  'billing.rows': { en: 'Rows', nl: 'Rijen' },
  'billing.tables': { en: 'Tables', nl: 'Tabellen' },
  'billing.count.rows': {
    en: (n: number, locale: Locale) => `${formatCount(n, locale)} rows`,
    nl: (n: number, locale: Locale) => `${formatCount(n, locale)} rijen`,
  },
  'billing.count.tables': {
    en: (n: number, locale: Locale) => `${formatCount(n, locale)} tables`,
    nl: (n: number, locale: Locale) => `${formatCount(n, locale)} tabellen`,
  },
  'billing.unlimited.rows': { en: 'unlimited rows', nl: 'onbeperkt veel rijen' },
  'billing.unlimited.tables': { en: 'unlimited tables', nl: 'onbeperkt veel tabellen' },
  'billing.usedOf': {
    en: (used: number, limit: string, locale: Locale) =>
      `${formatCount(used, locale)} of ${limit}`,
    nl: (used: number, limit: string, locale: Locale) =>
      `${formatCount(used, locale)} van ${limit}`,
  },

  'billing.invoicesGoTo': { en: 'Invoices go to', nl: 'Facturen gaan naar' },
  'billing.invoicesAddressed': {
    en: 'Invoices will be addressed there.',
    nl: 'Facturen gaan voortaan daarheen.',
  },
  'billing.needInvoiceAddress': {
    en: 'Say where the invoices should go before upgrading.',
    nl: 'Zeg eerst waar de facturen heen moeten voordat je upgradet.',
  },
  'billing.contactHint': {
    en: 'This address belongs to the workspace, so it stays put when people come and go — use the one your accounts are kept under, not a personal mailbox.',
    nl: 'Dit adres hoort bij de werkruimte, dus het blijft staan als mensen komen en gaan — gebruik het adres waar je boekhouding onder valt, geen persoonlijke mailbox.',
  },
  'billing.contactProviderHint': {
    en: (provider: string) =>
      ` Changing it here does not reach ${provider}, which holds its own copy from the checkout and is what the payment page will recognise.`,
    nl: (provider: string) =>
      ` Als je het hier wijzigt, bereikt dat ${provider} niet — die bewaart een eigen kopie van de checkout en dat is wat de betaalpagina herkent.`,
  },

  'billing.perMonth': { en: '/month', nl: '/maand' },
  'billing.currentPlan': { en: 'This is what applies now.', nl: 'Dit is wat nu geldt.' },
  'billing.upgrade': { en: 'Upgrade', nl: 'Upgraden' },
  'billing.noPaymentsBefore': {
    en: 'This installation takes no payments — whoever runs it moves a workspace between plans with ',
    nl: 'Deze installatie neemt geen betalingen aan — wie hem draait verplaatst een werkruimte tussen abonnementen met ',
  },
  'billing.noPaymentsAfter': { en: '.', nl: '.' },
  'billing.overLimitBefore': {
    en: 'Going over a limit only stops this workspace ',
    nl: 'Boven een limiet stopt alleen het ',
  },
  'billing.overLimitBold': { en: 'growing', nl: 'groeien' },
  'billing.overLimitAfter': {
    en: '. Reading, editing, deleting and exporting keep working, always.',
    nl: ' van deze werkruimte. Lezen, bewerken, verwijderen en exporteren blijven altijd werken.',
  },
  'billing.unmeteredHint': {
    en: 'There are no row or table limits on this installation, and nothing here expires. What it may be used for is whatever the licence for it says — this screen is not that agreement and does not enforce it.',
    nl: 'Deze installatie heeft geen rij- of tabellimieten, en niets hier verloopt. Waarvoor hij gebruikt mag worden staat in de licentie — dit scherm is die overeenkomst niet en dwingt hem niet af.',
  },

  /* "6 days left", never a raw timestamp — see daysLeft in BillingDialog. */
  'billing.daysLeft': {
    en: (n: number) => (n === 1 ? '1 day left' : `${n} days left`),
    nl: (n: number) => (n === 1 ? 'nog 1 dag' : `nog ${n} dagen`),
  },
  'billing.trialOver': { en: 'over', nl: 'voorbij' },

  /* The banner under the top bar. */
  'billing.pastDueBanner': {
    en: 'The last payment for this workspace did not go through. Nothing has been deleted.',
    nl: 'De laatste betaling voor deze werkruimte is niet gelukt. Er is niets verwijderd.',
  },
  'billing.fixPayment': { en: 'Fix the payment', nl: 'Betaling herstellen' },
  'billing.trialEndedBanner': {
    en: 'The trial has ended, so this workspace is on the free limits now.',
    nl: 'De proefperiode is afgelopen, dus deze werkruimte zit nu op de gratis limieten.',
  },
  'billing.seePlans': { en: 'See the plans', nl: 'Bekijk de abonnementen' },
  'billing.trialBanner': {
    en: (plan: string, remaining: string) =>
      `Trial of the ${plan} plan: ${remaining}. Nothing is deleted when it ends.`,
    nl: (plan: string, remaining: string) =>
      `Proefperiode van het ${plan}-abonnement: ${remaining}. Er wordt niets verwijderd als hij afloopt.`,
  },
} as const satisfies MessageCatalog;