This commit is contained in:
Joel Varty 2021-06-17 17:37:32 -04:00
parent d48aec2c2d
commit d9fe7d8e6b
23 changed files with 263 additions and 11789 deletions

View File

@ -5,7 +5,7 @@ import { Grid, Marquee, Hero } from '@components/ui'
import { ModuleWithInit } from '@agility/nextjs'
interface ICustomData {
bestSelling: any
products: any
}
interface IModule {
@ -14,21 +14,14 @@ interface IModule {
const BestsellingProducts: ModuleWithInit<IModule, ICustomData> = ({ customData }) => {
const bestSelling = customData.bestSelling
const products = customData.products
return (
<Marquee variant="secondary">
{bestSelling.slice(0, 12).map(({ node }: any) => (
<ProductCard
key={node.path}
product={node}
variant="slim"
imgWidth={320}
imgHeight={320}
imgLayout="fixed"
/>
))}
</Marquee>
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard key={product.id} product={product} variant="slim" />
))}
</Marquee>
)
}

View File

@ -1,13 +1,12 @@
import React, { FC } from 'react'
import { ProductCard } from '@components/product'
import { Grid, Marquee, Hero } from '@components/ui'
import useCart from '@framework/cart/use-cart'
import usePrice from '@framework/use-price'
import { Button } from '@components/ui'
import { Bag, Cross, Check } from '@components/icons'
import usePrice from '@framework/product/use-price'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { Button, Text } from '@components/ui'
import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons'
import { CartItem } from '@components/cart'
import { Text } from '@components/ui'
interface Fields {
}
@ -18,39 +17,37 @@ interface Props {
}
const Cart: FC<Props> = ({ fields, customData }) => {
const { data, isEmpty } = useCart()
const error = null
const success = null
const { data, isLoading, isEmpty } = useCart()
const { price: subTotal } = usePrice(
data && {
amount: data.base_amount,
amount: Number(data.subtotalPrice),
currencyCode: data.currency.code,
}
)
const { price: total } = usePrice(
data && {
amount: data.cart_amount,
amount: Number(data.totalPrice),
currencyCode: data.currency.code,
}
)
const items = data?.line_items.physical_items ?? []
const error = null
const success = null
return (
<div className="grid lg:grid-cols-12">
<div className="grid lg:grid-cols-12 w-full max-w-7xl mx-auto">
<div className="lg:col-span-8">
{isEmpty ? (
{isLoading || isEmpty ? (
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center ">
<span className="border border-dashed border-secondary flex items-center justify-center w-16 h-16 bg-primary p-12 rounded-lg text-primary">
<Bag className="absolute" />
</span>
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
Your cart is empty
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
</h2>
<p className="text-accent-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
</p>
</div>
) : error ? (
<div className="flex-1 px-4 flex flex-col justify-center items-center">
@ -60,7 +57,7 @@ const Cart: FC<Props> = ({ fields, customData }) => {
<h2 className="pt-6 text-xl font-light text-center">
We couldnt process the purchase. Please check your card
information and try again.
</h2>
</h2>
</div>
) : success ? (
<div className="flex-1 px-4 flex flex-col justify-center items-center">
@ -69,14 +66,14 @@ const Cart: FC<Props> = ({ fields, customData }) => {
</span>
<h2 className="pt-6 text-xl font-light text-center">
Thank you for your order.
</h2>
</h2>
</div>
) : (
<div className="px-4 sm:px-6 flex-1">
<Text variant="pageHeading">My Cart</Text>
<Text variant="sectionHeading">Review your Order</Text>
<ul className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accents-2 border-b border-accents-2">
{items.map((item) => (
<ul className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-b border-accent-2">
{data!.lineItems.map((item: any) => (
<CartItem
key={item.id}
item={item}
@ -91,7 +88,10 @@ const Cart: FC<Props> = ({ fields, customData }) => {
</Text>
<div className="flex py-6 space-x-6">
{[1, 2, 3, 4, 5, 6].map((x) => (
<div className="border border-accents-3 w-full h-24 bg-accents-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75" />
<div
key={x}
className="border border-accent-3 w-full h-24 bg-accent-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75"
/>
))}
</div>
</div>
@ -100,7 +100,36 @@ const Cart: FC<Props> = ({ fields, customData }) => {
</div>
<div className="lg:col-span-4">
<div className="flex-shrink-0 px-4 py-24 sm:px-6">
<div className="border-t border-accents-2">
{process.env.COMMERCE_CUSTOMCHECKOUT_ENABLED && (
<>
{/* Shipping Address */}
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
<div className="rounded-md border border-accent-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accent-4">
<div className="mr-5">
<MapPin />
</div>
<div className="text-sm text-center font-medium">
<span className="uppercase">+ Add Shipping Address</span>
{/* <span>
1046 Kearny Street.<br/>
San Franssisco, California
</span> */}
</div>
</div>
{/* Payment Method */}
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
<div className="rounded-md border border-accent-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accent-4">
<div className="mr-5">
<CreditCard />
</div>
<div className="text-sm text-center font-medium">
<span className="uppercase">+ Add Payment Method</span>
{/* <span>VISA #### #### #### 2345</span> */}
</div>
</div>
</>
)}
<div className="border-t border-accent-2">
<ul className="py-3">
<li className="flex justify-between py-1">
<span>Subtotal</span>
@ -115,7 +144,7 @@ const Cart: FC<Props> = ({ fields, customData }) => {
<span className="font-bold tracking-wide">FREE</span>
</li>
</ul>
<div className="flex justify-between border-t border-accents-2 py-3 font-bold mb-10">
<div className="flex justify-between border-t border-accent-2 py-3 font-bold mb-10">
<span>Total</span>
<span>{total}</span>
</div>
@ -127,10 +156,10 @@ const Cart: FC<Props> = ({ fields, customData }) => {
Continue Shopping
</Button>
) : (
<Button href="/checkout" Component="a" width="100%">
Proceed to Checkout
</Button>
)}
<Button href="/checkout" Component="a" width="100%">
Proceed to Checkout
</Button>
)}
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@ import { ProductCard } from '@components/product'
import { ModuleWithInit } from "@agility/nextjs"
interface ICustomData {
featured: any
products: any
}
interface IModule {
@ -17,16 +17,18 @@ const FeaturedProducts: ModuleWithInit<IModule, ICustomData> = ({ customData })
return <div>No featured products returned.</div>
}
const featured:any = customData.featured
const products:any = customData.products
return (
<Grid layout="B">
{featured.map(({ node }:any, i:number) => (
<Grid variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard
key={node.path}
product={node}
imgWidth={i === 1 ? 1080 : 540}
imgHeight={i === 1 ? 1080 : 540}
key={product.id}
product={product}
imgProps={{
width: i === 0 ? 1080 : 540,
height: i === 0 ? 1080 : 540,
}}
/>
))}
</Grid>

View File

@ -1,13 +1,13 @@
import React, { FC } from 'react'
import { Hero } from '@components/ui'
import * as AgilityTypes from "@agility/types"
import { URLField } from "@agility/nextjs"
import { Module } from '@agility/nextjs'
interface Fields {
title:string,
description:string
cTA?:AgilityTypes.URLField
cTA?:URLField
}
const HeroModule:Module<Fields> = ({ module: {fields }}) => {

View File

@ -1,13 +1,14 @@
import React, { FC } from 'react'
import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
import { ModuleWithInit } from '@agility/nextjs'
import { ProductCard } from '@components/product'
import { Grid, Marquee, Hero } from '@components/ui'
interface ICustomData {
categories: any
newestProducts: any
brands: any
products: any
}
interface IModule {
@ -16,19 +17,25 @@ interface IModule {
const HomeAllProductsGridModule: ModuleWithInit<IModule, ICustomData> = ({ customData }) => {
const categories = customData.categories
const newestProducts = customData.newestProducts
const brands = customData.brands
if (!categories) return <div>No data</div>
const products = customData.products
return (
<HomeAllProductsGrid
categories={categories}
brands={brands}
newestProducts={newestProducts}
/>
<Grid layout="B" variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard
key={product.id}
product={product}
imgProps={{
width: i === 0 ? 1080 : 540,
height: i === 0 ? 1080 : 540,
}}
/>
))}
</Grid>
)
}
export default HomeAllProductsGridModule

View File

@ -8,7 +8,7 @@ import { Module } from '@agility/nextjs'
interface Fields {
}
const Orders: Module<Fields> = ({ }) => {
const Orders: Module<Fields> = ({ }) => {
return (
<Container>
<Text variant="pageHeading">My Orders</Text>
@ -19,8 +19,8 @@ const Orders: Module<Fields> = ({ }) => {
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
No orders found
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
Orders coming soon!
<p className="text-accent-6 px-10 text-center pt-2">
Orders coming soon.
</p>
</div>
</Container>

View File

@ -1,20 +1,25 @@
import React, { FC } from 'react'
import { Hero } from '@components/ui'
import * as AgilityTypes from "@agility/types"
import { GetProductResult } from '@framework/api/operations/get-product'
import { ProductView } from '@components/product'
import { Module } from '@agility/nextjs'
interface Fields {
import { ProductView } from '@components/product'
import { Module, ModuleWithInit } from '@agility/nextjs'
interface IFields {
}
interface ICustomData {
products: any
}
const HeroModule:Module<Fields> = ({ dynamicPageItem }) => {
const ProductDetails:ModuleWithInit<IFields, ICustomData> = ({ dynamicPageItem, customData }) => {
const product:any = dynamicPageItem
const relatedProducts:[] = customData.products
return (
<ProductView product={product} />
<ProductView product={product} relatedProducts={relatedProducts} />
)
}
export default HeroModule
export default ProductDetails

View File

@ -1,31 +1,7 @@
import React, { FC } from 'react'
import cn from 'classnames'
import Link from 'next/link'
import { useState } from 'react'
import { useRouter } from 'next/router'
import useSearch from '@framework/products/use-search'
import { ProductCard } from '@components/product'
import { Container, Grid, Skeleton } from '@components/ui'
import rangeMap from '@lib/range-map'
import getSlug from '@lib/get-slug'
import {
filterQuery,
getCategoryPath,
getDesignerPath,
useSearchMeta,
} from '@lib/search'
import Search from '@components/search'
import { ModuleWithInit } from '@agility/nextjs'
const SORT = Object.entries({
'latest-desc': 'Latest arrivals',
'trending-desc': 'Trending',
'price-asc': 'Price: Low to high',
'price-desc': 'Price: High to low',
})
interface ICustomData {
categories: any
brands: any
@ -40,416 +16,8 @@ const ProductSearch: ModuleWithInit<IModule, ICustomData> = ({ customData }) =>
const categories:[any] = customData.categories
const brands:[any] = customData.brands
const [activeFilter, setActiveFilter] = useState('')
const [toggleFilter, setToggleFilter] = useState(false)
return <Search brands={brands} categories={categories} pages={[]} />
const router = useRouter()
const { asPath } = router
const { q, sort } = router.query
// `q` can be included but because categories and designers can't be searched
// in the same way of products, it's better to ignore the search input if one
// of those is selected
const query = filterQuery({ sort })
const { pathname, category, brand } = useSearchMeta(asPath)
const activeCategory = categories.find(
(cat) => getSlug(cat.path) === category
)
const activeBrand = brands.find(
(b) => getSlug(b.node.path) === `brands/${brand}`
)?.node
const { data } = useSearch({
search: typeof q === 'string' ? q : '',
categoryId: activeCategory?.entityId,
brandId: activeBrand?.entityId,
sort: typeof sort === 'string' ? sort : '',
})
const handleClick = (event: any, filter: string) => {
if (filter !== activeFilter) {
setToggleFilter(true)
} else {
setToggleFilter(!toggleFilter)
}
setActiveFilter(filter)
}
return (
<Container>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-4 mt-3 mb-20">
<div className="col-span-8 lg:col-span-2 order-1 lg:order-none">
{/* Categories */}
<div className="relative inline-block w-full">
<div className="lg:hidden">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'categories')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{activeCategory?.name
? `Category: ${activeCategory?.name}`
: 'All Categories'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'categories' || toggleFilter !== true
? 'hidden'
: ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !activeCategory?.name,
}
)}
>
<Link
href={{ pathname: getCategoryPath('', brand), query }}
>
<a
onClick={(e) => handleClick(e, 'categories')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
All Categories
</a>
</Link>
</li>
{categories.map((cat) => (
<li
key={cat.path}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline:
activeCategory?.entityId === cat.entityId,
}
)}
>
<Link
href={{
pathname: getCategoryPath(cat.path, brand),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'categories')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{cat.name}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
{/* Designs */}
<div className="relative inline-block w-full">
<div className="lg:hidden mt-3">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'brands')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-900 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{activeBrand?.name
? `Design: ${activeBrand?.name}`
: 'All Designs'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'brands' || toggleFilter !== true
? 'hidden'
: ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !activeBrand?.name,
}
)}
>
<Link
href={{
pathname: getDesignerPath('', category),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'brands')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
All Designers
</a>
</Link>
</li>
{brands.flatMap(({ node }) => (
<li
key={node.path}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: activeBrand?.entityId === node.entityId,
}
)}
>
<Link
href={{
pathname: getDesignerPath(node.path, category),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'brands')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{node.name}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
{/* Products */}
<div className="col-span-8 order-3 lg:order-none">
{(q || activeCategory || activeBrand) && (
<div className="mb-12 transition ease-in duration-75">
{data ? (
<>
<span
className={cn('animated', {
fadeIn: data.found,
hidden: !data.found,
})}
>
Showing {data.products.length} results{' '}
{q && (
<>
for "<strong>{q}</strong>"
</>
)}
</span>
<span
className={cn('animated', {
fadeIn: !data.found,
hidden: data.found,
})}
>
{q ? (
<>
There are no products that match "<strong>{q}</strong>"
</>
) : (
<>
There are no products that match the selected category &
designer
</>
)}
</span>
</>
) : q ? (
<>
Searching for: "<strong>{q}</strong>"
</>
) : (
<>Searching...</>
)}
</div>
)}
{data ? (
<Grid layout="normal">
{data.products.map(({ node }) => (
<ProductCard
variant="simple"
key={node.path}
className="animated fadeIn"
product={node}
imgWidth={480}
imgHeight={480}
/>
))}
</Grid>
) : (
<Grid layout="normal">
{rangeMap(12, (i) => (
<Skeleton
key={i}
className="w-full animated fadeIn"
height={325}
/>
))}
</Grid>
)}
</div>
{/* Sort */}
<div className="col-span-8 lg:col-span-2 order-2 lg:order-none">
<div className="relative inline-block w-full">
<div className="lg:hidden">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'sort')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{sort ? `Sort: ${sort}` : 'Relevance'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'sort' || toggleFilter !== true ? 'hidden' : ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !sort,
}
)}
>
<Link href={{ pathname, query: filterQuery({ q }) }}>
<a
onClick={(e) => handleClick(e, 'sort')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
Relevance
</a>
</Link>
</li>
{SORT.map(([key, text]) => (
<li
key={key}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: sort === key,
}
)}
>
<Link
href={{
pathname,
query: filterQuery({ q, sort: key }),
}}
>
<a
onClick={(e) => handleClick(e, 'sort')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{text}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</Container>
)
}

View File

@ -1,6 +1,6 @@
import React, { FC } from 'react'
import useCustomer from '@framework/use-customer'
import useCustomer from '@framework/customer/use-customer'
import { Container, Text } from '@components/ui'
import { Module } from '@agility/nextjs'
@ -12,34 +12,30 @@ interface Fields {
}
const ProfileModule:Module<Fields> = ({ module: {fields}}) => {
const ProfileModule: Module<Fields> = ({ module: { fields } }) => {
const { data } = useCustomer()
return (
<Container>
<Text variant="pageHeading">{fields.heading}</Text>
{data && (
<div className="grid lg:grid-cols-12">
<div className="lg:col-span-8 pr-4">
<div>
<Text variant="sectionHeading">{fields.fullNameLabel}</Text>
<span>
{data.firstName} {data.lastName}
</span>
</div>
<div className="mt-5">
<Text variant="sectionHeading">{fields.emailLabel}</Text>
<span>{data.email}</span>
</div>
</div>
</div>
)}
{ !data &&
<Text variant="body">{fields.notLoggedInMessage}</Text>
}
</Container>
)
return (
<Container>
<Text variant="pageHeading">My Profile</Text>
{data && (
<div className="grid lg:grid-cols-12">
<div className="lg:col-span-8 pr-4">
<div>
<Text variant="sectionHeading">Full Name</Text>
<span>
{data.firstName} {data.lastName}
</span>
</div>
<div className="mt-5">
<Text variant="sectionHeading">Email</Text>
<span>{data.email}</span>
</div>
</div>
</div>
)}
</Container>
)
}
export default ProfileModule

View File

@ -21,7 +21,7 @@ const LOCALES_MAP: Record<string, LOCALE_DATA> = {
alt: 'Bandera Colombiana',
},
},
'en-US': {
'en-us': {
name: 'English',
img: {
filename: 'flag-en-us.svg',

View File

@ -6,32 +6,23 @@ import Link from 'next/link'
interface HeroProps {
className?: string
headline: string
description: string,
linkText?: string,
linkUrl?: string
description: string
}
const Hero: FC<Props> = ({ headline, description, linkText, linkUrl }) => {
const Hero: FC<HeroProps> = ({ headline, description }) => {
return (
<div className="bg-accent-9 border-b border-t border-accent-2">
<Container>
<div className={s.root}>
<h2 className="text-4xl leading-10 font-extrabold text-white sm:text-5xl sm:leading-none sm:tracking-tight lg:text-6xl">
{headline}
</h2>
<div className="flex flex-col justify-between">
<p className="mt-5 text-xl leading-7 text-accent-2 text-white">
{description}
</p>
{ linkText && linkUrl &&
<Link href={linkUrl}>
<a className="text-white pt-3 font-bold hover:underline flex flex-row cursor-pointer w-max-content">
{linkText}
<RightArrow width="20" heigh="20" className="ml-1" />
<h2 className={s.title}>{headline}</h2>
<div className={s.description}>
<p>{description}</p>
<Link href="/">
<a className="flex items-center text-accent-0 pt-3 font-bold hover:underline cursor-pointer w-max-content">
Read it here
<ArrowRight width="20" heigh="20" className="ml-1" />
</a>
</Link>
}
</div>
</div>
</Container>

View File

@ -1,55 +1,27 @@
import { getConfig } from '@framework/api'
import getAllProducts from '@framework/api/operations/get-all-products'
import commerce from '@lib/api/commerce'
import rangeMap from '@lib/range-map'
const nonNullable = (v: any) => v
const getCustomInitialProps = async function ({ }):Promise<{bestSelling:any}> {
const getCustomInitialProps = async function ({ item, agility, languageCode, channelName, pageInSitemap, dynamicPageItem }: any) {
//TODO: pass the locale and preview mode as props...
const locale = "en-US"
const preview = false
const config = getConfig({ locale })
// Get Best Selling Products
const { products: bestSellingProducts } = await getAllProducts({
variables: { field: 'bestSellingProducts', first: 6 },
const config = { locale, locales: [locale] }
const productsPromise = commerce.getAllProducts({
variables: { first: 6 },
config,
preview,
})
// Saleor provider only
...({ featured: true } as any),
})
// Get Best Newest Products
const { products: newestProducts } = await getAllProducts({
variables: { field: 'newestProducts', first: 12 },
config,
preview,
})
// These are the products that are going to be displayed in the landing.
// We prefer to do the computation at buildtime/servertime
const { bestSelling } = (() => {
// Create a copy of products that we can mutate
const products = [...newestProducts]
// If the lists of featured and best selling products don't have enough
// products, then fill them with products from the products list, this
// is useful for new commerce sites that don't have a lot of products
return {
bestSelling: rangeMap(
6,
(i) => bestSellingProducts[i] ?? products.shift()
).filter(nonNullable),
}
})()
const { products } = await productsPromise
return {
bestSelling
products
}
}
export default {getCustomInitialProps}
export default { getCustomInitialProps }

View File

@ -0,0 +1,17 @@
import commerce from '@lib/api/commerce'
const getCustomInitialProps = async function ({ }):Promise<{pages:any, categories: any}> {
const languageCode = "en-us"
const preview = false
const config = { locale: languageCode, locales: [languageCode] }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
pages, categories
}
}
export default {getCustomInitialProps}

View File

@ -1,11 +1,4 @@
import { getConfig } from '@framework/api'
import getAllProducts from '@framework/api/operations/get-all-products'
import rangeMap from '@lib/range-map'
const nonNullable = (v: any) => v
import commerce from '@lib/api/commerce'
const getCustomInitialProps = async function ({ item, agility, languageCode, channelName, pageInSitemap, dynamicPageItem }: any) {
//TODO: pass the locale and preview mode as props...
@ -14,21 +7,21 @@ const getCustomInitialProps = async function ({ item, agility, languageCode, cha
const locale = "en-US"
const preview = false
const config = getConfig({ locale })
// Get Featured Products
const { products: featuredProducts } = await getAllProducts({
variables: { field: 'featuredProducts', first: 6 },
const config = { locale, locales: [locale] }
const productsPromise = commerce.getAllProducts({
variables: { first: 6 },
config,
preview,
// Saleor provider only
...({ featured: true } as any),
})
const { products } = await productsPromise
return {
featured: featuredProducts
products
}
}
export default { getCustomInitialProps }

View File

@ -1,38 +1,27 @@
import { getConfig } from '@framework/api'
import getSiteInfo from '@framework/api/operations/get-site-info'
import getAllProducts from '@framework/api/operations/get-all-products'
import rangeMap from '@lib/range-map'
const nonNullable = (v: any) => v
import commerce from '@lib/api/commerce'
const getCustomInitialProps = async function ({ item, agility, languageCode, channelName, pageInSitemap, dynamicPageItem }: any) {
//TODO: pass the locale and preview mode as props...
const locale = "en-US"
const preview = false
const config = getConfig({ locale })
const { categories, brands } = await getSiteInfo({ config, preview })
// Get Best Newest Products
const { products: newestProducts } = await getAllProducts({
variables: { field: 'newestProducts', first: 12 },
const config = { locale, locales: [locale] }
const productsPromise = commerce.getAllProducts({
variables: { first: 6 },
config,
preview,
})
// Saleor provider only
...({ featured: true } as any),
})
const { products } = await productsPromise
return {
newestProducts: newestProducts,
categories,
brands
products
}
}
export default { getCustomInitialProps }

View File

@ -0,0 +1,26 @@
import commerce from '@lib/api/commerce'
const getCustomInitialProps = async function ({ item, agility, languageCode, channelName, pageInSitemap, dynamicPageItem }: any) {
//TODO: pass the locale and preview mode as props...
const locale = "en-us"
const preview = false
const config = { locale, locales: [locale] }
const productsPromise = commerce.getAllProducts({
variables: { first: 4 },
config,
preview,
})
const { products } = await productsPromise
return {
products
}
}
export default { getCustomInitialProps }

View File

@ -1,5 +1,4 @@
import { getConfig } from '@framework/api'
import getSiteInfo from '@framework/api/operations/get-site-info'
import commerce from '@lib/api/commerce'
const getCustomInitialProps = async ({ agility, channelName, languageCode }:any) => {
@ -7,14 +6,16 @@ const getCustomInitialProps = async ({ agility, channelName, languageCode }:any)
const locale = "en-US"
const preview = false
const config = { locale, locales: [locale] }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const config = getConfig({ locale })
const { categories, brands } = await getSiteInfo({ config, preview })
const { categories, brands } = await siteInfoPromise
return {
categories,
brands,
}
return {
categories,
brands
}
}

View File

@ -1,13 +1,17 @@
import BestsellingProductsData from "./BestsellingProductsData"
import CartData from "./CartData"
import FeaturedProductsData from "./FeaturedProductsData"
import HomeAllProductsGridData from "./HomeAllProductsGridData"
import ProductSearchData from "./ProductSearchData"
import ProductDetailsData from "./ProductDetailsData"
const allModules:any =[
{ name: "BestsellingProducts", init: BestsellingProductsData },
{ name: "FeaturedProducts", init: FeaturedProductsData},
{ name: "HomeAllProductsGrid", init: HomeAllProductsGridData},
{ name: "ProductSearch", init: ProductSearchData}
{ name: "ProductSearch", init: ProductSearchData},
{ name: "Cart", init: CartData},
{ name: "ProductDetails", init: ProductDetailsData}
]
/**

View File

@ -17,8 +17,8 @@ module.exports = withCommerceConfig({
},
commerce,
i18n: {
locales: ['en-US', 'es'],
defaultLocale: 'en-US',
locales: ['en-us'],
defaultLocale: 'en-us',
},
rewrites() {
return [

11033
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,20 +5,14 @@ import type {
} from 'next'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { missingLocaleInPages } from '@lib/usage-warns'
import { getAgilityPageProps, getAgilityPaths } from "@agility/nextjs/node"
import { handlePreview } from "@agility/nextjs"
import { defaultPageProps } from '@lib/defaults'
import AgilityPage from "components/agility-global/AgilityPage"
import { getConfig } from '@framework/api'
import getProduct from '@framework/api/operations/get-product'
import getModuleData from "framework/module-data"
import getAllProductPaths from '@framework/api/operations/get-all-product-paths'
import getModuleData from "framework/module-data"
export async function getStaticProps({ preview, params, locale, locales, defaultLocale }: GetStaticPropsContext<{ slug: string[] }>) {
@ -43,11 +37,13 @@ export async function getStaticProps({ preview, params, locale, locales, default
let rebuildFrequency = 10
let productDetail:any = null
let productDetail: any = null
if (productCode) {
const config = getConfig({ locale })
const { product } = await getProduct({
const config = { locale, locales }
const { product } = await commerce.getProduct({
variables: { slug: productCode },
config,
preview,
@ -69,7 +65,7 @@ export async function getStaticProps({ preview, params, locale, locales, default
}
return {
props: { ...defaultPageProps, agilityProps },
props: { agilityProps },
revalidate: rebuildFrequency
}
} catch (err) {
@ -81,7 +77,6 @@ export async function getStaticProps({ preview, params, locale, locales, default
return {
props: {
error: `Params: ${params}, Error: ${err}, Stack: ${st}`,
header: null,
agilityProps: null
},
revalidate: 60000
@ -98,14 +93,26 @@ export async function getStaticPaths({ defaultLocale, locales }: GetStaticPathsC
agilityPaths = agilityPaths.filter(p => p !== "/product/product-details")
//get the product paths from the commerce api
const { products } = await getAllProductPaths()
const productPaths = products.map(p => `/product${p.node.path}`)
const { products } = await commerce.getAllProductPaths()
let productPaths = []
if (locales) {
productPaths = locales.reduce<string[]>((arr, locale) => {
// Add a product path for every locale
products.forEach((product: any) => {
arr.push(`/${locale}/product${product.path}`)
})
return arr
}, [])
} else {
productPaths = products.map((product: any) => `/product${product.path}`)
}
const paths = [...agilityPaths, ...productPaths]
return {
paths,
fallback: true,
fallback: 'blocking',
}
}

View File

@ -1,94 +1,2 @@
//this is just a pointer to the catch-all route and logic for all CMS driven pages (i.e. even rootpage is dynamic from the CMS)
export { default, getStaticProps } from './[...slug]';
// import commerce from '@lib/api/commerce'
// import { Layout } from '@components/common'
// import { ProductCard } from '@components/product'
// import { Grid, Marquee, Hero } from '@components/ui'
// // import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
// import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
// export async function getStaticProps({
// preview,
// locale,
// locales,
// }: GetStaticPropsContext) {
// const config = { locale, locales }
// const productsPromise = commerce.getAllProducts({
// variables: { first: 6 },
// config,
// preview,
// // Saleor provider only
// ...({ featured: true } as any),
// })
// const pagesPromise = commerce.getAllPages({ config, preview })
// const siteInfoPromise = commerce.getSiteInfo({ config, preview })
// const { products } = await productsPromise
// const { pages } = await pagesPromise
// const { categories, brands } = await siteInfoPromise
// return {
// props: {
// products,
// categories,
// brands,
// pages,
// },
// revalidate: 60,
// }
// }
// export default function Home({
// products,
// }: InferGetStaticPropsType<typeof getStaticProps>) {
// return (
// <>
// <Grid variant="filled">
// {products.slice(0, 3).map((product: any, i: number) => (
// <ProductCard
// key={product.id}
// product={product}
// imgProps={{
// width: i === 0 ? 1080 : 540,
// height: i === 0 ? 1080 : 540,
// }}
// />
// ))}
// </Grid>
// <Marquee variant="secondary">
// {products.slice(0, 3).map((product: any, i: number) => (
// <ProductCard key={product.id} product={product} variant="slim" />
// ))}
// </Marquee>
// <Hero
// headline=" Dessert dragée halvah croissant."
// description="Cupcake ipsum dolor sit amet lemon drops pastry cotton candy. Sweet carrot cake macaroon bonbon croissant fruitcake jujubes macaroon oat cake. Soufflé bonbon caramels jelly beans. Tiramisu sweet roll cheesecake pie carrot cake. "
// />
// <Grid layout="B" variant="filled">
// {products.slice(0, 3).map((product: any, i: number) => (
// <ProductCard
// key={product.id}
// product={product}
// imgProps={{
// width: i === 0 ? 1080 : 540,
// height: i === 0 ? 1080 : 540,
// }}
// />
// ))}
// </Grid>
// <Marquee>
// {products.slice(3).map((product: any, i: number) => (
// <ProductCard key={product.id} product={product} variant="slim" />
// ))}
// </Marquee>
// {/* <HomeAllProductsGrid
// newestProducts={products}
// categories={categories}
// brands={brands}
// /> */}
// </>
// )
// }
// Home.Layout = Layout
export { default, getStaticProps } from './[...slug]';

View File

@ -22,14 +22,13 @@
"@components/*": ["components/*"],
"@commerce": ["framework/commerce"],
"@commerce/*": ["framework/commerce/*"],
"@framework": ["framework/local"],
"@framework/*": ["framework/local/*"]
"@framework": ["framework/bigcommerce"],
"@framework/*": ["framework/bigcommerce/*"]
}
},
"include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],
"exclude": [
"node_modules",
"./framework/bigcommerce",
"./framework/shopify",
"./framework/swell",
"./framework/vendure",