diff --git a/src/app/[locale]/checkout/page.tsx b/src/app/[locale]/checkout/page.tsx index 6b3827a..7b34a26 100644 --- a/src/app/[locale]/checkout/page.tsx +++ b/src/app/[locale]/checkout/page.tsx @@ -14,6 +14,7 @@ import { CHECKOUT_SHIPPING_ADDRESS_UPDATE, CHECKOUT_BILLING_ADDRESS_UPDATE, CHECKOUT_COMPLETE, + CHECKOUT_EMAIL_UPDATE, } from "@/lib/saleor/mutations/Checkout"; import type { Checkout } from "@/types/saleor"; @@ -38,6 +39,13 @@ interface CheckoutCompleteResponse { }; } +interface EmailUpdateResponse { + checkoutEmailUpdate?: { + checkout?: Checkout; + errors?: Array<{ message: string }>; + }; +} + interface AddressForm { firstName: string; lastName: string; @@ -45,7 +53,9 @@ interface AddressForm { streetAddress2: string; city: string; postalCode: string; + country: string; phone: string; + email: string; } export default function CheckoutPage() { @@ -66,7 +76,9 @@ export default function CheckoutPage() { streetAddress2: "", city: "", postalCode: "", + country: "RS", phone: "", + email: "", }); const [billingAddress, setBillingAddress] = useState({ firstName: "", @@ -75,7 +87,9 @@ export default function CheckoutPage() { streetAddress2: "", city: "", postalCode: "", + country: "RS", phone: "", + email: "", }); const lines = getLines(); @@ -89,7 +103,7 @@ export default function CheckoutPage() { const handleShippingChange = (field: keyof AddressForm, value: string) => { setShippingAddress((prev) => ({ ...prev, [field]: value })); - if (sameAsShipping) { + if (sameAsShipping && field !== "email") { setBillingAddress((prev) => ({ ...prev, [field]: value })); } }; @@ -98,6 +112,10 @@ export default function CheckoutPage() { setBillingAddress((prev) => ({ ...prev, [field]: value })); }; + const handleEmailChange = (value: string) => { + setShippingAddress((prev) => ({ ...prev, email: value })); + }; + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -106,17 +124,45 @@ export default function CheckoutPage() { return; } + if (!shippingAddress.email || !shippingAddress.email.includes("@")) { + setError(t("errorEmailRequired")); + return; + } + + if (!shippingAddress.firstName || !shippingAddress.lastName || !shippingAddress.streetAddress1 || !shippingAddress.city || !shippingAddress.postalCode || !shippingAddress.phone) { + setError(t("errorFieldsRequired")); + return; + } + setIsLoading(true); setError(null); try { + const emailResult = await saleorClient.mutate({ + mutation: CHECKOUT_EMAIL_UPDATE, + variables: { + checkoutId: checkout.id, + email: shippingAddress.email, + }, + }); + + if (emailResult.data?.checkoutEmailUpdate?.errors && emailResult.data.checkoutEmailUpdate.errors.length > 0) { + throw new Error(emailResult.data.checkoutEmailUpdate.errors[0].message); + } + const shippingResult = await saleorClient.mutate({ mutation: CHECKOUT_SHIPPING_ADDRESS_UPDATE, variables: { checkoutId: checkout.id, shippingAddress: { - ...shippingAddress, - country: "RS", + firstName: shippingAddress.firstName, + lastName: shippingAddress.lastName, + streetAddress1: shippingAddress.streetAddress1, + streetAddress2: shippingAddress.streetAddress2, + city: shippingAddress.city, + postalCode: shippingAddress.postalCode, + country: shippingAddress.country, + phone: shippingAddress.phone, }, }, }); @@ -130,8 +176,14 @@ export default function CheckoutPage() { variables: { checkoutId: checkout.id, billingAddress: { - ...billingAddress, - country: "RS", + firstName: billingAddress.firstName, + lastName: billingAddress.lastName, + streetAddress1: billingAddress.streetAddress1, + streetAddress2: billingAddress.streetAddress2, + city: billingAddress.city, + postalCode: billingAddress.postalCode, + country: billingAddress.country, + phone: billingAddress.phone, }, }, }); @@ -227,6 +279,36 @@ export default function CheckoutPage() {
+
+

{t("contactInfo")}

+
+
+ + handleEmailChange(e.target.value)} + className="w-full border border-border px-4 py-2 rounded" + placeholder="email@example.com" + /> +

{t("emailRequired")}

+
+
+ + handleShippingChange("phone", e.target.value)} + className="w-full border border-border px-4 py-2 rounded" + placeholder="+381..." + /> +

{t("phoneRequired")}

+
+
+
+

{t("shippingAddress")}

@@ -250,6 +332,35 @@ export default function CheckoutPage() { className="w-full border border-border px-4 py-2 rounded" />
+
+ + +
-
- - handleShippingChange("phone", e.target.value)} - className="w-full border border-border px-4 py-2 rounded" - /> -
diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index 89356d8..ec3e40d 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -340,7 +340,12 @@ }, "Checkout": { "checkout": "Kasse", + "contactInfo": "Kontaktinformationen", + "email": "E-Mail", + "emailRequired": "Erforderlich für Bestellbestätigung", + "phoneRequired": "Erforderlich für Lieferkoordination", "shippingAddress": "Lieferadresse", + "country": "Land", "firstName": "Vorname", "lastName": "Nachname", "streetAddress": "Straße und Nummer", @@ -364,6 +369,8 @@ "yourCartEmpty": "Ihr Warenkorb ist leer", "continueShopping": "Weiter einkaufen", "errorNoCheckout": "Keine aktive Kasse. Bitte versuchen Sie es erneut.", + "errorEmailRequired": "Bitte geben Sie eine gültige E-Mail-Adresse ein.", + "errorFieldsRequired": "Bitte füllen Sie alle erforderlichen Felder aus.", "errorOccurred": "Ein Fehler ist during des Checkouts aufgetreten.", "errorCreatingOrder": "Bestellung konnte nicht erstellt werden.", "orderConfirmed": "Bestellung bestätigt!", diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 2ecdd23..d276188 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -386,7 +386,12 @@ }, "Checkout": { "checkout": "Checkout", + "contactInfo": "Contact Information", + "email": "Email", + "emailRequired": "Required for order confirmation", + "phoneRequired": "Required for delivery coordination", "shippingAddress": "Shipping Address", + "country": "Country", "firstName": "First Name", "lastName": "Last Name", "streetAddress": "Street Address", @@ -410,6 +415,8 @@ "yourCartEmpty": "Your cart is empty", "continueShopping": "Continue Shopping", "errorNoCheckout": "No active checkout. Please try again.", + "errorEmailRequired": "Please enter a valid email address.", + "errorFieldsRequired": "Please fill in all required fields.", "errorOccurred": "An error occurred during checkout.", "errorCreatingOrder": "Failed to create order.", "orderConfirmed": "Order Confirmed!", diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index 163b427..2960399 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -340,7 +340,12 @@ }, "Checkout": { "checkout": "Commande", + "contactInfo": "Coordonnées", + "email": "E-mail", + "emailRequired": "Requis pour la confirmation de commande", + "phoneRequired": "Requis pour la coordination de livraison", "shippingAddress": "Adresse de Livraison", + "country": "Pays", "firstName": "Prénom", "lastName": "Nom", "streetAddress": "Rue et Numéro", @@ -364,6 +369,8 @@ "yourCartEmpty": "Votre panier est vide", "continueShopping": "Continuer les Achats", "errorNoCheckout": "Pas de paiement actif. Veuillez réessayer.", + "errorEmailRequired": "Veuillez entrer une adresse e-mail valide.", + "errorFieldsRequired": "Veuillez remplir tous les champs obligatoires.", "errorOccurred": "Une erreur s'est produite lors du paiement.", "errorCreatingOrder": "Échec de la création de la commande.", "orderConfirmed": "Commande Confirmée!", diff --git a/src/i18n/messages/sr.json b/src/i18n/messages/sr.json index d21670b..b159123 100644 --- a/src/i18n/messages/sr.json +++ b/src/i18n/messages/sr.json @@ -386,7 +386,12 @@ }, "Checkout": { "checkout": "Kupovina", + "contactInfo": "Kontakt informacije", + "email": "Email", + "emailRequired": "Potrebno za potvrdu narudžbine", + "phoneRequired": "Potrebno za koordinaciju dostave", "shippingAddress": "Adresa za dostavu", + "country": "Država", "firstName": "Ime", "lastName": "Prezime", "streetAddress": "Ulica i broj", @@ -410,6 +415,8 @@ "yourCartEmpty": "Vaša korpa je prazna", "continueShopping": "Nastavi kupovinu", "errorNoCheckout": "Nema aktivne korpe. Molimo pokušajte ponovo.", + "errorEmailRequired": "Molimo unesite validnu email adresu.", + "errorFieldsRequired": "Molimo popunite sva obavezna polja.", "errorOccurred": "Došlo je do greške prilikom kupovine.", "errorCreatingOrder": "Neuspešno kreiranje narudžbine.", "orderConfirmed": "Narudžbina potvrđena!",