diff --git a/src/App.tsx b/src/App.tsx index 2eb8052..023acab 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -89,10 +89,7 @@ export default function App() { } /> } /> } /> - } - /> + } /> } diff --git a/src/components/orders/OrderRow.tsx b/src/components/orders/OrderRow.tsx index 8cc1210..e942abd 100644 --- a/src/components/orders/OrderRow.tsx +++ b/src/components/orders/OrderRow.tsx @@ -6,6 +6,7 @@ import type { GetVariantResponseDTO } from "../../types/products"; import { formatDate } from "../../utils/string.ts"; import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import PaymentIcon from "@mui/icons-material/Payment"; import { Box, Button, @@ -23,6 +24,7 @@ import { CircularProgress, Avatar, } from "@mui/material"; +import { useNavigate } from "react-router-dom"; const calculateTotalPrice = (items: OrderItemDetails[]): number => { return items.reduce((sum, item) => sum + item.quantity * item.price, 0); @@ -217,11 +219,15 @@ const OrderItemsList: React.FC = ({ order }) => { }; interface OrderSummaryProps { - order: OrderDetailsResponse; totalPrice: number; + orderStatus: string; + orderId: string; } -const OrderSummary: React.FC = ({ order, totalPrice }) => { +const OrderSummary: React.FC = ({ totalPrice, orderStatus, orderId }) => { + const navigate = useNavigate(); + const isPending = orderStatus === "ORDER_STATUS_PENDING"; + return ( = ({ order, totalPrice }) => { {totalPrice.toFixed(2)} PLN - - - - {getStatusColor(order.orderStatus) === "error" && ( - - )} - + )} ); }; @@ -270,7 +277,11 @@ const OrderDetails: React.FC = ({ order, totalPrice }) => { - + ); diff --git a/src/hooks/useCheckout.ts b/src/hooks/useCheckout.ts index ea73a85..f512788 100644 --- a/src/hooks/useCheckout.ts +++ b/src/hooks/useCheckout.ts @@ -4,8 +4,6 @@ import type { ShippingFormValues } from "../components/forms/ShippingForm.tsx"; import { useCartContext } from "../contexts/CartContext"; import { useNavigate } from "react-router-dom"; -const SHIPPING_COST = 19.99; -const FREE_SHIPPING_THRESHOLD = 500; const DISCOUNT_CODE = "RABAT20"; const DISCOUNT_PERCENTAGE = 0.2; // 20% @@ -32,7 +30,6 @@ interface CheckoutStorageData { shippingData: ShippingFormValues; invoiceData: InvoiceFormValues; wantsInvoice: boolean; - paymentMethod: "card" | "cod"; discountCode: string; isDiscountApplied: boolean; } @@ -64,9 +61,6 @@ export const useCheckout = (initialOrderId?: string) => { const [shippingModalOpen, setShippingModalOpen] = useState(false); const [invoiceModalOpen, setInvoiceModalOpen] = useState(false); const [wantsInvoice, setWantsInvoice] = useState(savedData?.wantsInvoice || false); - const [paymentMethod, setPaymentMethod] = useState<"card" | "cod">( - savedData?.paymentMethod || "card", - ); const [discountCode, setDiscountCode] = useState(savedData?.discountCode || ""); const [isDiscountApplied, setIsDiscountApplied] = useState(savedData?.isDiscountApplied || false); const [discountError, setDiscountError] = useState(null); @@ -102,9 +96,6 @@ export const useCheckout = (initialOrderId?: string) => { if (newSavedData.wantsInvoice !== undefined && newSavedData.wantsInvoice !== wantsInvoice) { setWantsInvoice(newSavedData.wantsInvoice); } - if (newSavedData.paymentMethod && newSavedData.paymentMethod !== paymentMethod) { - setPaymentMethod(newSavedData.paymentMethod); - } if (newSavedData.discountCode && newSavedData.discountCode !== discountCode) { setDiscountCode(newSavedData.discountCode); } @@ -130,7 +121,6 @@ export const useCheckout = (initialOrderId?: string) => { JSON.stringify(parsed.shippingData) === JSON.stringify(shippingData) && JSON.stringify(parsed.invoiceData) === JSON.stringify(invoiceData) && parsed.wantsInvoice === wantsInvoice && - parsed.paymentMethod === paymentMethod && parsed.discountCode === discountCode && parsed.isDiscountApplied === isDiscountApplied ) { @@ -145,31 +135,19 @@ export const useCheckout = (initialOrderId?: string) => { shippingData, invoiceData, wantsInvoice, - paymentMethod, discountCode, isDiscountApplied, }; sessionStorage.setItem(storageKey, JSON.stringify(dataToSave)); } - }, [ - orderId, - shippingData, - invoiceData, - wantsInvoice, - paymentMethod, - discountCode, - isDiscountApplied, - ]); + }, [orderId, shippingData, invoiceData, wantsInvoice, discountCode, isDiscountApplied]); const subtotal = useMemo( () => cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0), [cartItems], ); - const shipping = useMemo( - () => (subtotal >= FREE_SHIPPING_THRESHOLD ? 0 : SHIPPING_COST), - [subtotal], - ); + const shipping = 0; // Always free shipping const discountAmount = useMemo(() => { if (!isDiscountApplied) return 0; @@ -228,13 +206,7 @@ export const useCheckout = (initialOrderId?: string) => { return; } - if (paymentMethod === "card") { - const paymentId = crypto.randomUUID(); - navigate(`/payment/${paymentId}/${orderId}`); - } else { - const confirmationToken = crypto.randomUUID(); - navigate(`/order-confirmation/${orderId}/${confirmationToken}`); - } + navigate(`/payment/${orderId}`); }; const getShippingDataForInvoice = (): @@ -268,13 +240,11 @@ export const useCheckout = (initialOrderId?: string) => { shippingModalOpen, invoiceModalOpen, wantsInvoice, - paymentMethod, discountCode, shippingData, invoiceData, orderId, subtotal, - shipping, total, totalBeforeDiscount, discountAmount, @@ -284,7 +254,6 @@ export const useCheckout = (initialOrderId?: string) => { setShippingModalOpen, setInvoiceModalOpen, - setPaymentMethod, setDiscountCode, handleShippingSubmit, diff --git a/src/hooks/usePayment.ts b/src/hooks/usePayment.ts index 0575a2c..3675673 100644 --- a/src/hooks/usePayment.ts +++ b/src/hooks/usePayment.ts @@ -8,9 +8,6 @@ const VALID_CARD = { cvv: "123", }; -const SHIPPING_COST = 19.99; -const FREE_SHIPPING_THRESHOLD = 500; - export interface CardFormValues { cardNumber: string; cardholderName: string; @@ -28,10 +25,7 @@ export const usePayment = () => { [cartItems], ); - const shipping = useMemo( - () => (subtotal >= FREE_SHIPPING_THRESHOLD ? 0 : SHIPPING_COST), - [subtotal], - ); + const shipping = 0; // Always free shipping const total = useMemo(() => subtotal + shipping, [subtotal, shipping]); @@ -81,7 +75,6 @@ export const usePayment = () => { return { subtotal, - shipping, total, paymentError, isProcessing, diff --git a/src/pages/CartPage.tsx b/src/pages/CartPage.tsx index ef74d72..460e9ef 100644 --- a/src/pages/CartPage.tsx +++ b/src/pages/CartPage.tsx @@ -29,9 +29,6 @@ import { } from "@mui/material"; import { useNavigate } from "react-router-dom"; -const SHIPPING_COST = 19.99; -const FREE_SHIPPING_THRESHOLD = 500; - const CartProductCard: React.FC<{ item: CartItem; onClick: () => void }> = ({ item, onClick }) => { const { updateProductQuantity, overwriteProductQuantity, removeProduct } = useCartContext(); const theme = useTheme(); @@ -281,7 +278,7 @@ const CartPage: React.FC = () => { } return sum + item.price * item.quantity; }, 0); - const shipping = subtotal >= FREE_SHIPPING_THRESHOLD ? 0 : SHIPPING_COST; + const shipping = 0; // Always free shipping const total = subtotal + shipping; const handleCheckout = async () => { @@ -349,56 +346,25 @@ const CartPage: React.FC = () => { ); })} - {FREE_SHIPPING_THRESHOLD - subtotal > 0 && ( - - - - - Free shipping within reach! - - - Add products worth{" "} - {(FREE_SHIPPING_THRESHOLD - subtotal).toFixed(2)} PLN{" "} - more and get free shipping! - - - - )} - - {shipping === 0 && ( - - - - Congratulations! You have free shipping! - - - )} + + + + Free shipping on all orders! + + ) : ( { - {shipping === 0 && } - {shipping === 0 ? "GRATIS" : `${shipping.toFixed(2)} PLN`} + + GRATIS diff --git a/src/pages/CheckoutPage.tsx b/src/pages/CheckoutPage.tsx index 57a1f4d..fbad9ef 100644 --- a/src/pages/CheckoutPage.tsx +++ b/src/pages/CheckoutPage.tsx @@ -6,7 +6,6 @@ import { useCheckout } from "../hooks/useCheckout.ts"; import DiscountSection from "./checkout/DiscountSection.tsx"; import InvoiceModal from "./checkout/InvoiceModal.tsx"; import OrderSummary from "./checkout/OrderSummary.tsx"; -import PaymentMethodSection from "./checkout/PaymentMethodSection.tsx"; import ShippingModal from "./checkout/ShippingModal.tsx"; import ShippingSection from "./checkout/ShippingSection.tsx"; import { Box, Typography, Container, Grid, Button } from "@mui/material"; @@ -20,12 +19,10 @@ const CheckoutPage: React.FC = () => { shippingModalOpen, invoiceModalOpen, wantsInvoice, - paymentMethod, discountCode, shippingData, invoiceData, subtotal, - shipping, total, totalBeforeDiscount, discountAmount, @@ -34,7 +31,6 @@ const CheckoutPage: React.FC = () => { canPay, setShippingModalOpen, setInvoiceModalOpen, - setPaymentMethod, setDiscountCode, handleShippingSubmit, handleInvoiceSubmit, @@ -83,12 +79,6 @@ const CheckoutPage: React.FC = () => { onInvoiceChange={handleInvoiceChange} onEditInvoice={() => setInvoiceModalOpen(true)} /> - - - { { const navigate = useNavigate(); const { orderId } = useParams<{ orderId: string }>(); const { cartItems, clearFullCart } = useCartContext(); - const { - subtotal, - shipping, - total, - paymentError, - isProcessing, - handlePayment, - clearPaymentError, - } = usePayment(); + const { subtotal, total, paymentError, isProcessing, handlePayment, clearPaymentError } = + usePayment(); const cardFormRef = useRef(null); const [isFormValid, setIsFormValid] = useState(false); + const [isRedirecting, setIsRedirecting] = useState(false); const handleSubmit = async (values: CardFormValues) => { clearPaymentError(); const success = await handlePayment(values); if (success) { + setIsRedirecting(true); await clearFullCart(); if (orderId) { const paymentLink = await getPaymentLink(orderId); @@ -48,7 +52,33 @@ const PaymentPage: React.FC = () => { } }; - if (cartItems.length === 0) { + if (isRedirecting) { + return ( + + + + + + Processing your payment... + + + Redirecting to confirmation page + + + + + ); + } + + if (cartItems.length === 0 && !isProcessing && !orderId) { return ( @@ -113,7 +143,6 @@ const PaymentPage: React.FC = () => { { const [stockLoading, setStockLoading] = useState(false); const [error, setError] = useState(null); - // Date range state - default to last 90 days const [dateRange, setDateRange] = useState(() => { const today = new Date(); const fromDate = new Date(); @@ -80,7 +79,6 @@ const SalesStatisticsPage: React.FC = () => { [dateRange], ); - // Load data when variant or date range changes useEffect(() => { if (selectedVariant) { if (activeTab === "sales") { @@ -115,7 +113,6 @@ const SalesStatisticsPage: React.FC = () => { return ( - {/* Breadcrumbs */} { ]} /> - {/* Header */} { - {/* Search Section - Sticky */} { /> - {/* Date Range Selector */} {selectedVariant && ( @@ -166,7 +160,6 @@ const SalesStatisticsPage: React.FC = () => { )} - {/* Error Alert */} {error && ( setError(null)}> @@ -175,11 +168,9 @@ const SalesStatisticsPage: React.FC = () => { )} - {/* Tabs and Charts Section */} {selectedVariant ? ( - {/* Tabs */} { - {/* Chart Content */} {activeTab === "sales" ? ( @@ -262,7 +252,6 @@ const SalesStatisticsPage: React.FC = () => { ) : ( - /* Empty State */ = ({ subtotal, - shipping, total, totalBeforeDiscount, discountAmount = 0, @@ -59,15 +57,15 @@ const OrderSummary: React.FC = ({ - {shipping === 0 && } - {shipping === 0 ? "GRATIS" : `${shipping.toFixed(2)} PLN`} + + GRATIS diff --git a/src/pages/checkout/PaymentMethodSection.tsx b/src/pages/checkout/PaymentMethodSection.tsx deleted file mode 100644 index 09cdf63..0000000 --- a/src/pages/checkout/PaymentMethodSection.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React from "react"; -import CreditCardIcon from "@mui/icons-material/CreditCard"; -import LocalAtmIcon from "@mui/icons-material/LocalAtm"; -import PaymentIcon from "@mui/icons-material/Payment"; -import { - Box, - Typography, - Card, - Divider, - Radio, - RadioGroup, - FormControl, - FormControlLabel, - alpha, - useTheme, -} from "@mui/material"; - -interface PaymentMethodSectionProps { - paymentMethod: "card" | "cod"; - onPaymentMethodChange: (method: "card" | "cod") => void; -} - -const PaymentMethodSection: React.FC = ({ - paymentMethod, - onPaymentMethodChange, -}) => { - const theme = useTheme(); - - return ( - - - - - Payment Method - - - - - - onPaymentMethodChange(e.target.value as "card" | "cod")} - sx={{ display: "flex", flexDirection: "column", gap: 2 }} - > - } - label={ - - - - Credit Card - - - } - sx={{ mb: 2, width: "100%", m: 0 }} - /> - } - label={ - - - - Cash on Delivery - - - } - sx={{ width: "100%", m: 0 }} - /> - - - - ); -}; - -export default PaymentMethodSection; diff --git a/src/pages/payment/PaymentSummary.tsx b/src/pages/payment/PaymentSummary.tsx index 0165233..cf6aa13 100644 --- a/src/pages/payment/PaymentSummary.tsx +++ b/src/pages/payment/PaymentSummary.tsx @@ -4,7 +4,6 @@ import { Box, Typography, Card, Divider, Button, alpha, useTheme } from "@mui/ma interface PaymentSummaryProps { subtotal: number; - shipping: number; total: number; canPay: boolean; isProcessing: boolean; @@ -13,7 +12,6 @@ interface PaymentSummaryProps { const PaymentSummary: React.FC = ({ subtotal, - shipping, total, canPay, isProcessing, @@ -55,15 +53,15 @@ const PaymentSummary: React.FC = ({ - {shipping === 0 && } - {shipping === 0 ? "GRATIS" : `${shipping.toFixed(2)} PLN`} + + GRATIS