Files
klimat24/app/zamowienie/page.tsx
T

141 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useCartStore } from '@/lib/cart-store';
import { useActionState, useEffect, startTransition } from 'react';
import Link from 'next/link';
import { submitOrderForm } from './actions';
import { ArrowLeft, CheckCircle2 } from 'lucide-react';
import { buttonClasses } from '@/components/ui/Button';
import { getRecaptchaToken } from '@/lib/getRecaptchaToken';
const initialState = { success: false, message: '' };
export default function ZamowieniePage() {
const { items, getTotal, clearCart } = useCartStore();
const [state, formAction, pending] = useActionState(submitOrderForm, initialState);
const total = getTotal();
useEffect(() => {
if (state.success) clearCart();
}, [state.success, clearCart]);
if (items.length === 0 && !state.success) {
return (
<main className="min-h-screen bg-slate-50 flex items-center justify-center">
<div className="text-center">
<p className="text-text-muted mb-4">Koszyk jest pusty.</p>
<Link href="/sklep" className={buttonClasses({ variant: 'primary', size: 'md' })}>
Wróć do sklepu
</Link>
</div>
</main>
);
}
if (state.success) {
return (
<main className="min-h-screen bg-slate-50 flex items-center justify-center py-16">
<div className="max-w-md mx-auto px-4 w-full">
<div className="bg-green-50 text-green-800 p-8 rounded-2xl border border-green-200 flex flex-col items-center text-center">
<CheckCircle2 className="w-16 h-16 text-green-500 mb-4" />
<h3 className="text-2xl font-bold font-heading mb-2">Zamówienie przyjęte!</h3>
<p className="text-green-700">{state.message}</p>
<Link href="/sklep" className="mt-6 px-6 py-2 bg-green-600 text-white rounded-lg font-semibold hover:bg-green-700 transition-colors">
Wróć do sklepu
</Link>
</div>
</div>
</main>
);
}
return (
<main className="bg-slate-50 min-h-screen py-8">
<div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8">
<Link href="/koszyk" className="inline-flex items-center gap-2 text-sm text-text-muted hover:text-accent mb-6">
<ArrowLeft className="size-4" /> Wróć do koszyka
</Link>
<h1 className="text-2xl font-bold text-primary font-heading mb-8">Złóż zamówienie</h1>
<div className="grid grid-cols-1 gap-6">
<div className="bg-white rounded-xl border border-border p-6">
<h2 className="text-base font-bold text-primary font-heading mb-4">Zamawiane produkty</h2>
<div className="flex flex-col gap-2">
{items.map((item) => (
<div key={item.id} className="flex justify-between text-sm">
<span className="text-text-muted">{item.name} × {item.quantity}</span>
<span className="font-semibold text-primary">{(item.price * item.quantity).toLocaleString('pl-PL')} zł</span>
</div>
))}
<div className="border-t border-border pt-2 mt-2 flex justify-between font-bold text-primary">
<span>Łącznie (urządzenia)</span>
<span>{total.toLocaleString('pl-PL')} zł</span>
</div>
</div>
</div>
<form onSubmit={async (e) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const token = await getRecaptchaToken('submit');
if (token) {
formData.append('recaptchaToken', token);
}
startTransition(() => {
formAction(formData);
});
}} className="bg-white rounded-xl border border-border p-6 flex flex-col gap-4">
<h2 className="text-base font-bold text-primary font-heading">Twoje dane</h2>
<input type="hidden" name="products" value={JSON.stringify(items)} />
<input type="hidden" name="total" value={total} />
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label className="text-xs font-medium text-primary mb-1 block">Imię i nazwisko *</label>
<input name="name" required className="w-full border border-border rounded-lg px-3 py-2.5 text-sm focus:border-accent outline-none" placeholder="Jan Kowalski" />
</div>
<div>
<label className="text-xs font-medium text-primary mb-1 block">Telefon *</label>
<input name="phone" required type="tel" className="w-full border border-border rounded-lg px-3 py-2.5 text-sm focus:border-accent outline-none" placeholder="+48 600 000 000" />
</div>
</div>
<div>
<label className="text-xs font-medium text-primary mb-1 block">Email *</label>
<input name="email" required type="email" className="w-full border border-border rounded-lg px-3 py-2.5 text-sm focus:border-accent outline-none" placeholder="[email protected]" />
</div>
<div>
<label className="text-xs font-medium text-primary mb-1 block">Adres dostawy / montażu</label>
<input name="address" className="w-full border border-border rounded-lg px-3 py-2.5 text-sm focus:border-accent outline-none" placeholder="ul. Przykładowa 1, 50-000 Wrocław" />
</div>
<div>
<label className="text-xs font-medium text-primary mb-1 block">Uwagi do zamówienia</label>
<textarea name="notes" rows={3} className="w-full border border-border rounded-lg px-3 py-2.5 text-sm focus:border-accent outline-none resize-none" placeholder="Np. preferowany termin montażu, piętro, specjalne wymagania..." />
</div>
<label className="flex items-start gap-3 cursor-pointer">
<input type="checkbox" name="consent" required className="mt-0.5 w-5 h-5 accent-accent shrink-0 cursor-pointer" />
<span className="text-xs text-text-muted">Wyrażam zgodę na przetwarzanie danych osobowych w celu realizacji zamówienia zgodnie z Polityką Prywatności. *</span>
</label>
{state.message && !state.success && (
<p className="text-sm text-red-500">{state.message}</p>
)}
<button type="submit" disabled={pending} className="btn btn-primary text-white font-bold w-full flex items-center justify-center gap-2">
{pending ? 'Wysyłanie...' : 'Wyślij zamówienie'}
</button>
<p className="text-xs text-text-muted text-center">
Po złożeniu zamówienia skontaktujemy się z Tobą telefonicznie w ciągu 24 godzin, aby potwierdzić szczegóły i ustalić termin montażu.
</p>
</form>
</div>
</div>
</main>
);
}