forked from crowetic/commerce
Changes
This commit is contained in:
commit
eb44455cde
7
.env.example
Normal file
7
.env.example
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
BIGCOMMERCE_STOREFRONT_API_URL=https://your-site.mybigcommerce.com/graphql
|
||||||
|
BIGCOMMERCE_STOREFRONT_API_TOKEN=
|
||||||
|
BIGCOMMERCE_STORE_API_URL=https://api.bigcommerce.com/stores/xxxxxxxxxxx
|
||||||
|
BIGCOMMERCE_STORE_API_CLIENT_ID=
|
||||||
|
BIGCOMMERCE_STORE_API_SECRET=
|
||||||
|
BIGCOMMERCE_STORE_API_TOKEN=
|
||||||
|
BIGCOMMERCE_TOKEN_SECRET="this-is-a-secret-value-with-at-least-32-characters"
|
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
.next/
|
||||||
|
out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
1
.vercelignore
Normal file
1
.vercelignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
lib
|
628
assets/font.css
Normal file
628
assets/font.css
Normal file
@ -0,0 +1,628 @@
|
|||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587415301/fonts/2/inter-var-latin.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||||
|
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* these other fonts are only used and downloaded when a special chars is shown
|
||||||
|
in most cases, they are not downloaded at all */
|
||||||
|
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-latin-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||||
|
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-cyrillic.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: swap;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: block;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418127/fonts/2/inter-var-cyrillic-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||||
|
U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* greek */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418276/fonts/2/inter-var-greek.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* greek-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-greek-ext.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://assets.vercel.com/raw/upload/v1587418275/fonts/2/inter-var-vietnamese.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||||
|
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
194
assets/global.css
Normal file
194
assets/global.css
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
@import "./font.css";
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* Spacing variables */
|
||||||
|
--geist-space: 4px;
|
||||||
|
--geist-space-2x: 8px;
|
||||||
|
--geist-space-4x: 16px;
|
||||||
|
--geist-space-8x: 32px;
|
||||||
|
--geist-space-16x: 64px;
|
||||||
|
--geist-space-24x: 96px;
|
||||||
|
--geist-space-32x: 128px;
|
||||||
|
--geist-space-48x: 192px;
|
||||||
|
--geist-space-64x: 256px;
|
||||||
|
|
||||||
|
--geist-space-small: 32px;
|
||||||
|
--geist-space-medium: 40px;
|
||||||
|
--geist-space-large: 48px;
|
||||||
|
|
||||||
|
--geist-space-gap: 24px;
|
||||||
|
--geist-space-gap-half: 12px;
|
||||||
|
--geist-space-gap-quarter: var(--geist-space-2x);
|
||||||
|
|
||||||
|
--geist-gap: var(--geist-space-gap);
|
||||||
|
--geist-gap-half: var(--geist-space-gap-half);
|
||||||
|
--geist-gap-quarter: var(--geist-space-gap-quarter);
|
||||||
|
--geist-gap-double: var(--geist-space-large);
|
||||||
|
|
||||||
|
/* Negative values */
|
||||||
|
--geist-space-negative: -4px;
|
||||||
|
--geist-space-2x-negative: -8px;
|
||||||
|
--geist-space-4x-negative: -16px;
|
||||||
|
--geist-space-8x-negative: -32px;
|
||||||
|
--geist-space-16x-negative: -64px;
|
||||||
|
--geist-space-24x-negative: -96px;
|
||||||
|
--geist-space-32x-negative: -128px;
|
||||||
|
--geist-space-48x-negative: -192px;
|
||||||
|
--geist-space-64x-negative: -256px;
|
||||||
|
|
||||||
|
--geist-space-small-negative: -32px;
|
||||||
|
--geist-space-medium-negative: -40px;
|
||||||
|
--geist-space-large-negative: -48px;
|
||||||
|
|
||||||
|
--geist-space-gap-negative: -24px;
|
||||||
|
--geist-space-gap-half-negative: -12px;
|
||||||
|
--geist-space-gap-quarter-negative: var(--geist-space-2x-negative);
|
||||||
|
|
||||||
|
--geist-gap-negative: var(--geist-space-gap-negative);
|
||||||
|
--geist-gap-half-negative: var(--geist-space-gap-half-negative);
|
||||||
|
--geist-gap-quarter-negative: var(--geist-space-gap-quarter-negative);
|
||||||
|
--geist-gap-double-negative: var(--geist-space-large-negative);
|
||||||
|
|
||||||
|
/* Page values */
|
||||||
|
--geist-page-margin: var(--geist-space-gap);
|
||||||
|
--geist-page-width: 1000px;
|
||||||
|
--geist-page-width-with-margin: 1048px; /* 1000px + (2 * page margin) */
|
||||||
|
|
||||||
|
/* Appearance */
|
||||||
|
--geist-radius: 5px;
|
||||||
|
--geist-marketing-radius: 8px;
|
||||||
|
|
||||||
|
/* Fonts */
|
||||||
|
--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
|
||||||
|
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||||
|
sans-serif;
|
||||||
|
--font-mono: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
|
||||||
|
Bitstream Vera Sans Mono, Courier New, monospace;
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
--header-height: 64px;
|
||||||
|
--header-border-bottom: inset 0 -1px 0 0 rgba(0, 0, 0, 0.1);
|
||||||
|
--header-background: rgba(255, 255, 255, 0.8);
|
||||||
|
|
||||||
|
/* Form sizing */
|
||||||
|
--geist-form-large-font: 1rem;
|
||||||
|
--geist-form-large-line-height: 1.5rem;
|
||||||
|
--geist-form-large-height: var(--geist-space-large);
|
||||||
|
|
||||||
|
--geist-form-small-font: 0.875rem;
|
||||||
|
--geist-form-small-line-height: 0.875rem;
|
||||||
|
--geist-form-small-height: var(--geist-space-small);
|
||||||
|
|
||||||
|
--geist-form-font: 0.875rem;
|
||||||
|
--geist-form-line-height: 1.25rem;
|
||||||
|
--geist-form-height: var(--geist-space-medium);
|
||||||
|
|
||||||
|
--geist-success-lighter: #d3e5ff;
|
||||||
|
--geist-success-light: #3291ff;
|
||||||
|
--geist-success: #0070f3;
|
||||||
|
--geist-success-dark: #0761d1;
|
||||||
|
|
||||||
|
--geist-error-lighter: #f7d4d6;
|
||||||
|
--geist-error-light: #ff1a1a;
|
||||||
|
--geist-error: #ee0000;
|
||||||
|
--geist-error-dark: #c50000;
|
||||||
|
|
||||||
|
--geist-warning-lighter: #ffefcf;
|
||||||
|
--geist-warning-light: #f7b955;
|
||||||
|
--geist-warning: #f5a623;
|
||||||
|
--geist-warning-dark: #ab570a;
|
||||||
|
|
||||||
|
--geist-violet-lighter: #e3d7fc;
|
||||||
|
--geist-violet-light: #8a63d2;
|
||||||
|
--geist-violet: #7928ca;
|
||||||
|
--geist-violet-dark: #4c2889;
|
||||||
|
|
||||||
|
--geist-cyan-lighter: #aaffec;
|
||||||
|
--geist-cyan-light: #79ffe1;
|
||||||
|
--geist-cyan: #50e3c2;
|
||||||
|
--geist-cyan-dark: #29bc9b;
|
||||||
|
|
||||||
|
--geist-highlight-purple: #f81ce5;
|
||||||
|
--geist-highlight-magenta: #eb367f;
|
||||||
|
--geist-highlight-pink: #ff0080;
|
||||||
|
|
||||||
|
--geist-foreground: #000;
|
||||||
|
--geist-background: #fff;
|
||||||
|
--geist-selection: var(--geist-cyan-light);
|
||||||
|
--accents-1: #fafafa;
|
||||||
|
--accents-2: #eaeaea;
|
||||||
|
--accents-3: #999999;
|
||||||
|
--accents-4: #888888;
|
||||||
|
--accents-5: #666666;
|
||||||
|
--accents-6: #444444;
|
||||||
|
--accents-7: #333333;
|
||||||
|
--accents-8: #111111;
|
||||||
|
|
||||||
|
--geist-link-color: var(--geist-success);
|
||||||
|
--geist-marketing-gray: #fafbfc;
|
||||||
|
--geist-code: var(--geist-highlight-purple);
|
||||||
|
|
||||||
|
/* Secondary (Gray) */
|
||||||
|
--geist-secondary-lighter: var(--accents-2);
|
||||||
|
--geist-secondary-light: var(--accents-3);
|
||||||
|
--geist-secondary: var(--accents-5);
|
||||||
|
--geist-secondary-dark: var(--accents-7);
|
||||||
|
|
||||||
|
/* Shadows and other values */
|
||||||
|
|
||||||
|
--dropdown-box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.02);
|
||||||
|
--dropdown-triangle-stroke: #fff;
|
||||||
|
|
||||||
|
--scroller-start: rgba(255, 255, 255, 1);
|
||||||
|
--scroller-end: rgba(255, 255, 255, 0);
|
||||||
|
|
||||||
|
--shadow-smallest: 0px 4px 8px rgba(0, 0, 0, 0.12);
|
||||||
|
--shadow-small: 0 5px 10px rgba(0, 0, 0, 0.12);
|
||||||
|
--shadow-medium: 0 8px 30px rgba(0, 0, 0, 0.12);
|
||||||
|
--shadow-large: 0 30px 60px rgba(0, 0, 0, 0.12);
|
||||||
|
--shadow-hover: 0 30px 60px rgba(0, 0, 0, 0.12);
|
||||||
|
|
||||||
|
--shadow-sticky: 0 12px 10px -10px rgba(0, 0, 0, 0.12);
|
||||||
|
--portal-opacity: 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after {
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
touch-action: manipulation;
|
||||||
|
font-feature-settings: "case" 1, "rlig" 1, "calt" 0;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
background-color: var(--geist-background);
|
||||||
|
color: var(--geist-foreground);
|
||||||
|
scroll-padding-top: var(--header-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@tailwind utilities;
|
24
codegen.json
Normal file
24
codegen.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"schema": {
|
||||||
|
"https://buybutton.store/graphql": {
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJlYXQiOjE3NjcxMzkyMDAsInN1Yl90eXBlIjoyLCJ0b2tlbl90eXBlIjoxLCJjb3JzIjpbImh0dHBzOi8vZGV2ZWxvcGVyLmJpZ2NvbW1lcmNlLmNvbSJdLCJjaWQiOjEsImlhdCI6MTU3NjI1MzgyNCwic3ViIjoiM3dtZThrcWtrNjQwNzZueWljMGkzamk0NG5wajQ2byIsInNpZCI6OTk5MzMxNzg0LCJpc3MiOiJCQyJ9.Rqt6hNI2W-XSOzHl4pqtfhAOygwka6atCIaIZ_WAa9v3dOctnBlZpBV5wzd3ICCy4sTCOZ9mJwcFH5_CHmJpNQ"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"documents": [
|
||||||
|
{
|
||||||
|
"./lib/bigcommerce/api/queries/**/*.ts": {
|
||||||
|
"noRequire": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"generates": {
|
||||||
|
"./lib/bigcommerce/schema.d.ts": {
|
||||||
|
"plugins": ["typescript", "typescript-operations"]
|
||||||
|
},
|
||||||
|
"./lib/bigcommerce/schema.graphql": {
|
||||||
|
"plugins": ["schema-ast"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
components/core/Avatar/Avatar.module.css
Normal file
2
components/core/Avatar/Avatar.module.css
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.root {
|
||||||
|
}
|
23
components/core/Avatar/Avatar.tsx
Normal file
23
components/core/Avatar/Avatar.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import React, { FunctionComponent } from "react";
|
||||||
|
import s from "./Avatar.module.css";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
children?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Avatar: FunctionComponent<Props> = ({ className }) => {
|
||||||
|
const rootClassName = cn(s.root, className);
|
||||||
|
return (
|
||||||
|
<div className={rootClassName}>
|
||||||
|
<img
|
||||||
|
className="inline-block h-8 w-8 rounded-full"
|
||||||
|
src="https://vercel.com/api/www/avatar/61182a9f6bda512b4d9263c9c8a60aabe0402f4c?s=204"
|
||||||
|
alt=""
|
||||||
|
></img>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Avatar;
|
1
components/core/Avatar/index.ts
Normal file
1
components/core/Avatar/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Avatar";
|
21
components/core/Featurebar/Featurebar.module.css
Normal file
21
components/core/Featurebar/Featurebar.module.css
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.root {
|
||||||
|
@apply py-4 px-6 bg-black text-white flex flex-row justify-center items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@apply text-white font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
@apply mx-3 bg-white;
|
||||||
|
width: 1px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator:before {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
@apply text-white font-medium;
|
||||||
|
}
|
26
components/core/Featurebar/Featurebar.tsx
Normal file
26
components/core/Featurebar/Featurebar.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import { FunctionComponent } from "react";
|
||||||
|
import s from "./Featurebar.module.css";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Featurebar: FunctionComponent<Props> = ({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
className,
|
||||||
|
}) => {
|
||||||
|
const rootClassName = cn(s.root, className);
|
||||||
|
return (
|
||||||
|
<div className={rootClassName}>
|
||||||
|
<span className={s.title}>{title}</span>
|
||||||
|
<span className={s.separator} />
|
||||||
|
<span className={s.description}>{description}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Featurebar;
|
1
components/core/Featurebar/index.ts
Normal file
1
components/core/Featurebar/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Featurebar";
|
7
components/core/Footer/Footer.module.css
Normal file
7
components/core/Footer/Footer.module.css
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.root {
|
||||||
|
@apply p-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
@apply flex justify-between items-center flex-row px-4 py-5;
|
||||||
|
}
|
20
components/core/Footer/Footer.tsx
Normal file
20
components/core/Footer/Footer.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import React, { FunctionComponent } from "react";
|
||||||
|
import s from "./Footer.module.css";
|
||||||
|
import { Container } from "@components/ui";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
children?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Footer: FunctionComponent<Props> = ({ className }) => {
|
||||||
|
const rootClassName = cn(s.root, className);
|
||||||
|
return (
|
||||||
|
<footer className={rootClassName}>
|
||||||
|
<Container className={s.container}></Container>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Footer;
|
1
components/core/Footer/index.ts
Normal file
1
components/core/Footer/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Footer";
|
3
components/core/Layout/Layout.module.css
Normal file
3
components/core/Layout/Layout.module.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.root {
|
||||||
|
@apply h-full border-indigo-900;
|
||||||
|
}
|
26
components/core/Layout/Layout.tsx
Normal file
26
components/core/Layout/Layout.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import React, { FunctionComponent } from "react";
|
||||||
|
import s from "./Layout.module.css";
|
||||||
|
import { Navbar, Featurebar } from "@components/core";
|
||||||
|
import { Container } from "@components/ui";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
children?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Layout: FunctionComponent<Props> = ({ className, children }) => {
|
||||||
|
const rootClassName = cn(s.root, className);
|
||||||
|
return (
|
||||||
|
<Container className={rootClassName}>
|
||||||
|
<Featurebar
|
||||||
|
title="Free Standard Shipping on orders over $99.99"
|
||||||
|
description="Due to COVID-19, some orders may experience processing and delivery delays."
|
||||||
|
/>
|
||||||
|
<Navbar />
|
||||||
|
<main className="h-screen">{children}</main>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Layout;
|
1
components/core/Layout/index.ts
Normal file
1
components/core/Layout/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Layout";
|
3
components/core/Navbar/Navbar.module.css
Normal file
3
components/core/Navbar/Navbar.module.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.root {
|
||||||
|
@apply flex justify-between items-center flex-row px-6 h-20 relative;
|
||||||
|
}
|
0
components/core/Navbar/Navbar.tsx
Normal file
0
components/core/Navbar/Navbar.tsx
Normal file
1
components/core/Navbar/index.ts
Normal file
1
components/core/Navbar/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Navbar";
|
24
components/core/Searchbar/Searchbar.module.css
Normal file
24
components/core/Searchbar/Searchbar.module.css
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
.root {
|
||||||
|
@apply px-4 flex items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
@apply relative rounded-lg flex flex-row text-sm items-center bg-accent-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
@apply bg-transparent px-3 py-2 appearance-none w-full transition duration-150 ease-in-out rounded-lg text-accent-1 placeholder-accent-4;
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input:focus {
|
||||||
|
@apply outline-none shadow-outline-gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconContainer {
|
||||||
|
@apply absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
@apply h-5 w-5;
|
||||||
|
}
|
32
components/core/Searchbar/Searchbar.tsx
Normal file
32
components/core/Searchbar/Searchbar.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import React, { FunctionComponent } from "react";
|
||||||
|
import s from "./Searchbar.module.css";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
children?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Searchbar: FunctionComponent<Props> = ({ className }) => {
|
||||||
|
const rootClassName = cn(s.root, className);
|
||||||
|
return (
|
||||||
|
<div className={rootClassName}>
|
||||||
|
<div className="flex-1 flex justify-between px-2">
|
||||||
|
<div className={s.container}>
|
||||||
|
<input className={s.input} placeholder="Search for products..." />
|
||||||
|
<div className={s.iconContainer}>
|
||||||
|
<svg className={s.icon} fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Searchbar;
|
1
components/core/Searchbar/index.ts
Normal file
1
components/core/Searchbar/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Searchbar";
|
0
components/core/index.ts
Normal file
0
components/core/index.ts
Normal file
0
components/icon/Bag.tsx
Normal file
0
components/icon/Bag.tsx
Normal file
0
components/icon/Heart.tsx
Normal file
0
components/icon/Heart.tsx
Normal file
0
components/icon/Trash.tsx
Normal file
0
components/icon/Trash.tsx
Normal file
0
components/icon/index.ts
Normal file
0
components/icon/index.ts
Normal file
0
components/product/ProductView/ProductView.tsx
Normal file
0
components/product/ProductView/ProductView.tsx
Normal file
1
components/product/ProductView/index.ts
Normal file
1
components/product/ProductView/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./ProductView";
|
1
components/product/index.ts
Normal file
1
components/product/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default as ProductView } from "./ProductView";
|
0
components/ui/Button/Button.module.css
Normal file
0
components/ui/Button/Button.module.css
Normal file
54
components/ui/Button/Button.tsx
Normal file
54
components/ui/Button/Button.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import React, { ButtonHTMLAttributes } from "react";
|
||||||
|
import s from "./Button.module.css";
|
||||||
|
|
||||||
|
interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
|
href?: string;
|
||||||
|
className?: string;
|
||||||
|
variant?: "filled" | "outlined" | "flat" | "none";
|
||||||
|
active?: boolean;
|
||||||
|
type?: "submit" | "reset" | "button";
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Button extends React.Component<Props> {
|
||||||
|
public render() {
|
||||||
|
const {
|
||||||
|
className,
|
||||||
|
variant = "filled",
|
||||||
|
children,
|
||||||
|
disabled = false,
|
||||||
|
href,
|
||||||
|
active,
|
||||||
|
...rest
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
let Component: React.ComponentType<
|
||||||
|
React.AnchorHTMLAttributes<
|
||||||
|
HTMLAnchorElement | HTMLButtonElement | HTMLDivElement
|
||||||
|
> &
|
||||||
|
React.ClassAttributes<HTMLButtonElement | HTMLAnchorElement>
|
||||||
|
> = "a" as any;
|
||||||
|
|
||||||
|
// Catch for buttons / span / stc.
|
||||||
|
|
||||||
|
const rootClassName = cn(
|
||||||
|
s.root,
|
||||||
|
{
|
||||||
|
[s.filled]: variant === "filled",
|
||||||
|
},
|
||||||
|
className
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
className={rootClassName}
|
||||||
|
href={href}
|
||||||
|
aria-pressed={active}
|
||||||
|
data-variant={variant}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Component>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
1
components/ui/Button/index.ts
Normal file
1
components/ui/Button/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Button";
|
5
components/ui/Container/Container.module.css
Normal file
5
components/ui/Container/Container.module.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.root {
|
||||||
|
@apply mx-auto px-2;
|
||||||
|
display: inherit;
|
||||||
|
max-width: 1440px;
|
||||||
|
}
|
25
components/ui/Container/Container.tsx
Normal file
25
components/ui/Container/Container.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import { FunctionComponent } from "react";
|
||||||
|
import s from "./Container.module.css";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
children?: any;
|
||||||
|
el?: HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Container: FunctionComponent<Props> = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
el = "div",
|
||||||
|
}) => {
|
||||||
|
const rootClassName = cn(s.root, className);
|
||||||
|
|
||||||
|
let Component: React.ComponentType<React.HTMLAttributes<
|
||||||
|
HTMLDivElement
|
||||||
|
>> = el as any;
|
||||||
|
|
||||||
|
return <Component className={rootClassName}>{children}</Component>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Container;
|
1
components/ui/Container/index.ts
Normal file
1
components/ui/Container/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Container";
|
40
components/ui/Logo/Logo.tsx
Normal file
40
components/ui/Logo/Logo.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const Logo = () => (
|
||||||
|
<svg
|
||||||
|
width="265"
|
||||||
|
height="33"
|
||||||
|
viewBox="0 0 265 33"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M107.814 13.2069C107.157 9.51371 104.14 6.66301 99.8688 6.66301C94.8041 6.66301 91.1991 10.6893 91.1991 16.9687C91.1991 23.248 94.8041 27.2743 99.8688 27.2743C104.14 27.2743 107.157 24.4138 107.814 20.7304H105.972C105.413 23.4832 103.013 25.5502 99.8688 25.5502C96.0678 25.5502 92.9722 22.5427 92.9722 16.9687C92.9722 11.4142 96.0678 8.38715 99.8688 8.38715C103.013 8.38715 105.413 10.4639 105.972 13.2069H107.814ZM130.771 16.9687C130.771 10.6893 127.166 6.66301 122.092 6.66301C117.027 6.66301 113.422 10.6991 113.422 16.9687C113.422 23.2382 117.017 27.2743 122.092 27.2743C127.166 27.2743 130.771 23.248 130.771 16.9687ZM128.988 16.9687C128.998 22.3664 126.05 25.5502 122.092 25.5502C118.124 25.5502 115.195 22.3468 115.195 16.9687C115.195 11.5611 118.154 8.38715 122.092 8.38715C126.05 8.38715 128.988 11.5709 128.988 16.9687ZM137.409 6.9373V27H139.133V10.8068H139.289L146.059 27H147.724L154.493 10.8068H154.65V27H156.374V6.9373H154.258L146.979 24.4138H146.803L139.525 6.9373H137.409ZM163.915 6.9373V27H165.639V10.8068H165.796L172.565 27H174.23L181 10.8068H181.156V27H182.881V6.9373H180.765L173.486 24.4138H173.31L166.031 6.9373H163.915ZM190.421 27H202.255V25.3542H192.253V17.7817H201.442V16.136H192.253V8.58307H202.059V6.9373H190.421V27ZM209.008 27H210.84V18.8887H215.512C215.777 18.8887 216.032 18.8789 216.277 18.8593L220.675 27H222.791L218.157 18.5067C220.655 17.6838 221.949 15.6266 221.949 12.9424C221.949 9.43534 219.744 6.9373 215.483 6.9373H209.008V27ZM210.84 17.2136V8.58307H215.434C218.608 8.58307 220.146 10.317 220.146 12.9424C220.146 15.5678 218.608 17.2136 215.463 17.2136H210.84ZM244.331 13.2069C243.674 9.51371 240.657 6.66301 236.386 6.66301C231.321 6.66301 227.716 10.6893 227.716 16.9687C227.716 23.248 231.321 27.2743 236.386 27.2743C240.657 27.2743 243.674 24.4138 244.331 20.7304H242.489C241.931 23.4832 239.531 25.5502 236.386 25.5502C232.585 25.5502 229.489 22.5427 229.489 16.9687C229.489 11.4142 232.585 8.38715 236.386 8.38715C239.531 8.38715 241.931 10.4639 242.489 13.2069H244.331ZM250.841 27H262.675V25.3542H252.673V17.7817H261.861V16.136H252.673V8.58307H262.479V6.9373H250.841V27Z"
|
||||||
|
fill="#999999"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M1.00032 7.45572H0.847148L0.847146 7.60888L0.84683 26.3794L0.846827 26.5326H1H3.35085H3.50402V26.3794V11.0488L15.5865 26.4613L15.6325 26.52H15.7071H18.593H18.9075L18.7136 26.2724L4.02996 7.51447L3.98397 7.45572H3.90935H1.00032Z"
|
||||||
|
fill="black"
|
||||||
|
stroke="black"
|
||||||
|
strokeWidth="0.30634"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M72.7815 7.63232V7.47915H72.6284H65.1018H64.9486V7.63232V9.94681V10.1H65.1018H72.4752V26.4028V26.556H72.6284H74.914H75.0672V26.4028V10.1H82.556H82.7092V9.94681V7.63232V7.47915H82.556H74.7986H74.7322L74.6868 7.52755L72.7815 9.55953V7.63232Z"
|
||||||
|
fill="black"
|
||||||
|
stroke="black"
|
||||||
|
strokeWidth="0.30634"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M25.5445 17.8767H33.7028H33.856V17.7235V15.8719V15.7187H33.7028H27.2383H27.1748L27.1299 15.7637L25.5445 17.3531V10.041H36.4734H36.6265V9.88786V7.63232V7.47915H36.4734H23.1365H22.9833V7.63232V26.3797V26.5329H23.1365H36.4734H36.6265V26.3797V24.284V24.1308H36.4734H25.5445V17.8767Z"
|
||||||
|
fill="black"
|
||||||
|
stroke="black"
|
||||||
|
strokeWidth="0.30634"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M59.6859 7.67494L59.8579 7.43301L59.561 7.43301L56.7236 7.43301L56.6484 7.43301L56.6024 7.49249L50.8466 14.9361L45.091 7.51545L45.045 7.45616L44.9699 7.45616L42.0145 7.45616L41.7035 7.45616L41.8931 7.70271L43.6728 10.0167L43.6731 10.0172L49.0095 17.0137L43.6716 24.2008L43.6704 24.2024L42.1443 26.3132L41.9687 26.5561L42.2685 26.5561L44.9699 26.5561L45.0449 26.5561L45.0909 26.4969L50.8466 19.0886L56.6025 26.5199L56.6485 26.5793L56.7236 26.5793L59.561 26.5793L59.7142 26.5793L59.7142 26.4261L59.7142 26.403L59.7142 26.3499L59.6814 26.3082L58.0206 24.199L52.684 17.0137L58.0207 10.0167L58.0208 10.0168L58.0238 10.0126L59.6859 7.67494ZM59.6859 7.67494L59.561 7.58618L59.561 7.58618L59.6859 7.67494Z"
|
||||||
|
fill="black"
|
||||||
|
stroke="black"
|
||||||
|
strokeWidth="0.30634"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Logo;
|
1
components/ui/Logo/index.ts
Normal file
1
components/ui/Logo/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Logo";
|
3
components/ui/README.md
Normal file
3
components/ui/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# UI
|
||||||
|
|
||||||
|
Building blocks to build a rich graphical interfaces. Components should be atomic and pure. Serve one purpuse.
|
15
components/ui/_BLANK/Featurebar.tsx
Normal file
15
components/ui/_BLANK/Featurebar.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import { FunctionComponent } from "react";
|
||||||
|
import s from "./Featurebar.module.css";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
children?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Featurebar: FunctionComponent<Props> = ({ children, className }) => {
|
||||||
|
const rootClassName = cn(s.root, className);
|
||||||
|
return <div className={rootClassName}>{children}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Featurebar;
|
1
components/ui/_BLANK/index.ts
Normal file
1
components/ui/_BLANK/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from "./Featurebar";
|
4
components/ui/index.ts
Normal file
4
components/ui/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export { default as Button } from "./Button";
|
||||||
|
export { default as Container } from "./Container";
|
||||||
|
|
||||||
|
export { default as Logo } from "./Logo";
|
84
lib/bigcommerce/api/index.ts
Normal file
84
lib/bigcommerce/api/index.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import {
|
||||||
|
CommerceAPI,
|
||||||
|
CommerceAPIOptions,
|
||||||
|
CommerceAPIFetchOptions,
|
||||||
|
} from 'lib/commerce/api';
|
||||||
|
import { GetAllProductsQuery } from '../schema';
|
||||||
|
import { getAllProductsQuery } from './operations/get-all-products';
|
||||||
|
|
||||||
|
type RecursivePartial<T> = {
|
||||||
|
[P in keyof T]?: RecursivePartial<T[P]>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface GetAllProductsResult<T> {
|
||||||
|
products: T extends GetAllProductsQuery
|
||||||
|
? T['site']['products']['edges']
|
||||||
|
: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class BigcommerceAPI implements CommerceAPI {
|
||||||
|
protected commerceUrl: string;
|
||||||
|
protected apiToken: string;
|
||||||
|
|
||||||
|
constructor({ commerceUrl, apiToken }: CommerceAPIOptions) {
|
||||||
|
this.commerceUrl = commerceUrl;
|
||||||
|
this.apiToken = apiToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetch<T>(
|
||||||
|
query: string,
|
||||||
|
{ variables, preview }: CommerceAPIFetchOptions = {}
|
||||||
|
): Promise<T> {
|
||||||
|
const res = await fetch(this.commerceUrl + (preview ? '/preview' : ''), {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${this.apiToken}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
query,
|
||||||
|
variables,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = await res.json();
|
||||||
|
if (json.errors) {
|
||||||
|
console.error(json.errors);
|
||||||
|
throw new Error('Failed to fetch API');
|
||||||
|
}
|
||||||
|
return json.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllProducts<T>(opts: {
|
||||||
|
query: string;
|
||||||
|
}): Promise<GetAllProductsResult<T>>;
|
||||||
|
async getAllProducts<T = GetAllProductsQuery>({
|
||||||
|
query,
|
||||||
|
}: { query?: string } = {}): Promise<
|
||||||
|
GetAllProductsResult<T | GetAllProductsQuery>
|
||||||
|
// T extends GetAllProductsQuery
|
||||||
|
// ? GetAllProductsResult<T['site']['products']['edges']>
|
||||||
|
// : Partial<GetAllProductsResult<any>>
|
||||||
|
> {
|
||||||
|
if (!query) {
|
||||||
|
const data = await this.fetch<GetAllProductsQuery>(getAllProductsQuery);
|
||||||
|
|
||||||
|
return {
|
||||||
|
products: data.site.products.edges,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
products: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let h = new BigcommerceAPI({ apiToken: '', commerceUrl: '' });
|
||||||
|
|
||||||
|
async function yay() {
|
||||||
|
const x = await h.getAllProducts<{ custom: 'val' }>({ query: 'yes' });
|
||||||
|
const y = await h.getAllProducts();
|
||||||
|
|
||||||
|
console.log(x.products);
|
||||||
|
}
|
79
lib/bigcommerce/api/operations/get-all-products.ts
Normal file
79
lib/bigcommerce/api/operations/get-all-products.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
export const responsiveImageFragment = /* GraphQL */ `
|
||||||
|
fragment responsiveImage on Image {
|
||||||
|
url320wide: url(width: 320)
|
||||||
|
url640wide: url(width: 640)
|
||||||
|
url960wide: url(width: 960)
|
||||||
|
url1280wide: url(width: 1280)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const getAllProductsQuery = /* GraphQL */ `
|
||||||
|
query getAllProducts {
|
||||||
|
site {
|
||||||
|
products(first: 4) {
|
||||||
|
pageInfo {
|
||||||
|
startCursor
|
||||||
|
endCursor
|
||||||
|
}
|
||||||
|
edges {
|
||||||
|
cursor
|
||||||
|
node {
|
||||||
|
entityId
|
||||||
|
name
|
||||||
|
path
|
||||||
|
brand {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
description
|
||||||
|
prices {
|
||||||
|
price {
|
||||||
|
value
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
salePrice {
|
||||||
|
value
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
images {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...responsiveImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
variants {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
entityId
|
||||||
|
defaultImage {
|
||||||
|
...responsiveImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
entityId
|
||||||
|
displayName
|
||||||
|
isRequired
|
||||||
|
values {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
entityId
|
||||||
|
label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
${responsiveImageFragment}
|
||||||
|
`;
|
14
lib/bigcommerce/cart.tsx
Normal file
14
lib/bigcommerce/cart.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import {
|
||||||
|
CartProvider as CommerceCartProvider,
|
||||||
|
useCart as useCommerceCart,
|
||||||
|
} from 'lib/commerce/cart';
|
||||||
|
|
||||||
|
export type Cart = any;
|
||||||
|
|
||||||
|
export function CartProvider({ children }) {
|
||||||
|
return <CommerceCartProvider>{children}</CommerceCartProvider>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCart() {
|
||||||
|
return useCommerceCart<Cart>();
|
||||||
|
}
|
47
lib/bigcommerce/index.tsx
Normal file
47
lib/bigcommerce/index.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import {
|
||||||
|
CommerceProvider as CoreCommerceProvider,
|
||||||
|
Connector,
|
||||||
|
useCommerce as useCoreCommerce,
|
||||||
|
} from 'lib/commerce';
|
||||||
|
|
||||||
|
async function getText(res: Response) {
|
||||||
|
try {
|
||||||
|
return (await res.text()) || res.statusText;
|
||||||
|
} catch (error) {
|
||||||
|
return res.statusText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getError(res: Response) {
|
||||||
|
if (res.headers.get('Content-Type')?.includes('application/json')) {
|
||||||
|
const data = await res.json();
|
||||||
|
return data.errors[0];
|
||||||
|
}
|
||||||
|
return { message: await getText(res) };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetcher(url: string, query: string) {
|
||||||
|
const res = await fetch(url);
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw await getError(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const bigcommerce: Connector = {
|
||||||
|
locale: 'en-us',
|
||||||
|
fetcher,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: The connector should be extendable when a developer is using it
|
||||||
|
export function CommerceProvider({ children }) {
|
||||||
|
return (
|
||||||
|
<CoreCommerceProvider connector={bigcommerce}>
|
||||||
|
{children}
|
||||||
|
</CoreCommerceProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useCommerce = () => useCoreCommerce();
|
1733
lib/bigcommerce/schema.d.ts
vendored
Normal file
1733
lib/bigcommerce/schema.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1529
lib/bigcommerce/schema.graphql
Normal file
1529
lib/bigcommerce/schema.graphql
Normal file
File diff suppressed because it is too large
Load Diff
105
lib/cart.js
Normal file
105
lib/cart.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import { useState, useCallback } from "react";
|
||||||
|
import useSWR, { mutate } from "swr";
|
||||||
|
|
||||||
|
async function getText(res) {
|
||||||
|
try {
|
||||||
|
return (await res.text()) || res.statusText;
|
||||||
|
} catch (error) {
|
||||||
|
return res.statusText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getError(res) {
|
||||||
|
if (res.headers.get("Content-Type")?.includes("application/json")) {
|
||||||
|
const data = await res.json();
|
||||||
|
return data.errors[0];
|
||||||
|
}
|
||||||
|
return { message: await getText(res) };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetcher(url) {
|
||||||
|
const res = await fetch(url);
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
throw await getError(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCart() {
|
||||||
|
return useSWR("/api/cart", fetcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useAddToCart() {
|
||||||
|
const [{ addingToCart, error }, setStatus] = useState({
|
||||||
|
addingToCart: false,
|
||||||
|
});
|
||||||
|
const addToCart = useCallback(async ({ product }) => {
|
||||||
|
setStatus({ addingToCart: true });
|
||||||
|
|
||||||
|
const res = await fetch("/api/cart", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ product }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Product added as expected
|
||||||
|
if (res.status === 200) {
|
||||||
|
setStatus({ addingToCart: false });
|
||||||
|
return mutate("/api/cart");
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = await getError(res);
|
||||||
|
|
||||||
|
console.error("Adding product to cart failed with:", res.status, error);
|
||||||
|
setStatus({ addingToCart: false, error });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { addToCart, addingToCart, error };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useUpdateCart() {
|
||||||
|
const [{ updatingCart, error }, setStatus] = useState({
|
||||||
|
updatingCart: false,
|
||||||
|
});
|
||||||
|
const updateCart = useCallback(async ({ product, item }) => {
|
||||||
|
setStatus({ updatingCart: true });
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
`/api/cart?itemId=${item.id}`,
|
||||||
|
product.quantity < 1
|
||||||
|
? { method: "DELETE" }
|
||||||
|
: {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ product }),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Product updated as expected
|
||||||
|
if (res.status === 200) {
|
||||||
|
setStatus({ updatingCart: false });
|
||||||
|
return mutate("/api/cart");
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = await getError(res);
|
||||||
|
|
||||||
|
console.error("Update to cart failed with:", res.status, error);
|
||||||
|
setStatus({ updatingCart: false, error });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { updateCart, updatingCart, error };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useRemoveFromCart() {
|
||||||
|
const { updateCart, updatingCart, error } = useUpdateCart();
|
||||||
|
const removeFromCart = async ({ item }) => {
|
||||||
|
updateCart({ item, product: { quantity: 0 } });
|
||||||
|
};
|
||||||
|
|
||||||
|
return { removeFromCart, removingFromCart: updatingCart, error };
|
||||||
|
}
|
24
lib/commerce/api/index.ts
Normal file
24
lib/commerce/api/index.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
export interface CommerceAPIOptions {
|
||||||
|
commerceUrl: string;
|
||||||
|
apiToken: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CommerceAPIFetchOptions {
|
||||||
|
variables?: object;
|
||||||
|
preview?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CommerceAPI {
|
||||||
|
commerceUrl: string;
|
||||||
|
apiToken: string;
|
||||||
|
|
||||||
|
fetch<T>(query: string, queryData?: CommerceAPIFetchOptions): Promise<T>;
|
||||||
|
|
||||||
|
getAllProducts(options?: { query?: string }): Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// export default class CommerceAPI {
|
||||||
|
// getAllProducts(query: string) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
37
lib/commerce/cart.tsx
Normal file
37
lib/commerce/cart.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { createContext, useContext } from 'react';
|
||||||
|
import useSWR, { responseInterface } from 'swr';
|
||||||
|
import { useCommerce } from '.';
|
||||||
|
|
||||||
|
export type Cart = any;
|
||||||
|
|
||||||
|
export type CartResponse<C extends Cart> = responseInterface<C, Error> & {
|
||||||
|
isEmpty: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CartContext = createContext<CartResponse<Cart>>(null);
|
||||||
|
|
||||||
|
function getCartCookie() {
|
||||||
|
// TODO: Figure how the cart should be persisted
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CartProvider({ children }) {
|
||||||
|
const { hooks, fetcher } = useCommerce<Cart>();
|
||||||
|
const { useCart } = hooks;
|
||||||
|
const cartId = getCartCookie();
|
||||||
|
const response = useSWR(
|
||||||
|
() => (cartId ? [useCart.url, useCart.query, useCart.resolver] : null),
|
||||||
|
fetcher
|
||||||
|
);
|
||||||
|
const isEmpty = true;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CartContext.Provider value={{ ...response, isEmpty }}>
|
||||||
|
{children}
|
||||||
|
</CartContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCart<C extends Cart>() {
|
||||||
|
return useContext(CartContext) as CartResponse<C>;
|
||||||
|
}
|
29
lib/commerce/index.tsx
Normal file
29
lib/commerce/index.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { createContext, ReactNode, useContext } from 'react';
|
||||||
|
|
||||||
|
const Commerce = createContext<Connector>(null);
|
||||||
|
|
||||||
|
export type CommerceProps = {
|
||||||
|
children?: ReactNode;
|
||||||
|
connector: Connector;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Connector = {
|
||||||
|
fetcher: Fetcher<any>;
|
||||||
|
locale: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Fetcher<T> = (...args: any) => T | Promise<T>;
|
||||||
|
|
||||||
|
export function CommerceProvider({ children, connector }: CommerceProps) {
|
||||||
|
if (!connector) {
|
||||||
|
throw new Error(
|
||||||
|
'CommerceProvider requires a valid headless commerce connector'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Commerce.Provider value={connector}>{children}</Commerce.Provider>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCommerce<T extends Connector>() {
|
||||||
|
return useContext(Commerce) as T;
|
||||||
|
}
|
2
next-env.d.ts
vendored
Normal file
2
next-env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/// <reference types="next" />
|
||||||
|
/// <reference types="next/types/global" />
|
6710
package-lock.json
generated
Normal file
6710
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
41
package.json
Normal file
41
package.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "e-comm-example",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"generate": "graphql-codegen"
|
||||||
|
},
|
||||||
|
"graphql": {
|
||||||
|
"schema": "lib/bigcommerce/schema.graphql",
|
||||||
|
"documents": "lib/bigcommerce/**/*.{graphql,js,ts,jsx,tsx}"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@tailwindcss/ui": "^0.6.2",
|
||||||
|
"@types/classnames": "^2.2.10",
|
||||||
|
"classnames": "^2.2.6",
|
||||||
|
"next": "^9.5.4-canary.20",
|
||||||
|
"postcss-nested": "^5.0.0",
|
||||||
|
"react": "^16.13.1",
|
||||||
|
"react-dom": "^16.13.1",
|
||||||
|
"swr": "^0.3.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@graphql-codegen/cli": "^1.17.10",
|
||||||
|
"@graphql-codegen/schema-ast": "^1.17.8",
|
||||||
|
"@graphql-codegen/typescript": "^1.17.10",
|
||||||
|
"@graphql-codegen/typescript-operations": "^1.17.8",
|
||||||
|
"@types/node": "^14.11.2",
|
||||||
|
"@types/react": "^16.9.49",
|
||||||
|
"graphql": "^15.3.0",
|
||||||
|
"postcss-flexbugs-fixes": "^4.2.1",
|
||||||
|
"postcss-preset-env": "^6.7.0",
|
||||||
|
"tailwindcss": "^1.8.10",
|
||||||
|
"typescript": "^4.0.3"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"webpack": "^5.0.0-beta.30"
|
||||||
|
}
|
||||||
|
}
|
9
pages/_app.tsx
Normal file
9
pages/_app.tsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import "@assets/global.css";
|
||||||
|
|
||||||
|
export default function MyApp({ Component, pageProps }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
18
pages/_document.tsx
Normal file
18
pages/_document.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import Document_, { Html, Head, Main, NextScript } from "next/document";
|
||||||
|
|
||||||
|
export default class Document extends Document_ {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Html lang="en">
|
||||||
|
<Head />
|
||||||
|
<body>
|
||||||
|
<Main />
|
||||||
|
<NextScript />
|
||||||
|
{/**
|
||||||
|
* Here add your GA and more scripts.
|
||||||
|
*/}
|
||||||
|
</body>
|
||||||
|
</Html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
13
pages/index.tsx
Normal file
13
pages/index.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Layout } from "@components/core";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<div className="h-full grid grid-cols-1 h-full lg:grid-cols-3 lg:grid-rows-2">
|
||||||
|
<div className="lg:row-span-2 lg:col-span-2 bg-violet h-full"></div>
|
||||||
|
<div className="lg:row-span-1 lg:col-span-1 bg-black h-full"></div>
|
||||||
|
<div className="lg:row-span-1 lg:col-span-1 bg-pink"></div>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
42
pages/product/[id].tsx
Normal file
42
pages/product/[id].tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { Layout } from "@components/core";
|
||||||
|
import { ProductView } from "@components/product";
|
||||||
|
|
||||||
|
export async function getStaticProps() {
|
||||||
|
const productData = {
|
||||||
|
description: `
|
||||||
|
Nothing undercover about this tee. Nope. This is the official Bad
|
||||||
|
Boys tee. Printed in white or black ink on Black, Brown, or Oatmeal.
|
||||||
|
Like everything in this collection, it is extremely limited edition
|
||||||
|
and available for 10 days only. This is a limited edition production
|
||||||
|
run. Printing starts when the drop ends. Reminder: Bad Boys For
|
||||||
|
Life. Shipping may take 10+ days due to COVID-19.
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
productData,
|
||||||
|
},
|
||||||
|
revalidate: 200,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
return {
|
||||||
|
paths: [],
|
||||||
|
fallback: "unstable_blocking",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Home({ productData }) {
|
||||||
|
const router = useRouter();
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
{router.isFallback ? (
|
||||||
|
<h1>Loading...</h1>
|
||||||
|
) : (
|
||||||
|
<ProductView productData={productData} />
|
||||||
|
)}
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
18
postcss.config.js
Normal file
18
postcss.config.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
'tailwindcss',
|
||||||
|
'postcss-flexbugs-fixes',
|
||||||
|
[
|
||||||
|
'postcss-preset-env',
|
||||||
|
{
|
||||||
|
autoprefixer: {
|
||||||
|
flexbox: 'no-2009',
|
||||||
|
},
|
||||||
|
stage: 3,
|
||||||
|
features: {
|
||||||
|
'custom-properties': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
};
|
26
tailwind.config.js
Normal file
26
tailwind.config.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
module.exports = {
|
||||||
|
future: {
|
||||||
|
removeDeprecatedGapUtilities: true,
|
||||||
|
},
|
||||||
|
purge: [
|
||||||
|
"./components/**/*.{js,ts,jsx,tsx}",
|
||||||
|
"./pages/**/*.{js,ts,jsx,tsx}",
|
||||||
|
"./ui/**/*.{js,ts,jsx,tsx}",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
"accent-1": "#FAFAFA",
|
||||||
|
"accent-4": "#888",
|
||||||
|
violet: "#7928CA",
|
||||||
|
pink: "#FF0080",
|
||||||
|
cyan: "#50E3C2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
variants: {},
|
||||||
|
plugins: [require("@tailwindcss/ui")],
|
||||||
|
experimental: {
|
||||||
|
applyComplexClasses: true,
|
||||||
|
},
|
||||||
|
};
|
24
tsconfig.json
Normal file
24
tsconfig.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"paths": {
|
||||||
|
"@components/*": ["components/*"],
|
||||||
|
"@assets/*": ["assets/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user