Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ NEXT_PUBLIC_STRIPE_KEY=

# Your Next.js revalidation secret. See – https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#on-demand-revalidation
REVALIDATE_SECRET=supersecret

# displays missing translation keys for debugging
NEXT_PUBLIC_TRANSLATION_HELPERS=false
9 changes: 8 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
const checkEnvVariables = require("./check-env-variables")
const nextIntl = require("next-intl/plugin")


checkEnvVariables()

/**
* @type {import('next').NextConfig}
*/
const nextConfig = {

const withNextIntl = nextIntl("./src/lib/i18n/request-config.js")

const configOpts = {
reactStrictMode: true,
logging: {
fetches: {
Expand Down Expand Up @@ -40,4 +45,6 @@ const nextConfig = {
},
}

const nextConfig = withNextIntl(configOpts)

module.exports = nextConfig
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@stripe/stripe-js": "^1.29.0",
"lodash": "^4.17.21",
"next": "15.0.3",
"next-intl": "^3.26.3",
"pg": "^8.11.3",
"qs": "^6.12.1",
"react": "19.0.0-rc-66855b96-20241106",
Expand Down
43 changes: 0 additions & 43 deletions src/app/[countryCode]/(checkout)/layout.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import CheckoutForm from "@modules/checkout/templates/checkout-form"
import CheckoutSummary from "@modules/checkout/templates/checkout-summary"
import { Metadata } from "next"
import { notFound } from "next/navigation"
import { Suspense } from "react"


export const metadata: Metadata = {
title: "Checkout",
Expand All @@ -20,11 +22,13 @@ export default async function Checkout() {
const customer = await retrieveCustomer()

return (
<div className="grid grid-cols-1 small:grid-cols-[1fr_416px] content-container gap-x-40 py-12">
<PaymentWrapper cart={cart}>
<CheckoutForm cart={cart} customer={customer} />
</PaymentWrapper>
<CheckoutSummary cart={cart} />
</div>
<Suspense fallback={<></>}>
<div className="grid grid-cols-1 small:grid-cols-[1fr_416px] content-container gap-x-40 py-12">
<PaymentWrapper cart={cart}>
<CheckoutForm cart={cart} customer={customer} />
</PaymentWrapper>
<CheckoutSummary cart={cart} />
</div>
</Suspense>
)
}
50 changes: 50 additions & 0 deletions src/app/[locale]/[countryCode]/(checkout)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import k from "@lib/i18n/translations/keys"
import { getTranslations } from "next-intl/server"
import LocalizedClientLink from "@modules/common/components/localized-client-link"
import ChevronDown from "@modules/common/icons/chevron-down"
import MedusaCTA from "@modules/layout/components/medusa-cta"
import { Suspense } from "react"

export default async function CheckoutLayout({
children,
}: {
children: React.ReactNode
params: { locale: string }
}) {
const t = await getTranslations()
return (
<Suspense fallback={<></>}>
<div className="w-full bg-white relative small:min-h-screen">
<div className="h-16 bg-white border-b ">
<nav className="flex h-full items-center content-container justify-between">
<LocalizedClientLink
href="/cart"
className="text-small-semi text-ui-fg-base flex items-center gap-x-2 uppercase flex-1 basis-0"
data-testid="back-to-cart-link"
>
<ChevronDown className="rotate-90" size={16} />
<span className="mt-px hidden small:block txt-compact-plus text-ui-fg-subtle hover:text-ui-fg-base ">
{t(k.BACK_TO_SHOPPING_CART)}
</span>
<span className="mt-px block small:hidden txt-compact-plus text-ui-fg-subtle hover:text-ui-fg-base">
{t(k.BACK)}
</span>
</LocalizedClientLink>
<LocalizedClientLink
href="/"
className="txt-compact-xlarge-plus text-ui-fg-subtle hover:text-ui-fg-base uppercase"
data-testid="store-link"
>
{t(k.MEDUSA_STORE)}
</LocalizedClientLink>
<div className="flex-1 basis-0" />
</nav>
</div>
<div className="relative" data-testid="checkout-container">{children}</div>
<div className="py-4 w-full flex items-center justify-center">
<MedusaCTA />
</div>
</div>
</Suspense>
)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import k from "@lib/i18n/translations/keys"
import { useSafeTranslations } from "@lib/i18n/use-safe-translations"
import InteractiveLink from "@modules/common/components/interactive-link"
import { Metadata } from "next"

Expand All @@ -7,13 +9,14 @@ export const metadata: Metadata = {
}

export default async function NotFound() {
const t = useSafeTranslations()
return (
<div className="flex flex-col gap-4 items-center justify-center min-h-[calc(100vh-64px)]">
<h1 className="text-2xl-semi text-ui-fg-base">Page not found</h1>
<h1 className="text-2xl-semi text-ui-fg-base">{t(k.PAGE_NOT_FOUND)}</h1>
<p className="text-small-regular text-ui-fg-base">
The page you tried to access does not exist.
{t(k.THE_PAGE_YOU_TRIED_TO_ACCESS_D)}
</p>
<InteractiveLink href="/">Go to frontpage</InteractiveLink>
<InteractiveLink href="/">{t(k.GO_TO_FRONTPAGE)}</InteractiveLink>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import k from "@lib/i18n/translations/keys"
import { getTranslations } from "next-intl/server"

import { Metadata } from "next"
import { notFound } from "next/navigation"

Expand All @@ -18,6 +21,7 @@ export default async function Addresses(props: {
const { countryCode } = params
const customer = await retrieveCustomer()
const region = await getRegion(countryCode)
const t = await getTranslations()

if (!customer || !region) {
notFound()
Expand All @@ -26,10 +30,9 @@ export default async function Addresses(props: {
return (
<div className="w-full" data-testid="addresses-page-wrapper">
<div className="mb-8 flex flex-col gap-y-4">
<h1 className="text-2xl-semi">Shipping Addresses</h1>
<h1 className="text-2xl-semi">{t(k.SHIPPING_ADDRESSES)}</h1>
<p className="text-base-regular">
View and update your shipping addresses, you can add as many as you
like. Saving your addresses will make them available during checkout.
{t(k.VIEW_AND_UPDATE_YOUR_SHIPPING)}
</p>
</div>
<AddressBook customer={customer} region={region} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import k from "@lib/i18n/translations/keys"
import { useSafeTranslations } from "@lib/i18n/use-safe-translations"

import { retrieveOrder } from "@lib/data/orders"
import OrderDetailsTemplate from "@modules/order/templates/order-details-template"
import { Metadata } from "next"
Expand All @@ -8,16 +11,19 @@ type Props = {
}

export async function generateMetadata(props: Props): Promise<Metadata> {

const t = useSafeTranslations()

const params = await props.params
const order = await retrieveOrder(params.id).catch(() => null)

if (!order) {
notFound()
}

return {
title: `Order #${order.display_id}`,
description: `View your order`,
title: `${t(k.ORDER)} #${order.display_id}`,
description: `${t(k.VIEW_YOUR_ORDER)}`,
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import k from "@lib/i18n/translations/keys"
import { useSafeTranslations } from "@lib/i18n/use-safe-translations"
import { getTranslations } from "next-intl/server"
import { Metadata } from "next"

import OrderOverview from "@modules/account/components/order-overview"
Expand All @@ -13,6 +16,7 @@ export const metadata: Metadata = {

export default async function Orders() {
const orders = await listOrders()
const t = await getTranslations()

if (!orders) {
notFound()
Expand All @@ -21,10 +25,9 @@ export default async function Orders() {
return (
<div className="w-full" data-testid="orders-page-wrapper">
<div className="mb-8 flex flex-col gap-y-4">
<h1 className="text-2xl-semi">Orders</h1>
<h1 className="text-2xl-semi">{t(k.ORDERS)}</h1>
<p className="text-base-regular">
View your previous orders and their status. You can also create
returns or exchanges for your orders if needed.
{t(k.VIEW_YOUR_PREVIOUS_ORDERS_AND)}
</p>
</div>
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import k from "@lib/i18n/translations/keys"
import { getTranslations } from "next-intl/server"

import { Metadata } from "next"

import ProfilePhone from "@modules/account//components/profile-phone"
Expand All @@ -18,6 +21,7 @@ export const metadata: Metadata = {
export default async function Profile() {
const customer = await retrieveCustomer()
const regions = await listRegions()
const t = await getTranslations()

if (!customer || !regions) {
notFound()
Expand All @@ -26,11 +30,9 @@ export default async function Profile() {
return (
<div className="w-full" data-testid="profile-page-wrapper">
<div className="mb-8 flex flex-col gap-y-4">
<h1 className="text-2xl-semi">Profile</h1>
<h1 className="text-2xl-semi">{t(k.PROFILE)}</h1>
<p className="text-base-regular">
View and update your profile information, including your name, email,
and phone number. You can also update your billing address, or change
your password.
{t(k.VIEW_AND_UPDATE_YOUR_PROFILE_I)}
</p>
</div>
<div className="flex flex-col gap-y-8 w-full">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import k from "@lib/i18n/translations/keys"
import { useSafeTranslations } from "@lib/i18n/use-safe-translations"

import { Metadata } from "next"

import InteractiveLink from "@modules/common/components/interactive-link"

const t = useSafeTranslations()

export const metadata: Metadata = {
title: "404",
description: "Something went wrong",
Expand All @@ -10,12 +15,11 @@ export const metadata: Metadata = {
export default function NotFound() {
return (
<div className="flex flex-col items-center justify-center min-h-[calc(100vh-64px)]">
<h1 className="text-2xl-semi text-ui-fg-base">Page not found</h1>
<h1 className="text-2xl-semi text-ui-fg-base">{t(k.PAGE_NOT_FOUND)}</h1>
<p className="text-small-regular text-ui-fg-base">
The cart you tried to access does not exist. Clear your cookies and try
again.
{t(k.THE_CART_YOU_TRIED_TO_ACCESS_D)}
</p>
<InteractiveLink href="/">Go to frontpage</InteractiveLink>
<InteractiveLink href="/">{t(k.GO_TO_FRONTPAGE)}</InteractiveLink>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { listRegions } from "@lib/data/regions"
import { StoreRegion } from "@medusajs/types"
import CategoryTemplate from "@modules/categories/templates"
import { SortOptions } from "@modules/store/components/refinement-list/sort-products"
import { setRequestLocale } from "next-intl/server"

type Props = {
params: Promise<{ category: string[]; countryCode: string }>
params: Promise<{ category: string[]; countryCode: string; locale: string }>
searchParams: Promise<{
sortBy?: SortOptions
page?: string
Expand Down Expand Up @@ -66,6 +67,7 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
export default async function CategoryPage(props: Props) {
const searchParams = await props.searchParams
const params = await props.params
setRequestLocale(params.locale)
const { sortBy, page } = searchParams

const productCategory = await getCategoryByHandle(params.category)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { listRegions } from "@lib/data/regions"
import { StoreCollection, StoreRegion } from "@medusajs/types"
import CollectionTemplate from "@modules/collections/templates"
import { SortOptions } from "@modules/store/components/refinement-list/sort-products"
import { setRequestLocale } from "next-intl/server"

type Props = {
params: Promise<{ handle: string; countryCode: string }>
params: Promise<{ handle: string; countryCode: string; locale: string }>
searchParams: Promise<{
page?: string
sortBy?: SortOptions
Expand Down Expand Up @@ -70,6 +71,7 @@ export default async function CollectionPage(props: Props) {
const searchParams = await props.searchParams
const params = await props.params
const { sortBy, page } = searchParams
setRequestLocale(params.locale)

const collection = await getCollectionByHandle(params.handle).then(
(collection: StoreCollection) => collection
Expand Down
Loading