This repository has been archived on 2025-07-07. You can view files and clone it, but cannot push or open issues or pull requests.
Files
eternos/frontend/style/components/checkout-form.tsx
2025-02-24 19:35:16 +03:00

174 lines
5.9 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 type React from "react"
import { useState } from "react"
import { useRouter } from "next/navigation"
import { useCart } from "@/contexts/cart-context"
import { Button } from "@/components/ui/button"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { CheckCircle2, ExternalLink } from "lucide-react"
import Cookies from "js-cookie"
const setTotalPriceCookie = (totalPrice: number) => {
Cookies.set("totalPrice", totalPrice.toString(), { expires: 1 }) // Expires in 1 day
}
export function CheckoutForm() {
const [address, setAddress] = useState("")
const [isProcessing, setIsProcessing] = useState(false)
const [isOrderPlaced, setIsOrderPlaced] = useState(false)
const [step, setStep] = useState(0)
const [paymentLink, setPaymentLink] = useState("")
const [error, setError] = useState<string | null>(null)
const router = useRouter()
const { items, clearCart, getTotalItems } = useCart()
const totalPrice = items.reduce((sum, item) => sum + item.price * item.quantity, 0)
const handleAddressSubmit = (e: React.FormEvent) => {
e.preventDefault()
if (address.trim()) {
setStep(1)
}
}
const handleInitiatePayment = async () => {
setIsProcessing(true)
setError(null)
try {
setTotalPriceCookie(totalPrice)
const response = await fetch("http://localhost:8081/api/pay", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: totalPrice,
address: address,
items: items.map((item) => ({
id: item.id,
title: item.title,
price: item.price,
quantity: item.quantity,
})),
}),
})
if (!response.ok) {
throw new Error("Ошибка при создании платежа")
}
const data = await response.json()
if (!data.paymentUrl) {
throw new Error("Не получена ссылка на оплату")
}
setPaymentLink(data.paymentUrl)
setStep(2)
} catch (error) {
console.error("Error generating payment link:", error)
setError("Не удалось создать ссылку для оплаты. Пожалуйста, попробуйте еще раз.")
} finally {
setIsProcessing(false)
}
}
const handlePaymentConfirmation = async () => {
setIsProcessing(true)
setError(null)
try {
// Here you would typically check the payment status with your backend
clearCart()
setIsOrderPlaced(true)
} catch (error) {
console.error("Error verifying payment:", error)
setError("Не удалось проверить статус оплаты. Пожалуйста, попробуйте еще раз.")
} finally {
setIsProcessing(false)
}
}
if (getTotalItems() === 0) {
return (
<div className="text-center py-10">
<p className="text-xl">Ваша корзина пуста. Добавьте товары перед оформлением заказа.</p>
<Button onClick={() => router.push("/")} className="mt-4">
Вернуться к покупкам
</Button>
</div>
)
}
if (isOrderPlaced) {
return (
<div className="text-center py-10">
<CheckCircle2 className="w-16 h-16 text-green-500 mx-auto mb-4" />
<h2 className="text-2xl font-bold mb-2">Заказ успешно оформлен!</h2>
<p className="mb-4">Спасибо за покупку. Ваш заказ будет доставлен по указанному адресу.</p>
<Button onClick={() => router.push("/")}>Вернуться на главную</Button>
</div>
)
}
return (
<div className="space-y-8">
{error && <div className="bg-red-50 border border-red-200 text-red-600 px-4 py-3 rounded">{error}</div>}
{step === 0 && (
<form onSubmit={handleAddressSubmit} className="space-y-4">
<h2 className="text-xl font-bold mb-4">Адрес доставки</h2>
<div>
<Label htmlFor="address">Адрес</Label>
<Textarea
id="address"
value={address}
onChange={(e) => setAddress(e.target.value)}
placeholder="Введите полный адрес доставки"
required
/>
</div>
<Button type="submit" className="w-full">
Продолжить
</Button>
</form>
)}
{step === 1 && (
<div className="space-y-4">
<h2 className="text-xl font-bold mb-4">Оплата</h2>
<div className="bg-gray-100 p-4 rounded-md">
<h3 className="font-semibold mb-2">Итого к оплате:</h3>
<p className="text-2xl font-bold">{totalPrice} </p>
</div>
<Button onClick={handleInitiatePayment} disabled={isProcessing} className="w-full">
{isProcessing ? "Создание ссылки..." : "Перейти к оплате"}
</Button>
</div>
)}
{step === 2 && (
<div className="space-y-4">
<h2 className="text-xl font-bold mb-4">Завершение оплаты</h2>
<p>Пожалуйста, перейдите по ссылке ниже для оплаты:</p>
<a
href={paymentLink}
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 hover:underline flex items-center"
>
Оплатить заказ <ExternalLink className="ml-1 w-4 h-4" />
</a>
<Button onClick={handlePaymentConfirmation} disabled={isProcessing} className="w-full">
{isProcessing ? "Проверка оплаты..." : "Я оплатил"}
</Button>
</div>
)}
</div>
)
}