initial booking

This commit is contained in:
Ola Malmgren
2026-05-22 10:50:48 +02:00
commit 4d705a1005
77 changed files with 13827 additions and 0 deletions

290
messages/en.json Normal file
View File

@@ -0,0 +1,290 @@
{
"common": {
"siteName": "Gasol247 Booking",
"eventName": "Jamboree 2027",
"languageSwedish": "Svenska",
"languageEnglish": "English",
"back": "Back",
"save": "Save",
"cancel": "Cancel",
"loading": "Loading…",
"submit": "Submit",
"currency": "SEK",
"vat": "VAT",
"ofWhichVat": "of which VAT",
"inclVat": "incl. VAT",
"exclVat": "excl. VAT",
"total": "Total",
"subtotal": "Subtotal",
"quantity": "Qty",
"price": "Price",
"search": "Search"
},
"header": {
"tagline": "Book LPG cylinders for the Jamboree camp",
"switchLanguage": "Switch language"
},
"booking": {
"title": "LPG cylinder order",
"intro": "Reserve LPG cylinders for your contingent at the camp. A confirmation will be sent to the email you provide.",
"stepProducts": "Choose products",
"stepDetails": "Your details",
"stepPickup": "Pickup",
"stepReview": "Review",
"stepProductsShort": "Products",
"stepDetailsShort": "Details",
"stepPickupShort": "Pickup",
"stepReviewShort": "Review",
"stepOf": "Step {current} of {total}",
"products": {
"title": "Choose products",
"subtitle": "Adjust the quantity for each cylinder size below.",
"addToCart": "Add",
"remove": "Remove",
"perUnit": "/unit",
"noneSelected": "Select at least one product to continue."
},
"details": {
"title": "Your details",
"organization": "Organization",
"orgName": "Organization name",
"orgNamePlaceholder": "Scout group, association, company …",
"orgNumber": "Organization number",
"orgNumberPlaceholder": "XXXXXX-XXXX",
"contact": "Contact person",
"contactName": "Name",
"contactNamePlaceholder": "First and last name",
"email": "Email",
"emailPlaceholder": "example@group.org",
"phone": "Phone",
"phonePlaceholder": "+46 …",
"invoiceAddress": "Invoice address",
"address": "Street address",
"postalCode": "Postal code",
"city": "City",
"country": "Country"
},
"pickup": {
"title": "Choose a pickup time",
"subtitle": "Pick a time when you can collect the cylinders at the camp site.",
"noSlots": "No pickup times are configured yet.",
"capacity": "{count} slots left"
},
"notes": {
"label": "Additional notes (optional)",
"placeholder": "Any preferences or information we should know."
},
"review": {
"title": "Review your order",
"confirm": "I confirm that the details are correct and accept that a booking is created.",
"submitting": "Submitting booking…"
},
"errors": {
"required": "This field is required",
"invalidEmail": "Enter a valid email address",
"invalidOrgNumber": "Enter a valid organization number (XXXXXX-XXXX)",
"selectProduct": "Select at least one product",
"submitFailed": "Something went wrong. Try again or contact us."
},
"success": {
"title": "Thank you! Your booking has been received.",
"subtitle": "A confirmation has been sent to {email}.",
"bookingNumber": "Booking number: {number}",
"newOrder": "Make another booking"
},
"next": "Next",
"previous": "Previous"
},
"admin": {
"title": "Administration",
"login": {
"title": "Sign in",
"email": "Email",
"password": "Password",
"submit": "Sign in",
"error": "Invalid email or password."
},
"nav": {
"bookings": "Bookings",
"products": "Products",
"pickupSlots": "Pickup slots",
"settings": "Settings",
"users": "Users",
"admins": "Admins",
"signOut": "Sign out"
},
"users": {
"title": "Administrators",
"empty": "No administrators.",
"new": "New administrator",
"edit": "Edit",
"create": "Create",
"save": "Save",
"delete": "Delete",
"deleteConfirm": "Are you sure you want to delete this administrator?",
"cannotDeleteSelf": "You can't delete your own account.",
"cannotDeleteLast": "There must be at least one administrator.",
"emailInUse": "Email is already used by another administrator.",
"passwordMismatch": "Passwords don't match.",
"passwordTooShort": "Password must be at least 8 characters.",
"passwordChanged": "Password updated.",
"you": "(you)",
"columns": {
"name": "Name",
"email": "Email",
"created": "Created",
"actions": "Actions"
},
"fields": {
"name": "Name",
"email": "Email",
"password": "Password",
"passwordConfirm": "Confirm password",
"newPassword": "New password",
"newPasswordHint": "Leave empty to keep the current password",
"passwordHint": "Minimum 8 characters"
},
"changePassword": "Change password"
},
"settings": {
"title": "Settings",
"saved": "Settings saved.",
"save": "Save",
"pickupEnabled": "Show pickup step in the booking form",
"pickupEnabledHint": "When off, the entire step is removed from the form and no pickup slot is selected. Existing bookings and pickup slots are not affected."
},
"products": {
"title": "Products",
"empty": "No products yet.",
"new": "New product",
"edit": "Edit",
"create": "Create",
"save": "Save",
"delete": "Delete",
"deleteConfirm": "Are you sure you want to delete this product?",
"cannotDelete": "Cannot delete — used in {count} booking(s). Deactivate it instead.",
"activate": "Activate",
"deactivate": "Deactivate",
"active": "Active",
"inactive": "Inactive",
"columns": {
"sku": "SKU",
"name": "Name",
"price": "Price",
"vat": "VAT",
"active": "Active",
"actions": "Actions"
},
"fields": {
"sku": "SKU",
"skuHint": "Unique code, e.g. P11",
"nameSv": "Name (Swedish)",
"nameEn": "Name (English)",
"descriptionSv": "Description (Swedish)",
"descriptionEn": "Description (English)",
"priceSek": "Price (SEK ex VAT)",
"vatPct": "VAT (%)",
"sortOrder": "Sort order",
"sortOrderHint": "Lower values appear first",
"active": "Active (shown in booking form)"
}
},
"pickupSlots": {
"title": "Pickup slots",
"empty": "No pickup slots yet.",
"new": "New slot",
"edit": "Edit",
"create": "Create",
"save": "Save",
"delete": "Delete",
"deleteConfirm": "Are you sure you want to delete this slot?",
"cannotDelete": "Cannot delete — chosen by {count} booking(s). Deactivate it instead.",
"activate": "Activate",
"deactivate": "Deactivate",
"columns": {
"label": "Label",
"when": "When",
"capacity": "Capacity",
"bookings": "Bookings",
"active": "Active",
"actions": "Actions"
},
"fields": {
"labelSv": "Label (Swedish)",
"labelEn": "Label (English)",
"labelHint": "e.g. \"Day 1 — Morning\"",
"startsAt": "Starts",
"endsAt": "Ends",
"capacity": "Capacity",
"capacityHint": "Maximum bookings that can choose this slot",
"active": "Active (shown in booking form)"
},
"invalidTime": "End time must be after start time."
},
"bookings": {
"title": "Bookings",
"empty": "No bookings yet.",
"columns": {
"number": "Booking #",
"date": "Date",
"org": "Organization",
"contact": "Contact",
"total": "Amount",
"status": "Status",
"actions": "Actions"
},
"filters": {
"all": "All",
"search": "Search booking #, org or email"
},
"export": "Export CSV",
"view": "View",
"detail": {
"title": "Booking {number}",
"items": "Products",
"customer": "Customer",
"pickup": "Pickup",
"totals": "Totals",
"markInvoiced": "Mark invoiced",
"markDelivered": "Mark delivered",
"markCancelled": "Cancel booking",
"resendEmail": "Resend confirmation"
},
"status": {
"PENDING": "Pending",
"CONFIRMED": "Confirmed",
"DELIVERED_PARTIAL": "Partly handed out",
"DELIVERED": "Handed out",
"RETURNED_PARTIAL": "Partly returned",
"RETURNED": "Returned",
"INVOICED": "Invoiced",
"CANCELLED": "Cancelled"
},
"fulfillment": {
"title": "Handout & return",
"ordered": "Ordered",
"delivered": "Handed out",
"returned": "Returned",
"outstanding": "Out",
"deliverAll": "Hand out all",
"returnAll": "Return all",
"save": "Save",
"saved": "Saved",
"deliveredHint": "Cylinders the customer has collected",
"returnedHint": "Cylinders that have come back",
"invalidValue": "Value out of allowed range"
}
}
},
"email": {
"subject": "Booking confirmation {number} — {event}",
"greeting": "Hi {name},",
"intro": "Thank you for ordering LPG cylinders for {event}. Here is your booking confirmation.",
"bookingNumber": "Booking number",
"orderSummary": "Order",
"pickup": "Pickup",
"invoiceInfo": "An invoice will be sent to your organization after the event.",
"questions": "Questions? Reply to this email and we will help you.",
"footer": "This is an automated confirmation from Gasol247."
}
}

290
messages/sv.json Normal file
View File

@@ -0,0 +1,290 @@
{
"common": {
"siteName": "Gasol247 Bokning",
"eventName": "Jamboree 2027",
"languageSwedish": "Svenska",
"languageEnglish": "English",
"back": "Tillbaka",
"save": "Spara",
"cancel": "Avbryt",
"loading": "Laddar…",
"submit": "Skicka in",
"currency": "kr",
"vat": "moms",
"ofWhichVat": "varav moms",
"inclVat": "inkl. moms",
"exclVat": "exkl. moms",
"total": "Totalt",
"subtotal": "Delsumma",
"quantity": "Antal",
"price": "Pris",
"search": "Sök"
},
"header": {
"tagline": "Boka gasoltuber till Jamboree-lägret",
"switchLanguage": "Byt språk"
},
"booking": {
"title": "Beställning av gasoltuber",
"intro": "Reservera gasoltuber till ert kontingent på lägret. Bekräftelse skickas till angiven e-postadress.",
"stepProducts": "Välj produkter",
"stepDetails": "Era uppgifter",
"stepPickup": "Upphämtning",
"stepReview": "Sammanfattning",
"stepProductsShort": "Produkter",
"stepDetailsShort": "Uppgifter",
"stepPickupShort": "Upphämtning",
"stepReviewShort": "Granska",
"stepOf": "Steg {current} av {total}",
"products": {
"title": "Välj produkter",
"subtitle": "Justera antalet av varje tubstorlek nedan.",
"addToCart": "Lägg till",
"remove": "Ta bort",
"perUnit": "/st",
"noneSelected": "Välj minst en produkt för att fortsätta."
},
"details": {
"title": "Era uppgifter",
"organization": "Organisation",
"orgName": "Organisationsnamn",
"orgNamePlaceholder": "Scoutkår, förening, företag …",
"orgNumber": "Organisationsnummer",
"orgNumberPlaceholder": "XXXXXX-XXXX",
"contact": "Kontaktperson",
"contactName": "Namn",
"contactNamePlaceholder": "För- och efternamn",
"email": "E-post",
"emailPlaceholder": "exempel@kar.se",
"phone": "Telefon",
"phonePlaceholder": "07X-XXX XX XX",
"invoiceAddress": "Fakturaadress",
"address": "Gatuadress",
"postalCode": "Postnummer",
"city": "Ort",
"country": "Land"
},
"pickup": {
"title": "Välj upphämtningstid",
"subtitle": "Välj en tid då ni kan hämta tuberna på lägerplatsen.",
"noSlots": "Inga upphämtningstider är konfigurerade ännu.",
"capacity": "{count} platser kvar"
},
"notes": {
"label": "Övriga meddelanden (valfritt)",
"placeholder": "Eventuella önskemål eller information vi bör veta om."
},
"review": {
"title": "Granska din beställning",
"confirm": "Jag bekräftar att uppgifterna stämmer och godkänner att en bokning skapas.",
"submitting": "Skickar bokning…"
},
"errors": {
"required": "Detta fält är obligatoriskt",
"invalidEmail": "Ange en giltig e-postadress",
"invalidOrgNumber": "Ange ett giltigt organisationsnummer (XXXXXX-XXXX)",
"selectProduct": "Välj minst en produkt",
"submitFailed": "Något gick fel. Försök igen eller kontakta oss."
},
"success": {
"title": "Tack! Din beställning är mottagen.",
"subtitle": "Bekräftelse är skickad till {email}.",
"bookingNumber": "Bokningsnummer: {number}",
"newOrder": "Gör ny beställning"
},
"next": "Nästa",
"previous": "Föregående"
},
"admin": {
"title": "Administration",
"login": {
"title": "Logga in",
"email": "E-post",
"password": "Lösenord",
"submit": "Logga in",
"error": "Felaktig e-post eller lösenord."
},
"nav": {
"bookings": "Bokningar",
"products": "Produkter",
"pickupSlots": "Upphämtningstider",
"settings": "Inställningar",
"users": "Användare",
"admins": "Administratörer",
"signOut": "Logga ut"
},
"users": {
"title": "Administratörer",
"empty": "Inga administratörer.",
"new": "Ny administratör",
"edit": "Redigera",
"create": "Skapa",
"save": "Spara",
"delete": "Ta bort",
"deleteConfirm": "Är du säker på att du vill ta bort denna administratör?",
"cannotDeleteSelf": "Du kan inte ta bort ditt eget konto.",
"cannotDeleteLast": "Det måste finnas minst en administratör.",
"emailInUse": "E-postadressen används redan av en annan administratör.",
"passwordMismatch": "Lösenorden matchar inte.",
"passwordTooShort": "Lösenordet måste vara minst 8 tecken.",
"passwordChanged": "Lösenordet har uppdaterats.",
"you": "(du)",
"columns": {
"name": "Namn",
"email": "E-post",
"created": "Skapad",
"actions": "Åtgärder"
},
"fields": {
"name": "Namn",
"email": "E-post",
"password": "Lösenord",
"passwordConfirm": "Bekräfta lösenord",
"newPassword": "Nytt lösenord",
"newPasswordHint": "Lämna tomt för att behålla nuvarande lösenord",
"passwordHint": "Minst 8 tecken"
},
"changePassword": "Byt lösenord"
},
"settings": {
"title": "Inställningar",
"saved": "Inställningarna är sparade.",
"save": "Spara",
"pickupEnabled": "Visa upphämtningssteget i bokningsformuläret",
"pickupEnabledHint": "När detta är av tas hela steget bort från formuläret och inga upphämtningstider väljs. Befintliga bokningar och upphämtningstider påverkas inte."
},
"products": {
"title": "Produkter",
"empty": "Inga produkter ännu.",
"new": "Ny produkt",
"edit": "Redigera",
"create": "Skapa",
"save": "Spara",
"delete": "Ta bort",
"deleteConfirm": "Är du säker på att du vill ta bort produkten?",
"cannotDelete": "Produkten kan inte tas bort — den används i {count} bokning(ar). Inaktivera den i stället.",
"activate": "Aktivera",
"deactivate": "Inaktivera",
"active": "Aktiv",
"inactive": "Inaktiv",
"columns": {
"sku": "SKU",
"name": "Namn",
"price": "Pris",
"vat": "Moms",
"active": "Aktiv",
"actions": "Åtgärder"
},
"fields": {
"sku": "SKU",
"skuHint": "Unik kod, t.ex. P11",
"nameSv": "Namn (svenska)",
"nameEn": "Namn (engelska)",
"descriptionSv": "Beskrivning (svenska)",
"descriptionEn": "Beskrivning (engelska)",
"priceSek": "Pris (kr exkl. moms)",
"vatPct": "Moms (%)",
"sortOrder": "Sorteringsordning",
"sortOrderHint": "Lägre värde visas först",
"active": "Aktiv (visas i bokningsformuläret)"
}
},
"pickupSlots": {
"title": "Upphämtningstider",
"empty": "Inga upphämtningstider ännu.",
"new": "Ny tid",
"edit": "Redigera",
"create": "Skapa",
"save": "Spara",
"delete": "Ta bort",
"deleteConfirm": "Är du säker på att du vill ta bort tiden?",
"cannotDelete": "Tiden kan inte tas bort — den är vald i {count} bokning(ar). Inaktivera den i stället.",
"activate": "Aktivera",
"deactivate": "Inaktivera",
"columns": {
"label": "Etikett",
"when": "När",
"capacity": "Kapacitet",
"bookings": "Bokningar",
"active": "Aktiv",
"actions": "Åtgärder"
},
"fields": {
"labelSv": "Etikett (svenska)",
"labelEn": "Etikett (engelska)",
"labelHint": "T.ex. \"Dag 1 — Förmiddag\"",
"startsAt": "Startar",
"endsAt": "Slutar",
"capacity": "Kapacitet",
"capacityHint": "Max antal bokningar som kan välja denna tid",
"active": "Aktiv (visas i bokningsformuläret)"
},
"invalidTime": "Sluttiden måste vara efter starttiden."
},
"bookings": {
"title": "Bokningar",
"empty": "Inga bokningar ännu.",
"columns": {
"number": "Boknings-nr",
"date": "Datum",
"org": "Organisation",
"contact": "Kontakt",
"total": "Belopp",
"status": "Status",
"actions": "Åtgärder"
},
"filters": {
"all": "Alla",
"search": "Sök boknings-nr, organisation eller e-post"
},
"export": "Exportera CSV",
"view": "Visa",
"detail": {
"title": "Bokning {number}",
"items": "Produkter",
"customer": "Kund",
"pickup": "Upphämtning",
"totals": "Summor",
"markInvoiced": "Markera fakturerad",
"markDelivered": "Markera levererad",
"markCancelled": "Avboka",
"resendEmail": "Skicka om bekräftelse"
},
"status": {
"PENDING": "Väntar",
"CONFIRMED": "Bekräftad",
"DELIVERED_PARTIAL": "Delvis utlämnad",
"DELIVERED": "Utlämnad",
"RETURNED_PARTIAL": "Delvis inlämnad",
"RETURNED": "Inlämnad",
"INVOICED": "Fakturerad",
"CANCELLED": "Avbokad"
},
"fulfillment": {
"title": "Utlämning & retur",
"ordered": "Beställt",
"delivered": "Utlämnat",
"returned": "Inlämnat",
"outstanding": "Ute",
"deliverAll": "Utlämna allt",
"returnAll": "Lämna in allt",
"save": "Spara",
"saved": "Sparat",
"deliveredHint": "Antal tuber som kunden hämtat",
"returnedHint": "Antal tuber som kommit tillbaka",
"invalidValue": "Värdet ligger utanför tillåtet intervall"
}
}
},
"email": {
"subject": "Bokningsbekräftelse {number} — {event}",
"greeting": "Hej {name},",
"intro": "Tack för din beställning av gasoltuber till {event}. Här är din bokningsbekräftelse.",
"bookingNumber": "Bokningsnummer",
"orderSummary": "Beställning",
"pickup": "Upphämtning",
"invoiceInfo": "Faktura skickas till organisationen efter eventet.",
"questions": "Har du frågor? Svara på detta mejl så hjälper vi dig.",
"footer": "Detta är en automatiserad bekräftelse från Gasol247."
}
}