diff --git a/messages/de/marketing.json b/messages/de/marketing.json new file mode 100644 index 0000000..68cb1d5 --- /dev/null +++ b/messages/de/marketing.json @@ -0,0 +1,271 @@ +{ + "meta": { + "title": "Craftvia — Einsatz-App für Handwerk und Montage", + "description": "Aufträge, Planung, Zeiterfassung, Berichte und Abrechnung in einem System. Mobil, offline-fähig und mandantensicher — für Handwerks- und Montagebetriebe." + }, + "nav": { + "label": "Hauptnavigation", + "features": "Funktionen", + "planning": "Planung", + "mobile": "Baustelle", + "security": "Sicherheit", + "pricing": "Testphase", + "faq": "Fragen", + "login": "Anmelden", + "cta": "Kostenlos testen", + "menu": "Menü" + }, + "hero": { + "eyebrow": "Für Handwerks- und Montagebetriebe", + "title": "Handwerk. Digital auf Kurs.", + "subtitle": "Craftvia führt Auftrag, Planung, Zeiten, Material und Bericht an einer Stelle zusammen — im Büro am Rechner, auf der Baustelle am Telefon. Auch ohne Netz.", + "ctaPrimary": "14 Tage kostenlos testen", + "ctaSecondary": "Funktionen ansehen", + "bullet1": "In wenigen Minuten eingerichtet, ohne Installation", + "bullet2": "Offline nutzbar — Eingaben gehen nie verloren", + "bullet3": "Keine Zahlungsdaten für den Test nötig", + "mockup": { + "label": "Beispielansicht der Plantafel", + "board": "Plantafel", + "today": "Heute", + "crewNorth": "Team Nord", + "crewSouth": "Team Süd", + "job1": "Heizungswartung", + "job2": "Thermostatventile", + "job3": "Rückstauklappe", + "load": "7,5 h / 8 h", + "conflict": "Überbucht", + "live": "In Arbeit" + } + }, + "pillars": { + "title": "Was Craftvia zusammenhält", + "one": { + "title": "Ein Auftrag, eine Wahrheit", + "text": "Termin, Team, Zeiten, Material, Fotos und Bericht hängen am selben Auftrag — kein Zettel, keine Doppelerfassung." + }, + "two": { + "title": "Büro und Baustelle im Takt", + "text": "Das Büro plant, der Monteur arbeitet ab. Beide sehen denselben Stand, ohne Anruf." + }, + "three": { + "title": "Abschluss statt Nacharbeit", + "text": "Pflichtangaben, Fotos und Unterschrift werden vor Ort geprüft — der Auftrag ist fertig, wenn der Monteur vom Hof fährt." + } + }, + "features": { + "title": "Alles, was ein Einsatz braucht", + "sub": "Module, die zusammenarbeiten. Sie schalten frei, was Sie brauchen.", + "orders": { + "title": "Aufträge", + "text": "Vom Anruf bis zur Abnahme: anlegen, einplanen, zuweisen, Status jederzeit sehen. Eigene Auftragsarten mit Checklisten und Pflichtfotos." + }, + "board": { + "title": "Plantafel", + "text": "Aufträge per Maus auf Team und Tag ziehen. Auslastung, Überbuchung und Überschneidung sind sofort sichtbar." + }, + "live": { + "title": "Live-Lage", + "text": "Wer ist unterwegs, wer arbeitet, wer macht Pause — am Einsatzort des laufenden Auftrags. Ohne GPS-Ortung der Person." + }, + "time": { + "title": "Zeiterfassung", + "text": "Start, Pause, Ende mit einem Tipp. Fahrzeit und Arbeitszeit getrennt, Nachträge nur mit Begründung und Freigabe." + }, + "offline": { + "title": "Mobil und offline", + "text": "Im Keller, in der Tiefgarage, im Funkloch: Eingaben werden lokal gespeichert und automatisch nachgesendet." + }, + "reports": { + "title": "Bericht und Unterschrift", + "text": "Leistungsnachweis auf dem Gerät ausfüllen, Kunde unterschreibt direkt auf dem Display, das PDF geht an den Kunden." + }, + "material": { + "title": "Material", + "text": "Geplantes und tatsächlich verbautes Material erfassen, Abweichungen mit Grund — sauber für die Nachkalkulation." + }, + "billing": { + "title": "Abrechnungsübersicht", + "text": "Fertige Aufträge und erreichte Meilensteine laufen gesammelt auf: Zeiten, Material und Anfahrten als Grundlage für die Rechnung." + }, + "emergency": { + "title": "Notdienst", + "text": "Einsatz in Minuten anlegen, Pflichtangaben später nachziehen, Prüfung im Büro." + }, + "lotse": { + "title": "Lotse — der Assistent", + "text": "Der Monteur schreibt oder spricht wie im Chat. Der Lotse ordnet zu und fragt Fehlendes nach. Gebucht wird erst nach Bestätigung." + }, + "documents": { + "title": "Dokumente", + "text": "Pläne, Fotos und Datenblätter am Auftrag und am Objekt — auch unterwegs verfügbar." + }, + "imports": { + "title": "Auftragsimport", + "text": "Aufträge aus PDF einlesen: Daten werden vorgeschlagen und vor der Übernahme geprüft." + } + }, + "planning": { + "eyebrow": "Planung", + "title": "Die Woche im Blick, bevor sie schiefgeht", + "text": "Die Plantafel zeigt jede Kolonne mit ihrer Tageskapazität. Wird ein Tag zu voll oder überschneiden sich zwei Termine, steht es als Meldung auf der Karte — nicht erst im Anruf des Kunden.", + "point1": "Auslastung je Team und Tag in Prozent", + "point2": "Warnung bei Überbuchung, Überschneidung und unvollständiger Kolonne", + "point3": "Hinweis, wenn ein Einsatz länger dauert als geplant — und der Folgeauftrag wackelt", + "point4": "Vorschläge für Aufträge in der Nähe, wenn ein Team früher fertig ist" + }, + "mobile": { + "eyebrow": "Auf der Baustelle", + "title": "Vier Tipps, und der Einsatz ist dokumentiert", + "text": "Die mobile Ansicht ist für Handschuhe und helles Licht gebaut: große Flächen, klare Schritte, keine Suche im Menü.", + "step1": { + "title": "Anfahrt starten", + "text": "Fahrzeit läuft automatisch mit." + }, + "step2": { + "title": "Vor Ort arbeiten", + "text": "Checkliste abhaken, Fotos aufnehmen, Material buchen." + }, + "step3": { + "title": "Bericht ausfüllen", + "text": "Text diktieren oder tippen, Pflichtangaben werden geprüft." + }, + "step4": { + "title": "Unterschrift holen", + "text": "Kunde unterschreibt auf dem Display, PDF geht raus." + }, + "offlineNote": "Kein Netz? Alles läuft weiter und wird später automatisch übertragen." + }, + "lotse": { + "eyebrow": "Lotse", + "title": "Sagen, was war — statt Felder suchen", + "text": "Der Lotse versteht ganze Sätze, ordnet den Auftrag zu und fragt nach, was fehlt. Er zeigt eine Karte mit dem, was er buchen würde. Erst nach Bestätigung wird etwas geschrieben.", + "chatUser": "Auftrag fertig, Speicher eingebaut, 2 Stunden, einen Filter verbraucht", + "chatAssistant": "Ich ordne das Auftrag A-00042 zu, Wohnanlage Elbblick. Zwei Fragen: War die Anfahrt dabei, und soll ich den Auftrag technisch abschließen?", + "cardTitle": "Vorschlag", + "cardLine1": "2:00 Std. Arbeitszeit buchen", + "cardLine2": "1 × Filter als Material erfassen", + "cardLine3": "Auftrag technisch abschließen", + "cardConfirm": "Bestätigen", + "cardDiscard": "Verwerfen", + "note": "Rechte, Pflichtangaben und Freigaben gelten unverändert — der Assistent umgeht nichts." + }, + "steps": { + "title": "In drei Schritten startklar", + "one": { + "title": "Konto anlegen", + "text": "Firma eintragen, Testzeitraum wählen, E-Mail bestätigen. Auf Wunsch mit Beispieldaten zum Ausprobieren." + }, + "two": { + "title": "Team und Kunden anlegen", + "text": "Monteure einladen, Kolonnen bilden, Kunden und Objekte erfassen oder importieren." + }, + "three": { + "title": "Ersten Auftrag fahren", + "text": "Auftrag einplanen, Monteur arbeitet ihn mobil ab, Bericht kommt zurück ins Büro." + } + }, + "industries": { + "title": "Für Betriebe, die rausfahren", + "sub": "Gebaut für Montage und Service — unabhängig vom Gewerk.", + "shk": "Sanitär, Heizung, Klima", + "electric": "Elektrotechnik", + "cooling": "Kälte- und Lüftungstechnik", + "lifts": "Aufzüge, Tore, Antriebe", + "windows": "Fenster, Türen, Fassade", + "service": "Industrie- und Anlagenservice" + }, + "security": { + "eyebrow": "Sicherheit und Datenschutz", + "title": "Ihre Daten bleiben Ihre Daten", + "text": "Craftvia ist mandantenfähig gebaut: Jeder Betrieb sieht ausschließlich seine eigenen Daten — abgesichert bis in die Datenbank, nicht nur in der Oberfläche.", + "item1": { + "title": "Strikte Mandantentrennung", + "text": "Zugriffsregeln direkt in der Datenbank verhindern, dass Daten den Betrieb verlassen." + }, + "item2": { + "title": "Rollen und Rechte", + "text": "Admin, Backoffice, Teamleitung und Monteur sehen genau das, was sie brauchen. Serverseitig geprüft." + }, + "item3": { + "title": "Zwei-Faktor und Passkeys", + "text": "Anmeldung mit zweitem Faktor oder Passkey, erzwingbar für den ganzen Betrieb." + }, + "item4": { + "title": "Lückenloses Protokoll", + "text": "Jede schreibende Aktion wird revisionssicher protokolliert — wer, wann, was." + }, + "item5": { + "title": "Export jederzeit", + "text": "Ihre Daten lassen sich als Datei herunterladen — auch am Ende der Testphase." + }, + "item6": { + "title": "Sparsam mit Daten", + "text": "Standort heißt Einsatzort des laufenden Auftrags, keine Ortung von Personen." + } + }, + "trial": { + "eyebrow": "Testphase", + "title": "14 Tage testen, in Ruhe entscheiden", + "text": "Sie legen den Testzeitraum selbst fest und starten mit Beispieldaten oder leer. Nach Ablauf bleiben Ihre Daten lesbar und lassen sich exportieren — nichts verschwindet über Nacht.", + "point1": "Voller Funktionsumfang, keine Zahlungsdaten nötig", + "point2": "Erinnerung vor Ablauf, Verlängerung jederzeit möglich", + "point3": "Übernahme in die Vollversion ohne Datenumzug", + "cta": "Testphase starten", + "secondary": "Angebot anfragen", + "note": "Preise der Vollversion auf Anfrage — wir melden uns mit einem Vorschlag, der zur Betriebsgröße passt." + }, + "faq": { + "title": "Häufige Fragen", + "q1": { + "q": "Brauchen meine Monteure eine Schulung?", + "a": "Nein. Die mobile Ansicht führt durch den Einsatz: anfahren, arbeiten, dokumentieren, unterschreiben lassen. Die meisten Betriebe starten nach einer kurzen Einweisung." + }, + "q2": { + "q": "Funktioniert die App ohne Internet?", + "a": "Ja. Eingaben, Fotos und Zeiten werden auf dem Gerät gespeichert und automatisch übertragen, sobald wieder Verbindung besteht." + }, + "q3": { + "q": "Muss ich etwas installieren?", + "a": "Nein. Craftvia läuft im Browser und lässt sich auf dem Telefon wie eine App auf den Startbildschirm legen." + }, + "q4": { + "q": "Was passiert nach der Testphase?", + "a": "Ihre Daten bleiben lesbar und exportierbar. Sie können verlängern oder in die Vollversion wechseln — ohne Umzug der Daten." + }, + "q5": { + "q": "Kann ich bestehende Kunden und Aufträge übernehmen?", + "a": "Ja. Kunden und Objekte lassen sich importieren, Aufträge zusätzlich aus PDF einlesen und vor der Übernahme prüfen." + }, + "q6": { + "q": "Werden meine Monteure per GPS überwacht?", + "a": "Nein. Angezeigt wird der Einsatzort des laufenden Auftrags, nicht die Position des Geräts oder der Person." + }, + "q7": { + "q": "Ersetzt Craftvia meine Buchhaltung?", + "a": "Nein. Craftvia bereitet die Abrechnung auf — Zeiten, Material, Anfahrten und Meilensteine. Die Rechnung schreibt Ihre Buchhaltung." + }, + "q8": { + "q": "Wie viele Nutzer sind möglich?", + "a": "Vom Ein-Mann-Betrieb bis zu mehreren Kolonnen. Teams, Rollen und Kapazitäten legen Sie selbst fest." + } + }, + "closing": { + "title": "Bereit für den ersten Auftrag?", + "text": "Richten Sie Ihren Testzugang ein und planen Sie noch heute die erste Woche.", + "cta": "Kostenlos testen", + "login": "Ich habe schon ein Konto" + }, + "footer": { + "tagline": "Die Einsatz-App für Handwerks- und Montagebetriebe.", + "product": "Produkt", + "company": "Rechtliches", + "features": "Funktionen", + "trial": "Testphase", + "login": "Anmelden", + "terms": "Nutzungsbedingungen", + "privacy": "Datenschutz", + "imprint": "Impressum", + "rights": "Alle Rechte vorbehalten." + } +} diff --git a/messages/en/marketing.json b/messages/en/marketing.json new file mode 100644 index 0000000..935f717 --- /dev/null +++ b/messages/en/marketing.json @@ -0,0 +1,271 @@ +{ + "meta": { + "title": "Craftvia — field service app for trades and installation", + "description": "Jobs, scheduling, time tracking, reports and billing in one system. Mobile, offline-capable and tenant-safe — for trade and installation businesses." + }, + "nav": { + "label": "Main navigation", + "features": "Features", + "planning": "Scheduling", + "mobile": "On site", + "security": "Security", + "pricing": "Free trial", + "faq": "FAQ", + "login": "Sign in", + "cta": "Start free trial", + "menu": "Menu" + }, + "hero": { + "eyebrow": "For trade and installation businesses", + "title": "Craftwork. Digitally on course.", + "subtitle": "Craftvia brings jobs, scheduling, times, material and reports together — at the desk and on site. Even without a connection.", + "ctaPrimary": "Try it free for 14 days", + "ctaSecondary": "See the features", + "bullet1": "Set up in minutes, nothing to install", + "bullet2": "Works offline — entries are never lost", + "bullet3": "No payment details for the trial", + "mockup": { + "label": "Example of the scheduling board", + "board": "Scheduling board", + "today": "Today", + "crewNorth": "Crew North", + "crewSouth": "Crew South", + "job1": "Heating service", + "job2": "Thermostat valves", + "job3": "Backflow valve", + "load": "7.5 h / 8 h", + "conflict": "Overbooked", + "live": "Working" + } + }, + "pillars": { + "title": "What holds Craftvia together", + "one": { + "title": "One job, one truth", + "text": "Appointment, crew, times, material, photos and report belong to the same job — no notes, no double entry." + }, + "two": { + "title": "Office and site in sync", + "text": "The office plans, the technician works. Both see the same state, without a phone call." + }, + "three": { + "title": "Finished, not reworked", + "text": "Mandatory fields, photos and the signature are checked on site — the job is done when the technician drives off." + } + }, + "features": { + "title": "Everything a job needs", + "sub": "Modules that work together. Enable what you need.", + "orders": { + "title": "Jobs", + "text": "From the call to sign-off: create, schedule, assign, see the status. Custom job types with checklists and required photos." + }, + "board": { + "title": "Scheduling board", + "text": "Drag jobs onto a crew and a day. Utilisation, overbooking and overlaps are visible at once." + }, + "live": { + "title": "Live situation", + "text": "Who is en route, working or on a break — at the site of the running job. No GPS tracking of people." + }, + "time": { + "title": "Time tracking", + "text": "Start, pause, stop with one tap. Travel and work time separated; later corrections need a reason and approval." + }, + "offline": { + "title": "Mobile and offline", + "text": "In a basement or a dead spot: entries are stored on the device and sent automatically." + }, + "reports": { + "title": "Report and signature", + "text": "Fill in the service report on the device, the customer signs on screen, the PDF goes out." + }, + "material": { + "title": "Material", + "text": "Record planned and actually used material, deviations with a reason — clean for costing." + }, + "billing": { + "title": "Billing overview", + "text": "Completed jobs and reached milestones collect in one place: times, material and trips as the basis for the invoice." + }, + "emergency": { + "title": "Call-outs", + "text": "Create an emergency job in minutes, add the details later, review in the office." + }, + "lotse": { + "title": "Lotse — the assistant", + "text": "Technicians write or speak like in a chat. Lotse maps it to the job and asks what is missing. Nothing is booked before they confirm." + }, + "documents": { + "title": "Documents", + "text": "Plans, photos and datasheets on the job and the site — available on the road." + }, + "imports": { + "title": "Job import", + "text": "Read jobs from PDF: data is proposed and checked before it is accepted." + } + }, + "planning": { + "eyebrow": "Scheduling", + "title": "See the week before it goes wrong", + "text": "The board shows every crew with its daily capacity. If a day gets too full or two appointments overlap, it is written on the card — not in the customer's phone call.", + "point1": "Utilisation per crew and day in percent", + "point2": "Warnings for overbooking, overlap and incomplete crews", + "point3": "A hint when a job runs longer than planned — and the next one is at risk", + "point4": "Suggestions for nearby jobs when a crew finishes early" + }, + "mobile": { + "eyebrow": "On site", + "title": "Four taps and the job is documented", + "text": "The mobile view is built for gloves and bright light: large targets, clear steps, no hunting through menus.", + "step1": { + "title": "Start the drive", + "text": "Travel time runs automatically." + }, + "step2": { + "title": "Work on site", + "text": "Tick the checklist, take photos, record material." + }, + "step3": { + "title": "Fill in the report", + "text": "Dictate or type; mandatory fields are checked." + }, + "step4": { + "title": "Collect the signature", + "text": "The customer signs on screen, the PDF goes out." + }, + "offlineNote": "No connection? Everything keeps working and is transferred later." + }, + "lotse": { + "eyebrow": "Lotse", + "title": "Say what happened — instead of hunting for fields", + "text": "Lotse understands whole sentences, maps them to the job and asks for what is missing. It shows a card with what it would book. Nothing is written before you confirm.", + "chatUser": "Job done, installed the tank, two hours, used one filter", + "chatAssistant": "I'm mapping this to job A-00042, Elbblick apartments. Two questions: was travel included, and should I mark the job technically complete?", + "cardTitle": "Proposal", + "cardLine1": "Book 2:00 h of work time", + "cardLine2": "Record 1 × filter as material", + "cardLine3": "Mark the job technically complete", + "cardConfirm": "Confirm", + "cardDiscard": "Discard", + "note": "Permissions, mandatory fields and approvals still apply — the assistant bypasses nothing." + }, + "steps": { + "title": "Ready in three steps", + "one": { + "title": "Create the account", + "text": "Enter your company, pick the trial period, confirm your e-mail. With sample data if you like." + }, + "two": { + "title": "Add crew and customers", + "text": "Invite technicians, form crews, add or import customers and sites." + }, + "three": { + "title": "Run the first job", + "text": "Schedule it, the technician handles it on the phone, the report comes back to the office." + } + }, + "industries": { + "title": "For businesses that drive out", + "sub": "Built for installation and service — whatever the trade.", + "shk": "Plumbing, heating, air conditioning", + "electric": "Electrical engineering", + "cooling": "Refrigeration and ventilation", + "lifts": "Lifts, gates, drives", + "windows": "Windows, doors, façades", + "service": "Industrial and plant service" + }, + "security": { + "eyebrow": "Security and privacy", + "title": "Your data stays yours", + "text": "Craftvia is built multi-tenant: every business sees only its own data — enforced down in the database, not just in the interface.", + "item1": { + "title": "Strict tenant separation", + "text": "Access rules in the database itself keep data inside the business." + }, + "item2": { + "title": "Roles and permissions", + "text": "Admin, office, crew lead and technician see exactly what they need. Checked on the server." + }, + "item3": { + "title": "Two-factor and passkeys", + "text": "Sign in with a second factor or a passkey, enforceable for the whole business." + }, + "item4": { + "title": "Complete audit trail", + "text": "Every write is recorded — who, when, what." + }, + "item5": { + "title": "Export any time", + "text": "Download your data as a file — including at the end of the trial." + }, + "item6": { + "title": "Data minimalism", + "text": "Location means the site of the running job, never tracking of a person." + } + }, + "trial": { + "eyebrow": "Free trial", + "title": "Try it for 14 days, decide in peace", + "text": "You set the trial period yourself and start empty or with sample data. After it ends your data stays readable and exportable — nothing disappears overnight.", + "point1": "Full functionality, no payment details", + "point2": "Reminder before it ends, extension any time", + "point3": "Move to the full version without migrating data", + "cta": "Start the trial", + "secondary": "Request a quote", + "note": "Pricing for the full version on request — we come back with a proposal that fits your size." + }, + "faq": { + "title": "Frequently asked questions", + "q1": { + "q": "Do my technicians need training?", + "a": "No. The mobile view guides them through the job: drive, work, document, collect the signature. Most teams start after a short briefing." + }, + "q2": { + "q": "Does the app work without internet?", + "a": "Yes. Entries, photos and times are stored on the device and transferred automatically once there is a connection again." + }, + "q3": { + "q": "Do I have to install anything?", + "a": "No. Craftvia runs in the browser and can be added to the home screen like an app." + }, + "q4": { + "q": "What happens after the trial?", + "a": "Your data stays readable and exportable. You can extend or move to the full version — without migrating data." + }, + "q5": { + "q": "Can I bring existing customers and jobs?", + "a": "Yes. Customers and sites can be imported, jobs additionally read from PDF and checked before they are accepted." + }, + "q6": { + "q": "Are my technicians tracked by GPS?", + "a": "No. What is shown is the site of the running job, not the position of the device or the person." + }, + "q7": { + "q": "Does Craftvia replace my accounting?", + "a": "No. Craftvia prepares billing — times, material, trips and milestones. Your accounting writes the invoice." + }, + "q8": { + "q": "How many users are possible?", + "a": "From a one-person business to several crews. You define teams, roles and capacity yourself." + } + }, + "closing": { + "title": "Ready for the first job?", + "text": "Set up your trial access and plan the first week today.", + "cta": "Start free trial", + "login": "I already have an account" + }, + "footer": { + "tagline": "The field service app for trade and installation businesses.", + "product": "Product", + "company": "Legal", + "features": "Features", + "trial": "Free trial", + "login": "Sign in", + "terms": "Terms of use", + "privacy": "Privacy", + "imprint": "Imprint", + "rights": "All rights reserved." + } +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 2f55512..738f6f4 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,8 +1,21 @@ +import type { Metadata } from "next"; import { redirect } from "next/navigation"; +import { getTranslations } from "next-intl/server"; +import { MarketingHome } from "@/components/marketing/home"; import { auth } from "@/server/auth"; import { landingPath } from "@/server/app-access"; +export async function generateMetadata(): Promise { + const t = await getTranslations("marketing.meta"); + return { title: { absolute: t("title") }, description: t("description") }; +} + +/** + * Öffentliche Produktseite. Angemeldete Nutzer sehen sie nicht: Feldrollen → /m, + * Backoffice → /dashboard (ARCHITEKTUR §5). `/` ist deshalb in PUBLIC_PATHS (src/proxy.ts). + */ export default async function Home() { - // Feldrollen → /m, Backoffice → /dashboard (ARCHITEKTUR §5) - redirect(landingPath(await auth())); + const session = await auth(); + if (session?.user) redirect(landingPath(session)); + return ; } diff --git a/src/components/marketing/home.tsx b/src/components/marketing/home.tsx new file mode 100644 index 0000000..578b170 --- /dev/null +++ b/src/components/marketing/home.tsx @@ -0,0 +1,357 @@ +import Link from "next/link"; +import { getTranslations } from "next-intl/server"; +import { + ArrowRight, + Bot, + CalendarRange, + Check, + CheckCircle2, + ClipboardList, + Download, + EyeOff, + FileInput, + FileSignature, + FolderOpen, + KeyRound, + Layers, + MapPin, + Package, + Receipt, + ScrollText, + Siren, + Timer, + UsersRound, + WifiOff, + type LucideIcon, +} from "lucide-react"; +import { CraftviaLogo } from "@/components/brand/craftvia-logo"; +import { BRAND } from "@/lib/brand"; +import { BoardMockup, FieldMockup, LotseMockup } from "./mockups"; + +/** + * Öffentliche Startseite (Produktseite). Wird von `/` gerendert, solange keine Session besteht; + * angemeldete Nutzer leitet die Route auf Dashboard bzw. mobile Ansicht. Alle Texte kommen aus + * `messages//marketing.json` — keine Screenshots, die Vorschauen sind Markup (mockups.tsx). + */ + +const FEATURES: { key: string; icon: LucideIcon }[] = [ + { key: "orders", icon: ClipboardList }, + { key: "board", icon: CalendarRange }, + { key: "live", icon: MapPin }, + { key: "time", icon: Timer }, + { key: "offline", icon: WifiOff }, + { key: "reports", icon: FileSignature }, + { key: "material", icon: Package }, + { key: "billing", icon: Receipt }, + { key: "emergency", icon: Siren }, + { key: "lotse", icon: Bot }, + { key: "documents", icon: FolderOpen }, + { key: "imports", icon: FileInput }, +]; + +const SECURITY: { key: string; icon: LucideIcon }[] = [ + { key: "item1", icon: Layers }, + { key: "item2", icon: UsersRound }, + { key: "item3", icon: KeyRound }, + { key: "item4", icon: ScrollText }, + { key: "item5", icon: Download }, + { key: "item6", icon: EyeOff }, +]; + +const NAV = ["features", "planning", "mobile", "security", "pricing", "faq"] as const; +const FAQ = ["q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8"] as const; +const INDUSTRIES = ["shk", "electric", "cooling", "lifts", "windows", "service"] as const; + +const ctaCls = + "inline-flex min-h-12 items-center justify-center gap-2 rounded-lg bg-cta px-5 text-[15px] font-semibold text-cta-foreground hover:brightness-95 focus-visible:outline-2 focus-visible:outline-offset-2"; +const outlineCls = + "inline-flex min-h-12 items-center justify-center gap-2 rounded-lg border px-5 text-[15px] font-semibold hover:bg-muted focus-visible:outline-2 focus-visible:outline-offset-2"; + +export async function MarketingHome({ contactEmail }: { contactEmail?: string }) { + const t = await getTranslations("marketing"); + + return ( +
+
+
+ + + + +
+ + {t("nav.login")} + + + {t("nav.cta")} + +
+
+
+ +
+ {/* Hero */} +
+
+
+

{t("hero.eyebrow")}

+

{t("hero.title")}

+

{t("hero.subtitle")}

+
+ + {t("hero.ctaPrimary")} + + + + {t("hero.ctaSecondary")} + +
+
    + {(["bullet1", "bullet2", "bullet3"] as const).map((k) => ( +
  • + + {t(`hero.${k}`)} +
  • + ))} +
+
+ +
+
+ + {/* Leitgedanken */} +
+

{t("pillars.title")}

+
+ {(["one", "two", "three"] as const).map((k) => ( +
+

{t(`pillars.${k}.title`)}

+

{t(`pillars.${k}.text`)}

+
+ ))} +
+
+ + {/* Funktionen */} +
+
+

{t("features.title")}

+

{t("features.sub")}

+
    + {FEATURES.map(({ key, icon: Icon }) => ( +
  • + + + +

    {t(`features.${key}.title`)}

    +

    {t(`features.${key}.text`)}

    +
  • + ))} +
+
+
+ + {/* Planung */} +
+
+
+

{t("planning.eyebrow")}

+

{t("planning.title")}

+

{t("planning.text")}

+
    + {(["point1", "point2", "point3", "point4"] as const).map((k) => ( +
  • + + {t(`planning.${k}`)} +
  • + ))} +
+
+ +
+
+ + {/* Baustelle */} +
+
+
+

{t("mobile.eyebrow")}

+

{t("mobile.title")}

+

{t("mobile.text")}

+

+ + {t("mobile.offlineNote")} +

+
+ +
+
+ + {/* Lotse */} +
+
+
+

{t("lotse.eyebrow")}

+

{t("lotse.title")}

+

{t("lotse.text")}

+

{t("lotse.note")}

+
+ +
+
+ + {/* Ablauf */} +
+
+

{t("steps.title")}

+
    + {(["one", "two", "three"] as const).map((k, i) => ( +
  1. + {i + 1} +

    {t(`steps.${k}.title`)}

    +

    {t(`steps.${k}.text`)}

    +
  2. + ))} +
+
+
+ + {/* Gewerke */} +
+

{t("industries.title")}

+

{t("industries.sub")}

+
    + {INDUSTRIES.map((key) => ( +
  • + {t(`industries.${key}`)} +
  • + ))} +
+
+ + {/* Sicherheit */} +
+
+

{t("security.eyebrow")}

+

{t("security.title")}

+

{t("security.text")}

+
    + {SECURITY.map(({ key, icon: Icon }) => ( +
  • + + + +

    {t(`security.${key}.title`)}

    +

    {t(`security.${key}.text`)}

    +
  • + ))} +
+
+
+ + {/* Testphase */} +
+
+
+
+

{t("trial.eyebrow")}

+

{t("trial.title")}

+

{t("trial.text")}

+
    + {(["point1", "point2", "point3"] as const).map((k) => ( +
  • + + {t(`trial.${k}`)} +
  • + ))} +
+
+
+ + {t("trial.cta")} + + + {contactEmail && ( + + {t("trial.secondary")} + + )} +

{t("trial.note")}

+
+
+
+
+ + {/* Fragen */} +
+
+

{t("faq.title")}

+
+ {FAQ.map((key) => ( +
+ + {t(`faq.${key}.q`)} + + + +

{t(`faq.${key}.a`)}

+
+ ))} +
+
+
+ + {/* Abschluss */} +
+

{t("closing.title")}

+

{t("closing.text")}

+
+ + {t("closing.cta")} + + + + {t("closing.login")} + +
+
+
+ +
+
+
+ +

{t("footer.tagline")}

+
+ + +
+

+ © {new Date().getFullYear()} {BRAND.name} · {BRAND.tagline} · {t("footer.rights")} +

+
+
+ ); +} diff --git a/src/components/marketing/mockups.tsx b/src/components/marketing/mockups.tsx new file mode 100644 index 0000000..f7325f7 --- /dev/null +++ b/src/components/marketing/mockups.tsx @@ -0,0 +1,105 @@ +import { Check, MapPin, PenLine, Truck, Wrench } from "lucide-react"; +import { getTranslations } from "next-intl/server"; + +/** + * Abstrakte Produktvorschauen für die Startseite — bewusst als Markup statt Screenshot: + * bleibt scharf, mehrsprachig, ohne Bildassets und ohne Daten aus einem echten Mandanten. + */ + +const BAR = "h-2 rounded-full"; + +export async function BoardMockup() { + const t = await getTranslations("marketing.hero.mockup"); + const rows = [ + { crew: t("crewNorth"), load: t("load"), percent: 94, jobs: [t("job1"), t("job2")], tone: "var(--ok)" }, + { crew: t("crewSouth"), load: t("conflict"), percent: 113, jobs: [t("job3")], tone: "var(--warn)" }, + ]; + return ( +
+
+ {t("board")} + {t("today")} +
+
+ {rows.map((row) => ( +
+
+ {row.crew} + + {row.load} + +
+
+
+
+
    + {row.jobs.map((job) => ( +
  • + {job} +
  • + ))} +
+
+ ))} +
+

+ + {t("live")} +

+
+ ); +} + +export async function FieldMockup() { + const t = await getTranslations("marketing.mobile"); + const steps = [ + { icon: Truck, ...{ title: t("step1.title"), text: t("step1.text") } }, + { icon: Wrench, ...{ title: t("step2.title"), text: t("step2.text") } }, + { icon: PenLine, ...{ title: t("step3.title"), text: t("step3.text") } }, + { icon: Check, ...{ title: t("step4.title"), text: t("step4.text") } }, + ]; + return ( +
    + {steps.map((step, i) => { + const Icon = step.icon; + return ( +
  1. + + + +

    + {i + 1}. + {step.title} +

    +

    {step.text}

    +
  2. + ); + })} +
+ ); +} + +export async function LotseMockup() { + const t = await getTranslations("marketing.lotse"); + return ( +
+

{t("chatUser")}

+

{t("chatAssistant")}

+
+

{t("cardTitle")}

+
    + {[t("cardLine1"), t("cardLine2"), t("cardLine3")].map((line) => ( +
  • + + {line} +
  • + ))} +
+
+ {t("cardConfirm")} + {t("cardDiscard")} +
+
+
+ ); +} diff --git a/src/proxy.ts b/src/proxy.ts index 7b061ea..582daf4 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -11,7 +11,8 @@ import { NextResponse, type NextRequest } from "next/server"; // Enumeration-Neutralität und single-use-Tokens, nicht dieses Gate. // L15 Testphase: `/testen` (Wizard, Bestätigung, Nutzungsbedingungen, Datenschutz) ist öffentlich — // abgesichert über Rate-Limit je IP/E-Mail, Honeypot, Double-Opt-in und Enumeration-Neutralität. -const PUBLIC_PATHS = ["/login", "/api/auth", "/forgot-password", "/reset", "/invite", "/verify-email", "/platform/login", "/api/platform-auth", "/testen"]; +// Startseite ist die öffentliche Produktseite; angemeldete Nutzer leitet page.tsx weiter. +const PUBLIC_PATHS = ["/", "/login", "/api/auth", "/forgot-password", "/reset", "/invite", "/verify-email", "/platform/login", "/api/platform-auth", "/testen"]; // Plattform-Bereich (getrennte Session/Login): diese Routen werden über das // Plattform-Cookie gegatet und leiten anonyme Besucher auf /platform/login —