diff --git a/packages/nextjs/app/global.css b/packages/nextjs/app/global.css index 8c7d56cd..6f486bc8 100644 --- a/packages/nextjs/app/global.css +++ b/packages/nextjs/app/global.css @@ -6,78 +6,6 @@ body { @apply bg-secondary; } -/* Cabinet Grotesk */ -/* See: https://api.fontshare.com/v2/css?f[]=cabinet-grotesk@500,700,400,300&display=swap */ -/* See: https://nextjs.org/docs/app/building-your-application/styling/css-modules#external-stylesheets */ -@font-face { - font-family: 'Cabinet Grotesk'; - src: url('//cdn.fontshare.com/wf/7GWNQ5AHAZORLOWZ7ELKPLOIQITAR5S5/NYLYMGXMB4RANWVNJSIHG2IKPZ44CN5E/MT4CWVHB3N2C6KFUZ75QK4JQ2FYK4J4M.woff2') format('woff2'), - url('//cdn.fontshare.com/wf/7GWNQ5AHAZORLOWZ7ELKPLOIQITAR5S5/NYLYMGXMB4RANWVNJSIHG2IKPZ44CN5E/MT4CWVHB3N2C6KFUZ75QK4JQ2FYK4J4M.woff') format('woff'), - url('//cdn.fontshare.com/wf/7GWNQ5AHAZORLOWZ7ELKPLOIQITAR5S5/NYLYMGXMB4RANWVNJSIHG2IKPZ44CN5E/MT4CWVHB3N2C6KFUZ75QK4JQ2FYK4J4M.ttf') format('truetype'); - font-weight: 300; - font-display: swap; - font-style: normal; -} - -@font-face { - font-family: 'Cabinet Grotesk'; - src: url('//cdn.fontshare.com/wf/J6PPRPKWXDUIYA47IXLEQB4R4OPVYDQH/N2ZXAXWEHVMLISD2TIXJC7EF4GOY43L4/NXM4Z4TDCMYWBZ7AVI2N6DQ5VMWNENMU.woff2') format('woff2'), - url('//cdn.fontshare.com/wf/J6PPRPKWXDUIYA47IXLEQB4R4OPVYDQH/N2ZXAXWEHVMLISD2TIXJC7EF4GOY43L4/NXM4Z4TDCMYWBZ7AVI2N6DQ5VMWNENMU.woff') format('woff'), - url('//cdn.fontshare.com/wf/J6PPRPKWXDUIYA47IXLEQB4R4OPVYDQH/N2ZXAXWEHVMLISD2TIXJC7EF4GOY43L4/NXM4Z4TDCMYWBZ7AVI2N6DQ5VMWNENMU.ttf') format('truetype'); - font-weight: 400; - font-display: swap; - font-style: normal; -} - -@font-face { - font-family: 'Cabinet Grotesk'; - src: url('//cdn.fontshare.com/wf/CKQBK2QBTCDREE7L3MXZ3PPW7LDNJCWU/OTOY7FQFSFOJVZKJWKO2EHUJLOGBDN4Q/4CO2ETY7NITKLUDKMYJ75RHJSPHOJ7XT.woff2') format('woff2'), - url('//cdn.fontshare.com/wf/CKQBK2QBTCDREE7L3MXZ3PPW7LDNJCWU/OTOY7FQFSFOJVZKJWKO2EHUJLOGBDN4Q/4CO2ETY7NITKLUDKMYJ75RHJSPHOJ7XT.woff') format('woff'), - url('//cdn.fontshare.com/wf/CKQBK2QBTCDREE7L3MXZ3PPW7LDNJCWU/OTOY7FQFSFOJVZKJWKO2EHUJLOGBDN4Q/4CO2ETY7NITKLUDKMYJ75RHJSPHOJ7XT.ttf') format('truetype'); - font-weight: 500; - font-display: swap; - font-style: normal; -} - -@font-face { - font-family: 'Cabinet Grotesk'; - src: url('//cdn.fontshare.com/wf/XMXWOHABYLQDJ42L65EFRYNVRY37HQCB/B2O4O6V3JMFM2WDCYQI3A47L5U4THDUL/WN5274VQ3AUBDFP74GB4EC4XYJ3EKVNE.woff2') format('woff2'), - url('//cdn.fontshare.com/wf/XMXWOHABYLQDJ42L65EFRYNVRY37HQCB/B2O4O6V3JMFM2WDCYQI3A47L5U4THDUL/WN5274VQ3AUBDFP74GB4EC4XYJ3EKVNE.woff') format('woff'), - url('//cdn.fontshare.com/wf/XMXWOHABYLQDJ42L65EFRYNVRY37HQCB/B2O4O6V3JMFM2WDCYQI3A47L5U4THDUL/WN5274VQ3AUBDFP74GB4EC4XYJ3EKVNE.ttf') format('truetype'); - font-weight: 700; - font-display: swap; - font-style: normal; -} - - -@font-face { - font-family: "JeanLuc"; - src: url('../assets/fonts/jeanluc/jeanlucweb-bold.woff'); - font-weight: bold; - font-style: normal; -} - -@font-face { - font-family: "JeanLuc"; - src: url('../assets/fonts/jeanluc/jeanlucweb-thin.woff'); - font-weight: auto; - font-style: normal; -} - -@font-face { - font-family: "JetBrains Mono"; - src: url('../assets/fonts/jetbrainsmono/JetBrainsMono-Bold.woff2'); - font-weight: bold; - font-style: normal; -} - -@font-face { - font-family: "JetBrains Mono"; - src: url('../assets/fonts/jetbrainsmono/JetBrainsMono-Regular.woff2'); - font-weight: auto; - font-style: normal; -} - code { @apply rounded-md bg-black/5 px-1.5 py-0.5; font-family: 'JetBrains Mono', monospace; diff --git a/packages/nextjs/app/layout.tsx b/packages/nextjs/app/layout.tsx index 205793b2..c4112b4c 100644 --- a/packages/nextjs/app/layout.tsx +++ b/packages/nextjs/app/layout.tsx @@ -4,6 +4,7 @@ import { Header } from "components/Header/Header"; import { Metadata } from "next"; import { CartProvider } from "components/CartContext"; import { AnimatePresence, MotionConfig } from "./ui/framer"; +import localFont from "next/font/local"; export const metadata: Metadata = { title: "Home", @@ -14,9 +15,51 @@ export const viewport = { width: "device-width", }; +const cabinetFont = localFont({ + src: [ + { + path: "../assets/fonts/cabinetgrotesk/cabinetgrotesk-300.woff2", + weight: "300", + style: "normal", + }, + { + path: "../assets/fonts/cabinetgrotesk/cabinetgrotesk-400.woff2", + weight: "400", + style: "normal", + }, + { + path: "../assets/fonts/cabinetgrotesk/cabinetgrotesk-500.woff2", + weight: "500", + style: "normal", + }, + { + path: "../assets/fonts/cabinetgrotesk/cabinetgrotesk-700.woff2", + weight: "700", + style: "normal", + }, + ], + variable: "--font-cabinet", +}); + +const jeanLuc = localFont({ + src: [ + { + path: "../assets/fonts/jeanluc/jeanlucweb-bold.woff", + weight: "bold", + style: "normal", + }, + { + path: "../assets/fonts/jeanluc/jeanlucweb-thin.woff", + weight: "normal", + style: "normal", + }, + ], + variable: "--font-jeanLuc", +}); + export default function RootLayout({ children }: { children: React.ReactNode }) { return ( - + diff --git a/packages/nextjs/app/migration/about.tsx b/packages/nextjs/app/migration/about.tsx index 7a37ef49..a3b89afe 100644 --- a/packages/nextjs/app/migration/about.tsx +++ b/packages/nextjs/app/migration/about.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { NextPage } from "next"; -import NextImage from "next/legacy/image"; +import NextImage from "next/image"; import Link from "next/link"; import { BreadIcon } from "shared-ui"; @@ -60,14 +60,13 @@ const AboutPage: NextPage = () => {
@@ -162,14 +161,12 @@ const AboutPage: NextPage = () => {

diff --git a/packages/nextjs/app/migration/home-page.tsx b/packages/nextjs/app/migration/home-page.tsx index 645d6b15..30db70d2 100644 --- a/packages/nextjs/app/migration/home-page.tsx +++ b/packages/nextjs/app/migration/home-page.tsx @@ -5,7 +5,7 @@ import * as React from "react"; import { NextPage } from "next"; import { FiArrowRight } from "react-icons/fi"; import Link from "next/link"; -import NextImage from "next/legacy/image"; +import NextImage from "next/image"; import { Button, FeaturedQuote } from "../ui/shared-ui"; import { localImageLoader } from "utils/localImageLoader"; @@ -28,18 +28,16 @@ const Home: NextPage = ({ data }) => {

Formidable breads for your daily life.

- - - +
{data?.products[0].name @@ -50,11 +48,9 @@ const Home: NextPage = ({ data }) => { Our bestsellers
- - - +
@@ -70,9 +66,8 @@ const Home: NextPage = ({ data }) => {
diff --git a/packages/nextjs/app/migration/products/[slug].tsx b/packages/nextjs/app/migration/products/[slug].tsx index 389c7bd7..fcaffd0b 100644 --- a/packages/nextjs/app/migration/products/[slug].tsx +++ b/packages/nextjs/app/migration/products/[slug].tsx @@ -110,7 +110,9 @@ const PageBody = ({ variant, product }: { product?: ProductDetail; variant?: Pro
- {variant?.images && } + {variant?.images && ( + + )}

{product?.name}

diff --git a/packages/nextjs/app/migration/products/index.tsx b/packages/nextjs/app/migration/products/index.tsx index b8ea69aa..33819afc 100644 --- a/packages/nextjs/app/migration/products/index.tsx +++ b/packages/nextjs/app/migration/products/index.tsx @@ -102,8 +102,8 @@ const ProductsPage: NextPage = ({ )} key={productNames} > - {variants.map((variant) => ( - + {variants.map((variant, index) => ( + ))} {/* Add padder items when on page > 1 so pagination bar isn't moving around */} {+(query?.get("page") || 1) > 1 && diff --git a/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-300.woff2 b/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-300.woff2 new file mode 100644 index 00000000..5a9053b2 Binary files /dev/null and b/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-300.woff2 differ diff --git a/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-400.woff2 b/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-400.woff2 new file mode 100644 index 00000000..38a19070 Binary files /dev/null and b/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-400.woff2 differ diff --git a/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-500.woff2 b/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-500.woff2 new file mode 100644 index 00000000..22708d2e Binary files /dev/null and b/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-500.woff2 differ diff --git a/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-700.woff2 b/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-700.woff2 new file mode 100644 index 00000000..fc4f32d0 Binary files /dev/null and b/packages/nextjs/assets/fonts/cabinetgrotesk/cabinetgrotesk-700.woff2 differ diff --git a/packages/nextjs/components/Card.tsx b/packages/nextjs/components/Card.tsx index 52161acf..6fc27c34 100644 --- a/packages/nextjs/components/Card.tsx +++ b/packages/nextjs/components/Card.tsx @@ -13,6 +13,8 @@ export interface CardProps { imageProps: { src: SanityImageSource; alt: string; + priority?: boolean; + sizes?: string; containerClassName?: string; }; } @@ -35,7 +37,14 @@ export const Card = ({ href={to} className={className} > - {imageProps.alt} + {imageProps.alt} ); }; diff --git a/packages/nextjs/components/CategoryList.tsx b/packages/nextjs/components/CategoryList.tsx index 692d391f..a86c4ad6 100644 --- a/packages/nextjs/components/CategoryList.tsx +++ b/packages/nextjs/components/CategoryList.tsx @@ -10,7 +10,7 @@ export const CategoryList = ({ items }: CategoryListProps) => { return (
    - {items.map((category) => ( + {items.map((category, index) => (
  • { }, }} imageProps={{ + priority: index === 0, src: category.images?.[0]?.images ?? "", alt: category.images?.[0]?.name ?? "", + sizes: "(max-width: 768px) 100vw, 50vw", containerClassName: "aspect-[16/10]", }} title={category.name ?? ""} diff --git a/packages/nextjs/components/FeaturedList.tsx b/packages/nextjs/components/FeaturedList.tsx index b07d5acb..7ad8853b 100644 --- a/packages/nextjs/components/FeaturedList.tsx +++ b/packages/nextjs/components/FeaturedList.tsx @@ -35,6 +35,7 @@ export const FeaturedList = ({ items }: Props) => { src: item.variants?.[0]?.images?.[0] ?? "", alt: item.variants?.[0]?.name ?? "", containerClassName: "aspect-square", + sizes: "(max-width: 768px) 100vw, 33vw", }, }; } else if (item._type === "category") { @@ -52,6 +53,7 @@ export const FeaturedList = ({ items }: Props) => { src: item.images?.[0]?.images ?? "", alt: item.images?.[0]?.name ?? "", containerClassName: "aspect-[16/10]", + sizes: "(max-width: 768px) 100vw, 33vw", }, }; } diff --git a/packages/nextjs/components/Image.tsx b/packages/nextjs/components/Image.tsx index 0c35d815..0fcb1b42 100644 --- a/packages/nextjs/components/Image.tsx +++ b/packages/nextjs/components/Image.tsx @@ -1,7 +1,7 @@ -import type { ImageProps, ImageLoaderProps } from "next/legacy/image"; +import type { ImageProps, ImageLoaderProps } from "next/image"; import * as React from "react"; import { SanityImageSource } from "@sanity/image-url/lib/types/types"; -import NextImage from "next/legacy/image"; +import NextImage from "next/image"; import { imageBuilder } from "utils/sanityClient"; interface Props extends Omit { @@ -21,14 +21,16 @@ const sanityLoader = (sanitySrc: SanityImageSource, { width, quality }: ImageLoa export const Image = (props: Props) => { const baseURL = "https://cdn.sanity.io/images/"; + const { className, ...rest } = props; if (!props.src) return null; return ( sanityLoader(props.src, p)} - {...props} + {...rest} src={imageBuilder.image(props?.src).url()?.toString().replace(baseURL, "") ?? ""} + className={`${className} max-w-full`} /> ); }; diff --git a/packages/nextjs/components/ImageCarousel.tsx b/packages/nextjs/components/ImageCarousel.tsx index 54078e3a..7b746fa2 100644 --- a/packages/nextjs/components/ImageCarousel.tsx +++ b/packages/nextjs/components/ImageCarousel.tsx @@ -5,15 +5,19 @@ import { ImageCarousel as BaseImageCarousel } from "shared-ui"; export type ImageCarouselProps = { productImages: ProductImage[]; + imagePriority?: boolean; + sizes?: string; }; -export const ImageCarousel = ({ productImages }: ImageCarouselProps) => { +export const ImageCarousel = ({ productImages, imagePriority, sizes }: ImageCarouselProps) => { return ( {productImages?.map((image) => ( {image?.name ( - - handlePageChanged(e, page)} - className={classNames( - "border rounded w-10 aspect-square flex items-center justify-center", - page === currentPage ? "border-primary" : "border-[transparent]" - )} - aria-current={page === currentPage ? "page" : "false"} - > - {page} - + handlePageChanged(e, page)} + className={classNames( + "border rounded w-10 aspect-square flex items-center justify-center", + page === currentPage ? "border-primary" : "border-[transparent]" + )} + aria-current={page === currentPage ? "page" : "false"} + > + {page} )} /> diff --git a/packages/nextjs/components/Product.tsx b/packages/nextjs/components/Product.tsx index 37fdb936..d32514af 100644 --- a/packages/nextjs/components/Product.tsx +++ b/packages/nextjs/components/Product.tsx @@ -5,9 +5,10 @@ import { Image } from "./Image"; type Props = { item: PLPVariant; + priorityImage?: boolean; }; -export const Product = ({ item }: Props) => { +export const Product = ({ item, priorityImage }: Props) => { const href = { pathname: `/products/${item.productSlug}`, query: { @@ -18,7 +19,14 @@ export const Product = ({ item }: Props) => { return (
    - {item.name} + {item.name}

    {item.name}

    diff --git a/packages/nextjs/tailwind.config.js b/packages/nextjs/tailwind.config.js index 6dc93414..a9edb51d 100644 --- a/packages/nextjs/tailwind.config.js +++ b/packages/nextjs/tailwind.config.js @@ -18,8 +18,8 @@ module.exports = { }, }, fontFamily: { - sans: ["Cabinet Grotesk", ...defaultTheme.fontFamily.sans], - jeanLuc: ["JeanLuc", ...defaultTheme.fontFamily.sans], + sans: ["var(--font-cabinet)", ...defaultTheme.fontFamily.sans], + jeanLuc: ["var(--font-jeanLuc)", ...defaultTheme.fontFamily.sans], }, backgroundImage: { // converted to data url from Figma export diff --git a/packages/nextjs/utils/localImageLoader.ts b/packages/nextjs/utils/localImageLoader.ts index 08a54321..eea8a5be 100644 --- a/packages/nextjs/utils/localImageLoader.ts +++ b/packages/nextjs/utils/localImageLoader.ts @@ -1,4 +1,4 @@ -import { ImageLoader } from "next/legacy/image"; +import { ImageLoader } from "next/image"; // Note: The ?width query param doesn't actually do anything, but Next.js expects you to use it. // Adding it in here as a reminder that you _should_ use it in the case of custom loaders.