Docker Image bauen und veroeffentlichen / build-and-push (push) Successful in 2m21s
Chargen hatten bisher kein eigenes Bild-Feld (nur Ernten und Produkte) — neue Migration ergaenzt Batch.images (Json-Array, gleiches Muster wie Harvest.images/Product.images). Admin kann Chargenfotos jetzt unter /admin/chargen/[id] hochladen (AdminImageListField, identisch zum Ernten-Formular). Die oeffentliche Chargen-Seite (/charge/[code]) zeigt diese Fotos jetzt bevorzugt, faellt ohne eigene Chargenbilder weiterhin auf die Erntebilder zurueck. Hinweis fuer den naechsten Live-Deploy: die generierte Migration hat nebenbei eine bereits laenger bestehende Schema-Abweichung mitkorrigiert (harvests.images und products.images/tasteTags werden jetzt als NOT NULL erzwungen, wie im Schema schon laenger deklariert) - "prisma migrate deploy" schlaegt fehl, falls dort noch echte NULL-Werte stehen sollten. Co-Authored-By: Claude Sonnet 5 <[email protected]>
1186 lines
29 KiB
TypeScript
1186 lines
29 KiB
TypeScript
// Gemeinsamer Vertrag fuer alle Sprachversionen: jede Datei unter
|
|
// dictionaries/<code>.ts muss diesem Typ entsprechen. Fehlt in einer neuen
|
|
// Sprachdatei ein Schluessel oder stimmt ein Werttyp nicht, meldet TypeScript
|
|
// das beim Build — so kann eine neue Sprache nie "leise" unvollstaendig
|
|
// bleiben, ohne dass es dabei die deutschen Formulierungen 1:1 vorschreibt
|
|
// (die deutsche Datei ist keine Typquelle, sondern implementiert denselben
|
|
// Vertrag wie jede andere Sprache auch).
|
|
export interface TitledText {
|
|
title: string;
|
|
text: string;
|
|
}
|
|
|
|
// Slugs sind locale-unabhaengige URL-Bestandteile (bleiben in beiden Sprachen
|
|
// gleich, siehe lib/site-config.ts) — nur Titel/Anrisstext/Fliesstext pro
|
|
// Artikel werden uebersetzt. Als literale Union statt string, damit
|
|
// TypeScript erzwingt, dass jede Sprachdatei fuer JEDEN Slug einen Eintrag
|
|
// hat (kein leises Fehlen bei einer neuen Sprache).
|
|
export type WissenSlug =
|
|
| "warum-kristallisiert-honig"
|
|
| "fluessiger-oder-cremiger-honig"
|
|
| "was-bedeutet-fruehtracht"
|
|
| "was-bedeutet-sommertracht"
|
|
| "wie-entsteht-honig"
|
|
| "warum-schmeckt-jede-honigernte-anders"
|
|
| "wie-lange-ist-honig-haltbar"
|
|
| "was-macht-regionalen-honig-aus"
|
|
| "wie-honig-richtig-lagern"
|
|
| "warum-nie-ueber-28-grad-erwaermt";
|
|
|
|
export interface WissenArticleContent {
|
|
title: string;
|
|
excerpt: string;
|
|
body: string[];
|
|
}
|
|
|
|
export interface LegalSectionContent {
|
|
heading: string;
|
|
paragraphs: string[];
|
|
}
|
|
|
|
export interface Dictionary {
|
|
common: {
|
|
categories: {
|
|
HONIG: string;
|
|
KERZEN: string;
|
|
PROPOLIS: string;
|
|
};
|
|
siteDescription: string;
|
|
};
|
|
nav: {
|
|
shop: string;
|
|
harvests: string;
|
|
origin: string;
|
|
apiary: string;
|
|
business: string;
|
|
knowledge: string;
|
|
contact: string;
|
|
account: string;
|
|
discoverHoney: string;
|
|
searchPlaceholder: string;
|
|
openSearch: string;
|
|
openMenu: string;
|
|
closeMenu: string;
|
|
openCart: (count: number) => string;
|
|
skipToContent: string;
|
|
};
|
|
footer: {
|
|
columnWabenhain: string;
|
|
columnShopping: string;
|
|
columnLegal: string;
|
|
aboutUs: string;
|
|
businessCustomers: string;
|
|
trackOrder: string;
|
|
tagline: string;
|
|
bottomLine: string;
|
|
/** aria-label fuer die Social-Media-Icons im Footer, z.B. "Wabenhain bei TikTok". */
|
|
socialAriaLabel: (platform: string) => string;
|
|
};
|
|
legalTitles: {
|
|
impressum: string;
|
|
datenschutz: string;
|
|
agb: string;
|
|
widerruf: string;
|
|
versandZahlung: string;
|
|
cookieRichtlinie: string;
|
|
};
|
|
cart: {
|
|
title: string;
|
|
close: string;
|
|
empty: string;
|
|
remove: string;
|
|
subtotal: string;
|
|
checkout: string;
|
|
viewCart: string;
|
|
};
|
|
orderStatusBadge: {
|
|
NEU: string;
|
|
BEZAHLT: string;
|
|
IN_VORBEREITUNG: string;
|
|
VERSANDBEREIT: string;
|
|
VERSENDET: string;
|
|
ABHOLBEREIT: string;
|
|
ABGEHOLT: string;
|
|
STORNIERT: string;
|
|
};
|
|
orderStatusTimeline: {
|
|
ordered: string;
|
|
paid: string;
|
|
preparing: string;
|
|
readyToShip: string;
|
|
shipped: string;
|
|
readyForPickup: string;
|
|
pickedUp: string;
|
|
cancelled: string;
|
|
ariaLabel: string;
|
|
};
|
|
ordersPage: {
|
|
backToAccount: string;
|
|
title: string;
|
|
emptyTitle: string;
|
|
emptyDescription: string;
|
|
shippedOn: (date: string) => string;
|
|
shippingPending: string;
|
|
pickedUpOn: (date: string) => string;
|
|
pickupPending: string;
|
|
readySince: (date: string) => string;
|
|
giftMessagePrefix: string;
|
|
viewInvoice: string;
|
|
requestReturn: string;
|
|
reorder: string;
|
|
returnStatusLabels: {
|
|
ANGEFRAGT: string;
|
|
ANGENOMMEN: string;
|
|
ABGELEHNT: string;
|
|
ERSTATTET: string;
|
|
};
|
|
};
|
|
herkunftPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
subtitle: string;
|
|
aspects: TitledText[];
|
|
privacyNote: string;
|
|
};
|
|
imkereiPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
paragraphs: string[];
|
|
imageLabel: string;
|
|
};
|
|
unternehmenPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
subtitle: string;
|
|
packages: { key: string; title: string; text: string }[];
|
|
inquiryHeading: string;
|
|
};
|
|
businessInquiryForm: {
|
|
companyLabel: string;
|
|
contactPersonLabel: string;
|
|
emailLabel: string;
|
|
phoneOptionalLabel: string;
|
|
quantityLabel: string;
|
|
deliveryDateLabel: string;
|
|
packageLabel: string;
|
|
messageLabel: string;
|
|
submitting: string;
|
|
submit: string;
|
|
successMessage: string;
|
|
errorMessage: string;
|
|
};
|
|
legalPage: {
|
|
reviewNotice: string;
|
|
};
|
|
notFoundPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
text: string;
|
|
backToShop: string;
|
|
backToHome: string;
|
|
};
|
|
siteErrorPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
text: string;
|
|
retry: string;
|
|
backToHome: string;
|
|
};
|
|
cookieConsent: {
|
|
dialogLabel: string;
|
|
bannerTextBeforeLink: string;
|
|
policyLinkLabel: string;
|
|
bannerTextAfterLink: string;
|
|
essentialOnly: string;
|
|
acceptAll: string;
|
|
changeSettings: string;
|
|
};
|
|
impressumPage: {
|
|
title: string;
|
|
contactHeading: string;
|
|
phoneLabel: string;
|
|
emailLabel: string;
|
|
sections: LegalSectionContent[];
|
|
};
|
|
datenschutzPage: {
|
|
title: string;
|
|
sections: LegalSectionContent[];
|
|
};
|
|
agbPage: {
|
|
title: string;
|
|
sections: LegalSectionContent[];
|
|
};
|
|
widerrufPage: {
|
|
title: string;
|
|
sections: LegalSectionContent[];
|
|
};
|
|
versandZahlungPage: {
|
|
title: string;
|
|
shippingHeading: string;
|
|
shippingIntro: string;
|
|
tierRange: (min: number, max: number, price: string) => string;
|
|
tierMinimum: (min: number, price: string) => string;
|
|
tierFallback: string;
|
|
pickupNote: string;
|
|
paymentHeading: string;
|
|
paymentText: string;
|
|
deliveryTimeHeading: string;
|
|
deliveryTimeText: string;
|
|
};
|
|
cookieRichtliniePage: {
|
|
title: string;
|
|
sections: LegalSectionContent[];
|
|
};
|
|
wissenListPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
readMore: string;
|
|
};
|
|
wissenArticlePage: {
|
|
backLabel: string;
|
|
eyebrow: string;
|
|
otherArticlesHeading: string;
|
|
};
|
|
wissenArticles: Record<WissenSlug, WissenArticleContent>;
|
|
kontaktPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
pickupHeading: string;
|
|
pickupText: string;
|
|
};
|
|
twoFactorPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
subtitle: string;
|
|
backLabel: string;
|
|
activeStatus: (count: number) => string;
|
|
disableHeading: string;
|
|
passwordConfirmLabel: string;
|
|
disableButton: string;
|
|
setupButton: string;
|
|
};
|
|
wishlistPage: {
|
|
title: string;
|
|
emptyTitle: string;
|
|
emptyDescription: string;
|
|
};
|
|
twoFactorCodePage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
subtitle: string;
|
|
cancelLabel: string;
|
|
codeLabel: string;
|
|
confirm: string;
|
|
};
|
|
twoFactorBackupCodesPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
subtitle: string;
|
|
warning: string;
|
|
done: string;
|
|
};
|
|
twoFactorSetupPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
subtitle: string;
|
|
backLabel: string;
|
|
qrAlt: string;
|
|
manualEntryLabel: string;
|
|
appCodeLabel: string;
|
|
activate: string;
|
|
};
|
|
retourePage: {
|
|
backLabel: string;
|
|
orderEyebrow: (orderNumber: string) => string;
|
|
title: string;
|
|
reasonLabel: string;
|
|
reasonPlaceholder: string;
|
|
submit: string;
|
|
};
|
|
erntenPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
batchCount: (count: number) => string;
|
|
emptyText: string;
|
|
};
|
|
erntenDetailPage: {
|
|
backLabel: string;
|
|
batchesHeading: string;
|
|
productsHeading: string;
|
|
glassesAvailable: (remaining: number, total: number) => string;
|
|
};
|
|
chargePage: {
|
|
verifiedBatch: string;
|
|
provenanceNote: (code: string) => string;
|
|
stepHarvest: string;
|
|
stepFilling: string;
|
|
stepBestBefore: string;
|
|
regionLabel: string;
|
|
fromThisBatch: string;
|
|
};
|
|
newsletterBestaetigtPage: {
|
|
eyebrow: string;
|
|
confirmedTitle: string;
|
|
invalidTitle: string;
|
|
unsubscribedTitle: string;
|
|
confirmedText: string;
|
|
invalidText: string;
|
|
unsubscribedText: string;
|
|
backHome: string;
|
|
discountHeading: string;
|
|
discountText: (percent: number) => string;
|
|
discountCopyHint: string;
|
|
};
|
|
adminReviewsPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
searchLabel: string;
|
|
searchPlaceholder: string;
|
|
filterButton: string;
|
|
resetFilter: string;
|
|
noResultsFiltered: string;
|
|
colProduct: string;
|
|
colCustomer: string;
|
|
colRating: string;
|
|
colComment: string;
|
|
colDate: string;
|
|
colStatus: string;
|
|
statusPublished: string;
|
|
statusPending: string;
|
|
approve: string;
|
|
deleteConfirm: string;
|
|
delete: string;
|
|
noReviewsYet: string;
|
|
};
|
|
adminAuditLogPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
intro: (limit: number) => string;
|
|
colTimestamp: string;
|
|
colAdmin: string;
|
|
colAction: string;
|
|
colObject: string;
|
|
colDetails: string;
|
|
noEntriesYet: string;
|
|
};
|
|
adminVouchersPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
newVoucher: string;
|
|
colCode: string;
|
|
colDiscount: string;
|
|
colMinOrder: string;
|
|
colMinQuantity: string;
|
|
colUsage: string;
|
|
colValidity: string;
|
|
colStatus: string;
|
|
immediately: string;
|
|
unlimited: string;
|
|
statusActive: string;
|
|
statusInactive: string;
|
|
edit: string;
|
|
deleteConfirm: (code: string) => string;
|
|
delete: string;
|
|
noVouchersYet: string;
|
|
};
|
|
adminVoucherEditPage: {
|
|
backToVouchers: string;
|
|
title: string;
|
|
codeLabel: string;
|
|
typeLabel: string;
|
|
typePercent: string;
|
|
typeFixed: string;
|
|
valueLabel: string;
|
|
minOrderLabel: string;
|
|
minQuantityLabel: string;
|
|
maxUsesLabel: string;
|
|
validFromLabel: string;
|
|
validUntilLabel: string;
|
|
activeLabel: string;
|
|
redeemedSoFar: (count: number, max: number | null) => string;
|
|
save: string;
|
|
};
|
|
adminVoucherNewPage: {
|
|
backToVouchers: string;
|
|
title: string;
|
|
codeLabel: string;
|
|
codePlaceholder: string;
|
|
typeLabel: string;
|
|
typePercent: string;
|
|
typeFixed: string;
|
|
valueLabel: string;
|
|
minOrderLabel: string;
|
|
minQuantityLabel: string;
|
|
maxUsesLabel: string;
|
|
validFromLabel: string;
|
|
validUntilLabel: string;
|
|
activeLabel: string;
|
|
create: string;
|
|
};
|
|
adminShippingPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
newTier: string;
|
|
intro: string;
|
|
colQuantity: string;
|
|
colPrice: string;
|
|
quantityFrom: (min: number) => string;
|
|
quantityRange: (min: number, max: number) => string;
|
|
edit: string;
|
|
deleteConfirm: string;
|
|
delete: string;
|
|
noTiersYet: string;
|
|
};
|
|
adminShippingEditPage: {
|
|
backToShipping: string;
|
|
title: string;
|
|
minQuantityLabel: string;
|
|
maxQuantityLabel: string;
|
|
priceLabel: string;
|
|
save: string;
|
|
};
|
|
adminShippingNewPage: {
|
|
backToShipping: string;
|
|
title: string;
|
|
minQuantityLabel: string;
|
|
maxQuantityLabel: string;
|
|
priceLabel: string;
|
|
create: string;
|
|
};
|
|
adminUsersPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
newUser: string;
|
|
searchLabel: string;
|
|
searchPlaceholder: string;
|
|
filterButton: string;
|
|
resetFilter: string;
|
|
noResultsFiltered: string;
|
|
colName: string;
|
|
colEmail: string;
|
|
colRole: string;
|
|
colStatus: string;
|
|
col2fa: string;
|
|
colCreated: string;
|
|
roleCustomer: string;
|
|
roleAdmin: string;
|
|
youSuffix: string;
|
|
statusBlocked: string;
|
|
statusTemporarilyLocked: string;
|
|
statusActive: string;
|
|
edit: string;
|
|
unblock: string;
|
|
block: string;
|
|
delete: string;
|
|
deleteConfirm: (name: string) => string;
|
|
noUsersYet: string;
|
|
};
|
|
adminUserEditPage: {
|
|
backToUsers: string;
|
|
createdOn: (date: string) => string;
|
|
firstNameLabel: string;
|
|
lastNameLabel: string;
|
|
emailLabel: string;
|
|
phoneLabel: string;
|
|
roleLabel: string;
|
|
roleCustomer: string;
|
|
roleAdmin: string;
|
|
cannotChangeOwnRole: string;
|
|
save: string;
|
|
securityHeading: string;
|
|
twoFactorLabel: string;
|
|
twoFactorActive: string;
|
|
twoFactorInactive: string;
|
|
statusLabel: string;
|
|
blockedSince: (date: string) => string;
|
|
temporarilyLockedFailedAttempts: string;
|
|
statusActive: string;
|
|
sendPasswordReset: string;
|
|
unblock: string;
|
|
block: string;
|
|
deleteAccount: string;
|
|
deleteConfirm: (name: string) => string;
|
|
};
|
|
adminUserNewPage: {
|
|
backToUsers: string;
|
|
title: string;
|
|
intro: string;
|
|
firstNameLabel: string;
|
|
lastNameLabel: string;
|
|
emailLabel: string;
|
|
roleLabel: string;
|
|
roleCustomer: string;
|
|
roleAdmin: string;
|
|
createAndSend: string;
|
|
};
|
|
adminBatchesPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
colBatch: string;
|
|
colHarvest: string;
|
|
colFillDate: string;
|
|
colBestBefore: string;
|
|
colTotalGlasses: string;
|
|
colRemaining: string;
|
|
edit: string;
|
|
delete: string;
|
|
deleteConfirm: (code: string) => string;
|
|
noBatchesYet: string;
|
|
newBatchHeading: string;
|
|
codeLabel: string;
|
|
codePlaceholder: string;
|
|
harvestLabel: string;
|
|
fillDateLabel: string;
|
|
bestBeforeDateLabel: string;
|
|
glassCountLabel: string;
|
|
remainingGlassesLabel: string;
|
|
create: string;
|
|
};
|
|
adminBatchEditPage: {
|
|
backToBatches: string;
|
|
title: string;
|
|
fillDateLabel: string;
|
|
bestBeforeDateLabel: string;
|
|
glassCountLabel: string;
|
|
remainingGlassesLabel: string;
|
|
imagesLabel: string;
|
|
save: string;
|
|
};
|
|
trackOrderPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
intro: string;
|
|
orderNumberLabel: string;
|
|
orderNumberPlaceholder: string;
|
|
submit: string;
|
|
notFoundError: string;
|
|
rateLimitError: string;
|
|
itemsHeading: string;
|
|
totalLabel: string;
|
|
viewInvoice: string;
|
|
};
|
|
passwordStrength: {
|
|
weak: string;
|
|
fair: string;
|
|
strong: string;
|
|
};
|
|
shipmentInfo: {
|
|
heading: string;
|
|
carrierLabel: string;
|
|
trackingNumberLabel: string;
|
|
trackPackage: string;
|
|
};
|
|
errorPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
description: string;
|
|
retry: string;
|
|
backHome: string;
|
|
};
|
|
adminHarvestsPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
colType: string;
|
|
colYear: string;
|
|
colHarvestDate: string;
|
|
colLocation: string;
|
|
colBatches: string;
|
|
colProducts: string;
|
|
colStatus: string;
|
|
statusPublished: string;
|
|
statusDraft: string;
|
|
publish: string;
|
|
unpublish: string;
|
|
edit: string;
|
|
delete: string;
|
|
deleteConfirm: (label: string) => string;
|
|
noHarvestsYet: string;
|
|
newHarvestHeading: string;
|
|
typeLabel: string;
|
|
yearLabel: string;
|
|
harvestDateLabel: string;
|
|
locationLabel: string;
|
|
descriptionLabel: string;
|
|
isPublishedLabel: string;
|
|
create: string;
|
|
syncHeading: string;
|
|
syncIntro: string;
|
|
syncButton: string;
|
|
/** created, updated, skipped, failed */
|
|
syncResult: (created: number, updated: number, skipped: number, failed: number) => string;
|
|
syncError: string;
|
|
/** created, skipped, failed */
|
|
batchSyncResult: (created: number, skipped: number, failed: number) => string;
|
|
batchSyncError: string;
|
|
};
|
|
adminHarvestEditPage: {
|
|
backToHarvests: string;
|
|
title: string;
|
|
typeLabel: string;
|
|
yearLabel: string;
|
|
harvestDateLabel: string;
|
|
locationLabel: string;
|
|
descriptionLabel: string;
|
|
imagesLabel: string;
|
|
isPublishedLabel: string;
|
|
isPublishedHint: string;
|
|
draftNotice: string;
|
|
publishNow: string;
|
|
save: string;
|
|
};
|
|
adminProductsPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
newProduct: string;
|
|
colProduct: string;
|
|
colCategory: string;
|
|
colHarvest: string;
|
|
colBatch: string;
|
|
colWeight: string;
|
|
colPrice: string;
|
|
colStock: string;
|
|
colStatus: string;
|
|
statusActive: string;
|
|
statusInactive: string;
|
|
edit: string;
|
|
noProductsYet: string;
|
|
};
|
|
adminProductEditPage: {
|
|
backToProducts: string;
|
|
title: string;
|
|
harvestBatchSuffix: (type: string, year: number, code: string) => string;
|
|
nameLabel: string;
|
|
descriptionLabel: string;
|
|
tasteTagsLabel: string;
|
|
consistencyLabel: string;
|
|
intensityMildLabel: string;
|
|
intensityFloralLabel: string;
|
|
intensityKraeftigLabel: string;
|
|
weightLabel: string;
|
|
stockLabel: string;
|
|
priceLabel: string;
|
|
pricePerKgLabel: string;
|
|
imagesLabel: string;
|
|
visibleInShop: string;
|
|
save: string;
|
|
};
|
|
adminProductNewPage: {
|
|
backToProducts: string;
|
|
title: string;
|
|
nameLabel: string;
|
|
slugLabel: string;
|
|
categoryLabel: string;
|
|
categoryHint: string;
|
|
harvestLabel: string;
|
|
noneOption: string;
|
|
batchLabel: string;
|
|
batchOption: (code: string, type: string, year: number) => string;
|
|
descriptionLabel: string;
|
|
tasteTagsLabel: string;
|
|
tasteTagsPlaceholder: string;
|
|
consistencyLabel: string;
|
|
consistencyPlaceholder: string;
|
|
intensityMildLabel: string;
|
|
intensityFloralLabel: string;
|
|
intensityKraeftigLabel: string;
|
|
weightLabel: string;
|
|
stockLabel: string;
|
|
priceLabel: string;
|
|
pricePerKgLabel: string;
|
|
pricePlaceholder: string;
|
|
pricePerKgPlaceholder: string;
|
|
imagesLabel: string;
|
|
visibleInShop: string;
|
|
create: string;
|
|
};
|
|
adminReturnsPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
searchLabel: string;
|
|
searchPlaceholder: string;
|
|
filterButton: string;
|
|
resetFilter: string;
|
|
noResultsFiltered: string;
|
|
statusRequested: string;
|
|
statusAccepted: string;
|
|
statusRejected: string;
|
|
statusRefunded: string;
|
|
accept: string;
|
|
reject: string;
|
|
refundNow: string;
|
|
noRequestsYet: string;
|
|
};
|
|
adminInquiriesPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
searchLabel: string;
|
|
searchPlaceholder: string;
|
|
filterButton: string;
|
|
resetFilter: string;
|
|
noResultsFiltered: string;
|
|
statusNew: string;
|
|
statusInProgress: string;
|
|
statusCompleted: string;
|
|
statusRejected: string;
|
|
save: string;
|
|
packageLabel: string;
|
|
quantityLabel: string;
|
|
unitsSuffix: (quantity: number) => string;
|
|
deliveryDateLabel: string;
|
|
noInquiriesYet: string;
|
|
};
|
|
adminOrderDetailPage: {
|
|
backToOrders: string;
|
|
saveStatus: string;
|
|
giftHeading: string;
|
|
customerHeading: string;
|
|
registeredAccount: string;
|
|
guestOrder: string;
|
|
shippingAddressHeading: string;
|
|
pickupHeading: string;
|
|
shippedOn: (date: string) => string;
|
|
notShippedYet: string;
|
|
pickedUpOn: (date: string) => string;
|
|
notPickedUpYet: string;
|
|
readySince: (date: string) => string;
|
|
itemsHeading: string;
|
|
colProduct: string;
|
|
colBatch: string;
|
|
colQuantity: string;
|
|
colTotal: string;
|
|
subtotalLabel: string;
|
|
shippingLabel: string;
|
|
freeShipping: string;
|
|
discountLabel: string;
|
|
totalLabel: string;
|
|
paymentHeading: string;
|
|
paidOn: (date: string) => string;
|
|
noPaymentYet: string;
|
|
invoiceHeading: string;
|
|
downloadPdf: string;
|
|
noInvoiceYet: string;
|
|
trackingHeading: string;
|
|
carrierLabel: string;
|
|
carrierPlaceholder: string;
|
|
trackingNumberLabel: string;
|
|
saveTracking: string;
|
|
dhlHeading: string;
|
|
dhlCreateButton: string;
|
|
dhlAlreadyCreated: (trackingNumber: string) => string;
|
|
dhlNotConfigured: string;
|
|
};
|
|
adminOrdersPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
searchLabel: string;
|
|
searchPlaceholder: string;
|
|
statusLabel: string;
|
|
statusAll: string;
|
|
filterButton: string;
|
|
resetFilter: string;
|
|
colNumber: string;
|
|
colCustomer: string;
|
|
colDate: string;
|
|
colItems: string;
|
|
colTotal: string;
|
|
colStatus: string;
|
|
colFulfillment: string;
|
|
giftOrderTitle: string;
|
|
save: string;
|
|
shipping: string;
|
|
pickup: string;
|
|
noResultsFiltered: string;
|
|
noOrdersYet: string;
|
|
};
|
|
adminDashboardPage: {
|
|
title: string;
|
|
statRevenueToday: string;
|
|
statRevenueMonth: string;
|
|
statOpenOrders: string;
|
|
statInventory: string;
|
|
statSoldGlasses: string;
|
|
statAvgCart: string;
|
|
statRepeatCustomers: string;
|
|
topProductsHeading: string;
|
|
noSalesYet: string;
|
|
unitsSuffix: (quantity: number) => string;
|
|
revenueByCategoryHeading: string;
|
|
revenueTrendHeading: (days: number) => string;
|
|
daysAgoLabel: (days: number) => string;
|
|
todayLabel: string;
|
|
topVouchersHeading: string;
|
|
noVouchersYet: string;
|
|
usedCountLabel: (count: number, maxUses: number | null) => string;
|
|
viewAllOrders: string;
|
|
};
|
|
adminContentPage: {
|
|
backToDashboard: string;
|
|
title: string;
|
|
intro: string;
|
|
sectionImages: string;
|
|
sectionImagesIntro: string;
|
|
sectionText: string;
|
|
sectionTextIntro: string;
|
|
groupCompany: string;
|
|
groupHome: string;
|
|
groupPages: string;
|
|
groupLegal: string;
|
|
groupSocial: string;
|
|
deLabel: string;
|
|
enLabel: string;
|
|
save: string;
|
|
saved: string;
|
|
};
|
|
/** Gemeinsame Texte fuer AdminImageField/AdminImageListField (Bild-Upload
|
|
* in admin/inhalte, admin/produkte, admin/ernten). */
|
|
adminImageField: {
|
|
none: string;
|
|
chooseFile: string;
|
|
uploading: string;
|
|
remove: string;
|
|
removeImageAt: (position: number) => string;
|
|
uploadError: string;
|
|
};
|
|
/** Wie adminImageField, aber fuer AdminVideoField (Hero-Hintergrundvideo,
|
|
* admin/inhalte). */
|
|
adminVideoField: {
|
|
none: string;
|
|
chooseFile: string;
|
|
uploading: string;
|
|
remove: string;
|
|
uploadError: string;
|
|
};
|
|
adminShell: {
|
|
navDashboard: string;
|
|
navOrders: string;
|
|
navReturns: string;
|
|
navProducts: string;
|
|
navHarvests: string;
|
|
navBatches: string;
|
|
navBusinessInquiries: string;
|
|
navUsers: string;
|
|
navShipping: string;
|
|
navVouchers: string;
|
|
navReviews: string;
|
|
navAuditLog: string;
|
|
navContent: string;
|
|
navAriaLabel: string;
|
|
mobileNavAriaLabel: string;
|
|
openMenu: string;
|
|
closeMenu: string;
|
|
loggedInAs: (name: string) => string;
|
|
logout: string;
|
|
twoFactorWarning: string;
|
|
twoFactorSetupLink: string;
|
|
};
|
|
invoicePage: {
|
|
loginRequiredError: string;
|
|
backToOrders: string;
|
|
downloadPdf: string;
|
|
invoiceLabel: (invoiceNumber: string) => string;
|
|
orderLabel: (orderNumber: string) => string;
|
|
dateLabel: string;
|
|
itemHeader: string;
|
|
quantityHeader: string;
|
|
priceHeader: string;
|
|
totalHeader: string;
|
|
subtotalLabel: string;
|
|
shippingLabel: string;
|
|
freeShipping: string;
|
|
discountLabel: string;
|
|
totalLabel: string;
|
|
legalNote: string;
|
|
};
|
|
addressesPage: {
|
|
title: string;
|
|
standard: string;
|
|
setDefault: string;
|
|
delete: string;
|
|
emptyTitle: string;
|
|
emptyDescription: string;
|
|
addNewHeading: string;
|
|
labelField: string;
|
|
labelDefaultValue: string;
|
|
useAsDefault: string;
|
|
save: string;
|
|
};
|
|
account: {
|
|
eyebrow: string;
|
|
loginRegisterTitle: string;
|
|
login: string;
|
|
register: string;
|
|
emailLabel: string;
|
|
passwordLabel: string;
|
|
passwordMinLabel: string;
|
|
passwordConfirmLabel: string;
|
|
firstNameLabel: string;
|
|
lastNameLabel: string;
|
|
forgotPassword: string;
|
|
ssoDivider: string;
|
|
ssoButton: string;
|
|
greeting: (name: string) => string;
|
|
verifyEmailPrompt: string;
|
|
resendVerification: string;
|
|
navOrders: { title: string; description: string };
|
|
navAddresses: { title: string; description: string };
|
|
navWishlist: { title: string; description: string };
|
|
navSecurity: { title: string; twoFactorLabel: string; twoFactorActive: string; twoFactorInactive: string };
|
|
navAdmin: { title: string; description: string };
|
|
newsletterHeading: string;
|
|
newsletterSubscribed: string;
|
|
newsletterNotSubscribed: string;
|
|
subscribe: string;
|
|
unsubscribe: string;
|
|
logoutAllDevicesHeading: string;
|
|
logoutAllDevicesDescription: string;
|
|
logout: string;
|
|
privacy: {
|
|
heading: string;
|
|
downloadDataHeading: string;
|
|
downloadDataDescription: string;
|
|
downloadDataButton: string;
|
|
deleteAccountHeading: string;
|
|
deleteAccountDescription: string;
|
|
deleteAccountPasswordLabel: string;
|
|
deleteAccountButton: string;
|
|
deleteAccountConfirm: string;
|
|
deleteAccountAdminBlocked: string;
|
|
};
|
|
};
|
|
trustBadges: {
|
|
sslEncrypted: string;
|
|
securePayment: string;
|
|
returnPolicy: string;
|
|
};
|
|
passwortVergessenPage: {
|
|
backLabel: string;
|
|
title: string;
|
|
sentMessage: string;
|
|
intro: string;
|
|
requestLink: string;
|
|
};
|
|
passwortZuruecksetzenPage: {
|
|
backLabel: string;
|
|
title: string;
|
|
incompleteLinkTextBefore: string;
|
|
incompleteLinkLabel: string;
|
|
incompleteLinkTextAfter: string;
|
|
newPasswordLabel: string;
|
|
save: string;
|
|
};
|
|
checkoutSuccessPage: {
|
|
pendingEyebrow: string;
|
|
successEyebrow: string;
|
|
pendingTitle: string;
|
|
successTitle: string;
|
|
orderNumberLabel: string;
|
|
pendingText: string;
|
|
successText: string;
|
|
continueShopping: string;
|
|
trackOrder: string;
|
|
};
|
|
checkoutCancelPage: {
|
|
eyebrow: string;
|
|
title: string;
|
|
text: string;
|
|
backToCart: string;
|
|
};
|
|
checkoutPage: {
|
|
eyebrow: string;
|
|
emptyCart: string;
|
|
yourDetails: string;
|
|
firstName: string;
|
|
lastName: string;
|
|
email: string;
|
|
phoneOptional: string;
|
|
fulfillmentLabel: string;
|
|
shippingOption: string;
|
|
pickupOption: string;
|
|
deliveryTimeNote: string;
|
|
streetLabel: string;
|
|
zipLabel: string;
|
|
cityLabel: string;
|
|
discountCodeLabel: string;
|
|
discountCodePlaceholder: string;
|
|
isGiftLabel: string;
|
|
giftMessageLabel: string;
|
|
giftMessagePlaceholder: string;
|
|
genericError: string;
|
|
submitting: string;
|
|
placeOrder: string;
|
|
paymentMethodsNote: string;
|
|
yourOrderHeading: string;
|
|
shippingWithCount: (count: number) => string;
|
|
shippingPickup: string;
|
|
};
|
|
cartPage: {
|
|
title: string;
|
|
goToShop: string;
|
|
shippingLabel: (count: number) => string;
|
|
free: string;
|
|
total: string;
|
|
nextTierHint: (unitsUntilNext: number, nextPrice: string) => string;
|
|
pickupHint: string;
|
|
bulkDiscountProgress: (unitsUntilNext: number, percent: number) => string;
|
|
discountLabel: string;
|
|
};
|
|
product: {
|
|
tasteMild: string;
|
|
tasteFloral: string;
|
|
tasteIntense: string;
|
|
addToCart: string;
|
|
added: string;
|
|
outOfStock: string;
|
|
onlyLeft: (count: number) => string;
|
|
toHoney: string;
|
|
toProduct: string;
|
|
viewProduct: string;
|
|
};
|
|
productPage: {
|
|
reviewsLink: (count: number) => string;
|
|
noReviews: string;
|
|
shippingHint: (price: string) => string;
|
|
onlyLeftInStock: (count: number) => string;
|
|
soldOut: string;
|
|
currentlyUnavailable: string;
|
|
notifyMeLabel: string;
|
|
emailPlaceholder: string;
|
|
notifySubmit: string;
|
|
removeFromWishlist: string;
|
|
addToWishlist: string;
|
|
loginToSave: string;
|
|
loginLinkLabel: string;
|
|
checklist: {
|
|
HONIG: string[];
|
|
KERZEN: string[];
|
|
PROPOLIS: string[];
|
|
};
|
|
detailLabels: {
|
|
description: string;
|
|
origin: string;
|
|
harvest: string;
|
|
batch: string;
|
|
storage: string;
|
|
note: string;
|
|
};
|
|
storageText: string;
|
|
infantWarningText: string;
|
|
nonHoneyOriginText: string;
|
|
viewBatchOrigin: string;
|
|
giftHint: string;
|
|
learnMoreLabel: string;
|
|
reviewsHeading: string;
|
|
noReviewsForProduct: string;
|
|
loginToReview: string;
|
|
alreadyReviewed: string;
|
|
alreadyReviewedPending: string;
|
|
onlyBuyersCanReview: string;
|
|
yourRating: string;
|
|
commentPlaceholder: string;
|
|
submitReview: string;
|
|
relatedProductsHeading: string;
|
|
recentlyViewedHeading: string;
|
|
starsOutOf5: (rating: number) => string;
|
|
starLabel: (value: number) => string;
|
|
};
|
|
shop: {
|
|
eyebrow: string;
|
|
title: string;
|
|
subtitle: string;
|
|
allCategories: string;
|
|
sortLabel: string;
|
|
sortNewest: string;
|
|
sortPriceAsc: string;
|
|
sortPriceDesc: string;
|
|
sortAvailability: string;
|
|
apply: string;
|
|
onlyAvailable: string;
|
|
searchInputLabel: string;
|
|
clearSearch: string;
|
|
searchResults: (query: string, count: number) => string;
|
|
noSearchResults: string;
|
|
noProducts: string;
|
|
productsHeading: string;
|
|
};
|
|
home: {
|
|
hero: {
|
|
intro: string;
|
|
ctaPrimary: string;
|
|
ctaSecondary: string;
|
|
footnote: string;
|
|
};
|
|
currentHarvest: {
|
|
eyebrow: string;
|
|
title: string;
|
|
subtitle: string;
|
|
};
|
|
originStory: {
|
|
eyebrow: string;
|
|
title: string;
|
|
paragraph1: string;
|
|
paragraph2: string;
|
|
facts: string[];
|
|
cta: string;
|
|
};
|
|
philosophy: {
|
|
eyebrow: string;
|
|
title: string;
|
|
items: TitledText[];
|
|
};
|
|
productSpotlight: {
|
|
description: string;
|
|
consistency: string;
|
|
harvest: string;
|
|
batch: string;
|
|
weight: string;
|
|
price: string;
|
|
cta: string;
|
|
};
|
|
processTimeline: {
|
|
eyebrow: string;
|
|
title: string;
|
|
steps: { number: string; title: string; text: string }[];
|
|
};
|
|
regionalSection: {
|
|
eyebrow: string;
|
|
title: string;
|
|
paragraph1: string;
|
|
paragraph2: string;
|
|
ctaAbout: string;
|
|
ctaPickup: string;
|
|
};
|
|
sustainability: {
|
|
eyebrow: string;
|
|
title: string;
|
|
items: TitledText[];
|
|
};
|
|
businessTeaser: {
|
|
eyebrow: string;
|
|
title: string;
|
|
paragraph: string;
|
|
cta: string;
|
|
};
|
|
reviews: {
|
|
eyebrow: string;
|
|
title: string;
|
|
googleReviewsCount: (rating: string, count: number) => string;
|
|
seeAllOnGoogle: string;
|
|
starsOutOf5: (rating: number) => string;
|
|
testimonials: { quote: string; author: string }[];
|
|
};
|
|
newsletter: {
|
|
eyebrow: string;
|
|
title: string;
|
|
description: string;
|
|
successMessage: string;
|
|
emailPlaceholder: string;
|
|
subscribe: string;
|
|
subscribing: string;
|
|
errorMessage: string;
|
|
consentBeforeLink: string;
|
|
consentAfterLink: string;
|
|
privacyLinkLabel: string;
|
|
};
|
|
};
|
|
}
|