// Base catalog — the source of truth for this app's UI strings. Every key here // MUST be mirrored in `de.ts` (and any other locale); `defineLocale()` // enforces that parity at build time, so a missing translation fails typecheck // rather than silently falling back. // // Messages use ICU syntax: `{name}` placeholders, `{n, plural, …}`, and rich // tags like `` (rendered by passing a matching function to // ` {c} }} />`). import { defineCatalog } from '@voltro/i18n' export default defineCatalog({ // Browser tab titles + description — locale-aware via each page's `meta({ locale })`. 'meta.landing.title': 'Admin', 'meta.landing.description': 'An auto-admin back-office that discovers your api’s entities and renders a live, permission-gated, undoable UI per entity.', 'meta.login.title': 'Sign in', 'meta.overview.title': 'Overview', 'meta.entity.title': 'Entity', // ---- Marketing header ((marketing)/layout.tsx) ---- 'nav.admin': 'Admin', 'nav.signIn': 'Sign in', 'lang.label': 'Language', // ---- Public landing ((marketing)/index.tsx) ---- 'landing.heading': 'The back-office, done for you.', 'landing.body': 'This admin reads your api’s capability map at runtime and renders a live, reactive DataTable + AutoForm for every entity it exposes — gated on the access each procedure itself declares, with a per-row provenance drawer and universal undo/redo. Point it at any Voltro api and it adapts; the page code under src/pages/admin/ is yours to edit.', 'landing.cta': 'Sign in to the admin →', // ---- Public sign-in ((marketing)/login.tsx) ---- 'login.heading': 'Sign in', 'login.body': 'No real auth here — this button sets a demo session cookie so you can see the admin gate let you through.', 'login.cta': 'Continue as Demo Admin →', // ---- Admin shell (admin/layout.tsx) ---- 'admin.undo': '↶ Undo', 'admin.redo': '↷ Redo', 'admin.nav.overview': 'Overview', 'admin.nav.discovering': 'discovering…', 'admin.nav.backToSite': '← Back to site', // ---- Admin overview (admin/index.tsx) ---- 'overview.heading': 'Entities', 'overview.intro': 'Discovered from app’s capability map. Each card is a live, permission-gated CRUD view — no per-entity code.', 'overview.error': 'Couldn’t reach the api’s capability map. Is the api running with inspect enabled?', 'overview.columns': '{count, plural, one {# column} other {# columns}}', 'overview.reactiveSuffix': ' · reactive', 'overview.readonly': 'read-only', 'overview.empty': 'No user entities exposed by this api.', 'overview.serverOnly': '{count, plural, one {# server-only column, hidden} other {# server-only columns, hidden}}', // ---- Per-entity CRUD (admin/[entity].tsx) ---- 'entity.create': 'Create', 'entity.addLabel': 'Add {table}', 'entity.rows': 'Rows', 'entity.noList': 'This entity exposes no list query.', 'entity.empty': 'No {table} yet.', 'entity.why': 'Why?', 'entity.delete': 'Delete', 'entity.unknown': 'No entity {entity} in this api’s capability map.', // ---- Declared access, shown rather than guessed (admin/[entity].tsx) ---- 'entity.requires': 'requires {scopes}', 'entity.openAccess': 'open access — {reason}', 'entity.accessUndeclared': 'no access decision declared', 'entity.accessUnknown': 'This api checks permission per row, so only it can answer. The control is shown; the api decides when you submit.', // ---- Exposure axes, straight from the schema (admin/[entity].tsx) ---- 'entity.serverOnly': '{count, plural, one {# server-only column} other {# server-only columns}} never leave the api and cannot be submitted: {names}', 'entity.sensitive': 'Personal data — masked in exports: {names}', 'entity.notEditable': 'No single primary key, so rows can’t be addressed for edit or delete. List only.', // ---- Provenance drawer (admin/[entity].tsx) ---- 'prov.title': 'Provenance · {table} #{id}', 'prov.close': 'close', 'prov.loading': 'loading…', 'prov.none': 'No provenance (is audit() on this table + inspect enabled?).', 'prov.lastWrite': 'last write', 'prov.byActor': 'by actor', 'prov.attribution': 'attribution', 'prov.via': ' (via {via})', 'prov.derived': 'derived', 'prov.yes': 'yes', // ---- Scoped fallbacks (admin/error.tsx, not-found.tsx) ---- 'error.heading': 'Something went wrong', 'error.retry': 'Try again', 'notFound.heading': 'Not found', 'notFound.body': 'That admin page doesn’t exist.', 'notFound.back': '← Back to overview', } as const)