Merge pull request #3 from zenzen-sol/sol/2023-08-24-updates

fix: Updates from Alisa's feedback
This commit is contained in:
Sol Irvine 2023-08-25 03:18:34 +09:00 committed by GitHub
commit 35902421ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 361 additions and 95 deletions

View File

@ -1,7 +1,12 @@
'use client';
import CompanyImage001 from '@images/company-images/irie.webp';
import CompanyImage002 from '@images/company-images/kou.webp';
import CompanyImage003 from '@images/company-images/yamano.webp';
import AlisaImage from '@images/company-images/sb_profile_photo_alisa.webp';
import IrieImage from '@images/company-images/sb_profile_photo_irie.webp';
import SundbergImage from '@images/company-images/sb_profile_photo_kou.webp';
import MasaImage from '@images/company-images/sb_profile_photo_masa.webp';
import NishikawaImage from '@images/company-images/sb_profile_photo_nishikawa.webp';
import ShinyaImage from '@images/company-images/sb_profile_photo_shinya.webp';
import TakaImage from '@images/company-images/sb_profile_photo_taka.webp';
import clsx from 'clsx';
import VideoPlayer from 'components/video/video-player';
import { useTranslations } from 'next-intl';
@ -70,7 +75,7 @@ export default function CompanyDetail() {
<div className="font-multilingual col-span-1 py-4 text-base font-extralight">
<div className="relative aspect-square">
<Image
src={CompanyImage001}
src={IrieImage}
priority={true}
alt="A picture of Irie Masayuki."
className={clsx('h-full w-full object-cover')}
@ -84,7 +89,7 @@ export default function CompanyDetail() {
<div className="font-multilingual col-span-1 py-4 text-lg font-extralight">
<div className="relative aspect-square">
<Image
src={CompanyImage001}
src={NishikawaImage}
priority={true}
alt="A picture of Masataka Nishikawa."
className={clsx('h-full w-full object-cover')}
@ -98,7 +103,7 @@ export default function CompanyDetail() {
<div className="font-multilingual col-span-1 py-4 text-lg font-extralight">
<div className="relative aspect-square">
<Image
src={CompanyImage002}
src={SundbergImage}
priority={true}
alt="A picture of Kou Sundberg."
className={clsx('h-full w-full object-cover')}
@ -112,7 +117,21 @@ export default function CompanyDetail() {
<div className="font-multilingual col-span-1 py-4 text-lg font-extralight">
<div className="relative aspect-square">
<Image
src={CompanyImage003}
src={MasaImage}
priority={true}
alt="A picture of Masanori Komatsu."
className={clsx('h-full w-full object-cover')}
/>
</div>
<div className="pt-2">{t('company.masa.japanese')}</div>
<div className="pb-4">{t('company.masa.english')}</div>
<div className="text-sm">{t('company.masa.role')}</div>
</div>
<div className="font-multilingual col-span-1 py-4 text-lg font-extralight">
<div className="relative aspect-square">
<Image
src={TakaImage}
priority={true}
alt="A picture of Takatoshi Yamano."
className={clsx('h-full w-full object-cover')}
@ -126,7 +145,7 @@ export default function CompanyDetail() {
<div className="font-multilingual col-span-1 py-4 text-lg font-extralight">
<div className="relative aspect-square">
<Image
src={CompanyImage001}
src={AlisaImage}
priority={true}
alt="A picture of Alisa Yoshida."
className={clsx('h-full w-full object-cover')}
@ -140,7 +159,7 @@ export default function CompanyDetail() {
<div className="font-multilingual col-span-1 py-4 text-lg font-extralight">
<div className="relative aspect-square">
<Image
src={CompanyImage001}
src={ShinyaImage}
priority={true}
alt="A picture of Shinya Ikegaya."
className={clsx('h-full w-full object-cover')}

View File

@ -30,12 +30,13 @@ export default function ConceptDetail() {
<div className="md:w-1/2">
<h2 className="max-w-sm pb-12 text-4xl md:text-5xl">{t('concept.title')}</h2>
<p className="font-multilingual text-base font-extralight">
{t('concept.para001')} {t('concept.para002')} {t('concept.para003')}
<div>{t('concept.para001')}</div>
<div>{t('concept.para002')}</div>
<div>{t('concept.para003')}</div>
</p>
<div className="font-multilingual pt-24 font-extralight">
<p className="pb-6 text-xl font-normal">{t('concept.subtitle001')}</p>
<p className="pb-24 text-base leading-relaxed">{t('concept.para004')}</p>
<p className="pb-6 text-xl font-normal">{t('concept.subtitle002')}</p>
<p className="pb-4 text-base leading-relaxed">{t('concept.para005')}</p>
<p className="pb-4 text-base leading-relaxed">
{t('concept.para006')} {t('concept.para007')} {t('concept.para008')}

View File

@ -9,101 +9,131 @@ export default function Disclosures() {
<>
<div className="mx-auto font-serif">
<h4 className="mx-auto max-w-4xl text-2xl font-extrabold tracking-tight sm:text-3xl">
{t('disclosurePage.title')}
{t('disclosure-page.title')}
</h4>
<div className="mx-auto max-w-4xl">
<div className="font-multilingual my-12">
<section className="font-multilingual mb-36 mt-12 flex flex-col space-y-6 text-base md:space-y-3">
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.distributor.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.distributor.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.distributor.value')}</div>
<div>{t('disclosure-page.distributor.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.representative.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.representative.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.representative.value')}</div>
<div>{t('disclosure-page.representative.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.address.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.address.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.address.one')}</div>
<div>{t('disclosurePage.address.two')}</div>
<div>{t('disclosure-page.address.one')}</div>
<div>{t('disclosure-page.address.two')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.phone.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.phone.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.phone.value')}</div>
<div>{t('disclosure-page.phone.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.email.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.email.label')}</div>
<div className="md:w-2/3">
<Link
href={`mailto:${t('disclosurePage.homepage.value')}`}
href={`mailto:${t('disclosure-page.homepage.value')}`}
className="transition-opacity duration-150 hover:opacity-90"
>
<div>{t('disclosurePage.email.value')}</div>
<div>{t('disclosure-page.email.value')}</div>
</Link>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">
<div>{t('disclosurePage.homepage.label')}</div>
<div>{t('disclosure-page.homepage.label')}</div>
</div>
<div className="md:w-2/3">
<div></div>
<Link
href={t('disclosurePage.homepage.value')}
href={t('disclosure-page.homepage.value')}
className="transition-opacity duration-150 hover:opacity-90"
>
{t('disclosurePage.homepage.value')}
{t('disclosure-page.homepage.value')}
</Link>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.price.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.price.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.price.value')}</div>
<div>{t('disclosure-page.price.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.otherCharges.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.paymentMethod.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.otherCharges.value')}</div>
<div>{t('disclosure-page.paymentMethod.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.paymentMethod.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.paymentPeriod.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.paymentMethod.value')}</div>
<div>{t('disclosure-page.paymentPeriod.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.paymentPeriod.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.delivery.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.paymentPeriod.value')}</div>
<div>{t('disclosure-page.delivery.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.delivery.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.returnsAndExchanges.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.delivery.value')}</div>
<div>{t('disclosure-page.returnsAndExchanges.one')}</div>
<div className="pt-4">{t('disclosure-page.returnsAndExchanges.two')}</div>
</div>
</div>
<div className="flex flex-col space-y-4 pt-12">
<h2 className="font-multilingual text-[30px] font-extralight">
{t('disclosure-page.legal.title')}
</h2>
</div>
<div className="flex flex-col space-y-2 pt-6 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosure-page.legal.001.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosure-page.legal.001.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosurePage.returnsAndExchanges.label')}</div>
<div className="md:w-1/3">{t('disclosure-page.legal.002.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosurePage.returnsAndExchanges.one')}</div>
<div className="pt-4">{t('disclosurePage.returnsAndExchanges.two')}</div>
<div>{t('disclosure-page.legal.002.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosure-page.legal.003.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosure-page.legal.003.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosure-page.legal.004.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosure-page.legal.004.value')}</div>
</div>
</div>
<div className="flex flex-col space-y-2 md:flex-row md:space-x-3 md:space-y-0">
<div className="md:w-1/3">{t('disclosure-page.legal.005.label')}</div>
<div className="md:w-2/3">
<div>{t('disclosure-page.legal.005.value')}</div>
</div>
</div>
<div className="pt-8">
<Link href="/" className="transition-opacity duration-150 hover:opacity-90">
{t('disclosurePage.return')}
{t('disclosure-page.return')}
</Link>
</div>
</section>

View File

@ -3,7 +3,7 @@ import { notFound } from 'next/navigation';
import { Suspense } from 'react';
import clsx from 'clsx';
import { AddToCart } from 'components/cart/add-to-cart';
import { AddManyToCart } from 'components/cart/add-many-to-cart';
import { GridTileImage } from 'components/grid/tile';
import Label from 'components/label';
import { SupportedLocale } from 'components/layout/navbar/language-control';
@ -135,7 +135,8 @@ export default async function ProductPage({
<div className="max-w-sm">
<VariantSelector options={product.options} variants={product.variants} />
<AddToCart
<AddManyToCart
quantity={1}
variants={product.variants}
availableForSale={product.availableForSale}
/>

View File

@ -28,6 +28,37 @@ export const addItem = async (variantId: string | undefined): Promise<String | u
}
};
export const addItems = async ({
variantId,
quantity = 1
}: {
variantId: string | undefined;
quantity: number;
}): Promise<String | undefined> => {
let cartId = cookies().get('cartId')?.value;
let cart;
if (cartId) {
cart = await getCart(cartId);
}
if (!cartId || !cart) {
cart = await createCart();
cartId = cart.id;
cookies().set('cartId', cartId);
}
if (!variantId) {
return 'Missing product variant ID';
}
try {
await addToCart(cartId, [{ merchandiseId: variantId, quantity }]);
} catch (e) {
return quantity === 1 ? 'Error adding item to cart' : 'Error adding items to cart';
}
};
export const removeItem = async (lineId: string): Promise<String | undefined> => {
const cartId = cookies().get('cartId')?.value;

View File

@ -0,0 +1,114 @@
'use client';
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';
import clsx from 'clsx';
import LoadingDots from 'components/loading-dots';
import { ProductVariant } from 'lib/shopify/types';
import { useTranslations } from 'next-intl';
import { useRouter, useSearchParams } from 'next/navigation';
import { useState, useTransition } from 'react';
import { addItems } from './actions';
export function AddManyToCart({
quantity = 1,
variants,
availableForSale
}: {
quantity: number;
variants: ProductVariant[];
availableForSale: boolean;
}) {
const router = useRouter();
const searchParams = useSearchParams();
const t = useTranslations('Index');
const [currentQuantity, setCurrentQuantity] = useState<number>(quantity);
const [isPending, startTransition] = useTransition();
const defaultVariantId = variants.length === 1 ? variants[0]?.id : undefined;
const variant = variants.find((variant: ProductVariant) =>
variant.selectedOptions.every(
(option) => option.value === searchParams.get(option.name.toLowerCase())
)
);
const selectedVariantId = variant?.id || defaultVariantId;
const title = !availableForSale
? t('cart.out-of-stock')
: !selectedVariantId
? t('cart.options')
: undefined;
return (
<div className="flex flex-col space-y-2">
<div className="font-multilingual flex flex-row items-center space-x-2 border border-white/50">
<div className="px-3">{t('cart.quantity-label')}</div>
<input
value={currentQuantity}
onChange={(e) => setCurrentQuantity(Number(e.target.value))}
className={clsx(
'w-auto grow bg-transparent px-2 py-3 text-right text-white',
'outline-none focus:border-0 focus:outline-none focus:ring-0',
'focus-visible:ring-none focus-visible:border-none focus-visible:outline-none',
'focus-visible:ring-0 focus-visible:ring-offset-0',
'active:border-none active:outline-none active:ring-0'
)}
/>
<div className="flex h-full flex-col space-y-px">
<button
onClick={() => setCurrentQuantity(currentQuantity ? currentQuantity + 1 : 1)}
className="grow px-2 py-0.5"
>
<span>
<ChevronUpIcon className="h-4 w-4" />
</span>
</button>
<button
onClick={() => setCurrentQuantity(currentQuantity > 0 ? currentQuantity - 1 : 0)}
className="grow px-2 py-0.5"
>
<span>
<ChevronDownIcon className="h-4 w-4" />
</span>
</button>
</div>
</div>
<button
aria-label="Add items to cart"
disabled={isPending || !availableForSale || !selectedVariantId}
title={title}
onClick={() => {
// Safeguard in case someone messes with `disabled` in devtools.
if (!availableForSale || !selectedVariantId) return;
startTransition(async () => {
const error = await addItems({
variantId: selectedVariantId,
quantity: currentQuantity
});
if (error) {
// Trigger the error boundary in the root error.js
throw new Error(error.toString());
}
router.refresh();
});
}}
className={clsx(
'relative flex w-full items-center justify-center bg-white p-4 font-serif text-xl tracking-wide text-black hover:opacity-90',
{
'cursor-not-allowed opacity-60 hover:opacity-60':
!availableForSale || !selectedVariantId,
'cursor-not-allowed': isPending
}
)}
>
{!isPending ? (
<span>{availableForSale ? t('cart.add') : t('cart.out-of-stock')}</span>
) : (
<LoadingDots className="my-3 bg-black" />
)}
</button>
</div>
);
}

View File

@ -18,7 +18,7 @@ const Label = ({
<h3 className="mr-4 line-clamp-2 grow font-serif text-3xl tracking-wider md:text-4xl">
{title}
</h3>
<div className="font-multilingual flex flex-row items-center space-x-2 text-[17px]">
<div className="font-multilingual flex flex-row items-center space-x-2 text-[14px] font-normal">
<Price
className="flex-none"
amount={amount}

View File

@ -13,43 +13,43 @@ export default function FooterMenu() {
<nav className="font-multilingual flex flex-col space-y-2 text-left text-sm font-extralight">
<div>
<Link href="/products" className="transition-opacity duration-150 hover:opacity-50">
{t('menu.products')}
{t('footer.menu.products')}
</Link>
</div>
<div>
<Link href="/shop-list" className="transition-opacity duration-150 hover:opacity-50">
{t('menu.shops')}
{t('footer.menu.shops')}
</Link>
</div>
<div>
<Link href="/about" className="transition-opacity duration-150 hover:opacity-50">
{t('menu.about')}
{t('footer.menu.about')}
</Link>
</div>
<div>
<Link href="/bar" className="transition-opacity duration-150 hover:opacity-50">
{t('menu.bar')}
{t('footer.menu.bar')}
</Link>
</div>
<div>
<Link href="/concept" className="transition-opacity duration-150 hover:opacity-50">
{t('menu.concept')}
{t('footer.menu.concept')}
</Link>
</div>
<div>
<Link href="/stories" className="transition-opacity duration-150 hover:opacity-50">
{t('menu.stories')}
{t('footer.menu.stories')}
</Link>
</div>
<div>
<Link href="/company" className="transition-opacity duration-150 hover:opacity-50">
{t('menu.company')}
{t('footer.menu.company')}
</Link>
</div>
</nav>

View File

@ -71,30 +71,43 @@
"footer": {
"newsletter": {
"promo": "Get 10% off on your first order. Get discount."
},
"menu": {
"title": "menu",
"products": "products",
"shops": "shop list",
"about": "about narai",
"bar": "sagyobar",
"concept": "concept",
"stories": "stories",
"company": "company",
"contact": "contact"
}
},
"cart": {
"add": "add to cart",
"out-of-stock": "out of stock",
"title": "Shopping Bag",
"subtitle": "Review your Order",
"empty": "Your shopping bag is empty",
"declinedCard": "We couldn't process the purchase. Please check your card information and try again.",
"thankYou": "Thank you for your order.",
"subtotal": "Subtotal",
"taxes": "Taxes",
"taxCalculation": "Calculated at checkout",
"shipping": "Shipping",
"shippingCalculation": "Calculated at checkout",
"total": "Total",
"proceed": "Proceed to Checkout",
"continue": "Continue Shopping",
"note": "Notes",
"notePlaceholder": "Enter any notes you would like to include with your order",
"addNote": "Add a note to your order",
"editNote": "Edit note",
"hideNote": "Hide",
"saving": "Saving...",
"options": "please select options",
"quantity-label": "quantity",
"title": "shopping bag",
"subtitle": "review your order",
"empty": "your shopping bag is empty",
"declinedCard": "we couldn't process the purchase. Please check your card information and try again.",
"thankYou": "thank you for your order.",
"subtotal": "subtotal",
"taxes": "taxes",
"taxCalculation": "calculated at checkout",
"shipping": "shipping",
"shippingCalculation": "calculated at checkout",
"total": "total",
"proceed": "proceed to Checkout",
"continue": "continue Shopping",
"note": "notes",
"notePlaceholder": "enter any notes you would like to include with your order",
"addNote": "add a note to your order",
"editNote": "edit note",
"hideNote": "hide",
"saving": "saving...",
"addFeaturedProduct": "+ add"
},
"age-gate": {
@ -196,7 +209,6 @@
"para003": "We aim to go beyond brewing exploring sake with a free and creative approach, to help spread the beauty of sake to the world.",
"subtitle001": "about suginomori brewery",
"para004": "In 2021, we restored Suginomori Shuzo, a sake brewery nestled in the historic town of Narai-juku, established in 1793 but closed down in 2012. After upgrading the facilities and optimizing the space to a third of its original size, it was reborn as suginomori brewery.",
"subtitle002": "our approach",
"para005": "In the process of revitalization, we found that the number of sake breweries, which used to be close to local life, has been decreasing year by year due to the decline in domestic demand for sake, and that abandoned farmland has been growing along with it. We wanted to take these issues seriously.",
"para006": "We listen to what farmers have to say and visit their rice fields.",
"para007": "We will realize a stable production environment by introducing a new four-season brewing method that allows year-round brewing.",
@ -243,6 +255,11 @@
"english": "Kou Sundberg",
"role": "蔵元"
},
"masa": {
"japanese": "小松正則",
"english": "Masanori Komatsu",
"role": "COO"
},
"yamano": {
"japanese": "山野恭稔",
"english": "Takatoshi Yamano",
@ -469,7 +486,7 @@
"ariaLabel": "Contact our support email"
}
},
"disclosurePage": {
"disclosure-page": {
"title": "Disclosures",
"distributor": {
"label": "販売業者",
@ -500,10 +517,6 @@
"label": "商品の販売価格",
"value": "各商品ページをご参照ください。"
},
"otherCharges": {
"label": "商品以外の必要料金",
"value": "配送料1本500円。2本800円。3本以上のご購入で送料一律1,000円となります。"
},
"paymentMethod": {
"label": "支払方法",
"value": "クレジットカード決済"
@ -521,6 +534,29 @@
"one": "お客さま都合による返品・交換は対応いたしかねますので予めご了承ください。商品の欠陥による返品・交換は、商品到着後7日以内にご購入者のお名前・住所を送り状に明記の上、下記住所まで着払いにてご返送ください。",
"two": "〒399-6303 長野県塩尻市奈良井551-1"
},
"legal": {
"title": "酒類販売管理者標識",
"001": {
"label": "販売場の名称及び所在地",
"value": "杉の森酒造株式会社"
},
"002": {
"label": "酒類販売管理者の氏名",
"value": "西川正貴"
},
"003": {
"label": "酒類販売管理研修受講年月日",
"value": "令和2年9月11日"
},
"004": {
"label": "次回研修の受講期限",
"value": "令和5年8月31日"
},
"005": {
"label": "研修実施団体名",
"value": "一般社団法人 日本ボランタリーチェーン協会"
}
},
"return": "Return Home"
}
}

View File

@ -23,7 +23,7 @@
},
"newsletter": {
"title": "newsletter",
"description": "ニュースレターにご登録いただくと、初回送料無料クーポン、購読者限定の情報やペアリングディナーなどのご案内をお送りさせていただきます。",
"description": "ニュースレターにご登録いただくと、購読者限定の情報やペアリングディナーなどのご案内をお送りさせていただきます。",
"placeholder": "メールアドレス",
"button": "登録する"
},
@ -32,7 +32,7 @@
"about-narai": {
"title": "山の水、",
"subtitle": "空に一番近い酒",
"body": "標高約940mの日本でも有数の空に近い自然豊かな環境で醸造しています。多くの酒蔵が水の性質が安定している井戸水を使用しますが、naraiは標高1,000m以上から流れる天然の山水を使用。信濃川と木曽川の分水嶺付近の湧き水であるこの山水は、日本でも有数な「硬度25以下」の透明感と丸みのある滑らかな舌触りが特徴です。"
"body": "標高約940mの日本でも有数の空に近い自然に恵まれた環境で醸造しています。多くの酒蔵が水の性質が安定している井戸水を使用しますが、naraiは標高1,000m以上から流れる天然の山水を使用。信濃川と木曽川の分水嶺付近の湧き水であるこの山水は、日本でも有数な「硬度25以下」の透明感と丸みのある滑らかな舌触りが特徴です。"
},
"location": {
"title": "長野",
@ -46,13 +46,13 @@
"line002": "角打ち&作業場",
"line003": "sagyobar"
},
"body": "ここは、ボトルの箱詰めや出荷などの酒蔵作業 (sagyo) と、日本酒移動販売車「suginomori wagon」から提供されるSAKEを楽しむこともできる場(bar)が融合した、弊蔵の直営店です。酒蔵から徒歩1分。線路を挟み向かいの倉庫をリノベーションしました。",
"body": "ここは、ボトルの箱詰めや出荷などの酒蔵作業 (sagyo) と、日本酒移動販売車「suginomori wagon」から提供されるsakeを楽しむこともできる場(bar)が融合した、弊蔵の直営店です。酒蔵から徒歩1分。線路を挟み向かいの倉庫をリノベーションしました。",
"button": "sagyobarについて"
},
"concept": {
"title": "醸造のその先へ",
"subtitle": "",
"body": "私たちには、日本酒文化を未来に継承したいという信念があります。そのためには、これまでの常識をもう一度見つめ直すことや、新しい試みにも挑戦する。醸造のその先へ、自由な発想でSAKEを探究し、その魅力を伝えていきます。",
"body": "私たちには、日本酒文化を未来に継承したいという信念があります。そのためには、これまでの常識をもう一度見つめ直すことや、新しい試みにも挑戦する。醸造のその先へ、自由な発想でsakeを探究し、その魅力を伝えていきます。",
"button": "concept"
}
}
@ -70,12 +70,23 @@
},
"footer": {
"newsletter": {
"promo": "初回注文で10割引。割引を受ける。"
"promo": "購読者限定の情報やペアリングディナーなどのご案内をお送りさせていただきます。"
},
"menu": {
"products": "商品",
"shops": "取り扱い店",
"about": "naraiについて",
"bar": "sagyobar",
"concept": "コンセプト",
"stories": "ストーリー",
"company": "会社概要"
}
},
"cart": {
"add": "カートに入れる",
"add": "add to cart",
"out-of-stock": "品切れ中",
"options": "オプション",
"quantity-label": "購入数",
"title": "ショッピングカード",
"subtitle": "ご注文内容の確認",
"empty": "買い物袋が空っぽ",
@ -115,12 +126,12 @@
},
"002": {
"title": "長野 奈良井宿で醸す",
"para001": "私たちは、標高約940mの日本でも有数の空に近い自然豊かな環境で醸造しています。冬は氷点下20度近くまで冷え込み、山の水は凍ります。寒い冬を越えると、新緑に囲まれ、空気が清らかで過ごしやすい季節が続きます。秋には紅葉で山が鮮やかに染まります。日本らしい四季の移ろいを感じられる自然豊かな立地です。",
"para002": "この自然豊かな魅力を贅沢に味で表現したい… 通常の酒蔵では大きなチームが分業制で大量生産ができるよう、大型タンク3,000L〜8,000Lなどを使用しますが、私たちの蔵では杜氏1人でも丁寧な手作業で、効率的に全工程に関わり、小ロット生産ながらも高品質なSAKE造りができるよう900Lと1,800Lの小型タンクを採用しています。さらに、その時々に感じる季節の移ろいや、自然の美しさを味に反映させるために、年中生産可能な四季醸造方式を取り入れました。"
"para001": "私たちは、標高約940mの日本でも有数の空に近い自然豊かな環境で醸造しています。冬は氷点下20度近くまで冷え込み、山の水は凍ります。寒い冬を越えると、新緑に囲まれ、空気が清らかで過ごしやすい季節が続きます。秋には紅葉で山が鮮やかに染まります。日本らしい四季の移ろいを感じられる立地です。",
"para002": "この自然豊かな魅力を贅沢に味で表現したい… 通常の酒蔵では大きなチームが分業制で大量生産ができるよう、大型タンク3,000L〜8,000Lなどを使用しますが、私たちの蔵では杜氏1人でも丁寧な手作業で、効率的に全工程に関わり、小ロット生産ながらも高品質なsake造りができるよう900Lと1,800Lの小型タンクを採用しています。また、多くの酒蔵が冬季のみ醸造をする中、その時々に感じる季節の移ろいや、自然の美しさを味に反映させるために、年中生産可能な四季醸造方式を取り入れました。"
},
"003": {
"title": "多彩な黒 醸造の理念",
"para001": "多彩」と「黒」は、一見相反するように聞こえますが、僕の目指す「多彩な黒」は色ではなく、さまざまな絵の具で丁寧に色を重ね合わせて生まれる色をイメージしています。仕込みごとに山水や米の状態に合わせ、旨味やふくよかさ、辛味や甘味、香り等の要素を経験に基づく手作業で調和させることで、「全体ではまとまりを感じるが、口の中に広がった時に多彩な色を感じる」、そんな1 本を目指して醸造を探究しています。信州の自然を贅沢に表現した「山の水、空に一番近い酒」を是非お楽しみください。",
"para001": "多彩」と「黒」は、一見相反するように聞こえますが、僕の目指す「多彩な黒」は色ではなく、さまざまな絵の具で丁寧に色を重ね合わせて生まれる色をイメージしています。仕込みごとに山水や米の状態に合わせ、旨味やふくよかさ、辛味や甘味、香り等の要素を経験に基づく手作業で調和させることで、「全体ではまとまりを感じるが、口の中に広がった時に多彩な色を感じる」、そんな1 本を目指して醸造を探究しています。信州の自然を贅沢に表現した「山の水、空に一番近い酒」を是非お楽しみください。",
"master001": "Master Brewer",
"master002": "Masayuki Irie"
},
@ -159,7 +170,7 @@
"para001": "ここは、ボトルの箱詰めや出荷などの酒蔵作業 (sagyo) と、日本酒移動販売車「suginomori wagon」から提供されるsakeを楽しむこともできる場(bar)が融合した、弊蔵の直営店です。",
"para002": "リベーションした倉庫は、元々は先代の頃の杉の森酒蔵の機材や業務備品の保管用の場所として利用されていました。倉庫の建築はそのままに、入り口部分のゲートを刷新し、照明や空調等の設備を新設。什器は酒蔵の作業でも使用する酒瓶を運ぶための外装容器「P箱」を活用しています。このP箱を自在にレイアウトすることで、角打ちのようなスペースとしても活用できます。"
},
"002": "奈良井宿へ観光で来られたお客が、隣接する酒蔵で醸造したてのnaraiをお楽しみいただけるだけではなく、音楽イベントや、ワークショップなども企画中。さまざまな利用シーンを演出することで、奈良井宿の新たな観光スポットのつになることを目指していきます。",
"002": "奈良井宿へ観光で来られたお客さまが、隣接する酒蔵で醸造したてのnaraiをお楽しみいただけるだけではなく、音楽イベントや、ワークショップなども企画中。さまざまな利用シーンを演出することで、奈良井宿の新たな観光スポットのつになることを目指していきます。",
"003": {
"title": "suginomori wagon",
"body": "sagyobarでは、日本酒サーバーが搭載された移動販売車「suginomori wagon」を収容しており、naraiの飲み比べセットや、地域限定メニュー、オリジナルグッズなどの販売をしています。sagyobarでの活用はもちろんのこと、移動可能な販売空間として、長野県内や、全国のさまざまなイベントに出店しnaraiをお届けします。"
@ -186,7 +197,7 @@
},
"clerk": {
"title": "番頭:西川正貴",
"body": "製造管理、販売管理、酒税管理、総務、営業事務に携わる。「何かあれば西川に」が合言葉の頼れる存在。2006年に京都府の松本酒造に入社し、長年番頭を務めたのち、2021年より杉の森酒造に着任。製造者が最も集中できる環境づくりを心掛け、日々業務に取り組んでいる。"
"body": "広島出身。製造管理、販売管理、酒税管理、総務、営業事務に携わる。「何かあれば西川に」が合言葉の頼れる存在。2006年に京都府の松本酒造に入社し、長年番頭を務めたのち、2021年より杉の森酒造に着任。製造者が最も集中できる環境づくりを心掛け、日々業務に取り組んでいる。"
}
},
"concept": {
@ -196,11 +207,10 @@
"para003": "醸造のその先へ、自由な発想でsakeを探究し、その魅力を伝えていきます。",
"subtitle001": "suginomori brewery (当蔵) について",
"para004": "⻑野県に位置する日本最長の宿場町「奈良井宿」の歴史的な街並みの中で、1793年に創業し、2012年頃より休眠状態だった老舗酒蔵「杉の森酒造」を、2021年に製造面積を約1/3のサイズに最適化し、設備を一新する形で「suginomori brewery」として再生しました。",
"subtitle002": "私たちが想うこと—",
"para005": "再生にあたって、近年では日本酒の国内需要低下に伴い、地域の暮らしに密接だった酒蔵が年々減少し、それに伴い耕作放棄地が増えている課題や、一般的な酒蔵では冬季のみ酒造りを行うため働き手の仕事が安定しないことがわかり、私たちの酒蔵ではこれらの課題を真摯に受け止めたいと考えました。",
"para006": "農家さんの言葉に耳を傾け、田んぼに足を運。",
"para006": "農家さんの言葉に耳を傾け、田んぼに足を運び、米作りの段階から一緒に携わっていく。",
"para007": "年中仕込みが可能な四季醸造方式を新たに導入することで安定した製造環境を実現する。",
"para008": "・・・小さなことの積み重ねですが、これらの取り組みが未来に繋がると信じています。",
"para008": "・・・このような小さなことの積み重ねですが、これらの取り組みが未来に繋がると信じています。",
"para009": "またこれらに関連し、私たちが挑戦したことの1つが、「開かれた酒蔵」としての在り方です。弊蔵は、同敷地内の古民家や、旧酒蔵の一部を改修した宿泊施設(BYAKU Narai)のレストランに隣接しています。大きなガラスの仕切り1枚で仕切られており、普段はなかなか見ることの出来ない酒造りを間近で感じられることは、日本酒に興味を持って頂くきっかけになると信じています。",
"para010": "最後に、ブランド名の【narai】は、「私たちのsakeをきっかけに、奈良井宿という魅力的な宿場町を世界の人に知ってもらい、足を運んで頂きたい」という想いを込めて名付けました。奈良井に来られる際には、suginomori breweryに立ち寄って頂けたら嬉しいです。"
},
@ -243,6 +253,11 @@
"english": "Kou Sundberg",
"role": "蔵元"
},
"masa": {
"japanese": "小松正則",
"english": "Masanori Komatsu",
"role": "COO"
},
"yamano": {
"japanese": "山野恭稔",
"english": "Takatoshi Yamano",
@ -469,7 +484,7 @@
"ariaLabel": "Contact our support email"
}
},
"disclosurePage": {
"disclosure-page": {
"title": "Disclosures",
"distributor": {
"label": "販売業者",
@ -500,10 +515,6 @@
"label": "商品の販売価格",
"value": "各商品ページをご参照ください。"
},
"otherCharges": {
"label": "商品以外の必要料金",
"value": "配送料1本500円。2本800円。3本以上のご購入で送料一律1,000円となります。"
},
"paymentMethod": {
"label": "支払方法",
"value": "クレジットカード決済"
@ -521,6 +532,29 @@
"one": "お客さま都合による返品・交換は対応いたしかねますので予めご了承ください。商品の欠陥による返品・交換は、商品到着後7日以内にご購入者のお名前・住所を送り状に明記の上、下記住所まで着払いにてご返送ください。",
"two": "〒399-6303 長野県塩尻市奈良井551-1"
},
"legal": {
"title": "酒類販売管理者標識",
"001": {
"label": "販売場の名称及び所在地",
"value": "杉の森酒造株式会社"
},
"002": {
"label": "酒類販売管理者の氏名",
"value": "西川正貴"
},
"003": {
"label": "酒類販売管理研修受講年月日",
"value": "令和2年9月11日"
},
"004": {
"label": "次回研修の受講期限",
"value": "令和5年8月31日"
},
"005": {
"label": "研修実施団体名",
"value": "一般社団法人 日本ボランタリーチェーン協会"
}
},
"return": "Return Home"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB