codex has reworked checkout, but frontend doesnt work
This commit is contained in:
118
resources/js/pages/marketing/checkout/steps/PackageStep.tsx
Normal file
118
resources/js/pages/marketing/checkout/steps/PackageStep.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
import React, { useMemo } from "react";
|
||||
import { Check, Package as PackageIcon } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { useCheckoutWizard } from "../WizardContext";
|
||||
import type { CheckoutPackage } from "../types";
|
||||
|
||||
const currencyFormatter = new Intl.NumberFormat("de-DE", {
|
||||
style: "currency",
|
||||
currency: "EUR",
|
||||
minimumFractionDigits: 2,
|
||||
});
|
||||
|
||||
function PackageSummary({ pkg }: { pkg: CheckoutPackage }) {
|
||||
return (
|
||||
<Card className="shadow-sm">
|
||||
<CardHeader className="space-y-1">
|
||||
<CardTitle className="flex items-center gap-3 text-2xl">
|
||||
<PackageIcon className="h-6 w-6 text-primary" />
|
||||
{pkg.name}
|
||||
</CardTitle>
|
||||
<CardDescription className="text-base text-muted-foreground">
|
||||
{pkg.description}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="flex items-baseline gap-2">
|
||||
<span className="text-3xl font-semibold">
|
||||
{pkg.price === 0 ? "Kostenlos" : currencyFormatter.format(pkg.price)}
|
||||
</span>
|
||||
<Badge variant="secondary" className="uppercase tracking-wider text-xs">
|
||||
{pkg.type === "reseller" ? "Reseller" : "Endkunde"}
|
||||
</Badge>
|
||||
</div>
|
||||
{Array.isArray(pkg.features) && pkg.features.length > 0 && (
|
||||
<ul className="space-y-3">
|
||||
{pkg.features.map((feature, index) => (
|
||||
<li key={index} className="flex items-start gap-3 text-sm text-muted-foreground">
|
||||
<Check className="mt-0.5 h-4 w-4 text-primary" />
|
||||
<span>{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
function PackageOption({ pkg, isActive, onSelect }: { pkg: CheckoutPackage; isActive: boolean; onSelect: () => void }) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onSelect}
|
||||
className={`w-full rounded-md border bg-background p-4 text-left transition focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 ${
|
||||
isActive ? "border-primary shadow-sm" : "border-border hover:border-primary/40"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between text-sm font-medium">
|
||||
<span>{pkg.name}</span>
|
||||
<span className="text-muted-foreground">
|
||||
{pkg.price === 0 ? "Kostenlos" : currencyFormatter.format(pkg.price)}
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-1 line-clamp-2 text-xs text-muted-foreground">{pkg.description}</p>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export const PackageStep: React.FC = () => {
|
||||
const { selectedPackage, packageOptions, setSelectedPackage, resetPaymentState, nextStep } = useCheckoutWizard();
|
||||
|
||||
const comparablePackages = useMemo(() => {
|
||||
return packageOptions.filter((pkg) => pkg.type === selectedPackage.type);
|
||||
}, [packageOptions, selectedPackage.type]);
|
||||
|
||||
const handlePackageChange = (pkg: CheckoutPackage) => {
|
||||
if (pkg.id === selectedPackage.id) {
|
||||
return;
|
||||
}
|
||||
setSelectedPackage(pkg);
|
||||
resetPaymentState();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="grid gap-8 lg:grid-cols-[2fr_1fr]">
|
||||
<div className="space-y-6">
|
||||
<PackageSummary pkg={selectedPackage} />
|
||||
<div className="flex justify-end">
|
||||
<Button size="lg" onClick={nextStep}>
|
||||
Weiter zum Konto
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<aside className="space-y-4">
|
||||
<h3 className="text-sm font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
Alternative Pakete
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
{comparablePackages.map((pkg) => (
|
||||
<PackageOption
|
||||
key={pkg.id}
|
||||
pkg={pkg}
|
||||
isActive={pkg.id === selectedPackage.id}
|
||||
onSelect={() => handlePackageChange(pkg)}
|
||||
/>
|
||||
))}
|
||||
{comparablePackages.length === 0 && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Keine weiteren Pakete in dieser Kategorie verfuegbar.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user