diff options
Diffstat (limited to 'storefront')
| -rw-r--r-- | storefront/components/Layout.js | 154 | ||||
| -rw-r--r-- | storefront/lib/format.js | 22 | ||||
| -rw-r--r-- | storefront/lib/storefront.js | 132 | ||||
| -rw-r--r-- | storefront/pages/cart.js | 202 | ||||
| -rw-r--r-- | storefront/pages/checkout.js | 384 | ||||
| -rw-r--r-- | storefront/pages/login.js | 164 | ||||
| -rw-r--r-- | storefront/pages/order-confirmation.js | 34 | ||||
| -rw-r--r-- | storefront/pages/register.js | 200 |
8 files changed, 646 insertions, 646 deletions
diff --git a/storefront/components/Layout.js b/storefront/components/Layout.js index dce09eb..bb3070f 100644 --- a/storefront/components/Layout.js +++ b/storefront/components/Layout.js @@ -1,77 +1,77 @@ -import { useEffect, useState } from "react" -import Link from "next/link" -import { medusaClient } from "../lib/medusa-client" -import { clearStoredToken, getStoredToken } from "../lib/storefront" - -export default function Layout({ children }) { - const [isLoggedIn, setIsLoggedIn] = useState(false) - - useEffect(() => { - const token = getStoredToken() - if (token) { - medusaClient.setToken(token) - setIsLoggedIn(true) - } - }, []) - - const handleLogout = () => { - clearStoredToken() - medusaClient.setToken(null) - setIsLoggedIn(false) - } - - return ( - <div style={{ minHeight: "100vh", fontFamily: "sans-serif", background: "#f8f8f8" }}> - <header - style={{ - display: "flex", - alignItems: "center", - justifyContent: "space-between", - padding: "1rem 2rem", - background: "#fff", - borderBottom: "1px solid #e6e6e6", - }} - > - <Link href="/" style={{ fontWeight: 600, textDecoration: "none", color: "#222" }}> - Lucien-sens-bon - </Link> - <nav style={{ display: "flex", gap: "1rem", alignItems: "center" }}> - <Link href="/" style={{ textDecoration: "none", color: "#444" }}> - Boutique - </Link> - <Link href="/cart" style={{ textDecoration: "none", color: "#444" }}> - Panier - </Link> - <Link href="/checkout" style={{ textDecoration: "none", color: "#444" }}> - Commander - </Link> - {!isLoggedIn ? ( - <> - <Link href="/register" style={{ textDecoration: "none", color: "#444" }}> - Créer un compte - </Link> - <Link href="/login" style={{ textDecoration: "none", color: "#444" }}> - Se connecter - </Link> - </> - ) : ( - <button - type="button" - onClick={handleLogout} - style={{ - border: "1px solid #ccc", - background: "#fff", - borderRadius: "6px", - padding: "0.4rem 0.8rem", - cursor: "pointer", - }} - > - Se déconnecter - </button> - )} - </nav> - </header> - <main style={{ padding: "2rem" }}>{children}</main> - </div> - ) -} +import { useEffect, useState } from "react"
+import Link from "next/link"
+import { medusaClient } from "../lib/medusa-client"
+import { clearStoredToken, getStoredToken } from "../lib/storefront"
+
+export default function Layout({ children }) {
+ const [isLoggedIn, setIsLoggedIn] = useState(false)
+
+ useEffect(() => {
+ const token = getStoredToken()
+ if (token) {
+ medusaClient.setToken(token)
+ setIsLoggedIn(true)
+ }
+ }, [])
+
+ const handleLogout = () => {
+ clearStoredToken()
+ medusaClient.setToken(null)
+ setIsLoggedIn(false)
+ }
+
+ return (
+ <div style={{ minHeight: "100vh", fontFamily: "sans-serif", background: "#f8f8f8" }}>
+ <header
+ style={{
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "space-between",
+ padding: "1rem 2rem",
+ background: "#fff",
+ borderBottom: "1px solid #e6e6e6",
+ }}
+ >
+ <Link href="/" style={{ fontWeight: 600, textDecoration: "none", color: "#222" }}>
+ Lucien-sens-bon
+ </Link>
+ <nav style={{ display: "flex", gap: "1rem", alignItems: "center" }}>
+ <Link href="/" style={{ textDecoration: "none", color: "#444" }}>
+ Boutique
+ </Link>
+ <Link href="/cart" style={{ textDecoration: "none", color: "#444" }}>
+ Panier
+ </Link>
+ <Link href="/checkout" style={{ textDecoration: "none", color: "#444" }}>
+ Commander
+ </Link>
+ {!isLoggedIn ? (
+ <>
+ <Link href="/register" style={{ textDecoration: "none", color: "#444" }}>
+ Créer un compte
+ </Link>
+ <Link href="/login" style={{ textDecoration: "none", color: "#444" }}>
+ Se connecter
+ </Link>
+ </>
+ ) : (
+ <button
+ type="button"
+ onClick={handleLogout}
+ style={{
+ border: "1px solid #ccc",
+ background: "#fff",
+ borderRadius: "6px",
+ padding: "0.4rem 0.8rem",
+ cursor: "pointer",
+ }}
+ >
+ Se déconnecter
+ </button>
+ )}
+ </nav>
+ </header>
+ <main style={{ padding: "2rem" }}>{children}</main>
+ </div>
+ )
+}
diff --git a/storefront/lib/format.js b/storefront/lib/format.js index 2f44c2e..9e92a8b 100644 --- a/storefront/lib/format.js +++ b/storefront/lib/format.js @@ -1,11 +1,11 @@ -export const formatAmount = (amount, currencyCode = "EUR") => { - if (typeof amount !== "number") { - return "" - } - - const normalizedCurrency = currencyCode.toUpperCase() - return new Intl.NumberFormat("fr-FR", { - style: "currency", - currency: normalizedCurrency, - }).format(amount / 100) -} +export const formatAmount = (amount, currencyCode = "EUR") => {
+ if (typeof amount !== "number") {
+ return ""
+ }
+
+ const normalizedCurrency = currencyCode.toUpperCase()
+ return new Intl.NumberFormat("fr-FR", {
+ style: "currency",
+ currency: normalizedCurrency,
+ }).format(amount / 100)
+}
diff --git a/storefront/lib/storefront.js b/storefront/lib/storefront.js index b6433a9..ccfe1cd 100644 --- a/storefront/lib/storefront.js +++ b/storefront/lib/storefront.js @@ -1,66 +1,66 @@ -export const cartStorageKey = "lsb_cart_id" -export const tokenStorageKey = "lsb_customer_token" - -export const getStoredCartId = () => { - if (typeof window === "undefined") { - return null - } - return window.localStorage.getItem(cartStorageKey) -} - -export const setStoredCartId = (cartId) => { - if (typeof window === "undefined") { - return - } - window.localStorage.setItem(cartStorageKey, cartId) -} - -export const clearStoredCartId = () => { - if (typeof window === "undefined") { - return - } - window.localStorage.removeItem(cartStorageKey) -} - -export const getStoredToken = () => { - if (typeof window === "undefined") { - return null - } - return window.localStorage.getItem(tokenStorageKey) -} - -export const setStoredToken = (token) => { - if (typeof window === "undefined") { - return - } - window.localStorage.setItem(tokenStorageKey, token) -} - -export const clearStoredToken = () => { - if (typeof window === "undefined") { - return - } - window.localStorage.removeItem(tokenStorageKey) -} - -export const ensureCart = async (client) => { - const storedCartId = getStoredCartId() - - if (storedCartId) { - try { - const { cart } = await client.carts.retrieve(storedCartId) - return cart - } catch (error) { - clearStoredCartId() - } - } - - const { regions } = await client.regions.list() - if (!regions?.length) { - throw new Error("Aucune région disponible pour créer un panier.") - } - - const { cart } = await client.carts.create({ region_id: regions[0].id }) - setStoredCartId(cart.id) - return cart -} +export const cartStorageKey = "lsb_cart_id"
+export const tokenStorageKey = "lsb_customer_token"
+
+export const getStoredCartId = () => {
+ if (typeof window === "undefined") {
+ return null
+ }
+ return window.localStorage.getItem(cartStorageKey)
+}
+
+export const setStoredCartId = (cartId) => {
+ if (typeof window === "undefined") {
+ return
+ }
+ window.localStorage.setItem(cartStorageKey, cartId)
+}
+
+export const clearStoredCartId = () => {
+ if (typeof window === "undefined") {
+ return
+ }
+ window.localStorage.removeItem(cartStorageKey)
+}
+
+export const getStoredToken = () => {
+ if (typeof window === "undefined") {
+ return null
+ }
+ return window.localStorage.getItem(tokenStorageKey)
+}
+
+export const setStoredToken = (token) => {
+ if (typeof window === "undefined") {
+ return
+ }
+ window.localStorage.setItem(tokenStorageKey, token)
+}
+
+export const clearStoredToken = () => {
+ if (typeof window === "undefined") {
+ return
+ }
+ window.localStorage.removeItem(tokenStorageKey)
+}
+
+export const ensureCart = async (client) => {
+ const storedCartId = getStoredCartId()
+
+ if (storedCartId) {
+ try {
+ const { cart } = await client.carts.retrieve(storedCartId)
+ return cart
+ } catch (error) {
+ clearStoredCartId()
+ }
+ }
+
+ const { regions } = await client.regions.list()
+ if (!regions?.length) {
+ throw new Error("Aucune région disponible pour créer un panier.")
+ }
+
+ const { cart } = await client.carts.create({ region_id: regions[0].id })
+ setStoredCartId(cart.id)
+ return cart
+}
diff --git a/storefront/pages/cart.js b/storefront/pages/cart.js index fa625a9..3b02b50 100644 --- a/storefront/pages/cart.js +++ b/storefront/pages/cart.js @@ -1,101 +1,101 @@ -import { useCallback, useEffect, useState } from "react" -import { medusaClient } from "../lib/medusa-client" -import { formatAmount } from "../lib/format" -import { getStoredCartId, clearStoredCartId } from "../lib/storefront" - -export default function CartPage() { - const [cart, setCart] = useState(null) - const [status, setStatus] = useState("") - const [isLoading, setIsLoading] = useState(true) - - const loadCart = useCallback(async () => { - const storedCartId = getStoredCartId() - if (!storedCartId) { - setCart(null) - setIsLoading(false) - return - } - - try { - const { cart: fetchedCart } = await medusaClient.carts.retrieve(storedCartId) - setCart(fetchedCart) - } catch (error) { - clearStoredCartId() - setCart(null) - } finally { - setIsLoading(false) - } - }, []) - - useEffect(() => { - loadCart() - }, [loadCart]) - - const handleRemove = async (lineItemId) => { - if (!cart) { - return - } - setStatus("") - try { - await medusaClient.carts.lineItems.delete(cart.id, lineItemId) - await loadCart() - } catch (error) { - setStatus("Impossible de retirer l'article.") - } - } - - if (isLoading) { - return <p>Chargement du panier...</p> - } - - if (!cart || !cart.items?.length) { - return <p>Votre panier est vide.</p> - } - - return ( - <div style={{ maxWidth: "720px", margin: "0 auto" }}> - <h1>Panier</h1> - {status && <p>{status}</p>} - <div style={{ display: "grid", gap: "1rem", marginTop: "1rem" }}> - {cart.items.map((item) => ( - <div - key={item.id} - style={{ - border: "1px solid #ccc", - borderRadius: "8px", - padding: "1rem", - display: "flex", - justifyContent: "space-between", - gap: "1rem", - }} - > - <div> - <strong>{item.title}</strong> - <p>Quantité : {item.quantity}</p> - <p> - {formatAmount(item.unit_price, cart.region?.currency_code || "eur")} - </p> - </div> - <button - type="button" - onClick={() => handleRemove(item.id)} - style={{ - border: "1px solid #ccc", - background: "#fff", - borderRadius: "6px", - padding: "0.4rem 0.8rem", - cursor: "pointer", - height: "fit-content", - }} - > - Retirer - </button> - </div> - ))} - </div> - <p style={{ marginTop: "1.5rem", fontWeight: 600 }}> - Total : {formatAmount(cart.total, cart.region?.currency_code || "eur")} - </p> - </div> - ) -} +import { useCallback, useEffect, useState } from "react"
+import { medusaClient } from "../lib/medusa-client"
+import { formatAmount } from "../lib/format"
+import { getStoredCartId, clearStoredCartId } from "../lib/storefront"
+
+export default function CartPage() {
+ const [cart, setCart] = useState(null)
+ const [status, setStatus] = useState("")
+ const [isLoading, setIsLoading] = useState(true)
+
+ const loadCart = useCallback(async () => {
+ const storedCartId = getStoredCartId()
+ if (!storedCartId) {
+ setCart(null)
+ setIsLoading(false)
+ return
+ }
+
+ try {
+ const { cart: fetchedCart } = await medusaClient.carts.retrieve(storedCartId)
+ setCart(fetchedCart)
+ } catch (error) {
+ clearStoredCartId()
+ setCart(null)
+ } finally {
+ setIsLoading(false)
+ }
+ }, [])
+
+ useEffect(() => {
+ loadCart()
+ }, [loadCart])
+
+ const handleRemove = async (lineItemId) => {
+ if (!cart) {
+ return
+ }
+ setStatus("")
+ try {
+ await medusaClient.carts.lineItems.delete(cart.id, lineItemId)
+ await loadCart()
+ } catch (error) {
+ setStatus("Impossible de retirer l'article.")
+ }
+ }
+
+ if (isLoading) {
+ return <p>Chargement du panier...</p>
+ }
+
+ if (!cart || !cart.items?.length) {
+ return <p>Votre panier est vide.</p>
+ }
+
+ return (
+ <div style={{ maxWidth: "720px", margin: "0 auto" }}>
+ <h1>Panier</h1>
+ {status && <p>{status}</p>}
+ <div style={{ display: "grid", gap: "1rem", marginTop: "1rem" }}>
+ {cart.items.map((item) => (
+ <div
+ key={item.id}
+ style={{
+ border: "1px solid #ccc",
+ borderRadius: "8px",
+ padding: "1rem",
+ display: "flex",
+ justifyContent: "space-between",
+ gap: "1rem",
+ }}
+ >
+ <div>
+ <strong>{item.title}</strong>
+ <p>Quantité : {item.quantity}</p>
+ <p>
+ {formatAmount(item.unit_price, cart.region?.currency_code || "eur")}
+ </p>
+ </div>
+ <button
+ type="button"
+ onClick={() => handleRemove(item.id)}
+ style={{
+ border: "1px solid #ccc",
+ background: "#fff",
+ borderRadius: "6px",
+ padding: "0.4rem 0.8rem",
+ cursor: "pointer",
+ height: "fit-content",
+ }}
+ >
+ Retirer
+ </button>
+ </div>
+ ))}
+ </div>
+ <p style={{ marginTop: "1.5rem", fontWeight: 600 }}>
+ Total : {formatAmount(cart.total, cart.region?.currency_code || "eur")}
+ </p>
+ </div>
+ )
+}
diff --git a/storefront/pages/checkout.js b/storefront/pages/checkout.js index 1970df4..9457daa 100644 --- a/storefront/pages/checkout.js +++ b/storefront/pages/checkout.js @@ -1,192 +1,192 @@ -import { useEffect, useState } from "react" -import { useRouter } from "next/router" -import { medusaClient } from "../lib/medusa-client" -import { getStoredCartId, clearStoredCartId } from "../lib/storefront" - -const initialForm = { - email: "", - first_name: "", - last_name: "", - address_1: "", - postal_code: "", - city: "", - country_code: "fr", -} - -export default function CheckoutPage() { - const router = useRouter() - const [form, setForm] = useState(initialForm) - const [status, setStatus] = useState("") - const [isLoading, setIsLoading] = useState(false) - const [cartId, setCartId] = useState(null) - - useEffect(() => { - const storedCartId = getStoredCartId() - setCartId(storedCartId) - }, []) - - const handleChange = (event) => { - const { name, value } = event.target - setForm((prev) => ({ ...prev, [name]: value })) - } - - const handleSubmit = async (event) => { - event.preventDefault() - setStatus("") - setIsLoading(true) - - if (!cartId) { - setStatus("Votre panier est vide.") - setIsLoading(false) - return - } - - try { - await medusaClient.carts.update(cartId, { - email: form.email, - shipping_address: { - first_name: form.first_name, - last_name: form.last_name, - address_1: form.address_1, - postal_code: form.postal_code, - city: form.city, - country_code: form.country_code, - }, - }) - - const { shipping_options: shippingOptions } = - await medusaClient.shippingOptions.listCartOptions(cartId) - - if (!shippingOptions?.length) { - throw new Error("Aucune option de livraison disponible.") - } - - await medusaClient.carts.addShippingMethod(cartId, { - option_id: shippingOptions[0].id, - }) - - const { cart: cartWithPayments } = await medusaClient.carts.createPaymentSessions( - cartId - ) - - const manualSession = cartWithPayments?.payment_sessions?.find( - (session) => session.provider_id === "manual" - ) - const providerId = - manualSession?.provider_id || - cartWithPayments?.payment_sessions?.[0]?.provider_id - - if (!providerId) { - throw new Error("Aucun moyen de paiement disponible.") - } - - await medusaClient.carts.setPaymentSession(cartId, { provider_id: providerId }) - - const { type, data } = await medusaClient.carts.complete(cartId) - if (type === "order" && data?.id) { - clearStoredCartId() - router.push(`/order-confirmation?order_id=${data.id}`) - return - } - - setStatus("Commande validée, mais sans numéro de commande.") - } catch (error) { - setStatus("Impossible de finaliser la commande.") - } finally { - setIsLoading(false) - } - } - - return ( - <div style={{ maxWidth: "520px", margin: "0 auto" }}> - <h1>Finaliser la commande</h1> - <form onSubmit={handleSubmit} style={{ display: "grid", gap: "1rem" }}> - <label> - Email - <input - name="email" - type="email" - value={form.email} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Prénom - <input - name="first_name" - value={form.first_name} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Nom - <input - name="last_name" - value={form.last_name} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Adresse - <input - name="address_1" - value={form.address_1} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Code postal - <input - name="postal_code" - value={form.postal_code} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Ville - <input - name="city" - value={form.city} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Pays - <input - name="country_code" - value={form.country_code} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <button - type="submit" - disabled={isLoading} - style={{ - border: "1px solid #ccc", - background: "#fff", - borderRadius: "6px", - padding: "0.6rem", - cursor: "pointer", - }} - > - {isLoading ? "Validation..." : "Passer la commande"} - </button> - {status && <p>{status}</p>} - </form> - </div> - ) -} +import { useEffect, useState } from "react"
+import { useRouter } from "next/router"
+import { medusaClient } from "../lib/medusa-client"
+import { getStoredCartId, clearStoredCartId } from "../lib/storefront"
+
+const initialForm = {
+ email: "",
+ first_name: "",
+ last_name: "",
+ address_1: "",
+ postal_code: "",
+ city: "",
+ country_code: "fr",
+}
+
+export default function CheckoutPage() {
+ const router = useRouter()
+ const [form, setForm] = useState(initialForm)
+ const [status, setStatus] = useState("")
+ const [isLoading, setIsLoading] = useState(false)
+ const [cartId, setCartId] = useState(null)
+
+ useEffect(() => {
+ const storedCartId = getStoredCartId()
+ setCartId(storedCartId)
+ }, [])
+
+ const handleChange = (event) => {
+ const { name, value } = event.target
+ setForm((prev) => ({ ...prev, [name]: value }))
+ }
+
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ setStatus("")
+ setIsLoading(true)
+
+ if (!cartId) {
+ setStatus("Votre panier est vide.")
+ setIsLoading(false)
+ return
+ }
+
+ try {
+ await medusaClient.carts.update(cartId, {
+ email: form.email,
+ shipping_address: {
+ first_name: form.first_name,
+ last_name: form.last_name,
+ address_1: form.address_1,
+ postal_code: form.postal_code,
+ city: form.city,
+ country_code: form.country_code,
+ },
+ })
+
+ const { shipping_options: shippingOptions } =
+ await medusaClient.shippingOptions.listCartOptions(cartId)
+
+ if (!shippingOptions?.length) {
+ throw new Error("Aucune option de livraison disponible.")
+ }
+
+ await medusaClient.carts.addShippingMethod(cartId, {
+ option_id: shippingOptions[0].id,
+ })
+
+ const { cart: cartWithPayments } = await medusaClient.carts.createPaymentSessions(
+ cartId
+ )
+
+ const manualSession = cartWithPayments?.payment_sessions?.find(
+ (session) => session.provider_id === "manual"
+ )
+ const providerId =
+ manualSession?.provider_id ||
+ cartWithPayments?.payment_sessions?.[0]?.provider_id
+
+ if (!providerId) {
+ throw new Error("Aucun moyen de paiement disponible.")
+ }
+
+ await medusaClient.carts.setPaymentSession(cartId, { provider_id: providerId })
+
+ const { type, data } = await medusaClient.carts.complete(cartId)
+ if (type === "order" && data?.id) {
+ clearStoredCartId()
+ router.push(`/order-confirmation?order_id=${data.id}`)
+ return
+ }
+
+ setStatus("Commande validée, mais sans numéro de commande.")
+ } catch (error) {
+ setStatus("Impossible de finaliser la commande.")
+ } finally {
+ setIsLoading(false)
+ }
+ }
+
+ return (
+ <div style={{ maxWidth: "520px", margin: "0 auto" }}>
+ <h1>Finaliser la commande</h1>
+ <form onSubmit={handleSubmit} style={{ display: "grid", gap: "1rem" }}>
+ <label>
+ Email
+ <input
+ name="email"
+ type="email"
+ value={form.email}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Prénom
+ <input
+ name="first_name"
+ value={form.first_name}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Nom
+ <input
+ name="last_name"
+ value={form.last_name}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Adresse
+ <input
+ name="address_1"
+ value={form.address_1}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Code postal
+ <input
+ name="postal_code"
+ value={form.postal_code}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Ville
+ <input
+ name="city"
+ value={form.city}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Pays
+ <input
+ name="country_code"
+ value={form.country_code}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <button
+ type="submit"
+ disabled={isLoading}
+ style={{
+ border: "1px solid #ccc",
+ background: "#fff",
+ borderRadius: "6px",
+ padding: "0.6rem",
+ cursor: "pointer",
+ }}
+ >
+ {isLoading ? "Validation..." : "Passer la commande"}
+ </button>
+ {status && <p>{status}</p>}
+ </form>
+ </div>
+ )
+}
diff --git a/storefront/pages/login.js b/storefront/pages/login.js index 033f9b5..9539a51 100644 --- a/storefront/pages/login.js +++ b/storefront/pages/login.js @@ -1,82 +1,82 @@ -import { useState } from "react" -import { useRouter } from "next/router" -import { medusaClient } from "../lib/medusa-client" -import { setStoredToken } from "../lib/storefront" - -export default function LoginPage() { - const router = useRouter() - const [form, setForm] = useState({ email: "", password: "" }) - const [status, setStatus] = useState("") - const [isLoading, setIsLoading] = useState(false) - - const handleChange = (event) => { - const { name, value } = event.target - setForm((prev) => ({ ...prev, [name]: value })) - } - - const handleSubmit = async (event) => { - event.preventDefault() - setStatus("") - setIsLoading(true) - - try { - const { access_token: accessToken } = await medusaClient.auth.getToken({ - email: form.email, - password: form.password, - }) - - setStoredToken(accessToken) - medusaClient.setToken(accessToken) - setStatus("Connexion réussie.") - router.push("/") - } catch (error) { - setStatus("Identifiants invalides ou indisponibles.") - } finally { - setIsLoading(false) - } - } - - return ( - <div style={{ maxWidth: "420px", margin: "0 auto" }}> - <h1>Se connecter</h1> - <form onSubmit={handleSubmit} style={{ display: "grid", gap: "1rem" }}> - <label> - Email - <input - name="email" - type="email" - value={form.email} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Mot de passe - <input - name="password" - type="password" - value={form.password} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <button - type="submit" - disabled={isLoading} - style={{ - border: "1px solid #ccc", - background: "#fff", - borderRadius: "6px", - padding: "0.6rem", - cursor: "pointer", - }} - > - {isLoading ? "Connexion..." : "Se connecter"} - </button> - {status && <p>{status}</p>} - </form> - </div> - ) -} +import { useState } from "react"
+import { useRouter } from "next/router"
+import { medusaClient } from "../lib/medusa-client"
+import { setStoredToken } from "../lib/storefront"
+
+export default function LoginPage() {
+ const router = useRouter()
+ const [form, setForm] = useState({ email: "", password: "" })
+ const [status, setStatus] = useState("")
+ const [isLoading, setIsLoading] = useState(false)
+
+ const handleChange = (event) => {
+ const { name, value } = event.target
+ setForm((prev) => ({ ...prev, [name]: value }))
+ }
+
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ setStatus("")
+ setIsLoading(true)
+
+ try {
+ const { access_token: accessToken } = await medusaClient.auth.getToken({
+ email: form.email,
+ password: form.password,
+ })
+
+ setStoredToken(accessToken)
+ medusaClient.setToken(accessToken)
+ setStatus("Connexion réussie.")
+ router.push("/")
+ } catch (error) {
+ setStatus("Identifiants invalides ou indisponibles.")
+ } finally {
+ setIsLoading(false)
+ }
+ }
+
+ return (
+ <div style={{ maxWidth: "420px", margin: "0 auto" }}>
+ <h1>Se connecter</h1>
+ <form onSubmit={handleSubmit} style={{ display: "grid", gap: "1rem" }}>
+ <label>
+ Email
+ <input
+ name="email"
+ type="email"
+ value={form.email}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Mot de passe
+ <input
+ name="password"
+ type="password"
+ value={form.password}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <button
+ type="submit"
+ disabled={isLoading}
+ style={{
+ border: "1px solid #ccc",
+ background: "#fff",
+ borderRadius: "6px",
+ padding: "0.6rem",
+ cursor: "pointer",
+ }}
+ >
+ {isLoading ? "Connexion..." : "Se connecter"}
+ </button>
+ {status && <p>{status}</p>}
+ </form>
+ </div>
+ )
+}
diff --git a/storefront/pages/order-confirmation.js b/storefront/pages/order-confirmation.js index 4c7930f..c1ce8df 100644 --- a/storefront/pages/order-confirmation.js +++ b/storefront/pages/order-confirmation.js @@ -1,17 +1,17 @@ -import { useRouter } from "next/router" - -export default function OrderConfirmationPage() { - const router = useRouter() - const { order_id: orderId } = router.query - - return ( - <div style={{ maxWidth: "520px", margin: "0 auto" }}> - <h1>Merci pour votre commande</h1> - {orderId ? ( - <p>Votre commande a bien été enregistrée : {orderId}</p> - ) : ( - <p>Votre commande a bien été enregistrée.</p> - )} - </div> - ) -} +import { useRouter } from "next/router"
+
+export default function OrderConfirmationPage() {
+ const router = useRouter()
+ const { order_id: orderId } = router.query
+
+ return (
+ <div style={{ maxWidth: "520px", margin: "0 auto" }}>
+ <h1>Merci pour votre commande</h1>
+ {orderId ? (
+ <p>Votre commande a bien été enregistrée : {orderId}</p>
+ ) : (
+ <p>Votre commande a bien été enregistrée.</p>
+ )}
+ </div>
+ )
+}
diff --git a/storefront/pages/register.js b/storefront/pages/register.js index 48831ea..688a09e 100644 --- a/storefront/pages/register.js +++ b/storefront/pages/register.js @@ -1,100 +1,100 @@ -import { useState } from "react" -import { useRouter } from "next/router" -import { medusaClient } from "../lib/medusa-client" - -export default function RegisterPage() { - const router = useRouter() - const [form, setForm] = useState({ - first_name: "", - last_name: "", - email: "", - password: "", - }) - const [status, setStatus] = useState("") - const [isLoading, setIsLoading] = useState(false) - - const handleChange = (event) => { - const { name, value } = event.target - setForm((prev) => ({ ...prev, [name]: value })) - } - - const handleSubmit = async (event) => { - event.preventDefault() - setStatus("") - setIsLoading(true) - - try { - await medusaClient.customers.create(form) - setStatus("Compte créé. Vous pouvez vous connecter.") - router.push("/login") - } catch (error) { - setStatus("Impossible de créer le compte pour le moment.") - } finally { - setIsLoading(false) - } - } - - return ( - <div style={{ maxWidth: "420px", margin: "0 auto" }}> - <h1>Créer un compte</h1> - <form onSubmit={handleSubmit} style={{ display: "grid", gap: "1rem" }}> - <label> - Prénom - <input - name="first_name" - value={form.first_name} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Nom - <input - name="last_name" - value={form.last_name} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Email - <input - name="email" - type="email" - value={form.email} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <label> - Mot de passe - <input - name="password" - type="password" - value={form.password} - onChange={handleChange} - required - style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }} - /> - </label> - <button - type="submit" - disabled={isLoading} - style={{ - border: "1px solid #ccc", - background: "#fff", - borderRadius: "6px", - padding: "0.6rem", - cursor: "pointer", - }} - > - {isLoading ? "Création..." : "Créer mon compte"} - </button> - {status && <p>{status}</p>} - </form> - </div> - ) -} +import { useState } from "react"
+import { useRouter } from "next/router"
+import { medusaClient } from "../lib/medusa-client"
+
+export default function RegisterPage() {
+ const router = useRouter()
+ const [form, setForm] = useState({
+ first_name: "",
+ last_name: "",
+ email: "",
+ password: "",
+ })
+ const [status, setStatus] = useState("")
+ const [isLoading, setIsLoading] = useState(false)
+
+ const handleChange = (event) => {
+ const { name, value } = event.target
+ setForm((prev) => ({ ...prev, [name]: value }))
+ }
+
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ setStatus("")
+ setIsLoading(true)
+
+ try {
+ await medusaClient.customers.create(form)
+ setStatus("Compte créé. Vous pouvez vous connecter.")
+ router.push("/login")
+ } catch (error) {
+ setStatus("Impossible de créer le compte pour le moment.")
+ } finally {
+ setIsLoading(false)
+ }
+ }
+
+ return (
+ <div style={{ maxWidth: "420px", margin: "0 auto" }}>
+ <h1>Créer un compte</h1>
+ <form onSubmit={handleSubmit} style={{ display: "grid", gap: "1rem" }}>
+ <label>
+ Prénom
+ <input
+ name="first_name"
+ value={form.first_name}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Nom
+ <input
+ name="last_name"
+ value={form.last_name}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Email
+ <input
+ name="email"
+ type="email"
+ value={form.email}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <label>
+ Mot de passe
+ <input
+ name="password"
+ type="password"
+ value={form.password}
+ onChange={handleChange}
+ required
+ style={{ width: "100%", padding: "0.5rem", marginTop: "0.5rem" }}
+ />
+ </label>
+ <button
+ type="submit"
+ disabled={isLoading}
+ style={{
+ border: "1px solid #ccc",
+ background: "#fff",
+ borderRadius: "6px",
+ padding: "0.6rem",
+ cursor: "pointer",
+ }}
+ >
+ {isLoading ? "Création..." : "Créer mon compte"}
+ </button>
+ {status && <p>{status}</p>}
+ </form>
+ </div>
+ )
+}
|
