├── .editorconfig
├── .env.example
├── .eslintrc.js
├── .gitignore
├── .prettierrc.js
├── README.md
├── blocks
├── ArchiveBlock
│ ├── index.module.scss
│ ├── index.tsx
│ └── types.ts
├── CallToAction
│ ├── index.module.scss
│ └── index.tsx
├── Content
│ ├── index.module.scss
│ └── index.tsx
└── MediaBlock
│ ├── index.module.scss
│ └── index.tsx
├── components
├── AddToCartButton
│ ├── index.module.scss
│ └── index.tsx
├── AdminBar
│ ├── index.module.scss
│ └── index.tsx
├── BackgroundColor
│ ├── index.module.scss
│ └── index.tsx
├── Blocks
│ └── index.tsx
├── Button
│ ├── index.module.scss
│ └── index.tsx
├── Card
│ ├── index.module.scss
│ └── index.tsx
├── CartLink
│ ├── index.module.scss
│ └── index.tsx
├── CheckoutForm
│ ├── index.module.scss
│ └── index.tsx
├── CollectionArchive
│ ├── index.module.scss
│ └── index.tsx
├── Footer
│ ├── index.module.scss
│ └── index.tsx
├── Gutter
│ ├── index.module.scss
│ └── index.tsx
├── Header
│ ├── MobileMenuModal.tsx
│ ├── index.module.scss
│ ├── index.tsx
│ └── mobileMenuModal.module.scss
├── Hero
│ ├── HighImpact
│ │ ├── index.module.scss
│ │ └── index.tsx
│ ├── LowImpact
│ │ ├── index.module.scss
│ │ └── index.tsx
│ ├── MediumImpact
│ │ ├── index.module.scss
│ │ └── index.tsx
│ ├── Product
│ │ ├── index.module.scss
│ │ └── index.tsx
│ └── index.tsx
├── Input
│ ├── index.module.scss
│ └── index.tsx
├── Label
│ ├── index.module.scss
│ └── index.tsx
├── LargeBody
│ ├── index.module.scss
│ └── index.tsx
├── Link
│ └── index.tsx
├── Logo
│ └── index.tsx
├── Media
│ ├── Image
│ │ ├── index.module.scss
│ │ └── index.tsx
│ ├── Video
│ │ ├── index.module.scss
│ │ └── index.tsx
│ ├── index.tsx
│ └── types.ts
├── PageRange
│ ├── index.module.scss
│ └── index.tsx
├── PaywallBlocks
│ └── index.tsx
├── Price
│ ├── index.module.scss
│ └── index.tsx
├── RemoveFromCartButton
│ ├── index.module.scss
│ └── index.tsx
├── RichText
│ ├── index.module.scss
│ ├── index.tsx
│ └── serialize.tsx
├── VerticalPadding
│ ├── index.module.scss
│ └── index.tsx
└── icons
│ ├── Chevron
│ └── index.tsx
│ └── Menu
│ └── index.tsx
├── css
├── app.scss
├── colors.scss
├── common.scss
├── queries.scss
└── type.scss
├── cssVariables.js
├── graphql
├── blocks.ts
├── cart.ts
├── categories.ts
├── globals.ts
├── index.ts
├── link.ts
├── media.ts
├── meta.ts
├── pages.ts
└── products.ts
├── next.config.js
├── package.json
├── pages
├── [slug].tsx
├── _app.tsx
├── account
│ ├── index.module.css
│ └── index.tsx
├── cart
│ ├── index.module.scss
│ └── index.tsx
├── checkout
│ ├── index.module.scss
│ └── index.tsx
├── create-account
│ ├── index.module.css
│ └── index.tsx
├── index.tsx
├── login
│ ├── index.module.scss
│ └── index.tsx
├── logout
│ ├── index.module.scss
│ └── index.tsx
├── order-confirmation
│ ├── index.module.scss
│ └── index.tsx
├── orders
│ ├── [id]
│ │ ├── index.module.scss
│ │ └── index.tsx
│ ├── index.module.scss
│ └── index.tsx
├── products
│ └── [slug].tsx
├── recover-password
│ ├── index.module.scss
│ └── index.tsx
├── reset-password
│ ├── index.module.scss
│ └── index.tsx
└── styleguide
│ └── index.tsx
├── payload-types.ts
├── providers
├── Auth
│ └── index.tsx
└── Cart
│ ├── index.tsx
│ └── reducer.ts
├── public
└── favicon.ico
├── tsconfig.json
├── utilities
├── canUseDOM.ts
├── formatDateTime.ts
└── toKebabCase.ts
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 | end_of_line = lf
10 | max_line_length = null
11 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_APP_URL=http://localhost:3000
2 | NEXT_PUBLIC_CMS_URL=http://localhost:8000
3 | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
4 | STRIPE_SECRET_KEY=
5 | NEXT_PUBLIC_IS_LIVE=
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:@next/next/recommended', '@payloadcms'],
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | .env
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 100,
3 | parser: "typescript",
4 | semi: false,
5 | singleQuote: true,
6 | trailingComma: "all",
7 | arrowParens: "avoid",
8 | };
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This repo has moved!
2 |
3 | This repo has been merged into the [Templates Directory](https://github.com/payloadcms/payload/tree/main/templates) of the [Payload Monorepo](https://github.com/payloadcms/payload). Please refer to the new location of the [E-commerce Template](https://github.com/payloadcms/payload/tree/main/templates/ecommerce) for all future updates, issues, and pull requests.
4 |
--------------------------------------------------------------------------------
/blocks/ArchiveBlock/index.module.scss:
--------------------------------------------------------------------------------
1 | @import '../../css/common';
2 |
3 | .archiveBlock {
4 | position: relative;
5 | }
6 |
7 | .introContent {
8 | margin-bottom: calc(var(--base) * 2);
9 |
10 | @include mid-break {
11 | margin-bottom: calc(var(--base) * 2);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/blocks/ArchiveBlock/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Cell, Grid } from '@faceless-ui/css-grid'
3 |
4 | import { CollectionArchive } from '../../components/CollectionArchive'
5 | import { Gutter } from '../../components/Gutter'
6 | import RichText from '../../components/RichText'
7 | import { ArchiveBlockProps } from './types'
8 |
9 | import classes from './index.module.scss'
10 |
11 | export const ArchiveBlock: React.FC<
12 | ArchiveBlockProps & {
13 | id?: string
14 | }
15 | > = props => {
16 | const {
17 | introContent,
18 | id,
19 | relationTo,
20 | populateBy,
21 | limit,
22 | populatedDocs,
23 | populatedDocsTotal,
24 | categories,
25 | } = props
26 |
27 | return (
28 |
29 | {introContent && (
30 |
31 |
32 |
33 |
34 | |
35 |
36 |
37 | )}
38 |
47 |
48 | )
49 | }
50 |
--------------------------------------------------------------------------------
/blocks/ArchiveBlock/types.ts:
--------------------------------------------------------------------------------
1 | import type { Page } from '../../payload-types'
2 |
3 | export type ArchiveBlockProps = Extract
4 |
--------------------------------------------------------------------------------
/blocks/CallToAction/index.module.scss:
--------------------------------------------------------------------------------
1 | @use '../../css/queries.scss' as *;
2 |
3 | $spacer-h: calc(var(--block-padding) / 2);
4 |
5 | .callToAction {
6 | padding-left: $spacer-h;
7 | padding-right: $spacer-h;
8 | }
9 |
10 | .background--white {
11 | background-color: var(--color-base-1000);
12 | color: var(--color-base-0);
13 | }
14 |
15 | .linkGroup {
16 | display: flex;
17 | flex-direction: column;
18 | justify-content: center;
19 | height: 100%;
20 |
21 | > * {
22 | margin-bottom: calc(var(--base) / 2);
23 | &:last-child {
24 | margin-bottom: 0;
25 | }
26 | }
27 |
28 | @include mid-break {
29 | padding-top: 12px
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/blocks/CallToAction/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Cell, Grid } from '@faceless-ui/css-grid';
3 | import { Page } from '../../payload-types';
4 | import { BackgroundColor } from '../../components/BackgroundColor';
5 | import { Gutter } from '../../components/Gutter';
6 | import { CMSLink } from '../../components/Link';
7 | import RichText from '../../components/RichText';
8 |
9 | import classes from './index.module.scss';
10 | import { VerticalPadding } from '../../components/VerticalPadding';
11 |
12 | type Props = Extract
13 |
14 | export const CallToActionBlock: React.FC = ({ ctaBackgroundColor, links, richText }) => {
17 | const oppositeBackgroundColor = ctaBackgroundColor === 'white' ? 'black' : 'white';
18 |
19 | return (
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | |
29 |
37 |
38 | {(links || []).map(({ link }, i) => {
39 | return (
40 |
44 | )
45 | })}
46 |
47 | |
48 |
49 |
50 |
51 |
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/blocks/Content/index.module.scss:
--------------------------------------------------------------------------------
1 | @import '../../css/common';
2 |
3 | .grid {
4 | row-gap: calc(var(--base) * 2) !important;
5 |
6 | @include mid-break {
7 | row-gap: var(--base) !important;
8 | }
9 | }
10 |
11 | .link {
12 | margin-top: var(--base);
13 | }
14 |
--------------------------------------------------------------------------------
/blocks/Content/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Grid, Cell } from '@faceless-ui/css-grid'
3 | import { Page } from '../../payload-types';
4 | import RichText from '../../components/RichText';
5 | import { Gutter } from '../../components/Gutter';
6 | import { CMSLink } from '../../components/Link';
7 | import classes from './index.module.scss';
8 |
9 | type Props = Extract
10 |
11 | export const ContentBlock: React.FC = (props) => {
14 | const {
15 | columns,
16 | } = props;
17 |
18 | return (
19 |
20 |
21 | {columns && columns.length > 0 && columns.map((col, index) => {
22 | const {
23 | enableLink,
24 | richText,
25 | link,
26 | size
27 | }= col;
28 |
29 | let cols;
30 |
31 | if (size === 'oneThird') cols = 4;
32 | if (size === 'half') cols = 6;
33 | if (size === 'twoThirds') cols = 8;
34 | if (size === 'full') cols = 10;
35 |
36 | return (
37 |
42 |
43 | {enableLink && (
44 |
48 | )}
49 | |
50 | )
51 | })}
52 |
53 |
54 | )
55 | }
56 |
--------------------------------------------------------------------------------
/blocks/MediaBlock/index.module.scss:
--------------------------------------------------------------------------------
1 | .mediaBlock {
2 | position: relative;
3 | }
4 |
5 | .caption {
6 | margin-top: var(--base)
7 | }
8 |
--------------------------------------------------------------------------------
/blocks/MediaBlock/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Gutter } from '../../components/Gutter';
3 | import { Media } from '../../components/Media';
4 | import { Page } from '../../payload-types';
5 | import RichText from '../../components/RichText';
6 | import classes from './index.module.scss';
7 |
8 | type Props = Extract
9 |
10 | export const MediaBlock: React.FC = (props) => {
13 | const {
14 | media,
15 | position = 'default',
16 | } = props;
17 |
18 | let caption;
19 | if (media && typeof media === 'object') caption = media.caption;
20 |
21 | return (
22 |
23 | {position === 'fullscreen' && (
24 |
25 |
28 |
29 | )}
30 | {position === 'default' && (
31 |
32 |
33 |
36 |
37 |
38 | )}
39 | {caption && (
40 |
41 |
42 |
43 | )}
44 |
45 | )
46 | }
47 |
--------------------------------------------------------------------------------
/components/AddToCartButton/index.module.scss:
--------------------------------------------------------------------------------
1 | .addToCartButton {
2 | // cursor: pointer;
3 | // background-color: transparent;
4 | // padding: 0;
5 | // border: none;
6 | // font-size: inherit;
7 | // line-height: inherit;
8 | // text-decoration: underline;
9 | // white-space: nowrap;
10 | }
11 |
--------------------------------------------------------------------------------
/components/AddToCartButton/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 |
3 | import { Product } from '../../payload-types'
4 | import { useCart } from '../../providers/Cart'
5 | import { Button, Props } from '../Button'
6 |
7 | import classes from './index.module.scss'
8 |
9 | export const AddToCartButton: React.FC<{
10 | product: Product
11 | quantity?: number
12 | className?: string
13 | appearance?: Props['appearance']
14 | }> = props => {
15 | const { product, quantity = 1, className, appearance = 'primary' } = props
16 |
17 | const { cart, addItemToCart, isProductInCart } = useCart()
18 |
19 | const [showInCart, setShowInCart] = useState()
20 |
21 | useEffect(() => {
22 | setShowInCart(isProductInCart(product))
23 | }, [isProductInCart, product, cart])
24 |
25 | if (showInCart) {
26 | return (
27 |
34 | )
35 | }
36 |
37 | return (
38 |