mirror of
https://github.com/vercel/commerce.git
synced 2025-05-19 07:56:59 +00:00
wip: Saving work
This commit is contained in:
parent
ce40640353
commit
2319ed72db
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
@ -4,6 +4,7 @@ import localFont from 'next/font/local';
|
||||
import { ReactNode, Suspense } from 'react';
|
||||
|
||||
import { LanguageProvider } from 'app/context/language-context';
|
||||
import { getDictionary } from 'dictionaries';
|
||||
import './globals.css';
|
||||
|
||||
const { TWITTER_CREATOR, TWITTER_SITE, SITE_NAME } = process.env;
|
||||
@ -38,12 +39,6 @@ const cinzel = localFont({
|
||||
variable: '--font-cinzel'
|
||||
});
|
||||
|
||||
const mincho = localFont({
|
||||
src: '../fonts/A-OTF-A1MinchoStd-Bold.otf',
|
||||
display: 'swap',
|
||||
variable: '--font-cinzel'
|
||||
});
|
||||
|
||||
const alpina = localFont({
|
||||
src: [
|
||||
{
|
||||
@ -60,6 +55,12 @@ const alpina = localFont({
|
||||
variable: '--font-alpina'
|
||||
});
|
||||
|
||||
const mincho = localFont({
|
||||
src: '../fonts/A-OTF-A1MinchoStd-Bold.otf',
|
||||
display: 'swap',
|
||||
variable: '--font-mincho'
|
||||
});
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return i18n.locales.map((locale) => ({ lang: locale }));
|
||||
}
|
||||
@ -69,13 +70,15 @@ export default async function RootLayout({
|
||||
params
|
||||
}: {
|
||||
children: ReactNode;
|
||||
params: { lang: string };
|
||||
params: { lang: Locale };
|
||||
}) {
|
||||
const dictionary = await getDictionary(params?.lang);
|
||||
|
||||
return (
|
||||
<html lang={params.lang} className={`${cinzel.variable} ${alpina.variable} ${mincho.variable}`}>
|
||||
<body className="bg-dark text-white selection:bg-green-800 selection:text-green-400">
|
||||
<div className="mx-auto max-w-screen-2xl">
|
||||
<LanguageProvider language={params.lang as Locale}>
|
||||
<LanguageProvider language={params.lang as Locale} dictionary={dictionary}>
|
||||
<Navbar />
|
||||
<Suspense>
|
||||
<main>{children}</main>
|
||||
|
@ -4,8 +4,7 @@ import Footer from 'components/layout/footer';
|
||||
import { LanguageControl } from 'components/layout/navbar/language-control';
|
||||
import type { Locale } from '../../i18n-config';
|
||||
|
||||
import Image from 'next/image';
|
||||
import Namemark from 'public/assets/images/namemark.png';
|
||||
import LogoNamemark from 'components/icons/namemark';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
export const runtime = 'edge';
|
||||
@ -20,15 +19,13 @@ export const metadata = {
|
||||
};
|
||||
|
||||
export default async function HomePage({ params: { lang } }: { params: { lang: Locale } }) {
|
||||
// const dictionary = await getDictionary(lang);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="invisible absolute right-40 top-12 md:visible">
|
||||
<LanguageControl lang={lang} />
|
||||
</div>
|
||||
<div className="px-6 pb-12 pt-6 md:pb-48 md:pl-6 md:pt-12">
|
||||
<Image src={Namemark} alt="suginomori brewery" className="max-w-[260px] md:max-w-[600px]" />
|
||||
<LogoNamemark className="w-[260px] fill-current md:w-[600px]" />
|
||||
</div>
|
||||
<ThreeItemGrid lang={lang} />
|
||||
<Suspense>
|
||||
|
@ -6,24 +6,29 @@ import { ReactNode, createContext, useContext, useState } from 'react';
|
||||
interface IContextProps {
|
||||
currentLanguage?: Locale;
|
||||
setCurrentLanguage: (language: Locale) => void;
|
||||
currentDictionary?: any;
|
||||
}
|
||||
|
||||
export const LanguageContext = createContext<IContextProps>({} as IContextProps);
|
||||
|
||||
export function LanguageProvider({
|
||||
language,
|
||||
dictionary,
|
||||
children
|
||||
}: {
|
||||
language: Locale;
|
||||
dictionary?: any;
|
||||
children: ReactNode | ReactNode[] | string;
|
||||
}) {
|
||||
const [currentLanguage, setCurrentLanguage] = useState<Locale>(language || 'en');
|
||||
const [currentDictionary] = useState<any | undefined>(dictionary);
|
||||
|
||||
return (
|
||||
<LanguageContext.Provider
|
||||
value={{
|
||||
currentLanguage,
|
||||
setCurrentLanguage
|
||||
setCurrentLanguage,
|
||||
currentDictionary
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
@ -1,36 +1,35 @@
|
||||
import clsx from 'clsx';
|
||||
import { GridTileImage } from 'components/grid/tile';
|
||||
import { Locale } from 'i18n-config';
|
||||
import { getCollectionProducts } from 'lib/shopify';
|
||||
import type { Product } from 'lib/shopify/types';
|
||||
import Link from 'next/link';
|
||||
import Label from '../label';
|
||||
import { GridTileImage } from './tile';
|
||||
|
||||
function ThreeItemGridItem({ item, priority }: { item: Product; priority?: boolean }) {
|
||||
const size = item?.variants?.[0]?.selectedOptions?.find((option) => option.name === 'size');
|
||||
return (
|
||||
<div className={clsx('md:col-span-2 md:row-span-1')}>
|
||||
<div className={clsx('col-span-1 row-span-1 md:col-span-2 md:row-span-1')}>
|
||||
<Link
|
||||
className="relative block aspect-bottle h-full w-full overflow-hidden bg-black/30"
|
||||
className="relative block aspect-tall w-full overflow-hidden bg-black/30"
|
||||
href={`/product/${item.handle}`}
|
||||
>
|
||||
<GridTileImage
|
||||
src={item.featuredImage.url}
|
||||
height={1690}
|
||||
width={1192}
|
||||
fill
|
||||
sizes={'(min-width: 768px) 33vw, 100vw'}
|
||||
priority={priority}
|
||||
alt={item.title}
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
</Link>
|
||||
<div className="font-multingual max-w-sm pt-4">
|
||||
<div className="font-multilingual max-w-sm pt-4">
|
||||
<Label
|
||||
title={item.title as string}
|
||||
amount={item.priceRange.maxVariantPrice.amount}
|
||||
currencyCode={item.priceRange.maxVariantPrice.currencyCode}
|
||||
size={size?.value}
|
||||
/>
|
||||
<div className="line-clamp-4 pt-2">{item?.description}</div>
|
||||
<div className="font-regular line-clamp-4 pt-2">{item?.summary?.value}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -52,7 +51,8 @@ export async function ThreeItemGrid({ lang }: { lang: Locale }) {
|
||||
return (
|
||||
<section
|
||||
className={clsx(
|
||||
'mx-auto grid max-w-screen-2xl gap-6 px-4 pb-4 md:grid-cols-6',
|
||||
'mx-auto grid max-w-screen-2xl gap-6 px-4 pb-4 ',
|
||||
'grid-cols-1 md:grid-cols-6',
|
||||
'grid-rows-3 md:grid-rows-1'
|
||||
)}
|
||||
>
|
||||
|
@ -20,7 +20,7 @@ export function GridTileImage({
|
||||
{props.src ? (
|
||||
// eslint-disable-next-line jsx-a11y/alt-text -- `alt` is inherited from `props`, which is being enforced with TypeScript
|
||||
<Image
|
||||
className={clsx('h-full w-full object-contain', {
|
||||
className={clsx('h-full w-full object-cover', {
|
||||
'transition duration-300 ease-in-out hover:scale-105': isInteractive
|
||||
})}
|
||||
{...props}
|
||||
|
34
components/icons/namemark.tsx
Normal file
34
components/icons/namemark.tsx
Normal file
File diff suppressed because one or more lines are too long
@ -4,22 +4,32 @@ import Price from './price';
|
||||
const Label = ({
|
||||
title,
|
||||
amount,
|
||||
currencyCode
|
||||
currencyCode,
|
||||
size
|
||||
}: {
|
||||
title: string;
|
||||
amount: string;
|
||||
currencyCode: string;
|
||||
size?: string;
|
||||
}) => {
|
||||
return (
|
||||
<div className={clsx('@container/label')}>
|
||||
<div className="font-multilingual flex flex-col space-y-2">
|
||||
<h3 className="mr-4 line-clamp-2 flex-grow text-3xl">{title}</h3>
|
||||
<Price
|
||||
className="flex-none"
|
||||
amount={amount}
|
||||
currencyCode={currencyCode}
|
||||
currencyCodeClassName="hidden @[275px]/label:inline"
|
||||
/>
|
||||
<div className="flex flex-row items-center space-x-2">
|
||||
<Price
|
||||
className="flex-none"
|
||||
amount={amount}
|
||||
currencyCode={currencyCode}
|
||||
currencyCodeClassName="hidden @[275px]/label:inline"
|
||||
/>
|
||||
{!!size && (
|
||||
<>
|
||||
<div>/</div>
|
||||
<div>{size}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -9,7 +9,7 @@ import { Fragment, useRef, useState } from 'react';
|
||||
import { LanguageControl } from '../navbar/language-control';
|
||||
|
||||
export function MenuModal() {
|
||||
const { currentLanguage } = useLanguage();
|
||||
const { currentLanguage, currentDictionary } = useLanguage();
|
||||
let [isOpen, setIsOpen] = useState(false);
|
||||
let closeButtonRef = useRef(null);
|
||||
|
||||
@ -43,17 +43,6 @@ export function MenuModal() {
|
||||
>
|
||||
<div className="fixed inset-0 z-20" />
|
||||
</Transition.Child>
|
||||
<Transition.Child as={Fragment}>
|
||||
<div className="fixed right-5 top-6 z-40 px-2 py-1 md:top-11">
|
||||
<div className="flex flex-row space-x-6">
|
||||
<LanguageControl lang={currentLanguage} />
|
||||
|
||||
<button ref={closeButtonRef} onClick={close} className="">
|
||||
<CloseIcon className="h-10 w-10 stroke-current transition-opacity duration-150 hover:opacity-50" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition.Child>
|
||||
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
@ -66,6 +55,16 @@ export function MenuModal() {
|
||||
>
|
||||
<div className="fixed inset-0 z-30 backdrop-blur-sm">
|
||||
<Dialog.Panel>
|
||||
<div className="fixed right-5 top-6 z-40 px-2 py-1 md:top-11">
|
||||
<div className="flex flex-row space-x-6">
|
||||
<LanguageControl lang={currentLanguage} />
|
||||
|
||||
<button ref={closeButtonRef} onClick={close} className="">
|
||||
<CloseIcon className="h-10 w-10 stroke-current transition-opacity duration-150 hover:opacity-50" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="fixed inset-0 grid grid-cols-1 place-content-center bg-dark/80">
|
||||
<div className="flex flex-row justify-end">
|
||||
<div className="flex flex-col space-y-4 px-6 text-right">
|
||||
@ -74,7 +73,7 @@ export function MenuModal() {
|
||||
href="/products"
|
||||
className="font-serif text-4xl font-normal transition-opacity duration-150 hover:opacity-50"
|
||||
>
|
||||
products
|
||||
{currentDictionary?.menu?.products}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -83,7 +82,7 @@ export function MenuModal() {
|
||||
href="/shops"
|
||||
className="font-serif text-4xl font-normal transition-opacity duration-150 hover:opacity-50"
|
||||
>
|
||||
shop list
|
||||
{currentDictionary?.menu?.shops}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -92,7 +91,7 @@ export function MenuModal() {
|
||||
href="/about"
|
||||
className="font-serif text-4xl font-normal transition-opacity duration-150 hover:opacity-50"
|
||||
>
|
||||
about narai
|
||||
{currentDictionary?.menu?.about}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -101,7 +100,7 @@ export function MenuModal() {
|
||||
href="/bar"
|
||||
className="font-serif text-4xl font-normal transition-opacity duration-150 hover:opacity-50"
|
||||
>
|
||||
sagyobar
|
||||
{currentDictionary?.menu?.bar}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -110,7 +109,7 @@ export function MenuModal() {
|
||||
href="/concept"
|
||||
className="font-serif text-4xl font-normal transition-opacity duration-150 hover:opacity-50"
|
||||
>
|
||||
concept
|
||||
{currentDictionary?.menu?.concept}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -119,7 +118,7 @@ export function MenuModal() {
|
||||
href="/stories"
|
||||
className="font-serif text-4xl font-normal transition-opacity duration-150 hover:opacity-50"
|
||||
>
|
||||
stories
|
||||
{currentDictionary?.menu?.stories}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -128,7 +127,7 @@ export function MenuModal() {
|
||||
href="/company"
|
||||
className="font-serif text-4xl font-normal transition-opacity duration-150 hover:opacity-50"
|
||||
>
|
||||
company
|
||||
{currentDictionary?.menu?.company}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -137,6 +136,7 @@ export function MenuModal() {
|
||||
href="/contact"
|
||||
className="font-serif text-4xl font-normal transition-opacity duration-150 hover:opacity-50"
|
||||
>
|
||||
{currentDictionary?.menu?.contact}
|
||||
contact
|
||||
</Link>
|
||||
</div>
|
||||
|
@ -1,6 +1,12 @@
|
||||
{
|
||||
"hello": {
|
||||
"title": "Hello World",
|
||||
"description": "This is a description"
|
||||
"menu": {
|
||||
"products": "products",
|
||||
"shops": "shop list",
|
||||
"about": "about narai",
|
||||
"bar": "sagyobar",
|
||||
"concept": "concept",
|
||||
"stories": "stories",
|
||||
"company": "company",
|
||||
"contact": "contact"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,12 @@
|
||||
{
|
||||
"hello": {
|
||||
"title": "こんにちは",
|
||||
"description": "これはせつめいですよ"
|
||||
"menu": {
|
||||
"products": "商品",
|
||||
"shops": "取り扱い店",
|
||||
"about": "naraiについて",
|
||||
"bar": "sagyobar",
|
||||
"concept": "コンセプト",
|
||||
"stories": "ストーリー",
|
||||
"company": "会社概要",
|
||||
"contact": "contact"
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ const productFragment = /* GraphQL */ `
|
||||
title
|
||||
description
|
||||
descriptionHtml
|
||||
summary: metafield(namespace: "custom", key: "product_summary") {
|
||||
value
|
||||
}
|
||||
options {
|
||||
id
|
||||
name
|
||||
|
@ -115,6 +115,9 @@ export type ShopifyProduct = {
|
||||
title: string;
|
||||
description: string;
|
||||
descriptionHtml: string;
|
||||
summary: {
|
||||
value: string;
|
||||
};
|
||||
options: ProductOption[];
|
||||
priceRange: {
|
||||
maxVariantPrice: Money;
|
||||
|
@ -15,7 +15,7 @@ module.exports = {
|
||||
japan: ['var(--font-mincho)', 'sans-serif']
|
||||
},
|
||||
aspectRatio: {
|
||||
bottle: '1.11'
|
||||
tall: '596 / 845'
|
||||
},
|
||||
keyframes: {
|
||||
fadeIn: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user