style(shop): resolve merge conflict in license lookup placeholder
Some checks failed
Staging Build / build (push) Failing after 43s
Some checks failed
Staging Build / build (push) Failing after 43s
This commit is contained in:
@@ -18,9 +18,18 @@ import {
|
||||
Zap,
|
||||
ArrowUpRight,
|
||||
ShieldCheck,
|
||||
Calendar,
|
||||
Sparkles,
|
||||
Activity
|
||||
} from 'lucide-react'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
} from '@/components/ui/dialog'
|
||||
|
||||
interface HomeClientProps {
|
||||
initialUser: User | null
|
||||
@@ -29,6 +38,7 @@ interface HomeClientProps {
|
||||
export function HomeClient({ initialUser }: HomeClientProps) {
|
||||
const [user, setUser] = useState<User | null>(initialUser)
|
||||
const [mounted, setMounted] = useState(false)
|
||||
const [calendarOpen, setCalendarOpen] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
@@ -125,23 +135,23 @@ export function HomeClient({ initialUser }: HomeClientProps) {
|
||||
Mein Dashboard Schnellzugriff
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<Link href="/my-customers" className="group">
|
||||
<motion.div
|
||||
whileHover={{ y: -2 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
className="flex items-center justify-between p-4 rounded-xl border border-slate-800 bg-slate-950 hover:bg-slate-900 hover:border-slate-700 transition-all duration-200"
|
||||
className="flex items-center justify-between p-4 rounded-xl border border-slate-800 bg-slate-950 hover:bg-slate-900 hover:border-slate-700 transition-all duration-200 h-full"
|
||||
>
|
||||
<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 className="flex items-center gap-3">
|
||||
<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 shrink-0">
|
||||
<Users className="w-5 h-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>
|
||||
<span className="block text-xs text-slate-500 group-hover:text-slate-400 transition-colors">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" />
|
||||
<ArrowUpRight className="w-4 h-4 text-slate-600 group-hover:text-blue-400 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-all shrink-0" />
|
||||
</motion.div>
|
||||
</Link>
|
||||
|
||||
@@ -149,20 +159,42 @@ export function HomeClient({ initialUser }: HomeClientProps) {
|
||||
<motion.div
|
||||
whileHover={{ y: -2 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
className="flex items-center justify-between p-4 rounded-xl border border-slate-800 bg-slate-950 hover:bg-slate-900 hover:border-slate-700 transition-all duration-200"
|
||||
className="flex items-center justify-between p-4 rounded-xl border border-slate-800 bg-slate-950 hover:bg-slate-900 hover:border-slate-700 transition-all duration-200 h-full"
|
||||
>
|
||||
<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 className="flex items-center gap-3">
|
||||
<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 shrink-0">
|
||||
<ClipboardList className="w-5 h-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>
|
||||
<span className="block text-xs text-slate-500 group-hover:text-slate-400 transition-colors">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" />
|
||||
<ArrowUpRight className="w-4 h-4 text-slate-600 group-hover:text-blue-400 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-all shrink-0" />
|
||||
</motion.div>
|
||||
</Link>
|
||||
|
||||
<button type="button" onClick={() => setCalendarOpen(true)} className="group text-left w-full">
|
||||
<motion.div
|
||||
whileHover={{ y: -2 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
className="flex items-center justify-between p-4 rounded-xl border border-slate-800 bg-slate-950 hover:bg-slate-900 hover:border-slate-700 transition-all duration-200 h-full"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<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 shrink-0">
|
||||
<Calendar className="w-5 h-5" />
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="block font-bold text-sm text-slate-200 group-hover:text-white transition-colors">Termine</span>
|
||||
<span className="px-1.5 py-0.5 text-[10px] font-medium bg-amber-500/10 text-amber-400 border border-amber-500/20 rounded-md">Geplant</span>
|
||||
</div>
|
||||
<span className="block text-xs text-slate-500 group-hover:text-slate-400 transition-colors">Terminkalender</span>
|
||||
</div>
|
||||
</div>
|
||||
<ArrowUpRight className="w-4 h-4 text-slate-600 group-hover:text-blue-400 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-all shrink-0" />
|
||||
</motion.div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
@@ -171,6 +203,52 @@ export function HomeClient({ initialUser }: HomeClientProps) {
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Dialog / Popup für Termin-Kalender (Geplant) */}
|
||||
<Dialog open={calendarOpen} onOpenChange={setCalendarOpen}>
|
||||
<DialogContent className="bg-slate-900 border-slate-800 text-slate-100 max-w-md">
|
||||
<DialogHeader>
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="p-2.5 rounded-xl bg-blue-500/10 text-blue-400 border border-blue-500/20">
|
||||
<Calendar className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<DialogTitle className="text-xl font-bold text-white flex items-center gap-2">
|
||||
Termin-Kalender
|
||||
<span className="px-2 py-0.5 text-xs font-semibold bg-amber-500/10 text-amber-400 border border-amber-500/20 rounded-full">
|
||||
In Planung
|
||||
</span>
|
||||
</DialogTitle>
|
||||
</div>
|
||||
</div>
|
||||
<DialogDescription className="text-slate-400 text-sm leading-relaxed pt-2">
|
||||
Der Termin-Kalender bietet in Kürze eine Übersicht für anstehende Schulungen, Online- & Vor-Ort-Workshops sowie Termine für Blauer-Mittwoch-Partner zur direkten Anmeldung.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="p-4 my-2 rounded-xl bg-slate-950 border border-slate-800 text-xs text-slate-400 space-y-2">
|
||||
<div className="flex items-center justify-between text-slate-300 font-medium">
|
||||
<span>Geplante Features & Angebote:</span>
|
||||
</div>
|
||||
<ul className="list-disc list-inside space-y-1 text-slate-400">
|
||||
<li>Anmeldung zu Online- & Vor-Ort-Workshops</li>
|
||||
<li>Anstehende Schulungstermine auf einen Blick</li>
|
||||
<li>Spezielle Schulungen für Blauer-Mittwoch-Partner</li>
|
||||
<li>Kalender-Export (.ics / Google / Outlook)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setCalendarOpen(false)}
|
||||
className="w-full sm:w-auto border-slate-700 bg-slate-800 text-slate-200 hover:bg-slate-700 hover:text-white"
|
||||
>
|
||||
Schließen
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* 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">
|
||||
|
||||
@@ -179,7 +179,7 @@ export function OrderWizard({
|
||||
return 'one_time'
|
||||
})
|
||||
|
||||
// Falls "one_time" (Kauf) gewählt: optionales Datum der letzten CAS-Lizenzierung
|
||||
// Falls "one_time" (Kauf) gewählt: optionales Datum der letzten CASPOS-Lizenzierung
|
||||
const [lastLicenseDate, setLastLicenseDate] = useState<string>(
|
||||
initialOrder?.order_data?.last_license_date || ''
|
||||
)
|
||||
@@ -608,7 +608,7 @@ export function OrderWizard({
|
||||
setEditingIdx(null)
|
||||
setModuleQuantities({})
|
||||
setDeviceName('')
|
||||
|
||||
|
||||
const resetSels: Record<string, CategorySelection> = {}
|
||||
categories.forEach(cat => {
|
||||
const isVisible = selectedBillingInterval === 'one_time' ? cat.show_in_kauf !== false : cat.show_in_abo !== false
|
||||
|
||||
@@ -25,12 +25,21 @@ import { lookupLicenseFromLicServer } from '@/lib/actions/licserver-config'
|
||||
|
||||
// ─── MOCK DATA (until real LicServer API is wired up) ───────────────────────
|
||||
const MOCK_LICENSES: Record<string, LicenseInfo> = {
|
||||
<<<<<<< HEAD
|
||||
'995500-0005': {
|
||||
licenseKey: '995500-0005',
|
||||
status: 'active',
|
||||
product: 'CASPOS DEMO',
|
||||
edition: 'Professional',
|
||||
version: '14.1.2',
|
||||
=======
|
||||
'995502-00': {
|
||||
licenseKey: '995502-00',
|
||||
status: 'active',
|
||||
product: 'CASPOS',
|
||||
edition: 'GASTRO',
|
||||
version: '4.8.6',
|
||||
>>>>>>> 086a893e19593863f6b2044374187220cc3e392d
|
||||
seats: 10,
|
||||
customer: 'Mustermann GmbH',
|
||||
contact: 'Max Mustermann',
|
||||
@@ -39,6 +48,7 @@ const MOCK_LICENSES: Record<string, LicenseInfo> = {
|
||||
maintenanceUntil: '2025-03-31',
|
||||
modules: ['CRM', 'ERP-Link', 'Mobile Client', 'Web Client'],
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
'CAS-2020-STD-00456': {
|
||||
licenseKey: 'CAS-2020-STD-00456',
|
||||
status: 'expired',
|
||||
@@ -66,6 +76,35 @@ const MOCK_LICENSES: Record<string, LicenseInfo> = {
|
||||
expiresAt: '2026-12-31',
|
||||
maintenanceUntil: '2026-12-31',
|
||||
modules: ['CRM', 'ERP-Link', 'Mobile Client', 'Web Client', 'AI Assistant', 'Analytics Pro'],
|
||||
=======
|
||||
'995501-00': {
|
||||
licenseKey: '995501-00',
|
||||
status: 'expired',
|
||||
product: 'CASPOS Handel',
|
||||
edition: 'Standard',
|
||||
version: '3.12.1',
|
||||
seats: 1,
|
||||
customer: 'Beispiel AG',
|
||||
contact: 'Erika Muster',
|
||||
issuedAt: '2016-03-14',
|
||||
expiresAt: '2017-03-14',
|
||||
maintenanceUntil: '2017-03-14',
|
||||
modules: ['CASPOS Handel'],
|
||||
},
|
||||
'995500-00': {
|
||||
licenseKey: '995500-00',
|
||||
status: 'active',
|
||||
product: 'CASPOS Handel',
|
||||
edition: 'Standard',
|
||||
version: '4.11.2',
|
||||
seats: 2,
|
||||
customer: 'Tech Solutions GmbH & Co. KG',
|
||||
contact: 'Julia Schneider',
|
||||
issuedAt: '2026-01-01',
|
||||
expiresAt: '2027-12-31',
|
||||
maintenanceUntil: '2027-12-31',
|
||||
modules: ['CASPOS Handel'],
|
||||
>>>>>>> 086a893e19593863f6b2044374187220cc3e392d
|
||||
},
|
||||
}
|
||||
|
||||
@@ -224,7 +263,7 @@ export function LicenseLookupPanel({ onLicenseResolved }: LicenseLookupPanelProp
|
||||
{/* ── Input + Search Button ──────────────────────────────── */}
|
||||
<div className="pt-4">
|
||||
<p className="text-xs text-slate-400 mb-2 leading-relaxed">
|
||||
Geben Sie Ihre bisherige CAS-Lizenznummer ein,
|
||||
Geben Sie Ihre bisherige CASPOS-Lizenznummer ein,
|
||||
um Lizenzinformationen automatisch abzurufen.
|
||||
</p>
|
||||
|
||||
@@ -278,16 +317,28 @@ export function LicenseLookupPanel({ onLicenseResolved }: LicenseLookupPanelProp
|
||||
Demo:
|
||||
<span
|
||||
className="font-mono text-violet-400/80 cursor-pointer hover:text-violet-400 transition-colors"
|
||||
<<<<<<< HEAD
|
||||
onClick={() => setLicenseKey('995500-00')}
|
||||
>
|
||||
995500-00
|
||||
=======
|
||||
onClick={() => setLicenseKey('995502-00')}
|
||||
>
|
||||
995502-00
|
||||
>>>>>>> 086a893e19593863f6b2044374187220cc3e392d
|
||||
</span>
|
||||
{' · '}
|
||||
<span
|
||||
className="font-mono text-amber-400/80 cursor-pointer hover:text-amber-400 transition-colors"
|
||||
<<<<<<< HEAD
|
||||
onClick={() => setLicenseKey('995500-01')}
|
||||
>
|
||||
995500-01
|
||||
=======
|
||||
onClick={() => setLicenseKey('995501-00')}
|
||||
>
|
||||
995500-00
|
||||
>>>>>>> 086a893e19593863f6b2044374187220cc3e392d
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -44,11 +44,10 @@ export function StepBilling({
|
||||
{/* Option 1: Kauf */}
|
||||
<div
|
||||
onClick={() => handleBillingIntervalChange('one_time')}
|
||||
className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between h-48 hover:shadow-[0_0_20px_rgba(255,255,255,0.05)] ${
|
||||
selectedBillingInterval === 'one_time'
|
||||
className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between h-48 hover:shadow-[0_0_20px_rgba(255,255,255,0.05)] ${selectedBillingInterval === 'one_time'
|
||||
? 'border-primary bg-primary/10 shadow-[0_0_25px_rgba(59,130,246,0.2)]'
|
||||
: 'border-white/5 bg-white/5 hover:border-white/20'
|
||||
}`}
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
@@ -71,11 +70,10 @@ export function StepBilling({
|
||||
{/* Option 2: Abo */}
|
||||
<div
|
||||
onClick={() => handleBillingIntervalChange('monthly')}
|
||||
className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between h-48 hover:shadow-[0_0_20px_rgba(255,255,255,0.05)] ${
|
||||
selectedBillingInterval === 'monthly'
|
||||
className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between h-48 hover:shadow-[0_0_20px_rgba(255,255,255,0.05)] ${selectedBillingInterval === 'monthly'
|
||||
? 'border-primary bg-primary/10 shadow-[0_0_25px_rgba(59,130,246,0.2)]'
|
||||
: 'border-white/5 bg-white/5 hover:border-white/20'
|
||||
}`}
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
@@ -99,7 +97,7 @@ export function StepBilling({
|
||||
<div className="p-4 rounded-xl bg-white/5 border border-white/10 space-y-3 mt-6 max-w-md animate-in fade-in slide-in-from-top-2 duration-300">
|
||||
<Label htmlFor="last-license-date" className="text-white font-medium flex items-center gap-2">
|
||||
<Calendar className="w-4 h-4 text-primary" />
|
||||
Datum der letzten CAS-Lizenz (falls vorhanden)
|
||||
Datum der letzten CASPOS-Lizenz (falls vorhanden)
|
||||
</Label>
|
||||
<Input
|
||||
id="last-license-date"
|
||||
|
||||
Reference in New Issue
Block a user