mirror of
https://github.com/vercel/commerce.git
synced 2025-05-15 05:56:59 +00:00
Rewrite URLs for app router folders
This commit is contained in:
parent
6a5aa06841
commit
f14d0cb865
24
components/layout/header/desktop-menu/desktop-menu.tsx
Normal file
24
components/layout/header/desktop-menu/desktop-menu.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
export default function DesktopMenu({ items, locale }: { items: []; locale: string }) {
|
||||||
|
const t = useTranslations('routes');
|
||||||
|
return (
|
||||||
|
<ul className="flex gap-6">
|
||||||
|
{items.map((item: { title: string; slug: string }, i: number) => {
|
||||||
|
return (
|
||||||
|
<li key={i}>
|
||||||
|
<Link
|
||||||
|
className="font-medium underline-offset-2 hover:underline"
|
||||||
|
href={`/${locale}/${t('category')}/${item.slug}`}
|
||||||
|
>
|
||||||
|
{item.title}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
@ -3,8 +3,10 @@ import { clientFetch } from '@/lib/sanity/sanity.client';
|
|||||||
import Cart from 'components/cart';
|
import Cart from 'components/cart';
|
||||||
import OpenCart from 'components/cart/open-cart';
|
import OpenCart from 'components/cart/open-cart';
|
||||||
import Logo from 'components/ui/logo/logo';
|
import Logo from 'components/ui/logo/logo';
|
||||||
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
|
import DesktopMenu from './desktop-menu/desktop-menu';
|
||||||
import HeaderRoot from './header-root';
|
import HeaderRoot from './header-root';
|
||||||
import MobileMenuModal from './mobile-menu/modal';
|
import MobileMenuModal from './mobile-menu/modal';
|
||||||
import OpenMobileMenu from './mobile-menu/open-mobile-menu';
|
import OpenMobileMenu from './mobile-menu/open-mobile-menu';
|
||||||
@ -43,17 +45,7 @@ export default async function Header({ locale }: HeaderProps) {
|
|||||||
|
|
||||||
<div className="absolute left-1/2 top-1/2 hidden -translate-x-1/2 -translate-y-1/2 transform md:flex">
|
<div className="absolute left-1/2 top-1/2 hidden -translate-x-1/2 -translate-y-1/2 transform md:flex">
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<ul className="flex gap-6">
|
<DesktopMenu items={mainMenu} locale={locale} />
|
||||||
{mainMenu.map((item: { title: string; slug: string }, i: number) => {
|
|
||||||
return (
|
|
||||||
<li key={i}>
|
|
||||||
<Link className="font-medium" href={`/${locale}/category/${item.slug}`}>
|
|
||||||
{item.title}
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex translate-x-2 transform justify-end space-x-1">
|
<div className="flex translate-x-2 transform justify-end space-x-1">
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { Carousel, CarouselItem } from '@/components/modules/carousel/carousel';
|
|
||||||
import Card from '@/components/ui/card/card';
|
import Card from '@/components/ui/card/card';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
import Text from 'components/ui/text';
|
import Text from 'components/ui/text';
|
||||||
|
|
||||||
interface BlurbSectionProps {
|
interface BlurbSectionProps {
|
||||||
blurbs: any;
|
blurbs: any;
|
||||||
title: string;
|
title: string;
|
||||||
@ -24,9 +22,7 @@ const BlurbSection = ({
|
|||||||
: desktopLayout === '3-column'
|
: desktopLayout === '3-column'
|
||||||
? 'lg:grid-cols-3'
|
? 'lg:grid-cols-3'
|
||||||
: 'lg:grid-cols-4';
|
: 'lg:grid-cols-4';
|
||||||
|
console.log(imageFormat);
|
||||||
const sliderLayout = desktopLayout === '2-column' ? 2 : desktopLayout === '3-column' ? 3 : 4;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{title ? (
|
{title ? (
|
||||||
@ -42,52 +38,35 @@ const BlurbSection = ({
|
|||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`grid px-4 ${gridLayout} gap-x-4 gap-y-8 ${
|
className={cn(
|
||||||
mobileLayout === 'stacked' ? 'lg:hidden' : 'hidden'
|
'w-full gap-4 px-4 lg:px-8 2xl:px-16',
|
||||||
} lg:px-8 2xl:!px-16`}
|
{
|
||||||
|
['grid grid-cols-1']: mobileLayout !== 'horizontal',
|
||||||
|
['flex snap-x snap-proximity overflow-x-auto lg:grid lg:overflow-visible']:
|
||||||
|
mobileLayout === 'horizontal'
|
||||||
|
},
|
||||||
|
`${gridLayout}`
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{blurbs.map((blurb: object | any, index: number) => {
|
{blurbs.map((blurb: object | any, index: number) => {
|
||||||
return (
|
return (
|
||||||
<div key={index}>
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`${
|
||||||
|
mobileLayout === 'horizontal' && 'w-5/12 shrink-0 snap-center lg:w-full'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
<Card
|
<Card
|
||||||
title={blurb?.title}
|
title={blurb?.title}
|
||||||
link={blurb?.link}
|
link={blurb?.link}
|
||||||
image={blurb?.image}
|
image={blurb?.image}
|
||||||
text={blurb?.text}
|
text={blurb?.text}
|
||||||
imageFormat={blurb?.imageFormat}
|
imageFormat={imageFormat}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`${mobileLayout === 'stacked' ? 'hidden lg:block' : 'block'}`}>
|
|
||||||
{blurbs && (
|
|
||||||
<Carousel
|
|
||||||
gliderClasses={'px-4 lg:px-8 2xl:px-16'}
|
|
||||||
hasDots={true}
|
|
||||||
slidesToShow={2.2}
|
|
||||||
responsive={{
|
|
||||||
breakpoint: 1024,
|
|
||||||
settings: {
|
|
||||||
slidesToShow: sliderLayout <= 4 ? sliderLayout + 0.5 : sliderLayout
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{blurbs.map((blurb: any, index: number) => (
|
|
||||||
<CarouselItem key={`${index}`}>
|
|
||||||
<Card
|
|
||||||
title={blurb?.title}
|
|
||||||
link={blurb?.link}
|
|
||||||
image={blurb?.image}
|
|
||||||
text={blurb.text}
|
|
||||||
imageFormat={imageFormat}
|
|
||||||
/>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</Carousel>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,32 +1,30 @@
|
|||||||
'use client'
|
'use client';
|
||||||
|
|
||||||
import SanityImage from 'components/ui/sanity-image'
|
|
||||||
import { cn } from 'lib/utils'
|
|
||||||
import Link from 'next/link'
|
|
||||||
import { FC } from 'react'
|
|
||||||
|
|
||||||
|
|
||||||
|
import SanityImage from 'components/ui/sanity-image';
|
||||||
|
import { cn } from 'lib/utils';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { FC } from 'react';
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string
|
className?: string;
|
||||||
category: any
|
category: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const placeholderImg = '/product-img-placeholder.svg'
|
|
||||||
|
|
||||||
const CategoryCard: FC<Props> = ({ category, className }) => {
|
const CategoryCard: FC<Props> = ({ category, className }) => {
|
||||||
const rootClassName = cn(
|
const rootClassName = cn(
|
||||||
'w-1/2 min-w-0 grow-0 shrink-0 group relative box-border overflow-hidden transition-transform ease-linear cursor-pointer basis-[50%]',
|
'w-1/2 min-w-0 grow-0 shrink-0 group relative box-border overflow-hidden transition-transform ease-linear cursor-pointer basis-[50%]',
|
||||||
className
|
className
|
||||||
)
|
);
|
||||||
|
const t = useTranslations('routes');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`${category.slug}`}
|
href={`/${t('category')}/${category.slug}`}
|
||||||
className={rootClassName}
|
className={rootClassName}
|
||||||
aria-label={category.name}
|
aria-label={category.name}
|
||||||
>
|
>
|
||||||
<div className={'flex flex-col flex-1 justify-center w-full h-full'}>
|
<div className={'flex h-full w-full flex-1 flex-col justify-center'}>
|
||||||
<div className="w-full h-full aspect-[3/4] relative">
|
<div className="relative aspect-[3/4] h-full w-full">
|
||||||
<SanityImage
|
<SanityImage
|
||||||
image={category.image}
|
image={category.image}
|
||||||
alt={category.name || 'Category Image'}
|
alt={category.name || 'Category Image'}
|
||||||
@ -34,13 +32,13 @@ const CategoryCard: FC<Props> = ({ category, className }) => {
|
|||||||
height={400}
|
height={400}
|
||||||
sizes="(max-width: 1024px) 50vw, 25vw"
|
sizes="(max-width: 1024px) 50vw, 25vw"
|
||||||
/>
|
/>
|
||||||
<div className="absolute font-medium bg-high-contrast text-white py-3 px-6 md:py-5 md:px-10 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-high-contrast px-6 py-3 font-medium text-white md:px-10 md:py-5">
|
||||||
{category.title}
|
{category.title}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default CategoryCard
|
export default CategoryCard;
|
||||||
|
@ -5,6 +5,7 @@ import type { Product } from '@/lib/storm/product';
|
|||||||
import Price from 'components/price';
|
import Price from 'components/price';
|
||||||
import Text from 'components/ui/text';
|
import Text from 'components/ui/text';
|
||||||
import { cn } from 'lib/utils';
|
import { cn } from 'lib/utils';
|
||||||
|
import { useLocale, useTranslations } from 'next-intl';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -15,10 +16,12 @@ interface Props {
|
|||||||
|
|
||||||
const ProductCard: FC<Props> = ({ product, className, variant = 'default' }) => {
|
const ProductCard: FC<Props> = ({ product, className, variant = 'default' }) => {
|
||||||
const rootClassName = cn('w-full group relative overflow-hidden', className);
|
const rootClassName = cn('w-full group relative overflow-hidden', className);
|
||||||
|
const t = useTranslations('routes');
|
||||||
|
const locale = useLocale();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/product/${product.slug}`}
|
href={`/${locale}/${t('product')}/${product.slug}`}
|
||||||
className={rootClassName}
|
className={rootClassName}
|
||||||
aria-label={product.name}
|
aria-label={product.name}
|
||||||
locale={product.locale}
|
locale={product.locale}
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
"routes": {
|
||||||
|
"product": "product",
|
||||||
|
"category": "category",
|
||||||
|
"search": "search"
|
||||||
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"button": {
|
"button": {
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
"routes": {
|
||||||
|
"product": "produkt",
|
||||||
|
"category": "kategori",
|
||||||
|
"search": "sok"
|
||||||
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"button": {
|
"button": {
|
||||||
"close": "Stäng",
|
"close": "Stäng",
|
||||||
|
@ -6,7 +6,6 @@ export default createMiddleware({
|
|||||||
|
|
||||||
// If this locale is matched, pathnames work without a prefix (e.g. `/about`)
|
// If this locale is matched, pathnames work without a prefix (e.g. `/about`)
|
||||||
defaultLocale: 'sv',
|
defaultLocale: 'sv',
|
||||||
localeDetection: false
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
|
@ -5,6 +5,25 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({
|
|||||||
|
|
||||||
module.exports = withBundleAnalyzer(
|
module.exports = withBundleAnalyzer(
|
||||||
{
|
{
|
||||||
|
async rewrites() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: '/en/product/:slug',
|
||||||
|
destination: '/en/produkt/:slug',
|
||||||
|
locale: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: '/en/category/:slug',
|
||||||
|
destination: '/en/kategori/:slug',
|
||||||
|
locale: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: '/en/search',
|
||||||
|
destination: '/en/sok',
|
||||||
|
locale: false
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
eslint: {
|
eslint: {
|
||||||
// Disabling on production builds because we're running checks on PRs via GitHub Actions.
|
// Disabling on production builds because we're running checks on PRs via GitHub Actions.
|
||||||
ignoreDuringBuilds: true
|
ignoreDuringBuilds: true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user