feat: modernize landing page design, localize login/forgot password forms, and add public privacy/imprint pages
All checks were successful
Staging Build / build (push) Successful in 2m42s
All checks were successful
Staging Build / build (push) Successful in 2m42s
This commit is contained in:
59
shop/app/datenschutz/page.tsx
Normal file
59
shop/app/datenschutz/page.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import Link from 'next/link'
|
||||||
|
import { ArrowLeft, Lock } from 'lucide-react'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
|
||||||
|
export default function Datenschutz() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-slate-950 text-slate-100 py-16 px-4">
|
||||||
|
<div className="container max-w-3xl mx-auto space-y-8">
|
||||||
|
<Link href="/">
|
||||||
|
<Button variant="ghost" size="sm" className="gap-2 text-slate-400 hover:text-white">
|
||||||
|
<ArrowLeft className="w-4 h-4" /> Zurück zur Startseite
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="inline-flex p-3 bg-blue-500/10 rounded-xl text-blue-400">
|
||||||
|
<Lock className="w-6 h-6" />
|
||||||
|
</div>
|
||||||
|
<h1 className="text-4xl font-extrabold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-white via-slate-100 to-slate-400">
|
||||||
|
Datenschutzerklärung
|
||||||
|
</h1>
|
||||||
|
<p className="text-slate-400">Informationen über die Verarbeitung Ihrer personenbezogenen Daten.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr className="border-slate-900" />
|
||||||
|
|
||||||
|
<div className="space-y-6 text-slate-300">
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-xl font-bold text-white">1. Datenschutz auf einen Blick</h2>
|
||||||
|
<p className="text-sm text-slate-400 leading-relaxed">
|
||||||
|
Wir nehmen den Schutz Ihrer persönlichen Daten sehr ernst. Personenbezogene Daten werden auf dieser Webseite nur im technisch notwendigen Umfang erhoben und verarbeitet. Die nachfolgenden Erklärungen geben Ihnen einen Überblick darüber, wie wir diesen Schutz gewährleisten und welche Art von Daten zu welchem Zweck erhoben werden.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-xl font-bold text-white">2. Verantwortliche Stelle</h2>
|
||||||
|
<p className="text-sm text-slate-400 leading-relaxed">
|
||||||
|
Verantwortlich für die Datenverarbeitung auf dieser Website ist die CASPOS GmbH (Anschrift siehe Impressum).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-xl font-bold text-white">3. Datenerfassung auf unserer Website</h2>
|
||||||
|
<p className="text-sm text-slate-400 leading-relaxed">
|
||||||
|
Ihre Daten werden zum einen dadurch erhoben, dass Sie uns diese mitteilen. Hierbei kann es sich z. B. um Daten handeln, die Sie in ein Kontakt- oder Bestellformular eingeben. Andere Daten werden automatisch beim Besuch der Website durch unsere IT-Systeme erfasst. Das sind vor allem technische Daten (z. B. Internetbrowser, Betriebssystem oder Uhrzeit des Seitenaufrufs).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-xl font-bold text-white">4. Ihre Rechte</h2>
|
||||||
|
<p className="text-sm text-slate-400 leading-relaxed">
|
||||||
|
Sie haben jederzeit das Recht, unentgeltlich Auskunft über Herkunft, Empfänger und Zweck Ihrer gespeicherten personenbezogenen Daten zu erhalten. Sie haben außerdem ein Recht, die Berichtigung, Sperrung oder Löschung dieser Daten zu verlangen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
69
shop/app/impressum/page.tsx
Normal file
69
shop/app/impressum/page.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import Link from 'next/link'
|
||||||
|
import { ArrowLeft, Shield } from 'lucide-react'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
|
||||||
|
export default function Impressum() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-slate-950 text-slate-100 py-16 px-4">
|
||||||
|
<div className="container max-w-3xl mx-auto space-y-8">
|
||||||
|
<Link href="/">
|
||||||
|
<Button variant="ghost" size="sm" className="gap-2 text-slate-400 hover:text-white">
|
||||||
|
<ArrowLeft className="w-4 h-4" /> Zurück zur Startseite
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="inline-flex p-3 bg-blue-500/10 rounded-xl text-blue-400">
|
||||||
|
<Shield className="w-6 h-6" />
|
||||||
|
</div>
|
||||||
|
<h1 className="text-4xl font-extrabold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-white via-slate-100 to-slate-400">
|
||||||
|
Impressum
|
||||||
|
</h1>
|
||||||
|
<p className="text-slate-400">Angaben gemäß § 5 TMG.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr className="border-slate-900" />
|
||||||
|
|
||||||
|
<div className="space-y-6 text-slate-300">
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-lg font-bold text-white">CASPOS GmbH</h2>
|
||||||
|
<p className="text-sm text-slate-400">
|
||||||
|
Musterstraße 123<br />
|
||||||
|
12345 Musterstadt
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-lg font-bold text-white">Vertreten durch:</h2>
|
||||||
|
<p className="text-sm text-slate-400">Max Mustermann (Geschäftsführer)</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-lg font-bold text-white">Kontakt:</h2>
|
||||||
|
<p className="text-sm text-slate-400">
|
||||||
|
Telefon: +49 (0) 123 456789<br />
|
||||||
|
E-Mail: info@caspos.de
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-lg font-bold text-white">Registereintrag:</h2>
|
||||||
|
<p className="text-sm text-slate-400">
|
||||||
|
Eintragung im Handelsregister.<br />
|
||||||
|
Registergericht: Amtsgericht Musterstadt<br />
|
||||||
|
Registernummer: HRB 12345
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="space-y-2">
|
||||||
|
<h2 className="text-lg font-bold text-white">Umsatzsteuer-ID:</h2>
|
||||||
|
<p className="text-sm text-slate-400">
|
||||||
|
Umsatzsteuer-Identifikationsnummer gemäß §27 a Umsatzsteuergesetz:<br />
|
||||||
|
DE 123456789
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,110 +1,391 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
import { createClient } from '@/lib/supabase/client'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { ArrowRight, CheckCircle2, ShoppingCart, Utensils, Layers } from 'lucide-react'
|
import { motion } from 'framer-motion'
|
||||||
import { Navbar } from '@/components/Navbar'
|
import {
|
||||||
|
ArrowRight,
|
||||||
|
CheckCircle2,
|
||||||
|
ShoppingCart,
|
||||||
|
Utensils,
|
||||||
|
Layers,
|
||||||
|
Users,
|
||||||
|
ClipboardList,
|
||||||
|
Zap,
|
||||||
|
ArrowUpRight,
|
||||||
|
ShieldCheck,
|
||||||
|
Sparkles,
|
||||||
|
Activity
|
||||||
|
} from 'lucide-react'
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
const [user, setUser] = useState<any>(null)
|
||||||
|
const [mounted, setMounted] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true)
|
||||||
|
const supabase = createClient()
|
||||||
|
supabase.auth.getUser().then(({ data: { user } }) => {
|
||||||
|
setUser(user)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const containerVariants = {
|
||||||
|
hidden: { opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
staggerChildren: 0.15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemVariants = {
|
||||||
|
hidden: { y: 20, opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
y: 0,
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
type: "spring" as const,
|
||||||
|
stiffness: 100,
|
||||||
|
damping: 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="min-h-screen bg-slate-950 text-slate-100 overflow-hidden relative selection:bg-blue-500/30 selection:text-blue-200">
|
||||||
{/* Hero Section: Zielgerichtet auf Lizenzen */}
|
|
||||||
<section className="w-full py-12 md:py-24 lg:py-32 xl:py-48 px-4 overflow-hidden relative">
|
{/* Background Decorative Animated Blobs */}
|
||||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-[1000px] h-[600px] bg-blue-600/10 blur-[120px] rounded-full -z-10 opacity-30" />
|
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full max-w-7xl h-[600px] pointer-events-none -z-10 overflow-hidden">
|
||||||
<div className="container mx-auto">
|
<motion.div
|
||||||
<div className="flex flex-col items-center space-y-4 text-center">
|
animate={{
|
||||||
<div className="space-y-2">
|
scale: [1, 1.15, 0.95, 1],
|
||||||
<div className="inline-block rounded-full bg-blue-500/10 px-3 py-1 text-sm text-blue-600 dark:text-blue-400 font-medium border border-blue-500/20 mb-4">
|
rotate: [0, 90, 180, 270, 360],
|
||||||
CASPOS Lizenz-Management-Server
|
x: [0, 40, -30, 0],
|
||||||
|
y: [0, -20, 50, 0]
|
||||||
|
}}
|
||||||
|
transition={{
|
||||||
|
duration: 20,
|
||||||
|
repeat: Infinity,
|
||||||
|
ease: "easeInOut"
|
||||||
|
}}
|
||||||
|
className="absolute -top-[10%] left-[10%] w-[350px] sm:w-[500px] h-[350px] sm:h-[500px] bg-blue-600/15 blur-[120px] sm:blur-[160px] rounded-full"
|
||||||
|
/>
|
||||||
|
<motion.div
|
||||||
|
animate={{
|
||||||
|
scale: [1, 0.9, 1.1, 1],
|
||||||
|
rotate: [0, -90, -180, -270, -360],
|
||||||
|
x: [0, -30, 40, 0],
|
||||||
|
y: [0, 50, -30, 0]
|
||||||
|
}}
|
||||||
|
transition={{
|
||||||
|
duration: 25,
|
||||||
|
repeat: Infinity,
|
||||||
|
ease: "easeInOut"
|
||||||
|
}}
|
||||||
|
className="absolute -top-[5%] right-[15%] w-[300px] sm:w-[450px] h-[300px] sm:h-[450px] bg-purple-600/10 blur-[100px] sm:blur-[140px] rounded-full"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-3xl font-bold tracking-tighter sm:text-4xl md:text-5xl lg:text-7xl/none">
|
|
||||||
POS Software <span className="text-blue-600 dark:text-blue-500">Lizenzen & Module</span>
|
{/* Hero Section */}
|
||||||
</h1>
|
<section className="w-full pt-16 pb-12 md:pt-28 md:pb-20 px-4 relative flex flex-col items-center">
|
||||||
<p className="mx-auto max-w-[700px] text-slate-600 dark:text-slate-400 md:text-xl mt-6">
|
<motion.div
|
||||||
Erwerben und verwalten Sie digitale Lizenzen für CASPOS Kassensysteme. Sofortige Aktivierung und automatische Bereitstellung für Ihre Kunden.
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
variants={containerVariants}
|
||||||
|
className="container max-w-6xl mx-auto flex flex-col items-center text-center space-y-8"
|
||||||
|
>
|
||||||
|
{/* Badge */}
|
||||||
|
<motion.div
|
||||||
|
variants={itemVariants}
|
||||||
|
className="inline-flex items-center gap-2 rounded-full bg-blue-500/10 border border-blue-500/20 px-4 py-1.5 text-xs sm:text-sm text-blue-400 font-semibold tracking-wide backdrop-blur-md shadow-[0_0_15px_rgba(59,130,246,0.1)]"
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
animate={{ opacity: [0.5, 1, 0.5] }}
|
||||||
|
transition={{ repeat: Infinity, duration: 2, ease: "easeInOut" }}
|
||||||
|
>
|
||||||
|
<Zap className="w-3.5 h-3.5 text-blue-400 fill-blue-400/20" />
|
||||||
|
</motion.div>
|
||||||
|
CASPOS Lizenz-Order-Portal
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Headline */}
|
||||||
|
<div className="space-y-4 max-w-4xl">
|
||||||
|
<motion.h1
|
||||||
|
variants={itemVariants}
|
||||||
|
className="text-4xl font-extrabold tracking-tight sm:text-5xl md:text-6xl lg:text-7xl/tight bg-clip-text text-transparent bg-gradient-to-b from-white via-slate-100 to-slate-400"
|
||||||
|
>
|
||||||
|
POS Software <span className="bg-clip-text text-transparent bg-gradient-to-r from-blue-400 via-indigo-400 to-purple-500 font-black">Lizenzen & Module</span>
|
||||||
|
</motion.h1>
|
||||||
|
<motion.p
|
||||||
|
variants={itemVariants}
|
||||||
|
className="mx-auto max-w-[750px] text-slate-400 text-base sm:text-lg md:text-xl font-normal leading-relaxed"
|
||||||
|
>
|
||||||
|
Erwerben und verwalten Sie digitale Lizenzen für CASPOS Kassensysteme.
|
||||||
|
Sofortige Aktivierung und automatische Bereitstellung für Ihre Kunden.
|
||||||
|
</motion.p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Hero CTAs */}
|
||||||
|
<motion.div
|
||||||
|
variants={itemVariants}
|
||||||
|
className="flex flex-col sm:flex-row items-center justify-center gap-4 w-full max-w-md pt-4"
|
||||||
|
>
|
||||||
|
<Link href="/order" className="w-full sm:w-auto">
|
||||||
|
<Button size="lg" className="w-full sm:w-auto h-12 px-8 text-base font-bold transition-all duration-300 hover:scale-[1.02] bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-500 hover:to-indigo-500 text-white shadow-[0_0_25px_rgba(37,99,235,0.25)] hover:shadow-[0_0_35px_rgba(37,99,235,0.45)] border-none rounded-xl">
|
||||||
|
Lizenz bestellen <ArrowRight className="ml-2 h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<Link href="https://caspos.de/kontakt/" target="_blank" rel="noopener noreferrer" className="w-full sm:w-auto">
|
||||||
|
<Button size="lg" variant="outline" className="w-full sm:w-auto h-12 px-8 text-base font-semibold transition-all duration-300 hover:bg-white/5 border-slate-800 hover:border-slate-700 text-slate-300 hover:text-white rounded-xl backdrop-blur-sm">
|
||||||
|
Fragen? Kontakt
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Quick Access Actions Bar */}
|
||||||
|
{mounted && user && (
|
||||||
|
<motion.div
|
||||||
|
variants={itemVariants}
|
||||||
|
className="w-full max-w-3xl pt-12"
|
||||||
|
>
|
||||||
|
<div className="relative p-6 rounded-2xl border border-slate-900/80 bg-slate-950/40 backdrop-blur-xl shadow-2xl">
|
||||||
|
{/* Card border glow decoration */}
|
||||||
|
<div className="absolute inset-0 rounded-2xl border border-blue-500/10 pointer-events-none" />
|
||||||
|
<p className="text-xs font-bold uppercase tracking-widest text-slate-500 mb-5 text-left sm:text-center px-2">
|
||||||
|
Mein Dashboard Schnellzugriff
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
|
<Link href="/my-customers" className="group">
|
||||||
|
<motion.div
|
||||||
|
whileHover={{ y: -4, scale: 1.01 }}
|
||||||
|
whileTap={{ scale: 0.99 }}
|
||||||
|
className="flex items-center justify-between p-4 rounded-xl border border-slate-900 bg-slate-950/60 hover:bg-slate-900/30 hover:border-blue-500/20 transition-all duration-300"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="p-2.5 rounded-lg bg-blue-500/10 text-blue-400 group-hover:bg-blue-500/20 group-hover:text-blue-300 transition-colors">
|
||||||
|
<Users className="w-5.5 h-5.5" />
|
||||||
|
</div>
|
||||||
|
<div className="text-left">
|
||||||
|
<span className="block font-bold text-sm text-slate-200 group-hover:text-white transition-colors">Kundenliste</span>
|
||||||
|
<span className="block text-xs text-slate-500 group-hover:text-slate-400 transition-colors">Kunden & Lizenzen verwalten</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ArrowUpRight className="w-4.5 h-4.5 text-slate-600 group-hover:text-blue-400 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-all" />
|
||||||
|
</motion.div>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Link href="/my-orders" className="group">
|
||||||
|
<motion.div
|
||||||
|
whileHover={{ y: -4, scale: 1.01 }}
|
||||||
|
whileTap={{ scale: 0.99 }}
|
||||||
|
className="flex items-center justify-between p-4 rounded-xl border border-slate-900 bg-slate-950/60 hover:bg-slate-900/30 hover:border-blue-500/20 transition-all duration-300"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="p-2.5 rounded-lg bg-blue-500/10 text-blue-400 group-hover:bg-blue-500/20 group-hover:text-blue-300 transition-colors">
|
||||||
|
<ClipboardList className="w-5.5 h-5.5" />
|
||||||
|
</div>
|
||||||
|
<div className="text-left">
|
||||||
|
<span className="block font-bold text-sm text-slate-200 group-hover:text-white transition-colors">Bestellungen</span>
|
||||||
|
<span className="block text-xs text-slate-500 group-hover:text-slate-400 transition-colors">Aufträge & Status einsehen</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ArrowUpRight className="w-4.5 h-4.5 text-slate-600 group-hover:text-blue-400 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-all" />
|
||||||
|
</motion.div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Grid of modules */}
|
||||||
|
<section className="w-full py-16 md:py-24 border-t border-slate-900 bg-slate-950/50 relative">
|
||||||
|
<div className="container max-w-6xl mx-auto px-4 relative">
|
||||||
|
|
||||||
|
<div className="absolute top-1/4 right-0 w-[400px] h-[400px] bg-indigo-600/5 blur-[120px] rounded-full -z-10 pointer-events-none" />
|
||||||
|
|
||||||
|
<div className="text-center space-y-3 mb-16">
|
||||||
|
<div className="inline-flex items-center gap-1.5 text-xs font-bold text-indigo-400 uppercase tracking-widest bg-indigo-500/10 border border-indigo-500/20 px-3 py-1 rounded-full">
|
||||||
|
<Sparkles className="w-3 h-3" /> System-Module
|
||||||
|
</div>
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-white via-slate-100 to-slate-400">
|
||||||
|
Verfügbare System-Module
|
||||||
|
</h2>
|
||||||
|
<p className="text-slate-400 max-w-[600px] mx-auto text-sm sm:text-base">
|
||||||
|
Wählen Sie das passende Modul für das Kassensystem Ihres Kunden.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* High-Contrast Buttons (Light/Dark Ready) */}
|
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
<div className="space-x-4 mt-8">
|
{/* Card 1 */}
|
||||||
<Link href="/order">
|
<motion.div
|
||||||
<Button size="lg" className="h-12 px-8 text-lg font-bold transition-all hover:scale-105 bg-slate-900 text-white hover:bg-slate-800 border border-slate-200 dark:bg-white dark:text-black dark:hover:bg-slate-200 dark:border-none">
|
whileHover={{ y: -6 }}
|
||||||
Lizenz bestellen <ArrowRight className="ml-2 h-5 w-5" />
|
className="group relative flex flex-col p-6 rounded-2xl border border-slate-900 bg-slate-950/70 hover:bg-slate-900/40 hover:border-slate-800/80 transition-all duration-300 shadow-xl overflow-hidden"
|
||||||
</Button>
|
>
|
||||||
</Link>
|
{/* Highlight line hover effect */}
|
||||||
<Link href="https://caspos.de/kontakt/" target="_blank" rel="noopener noreferrer">
|
<div className="absolute top-0 left-0 w-full h-[2px] bg-gradient-to-r from-transparent via-blue-500 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||||
<Button size="lg" variant="outline" className="h-12 px-8 text-lg font-semibold bg-transparent border-slate-400 text-slate-900 hover:bg-slate-100 dark:border-white/40 dark:text-white dark:hover:bg-white/10">
|
<div className="space-y-4 relative">
|
||||||
Fragen? Kontaktieren Sie uns
|
<div className="inline-flex p-3 bg-blue-500/10 rounded-xl text-blue-400 group-hover:bg-blue-500/20 group-hover:scale-110 transition-all duration-300">
|
||||||
</Button>
|
<ShoppingCart className="h-6 w-6" />
|
||||||
</Link>
|
</div>
|
||||||
|
<h3 className="text-xl font-bold text-slate-200 group-hover:text-white transition-colors">Handel & ERP</h3>
|
||||||
|
<p className="text-slate-400 text-sm leading-relaxed">
|
||||||
|
Erweiterungen für Handelskassen, Bestandsführung und vollwertige Warenwirtschaftssysteme (ERP).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Card 2 */}
|
||||||
|
<motion.div
|
||||||
|
whileHover={{ y: -6 }}
|
||||||
|
className="group relative flex flex-col p-6 rounded-2xl border border-slate-900 bg-slate-950/70 hover:bg-slate-900/40 hover:border-slate-800/80 transition-all duration-300 shadow-xl overflow-hidden"
|
||||||
|
>
|
||||||
|
{/* Highlight line hover effect */}
|
||||||
|
<div className="absolute top-0 left-0 w-full h-[2px] bg-gradient-to-r from-transparent via-indigo-500 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||||
|
<div className="space-y-4 relative">
|
||||||
|
<div className="inline-flex p-3 bg-indigo-500/10 rounded-xl text-indigo-400 group-hover:bg-indigo-500/20 group-hover:scale-110 transition-all duration-300">
|
||||||
|
<Utensils className="h-6 w-6" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-xl font-bold text-slate-200 group-hover:text-white transition-colors">Gastronomie</h3>
|
||||||
|
<p className="text-slate-400 text-sm leading-relaxed">
|
||||||
|
Lizenzen für mobiles Bestellen (Orderman), digitale Küchen-Monitore und interaktive Abhol-Boards.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Card 3 */}
|
||||||
|
<motion.div
|
||||||
|
whileHover={{ y: -6 }}
|
||||||
|
className="group relative flex flex-col p-6 rounded-2xl border border-slate-900 bg-slate-950/70 hover:bg-slate-900/40 hover:border-slate-800/80 transition-all duration-300 shadow-xl overflow-hidden"
|
||||||
|
>
|
||||||
|
{/* Highlight line hover effect */}
|
||||||
|
<div className="absolute top-0 left-0 w-full h-[2px] bg-gradient-to-r from-transparent via-purple-500 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||||
|
<div className="space-y-4 relative">
|
||||||
|
<div className="inline-flex p-3 bg-purple-500/10 rounded-xl text-purple-400 group-hover:bg-purple-500/20 group-hover:scale-110 transition-all duration-300">
|
||||||
|
<Layers className="h-6 w-6" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-xl font-bold text-slate-200 group-hover:text-white transition-colors">Hybride Systeme</h3>
|
||||||
|
<p className="text-slate-400 text-sm leading-relaxed">
|
||||||
|
Das Beste aus beiden Welten. Nahtlose Kombination von Handel- und Gastronomie-Funktionalitäten.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Stepper info */}
|
||||||
|
<section className="w-full py-16 md:py-24 border-t border-slate-900 bg-slate-950/30">
|
||||||
|
<div className="container max-w-5xl mx-auto px-4">
|
||||||
|
<div className="text-center space-y-3 mb-16">
|
||||||
|
<div className="inline-flex items-center gap-1.5 text-xs font-bold text-blue-400 uppercase tracking-widest bg-blue-500/10 border border-blue-500/20 px-3 py-1 rounded-full">
|
||||||
|
<Activity className="w-3 h-3" /> Ablauf
|
||||||
|
</div>
|
||||||
|
<h2 className="text-2xl sm:text-3xl font-bold tracking-tight text-center bg-clip-text text-transparent bg-gradient-to-r from-white via-slate-200 to-slate-400">
|
||||||
|
Wie funktioniert die Bereitstellung?
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative">
|
||||||
|
{/* Connection line for Desktop */}
|
||||||
|
<div className="hidden md:block absolute top-[28px] left-[15%] right-[15%] h-[1px] bg-gradient-to-r from-blue-500/10 via-blue-500/30 to-blue-500/10 z-0" />
|
||||||
|
|
||||||
|
<div className="grid gap-8 md:grid-cols-3 relative z-10">
|
||||||
|
{/* Step 1 */}
|
||||||
|
<div className="flex flex-col items-center text-center space-y-4 p-4 group">
|
||||||
|
<div className="flex items-center justify-center w-14 h-14 rounded-2xl bg-slate-900 border border-slate-800 text-blue-400 font-black text-lg shadow-lg group-hover:border-blue-500/40 group-hover:shadow-[0_0_15px_rgba(59,130,246,0.15)] transition-all duration-300">
|
||||||
|
1
|
||||||
|
</div>
|
||||||
|
<h4 className="text-lg font-bold text-slate-200 group-hover:text-white transition-colors">Kunde wählen</h4>
|
||||||
|
<p className="text-sm text-slate-400 leading-relaxed max-w-[250px]">
|
||||||
|
Gewünschten Kunden auswählen, der die Lizenz erhalten soll.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Step 2 */}
|
||||||
|
<div className="flex flex-col items-center text-center space-y-4 p-4 group">
|
||||||
|
<div className="flex items-center justify-center w-14 h-14 rounded-2xl bg-slate-900 border border-slate-800 text-blue-400 font-black text-lg shadow-lg group-hover:border-blue-500/40 group-hover:shadow-[0_0_15px_rgba(59,130,246,0.15)] transition-all duration-300">
|
||||||
|
2
|
||||||
|
</div>
|
||||||
|
<h4 className="text-lg font-bold text-slate-200 group-hover:text-white transition-colors">Lizenz wählen</h4>
|
||||||
|
<p className="text-sm text-slate-400 leading-relaxed max-w-[250px]">
|
||||||
|
Gewünschte Lizenzen für den Kunden auswählen und den Bestellung abschließen.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Step 3 */}
|
||||||
|
<div className="flex flex-col items-center text-center space-y-4 p-4 group">
|
||||||
|
<div className="flex items-center justify-center w-14 h-14 rounded-2xl bg-slate-900 border border-slate-800 text-blue-400 font-black text-lg shadow-lg group-hover:border-blue-500/40 group-hover:shadow-[0_0_15px_rgba(59,130,246,0.15)] transition-all duration-300">
|
||||||
|
3
|
||||||
|
</div>
|
||||||
|
<h4 className="text-lg font-bold text-slate-200 group-hover:text-white transition-colors">Live gehen</h4>
|
||||||
|
<p className="text-sm text-slate-400 leading-relaxed max-w-[250px]">
|
||||||
|
Nach dem Erhalt der Lizenz Live gehen.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Grid: Aufgeteilt nach echten POS-Modulen */}
|
{/* Core values / Features list */}
|
||||||
<section className="w-full py-12 md:py-24 lg:py-32 border-t border-slate-200 dark:border-white/5 bg-slate-50 dark:bg-white/[0.02]">
|
<section className="w-full py-16 md:py-24 border-t border-slate-900 bg-slate-950/50">
|
||||||
<div className="container mx-auto px-4 md:px-6">
|
<div className="container max-w-5xl mx-auto px-4">
|
||||||
<div className="grid gap-12 lg:grid-cols-3">
|
<div className="grid gap-8 md:grid-cols-2 items-center">
|
||||||
|
<div className="space-y-6">
|
||||||
{/* Modul 1 */}
|
<div className="inline-flex items-center gap-1.5 text-xs font-bold text-blue-400 uppercase tracking-widest bg-blue-500/10 border border-blue-500/20 px-3 py-1 rounded-full">
|
||||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
<ShieldCheck className="w-3.5 h-3.5" /> Sicherheit & Stabilität
|
||||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
|
||||||
<ShoppingCart className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-xl font-bold">Handel & ERP</h3>
|
<h3 className="text-3xl font-extrabold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-white via-slate-100 to-slate-400">
|
||||||
<p className="text-slate-600 dark:text-slate-400">Erweiterungen für Handelskassen, Bestandsführung und vollwertige Warenwirtschaftssysteme (ERP).</p>
|
Verlässliche Plattform für Lizenz-Aktivierungen
|
||||||
|
</h3>
|
||||||
|
<p className="text-slate-400 text-sm sm:text-base leading-relaxed">
|
||||||
|
Unsere Kassenlösungen sind GoBD-konform und offline-fähig. Über den Lizenz-Management-Server werden alle Lizenzen und Module verschlüsselt übertragen und sind innerhalb weniger Millisekunden auf der Kasse aktiv.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="grid gap-4 sm:grid-cols-2">
|
||||||
{/* Modul 2 */}
|
<div className="p-5 rounded-xl border border-slate-900 bg-slate-950/70 space-y-2">
|
||||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
<CheckCircle2 className="w-5 h-5 text-blue-500" />
|
||||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
<h5 className="font-bold text-sm text-slate-200">GoBD Konformität</h5>
|
||||||
<Utensils className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
<p className="text-xs text-slate-400">Konform nach allen aktuellen steuerrechtlichen Anforderungen.</p>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-xl font-bold">Gastronomie</h3>
|
<div className="p-5 rounded-xl border border-slate-900 bg-slate-950/70 space-y-2">
|
||||||
<p className="text-slate-600 dark:text-slate-400">Lizenzen für mobiles Bestellen (Orderman), digitale Küchen-Monitore und interaktive Abhol-Boards.</p>
|
<CheckCircle2 className="w-5 h-5 text-blue-500" />
|
||||||
|
<h5 className="font-bold text-sm text-slate-200">Same-Day-Bearbeitung</h5>
|
||||||
|
<p className="text-xs text-slate-400">Bearbeitung und Erstellung Ihrer Lizenzen noch am selben Werktag.</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="p-5 rounded-xl border border-slate-900 bg-slate-950/70 space-y-2">
|
||||||
{/* Modul 3 */}
|
<CheckCircle2 className="w-5 h-5 text-blue-500" />
|
||||||
<div className="flex flex-col items-center space-y-4 text-center p-6 rounded-2xl border border-slate-200 dark:border-white/5 bg-white dark:bg-slate-900/50 shadow-sm">
|
<h5 className="font-bold text-sm text-slate-200">Verschlüsselte Keys</h5>
|
||||||
<div className="p-3 bg-blue-600/10 rounded-xl">
|
<p className="text-xs text-slate-400">Sichere Lizenz-Authentifizierung direkt auf der Kasse.</p>
|
||||||
<Layers className="h-8 w-8 text-blue-600 dark:text-blue-500" />
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-xl font-bold">Hybride Systeme</h3>
|
<div className="p-5 rounded-xl border border-slate-900 bg-slate-950/70 space-y-2">
|
||||||
<p className="text-slate-600 dark:text-slate-400">Das beste aus beiden Welten. Handel mit Gastronomie und umgekehrt. </p>
|
<CheckCircle2 className="w-5 h-5 text-blue-500" />
|
||||||
|
<h5 className="font-bold text-sm text-slate-200">Partner Support</h5>
|
||||||
|
<p className="text-xs text-slate-400">Schnelle Hilfe und kompetente Ansprechpartner für Händler.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Kurze Info-Sektion für Partner / Händler */}
|
|
||||||
<section className="w-full py-12 md:py-24 border-t border-slate-200 dark:border-white/5">
|
|
||||||
<div className="container mx-auto px-4 max-w-4xl text-center">
|
|
||||||
<h2 className="text-2xl font-bold tracking-tight sm:text-3xl mb-6">Wie funktioniert die Bereitstellung?</h2>
|
|
||||||
<div className="grid gap-6 sm:grid-cols-3 text-left">
|
|
||||||
<div className="flex gap-2 items-start">
|
|
||||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
|
||||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>1. Lizenz wählen:</strong> Gewünschtes POS-Modul im Shop selektieren.</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2 items-start">
|
|
||||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
|
||||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>2. Kunde zuweisen:</strong> Lizenz direkt einem Kunden-Account zuordnen.</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2 items-start">
|
|
||||||
<CheckCircle2 className="h-5 w-5 text-blue-600 dark:text-blue-500 shrink-0 mt-0.5" />
|
|
||||||
<p className="text-sm text-slate-600 dark:text-slate-400"><strong>3. Live gehen:</strong> Lizenz-Key (`.key`) wird sofort serverseitig aktiviert.</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<footer className="flex flex-col gap-2 sm:flex-row py-6 w-full shrink-0 items-center px-4 md:px-6 border-t border-slate-200 dark:border-white/5 bg-slate-50 dark:bg-[#020617]">
|
<footer className="w-full border-t border-slate-900 bg-slate-950 py-8 px-4 md:px-6 relative z-10">
|
||||||
|
<div className="container max-w-6xl mx-auto flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||||
<p className="text-xs text-slate-500">© 2026 CASPOS GmbH. Alle Rechte vorbehalten.</p>
|
<p className="text-xs text-slate-500">© 2026 CASPOS GmbH. Alle Rechte vorbehalten.</p>
|
||||||
<nav className="sm:ml-auto flex gap-4 sm:gap-6">
|
<nav className="flex gap-6">
|
||||||
<Link className="text-xs hover:underline underline-offset-4 text-slate-500" href="https://caspos.de/impressum/" target="_blank" rel="noopener noreferrer">Impressum</Link>
|
<Link className="text-xs text-slate-500 hover:text-slate-300 transition-colors" href="/impressum">Impressum</Link>
|
||||||
<Link className="text-xs hover:underline underline-offset-4 text-slate-500" href="https://caspos.de/datenschutz/" target="_blank" rel="noopener noreferrer">Datenschutz</Link>
|
<Link className="text-xs text-slate-500 hover:text-slate-300 transition-colors" href="/datenschutz">Datenschutz</Link>
|
||||||
</nav>
|
</nav>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ export function NavbarClient({ user, role = "partner" }: NavbarClientProps) {
|
|||||||
<>
|
<>
|
||||||
<header className="px-4 lg:px-6 h-16 flex items-center justify-between border-b border-white/5 backdrop-blur-md sticky top-0 z-50 bg-[#020617]/85">
|
<header className="px-4 lg:px-6 h-16 flex items-center justify-between border-b border-white/5 backdrop-blur-md sticky top-0 z-50 bg-[#020617]/85">
|
||||||
<Link className="flex items-center justify-center gap-2 group" href="/">
|
<Link className="flex items-center justify-center gap-2 group" href="/">
|
||||||
<span className="font-bold text-xl tracking-tighter text-white">CASPOS Store</span>
|
<span className="font-bold text-xl tracking-tighter text-white">CASPOS Shop</span>
|
||||||
<DemoWrapper>
|
<DemoWrapper>
|
||||||
<span className="text-[10px] bg-amber-500/20 text-amber-400 px-2 py-0.5 rounded-full font-semibold uppercase tracking-wider border border-amber-500/30">
|
<span className="text-[10px] bg-amber-500/20 text-amber-400 px-2 py-0.5 rounded-full font-semibold uppercase tracking-wider border border-amber-500/30">
|
||||||
Demo
|
Demo
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export function ForgotPasswordForm({
|
|||||||
await resetPassword(email);
|
await resetPassword(email);
|
||||||
setSuccess(true);
|
setSuccess(true);
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
setError(error instanceof Error ? error.message : "An error occurred");
|
setError(error instanceof Error ? error.message : "Ein Fehler ist aufgetreten.");
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -44,34 +44,34 @@ export function ForgotPasswordForm({
|
|||||||
{success ? (
|
{success ? (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-2xl">Check Your Email</CardTitle>
|
<CardTitle className="text-2xl">E-Mails prüfen</CardTitle>
|
||||||
<CardDescription>Password reset instructions sent</CardDescription>
|
<CardDescription>Link zum Zurücksetzen gesendet</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
If you registered using your email and password, you will receive
|
Wenn Sie sich mit E-Mail und Passwort registriert haben, erhalten Sie
|
||||||
a password reset email.
|
in Kürze eine E-Mail zum Zurücksetzen Ihres Passworts.
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
) : (
|
) : (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-2xl">Reset Your Password</CardTitle>
|
<CardTitle className="text-2xl">Passwort zurücksetzen</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Type in your email and we'll send you a link to reset your
|
Geben Sie Ihre E-Mail-Adresse ein. Wir senden Ihnen einen Link,
|
||||||
password
|
um Ihr Passwort zurückzusetzen.
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<form onSubmit={handleForgotPassword}>
|
<form onSubmit={handleForgotPassword}>
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="email">Email</Label>
|
<Label htmlFor="email">E-Mail</Label>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
id="email"
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="m@example.com"
|
placeholder="name@beispiel.de"
|
||||||
required
|
required
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
@@ -79,16 +79,16 @@ export function ForgotPasswordForm({
|
|||||||
</div>
|
</div>
|
||||||
{error && <p className="text-sm text-red-500">{error}</p>}
|
{error && <p className="text-sm text-red-500">{error}</p>}
|
||||||
<Button type="submit" className="w-full" disabled={isLoading}>
|
<Button type="submit" className="w-full" disabled={isLoading}>
|
||||||
{isLoading ? "Sending..." : "Send reset email"}
|
{isLoading ? "Wird gesendet..." : "Link senden"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4 text-center text-sm">
|
<div className="mt-4 text-center text-sm">
|
||||||
Already have an account?{" "}
|
Bereits ein Konto vorhanden?{" "}
|
||||||
<Link
|
<Link
|
||||||
href="/auth/login"
|
href="/auth/login"
|
||||||
className="underline underline-offset-4"
|
className="underline underline-offset-4"
|
||||||
>
|
>
|
||||||
Login
|
Anmelden
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export function LoginForm({
|
|||||||
try {
|
try {
|
||||||
const res = await signIn(email, password);
|
const res = await signIn(email, password);
|
||||||
if (!res.success) {
|
if (!res.success) {
|
||||||
setError(res.error || "An error occurred");
|
setError(res.error || "Ein Fehler ist aufgetreten.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nextParam) {
|
if (nextParam) {
|
||||||
@@ -55,7 +55,7 @@ export function LoginForm({
|
|||||||
router.push("/my-customers");
|
router.push("/my-customers");
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
setError(error instanceof Error ? error.message : "An error occurred");
|
setError(error instanceof Error ? error.message : "Ein Fehler ist aufgetreten.");
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -65,20 +65,20 @@ export function LoginForm({
|
|||||||
<div className={cn("flex flex-col gap-6", className)} {...props}>
|
<div className={cn("flex flex-col gap-6", className)} {...props}>
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-2xl">Login</CardTitle>
|
<CardTitle className="text-2xl">Anmelden</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Enter your email below to login to your account
|
Geben Sie Ihre E-Mail-Adresse und Ihr Passwort ein, um sich anzumelden.
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<form onSubmit={handleLogin}>
|
<form onSubmit={handleLogin}>
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="email">Email</Label>
|
<Label htmlFor="email">E-Mail</Label>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
id="email"
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="m@example.com"
|
placeholder="name@beispiel.de"
|
||||||
required
|
required
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
@@ -86,12 +86,12 @@ export function LoginForm({
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Label htmlFor="password">Password</Label>
|
<Label htmlFor="password">Passwort</Label>
|
||||||
<Link
|
<Link
|
||||||
href="/auth/forgot-password"
|
href="/auth/forgot-password"
|
||||||
className="ml-auto inline-block text-sm underline-offset-4 hover:underline"
|
className="ml-auto inline-block text-sm underline-offset-4 hover:underline"
|
||||||
>
|
>
|
||||||
Forgot your password?
|
Passwort vergessen?
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
@@ -114,7 +114,7 @@ export function LoginForm({
|
|||||||
)}
|
)}
|
||||||
{error && <p className="text-sm text-red-500">{error}</p>}
|
{error && <p className="text-sm text-red-500">{error}</p>}
|
||||||
<Button type="submit" className="w-full" disabled={isLoading}>
|
<Button type="submit" className="w-full" disabled={isLoading}>
|
||||||
{isLoading ? "Logging in..." : "Login"}
|
{isLoading ? "Wird angemeldet..." : "Anmelden"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -964,7 +964,7 @@ export function OrderWizard({
|
|||||||
)}
|
)}
|
||||||
<p className="text-xs text-slate-500 italic">
|
<p className="text-xs text-slate-500 italic">
|
||||||
Mit dem Klick auf „Kostenpflichtig bestellen" akzeptieren Sie unsere AGB und die{' '}
|
Mit dem Klick auf „Kostenpflichtig bestellen" akzeptieren Sie unsere AGB und die{' '}
|
||||||
<a href="https://caspos.de/datenschutz/" target="_blank" rel="noopener noreferrer" className="underline hover:text-slate-400">
|
<a href="/datenschutz" target="_blank" rel="noopener noreferrer" className="underline hover:text-slate-400">
|
||||||
Datenschutzerklärung
|
Datenschutzerklärung
|
||||||
</a>.
|
</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ export async function updateSession(request: NextRequest) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
request.nextUrl.pathname !== "/" &&
|
request.nextUrl.pathname !== "/" &&
|
||||||
|
request.nextUrl.pathname !== "/impressum" &&
|
||||||
|
request.nextUrl.pathname !== "/datenschutz" &&
|
||||||
!user &&
|
!user &&
|
||||||
!request.nextUrl.pathname.startsWith("/login") &&
|
!request.nextUrl.pathname.startsWith("/login") &&
|
||||||
!request.nextUrl.pathname.startsWith("/auth")
|
!request.nextUrl.pathname.startsWith("/auth")
|
||||||
|
|||||||
Reference in New Issue
Block a user