Spreadsheet-UX op een echte relationele engine
Deze repository wordt als momentopname gepubliceerd: een clone bevat de volledige inhoud, maar geen commitgeschiedenis.
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;