fix: shipping cost calculation and performance optimization

- Fix shipping cost not included in checkout total
- Add useShippingMethodSelector hook for proper abstraction
- Remove blocking initCheckout from Header for better performance
- Checkout now initializes lazily when cart opens or item added
This commit is contained in:
Unchained
2026-03-30 06:31:52 +02:00
parent adb28c2a91
commit 25e60457cc
3 changed files with 98 additions and 8 deletions

View File

@@ -19,6 +19,7 @@ import { DEFAULT_PAYMENT_METHOD } from "@/lib/config/paymentMethods";
import { GET_CHECKOUT_BY_ID } from "@/lib/saleor/queries/Checkout";
import type { Checkout } from "@/types/saleor";
import { createCheckoutService, type Address } from "@/lib/services/checkoutService";
import { useShippingMethodSelector } from "@/lib/hooks/useShippingMethodSelector";
interface ShippingAddressUpdateResponse {
checkoutShippingAddressUpdate?: {
@@ -31,6 +32,8 @@ interface CheckoutQueryResponse {
checkout?: Checkout;
}
interface ShippingMethod {
id: string;
name: string;
@@ -92,8 +95,16 @@ export default function CheckoutPage() {
const [selectedShippingMethod, setSelectedShippingMethod] = useState<string>("");
const [isLoadingShipping, setIsLoadingShipping] = useState(false);
// Hook to manage shipping method selection (both manual and auto)
const { selectShippingMethodWithApi } = useShippingMethodSelector({
checkoutId: checkout?.id ?? null,
onSelect: setSelectedShippingMethod,
onRefresh: refreshCheckout,
});
const lines = getLines();
const total = getTotal();
// Use checkout.totalPrice directly for reactive updates when shipping method changes
const total = checkout?.totalPrice?.gross?.amount || getTotal();
// Debounced shipping method fetching
useEffect(() => {
@@ -147,10 +158,12 @@ export default function CheckoutPage() {
console.log("Available shipping methods:", availableMethods);
setShippingMethods(availableMethods);
// Auto-select first method if none selected
if (availableMethods.length > 0 && !selectedShippingMethod) {
setSelectedShippingMethod(availableMethods[0].id);
const firstMethodId = availableMethods[0].id;
// Use the hook to both update UI and call API
await selectShippingMethodWithApi(firstMethodId);
}
} catch (err) {
console.error("Error fetching shipping methods:", err);
@@ -210,6 +223,10 @@ export default function CheckoutPage() {
setShippingAddress((prev) => ({ ...prev, email: value }));
};
const handleShippingMethodSelect = async (methodId: string) => {
await selectShippingMethodWithApi(methodId);
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
@@ -576,7 +593,7 @@ export default function CheckoutPage() {
name="shippingMethod"
value={method.id}
checked={selectedShippingMethod === method.id}
onChange={(e) => setSelectedShippingMethod(e.target.value)}
onChange={(e) => handleShippingMethodSelect(e.target.value)}
className="w-4 h-4"
/>
<span className="font-medium">{method.name}</span>