forked from crowetic/commerce
Merge branch 'master' of https://github.com/okbel/e-comm-example
This commit is contained in:
commit
e8e5ce11f5
@ -38,7 +38,7 @@ const CartSidebarView: FunctionComponent = () => {
|
||||
<span>-</span>
|
||||
<input
|
||||
className="w-6 border-gray-300 border mx-3 rounded text-center text-sm"
|
||||
value="1"
|
||||
defaultValue="1"
|
||||
/>
|
||||
<span>+</span>
|
||||
</div>
|
||||
|
@ -6,5 +6,5 @@
|
||||
}
|
||||
|
||||
.item {
|
||||
@apply mr-6 cursor-pointer;
|
||||
@apply mr-6 cursor-pointer relative;
|
||||
}
|
||||
|
@ -16,8 +16,11 @@ const UserNav: FunctionComponent<Props> = ({ className }) => {
|
||||
return (
|
||||
<nav className={rootClassName}>
|
||||
<ul className={s.list}>
|
||||
<li className={s.item}>
|
||||
<Bag onClick={openSidebar} />
|
||||
<li className={s.item} onClick={openSidebar}>
|
||||
<Bag />
|
||||
<span className="bg-black h-4 w-4 absolute rounded-full inset-3 text-white flex items-center justify-center font-bold text-xs">
|
||||
1
|
||||
</span>
|
||||
</li>
|
||||
<li className={s.item}>
|
||||
<Heart />
|
||||
|
@ -4,9 +4,9 @@ const Cross = ({ ...props }) => {
|
||||
return (
|
||||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" {...props}>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
|
3
components/product/ProductCard/ProductCard.module.css
Normal file
3
components/product/ProductCard/ProductCard.module.css
Normal file
@ -0,0 +1,3 @@
|
||||
.root {
|
||||
@apply w-full h-full flex flex-row px-2;
|
||||
}
|
32
components/product/ProductCard/ProductCard.tsx
Normal file
32
components/product/ProductCard/ProductCard.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import cn from "classnames";
|
||||
import s from "./ProductCard.module.css";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { Heart } from "@components/icon";
|
||||
interface Props {
|
||||
className?: string;
|
||||
children?: any;
|
||||
}
|
||||
|
||||
const ProductCard: FunctionComponent<Props> = ({ className }) => {
|
||||
const rootClassName = cn(s.root, className);
|
||||
return (
|
||||
<div className={rootClassName}>
|
||||
<div className="absolute">
|
||||
<h1 className="px-8 py-2 bg-white text-black font-bold text-3xl">
|
||||
T-Shirt
|
||||
</h1>
|
||||
<div className="px-6 py-2 pb-4 bg-white text-black font-semibold inline-block">
|
||||
$50
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute flex items-center justify-center h-12 w-12 bg-white text-black">
|
||||
<Heart />
|
||||
</div>
|
||||
<div className="flex-1 h-full p-24">
|
||||
<div className="bg-violet h-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductCard;
|
1
components/product/ProductCard/index.ts
Normal file
1
components/product/ProductCard/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from "./ProductCard";
|
4
components/product/ProductGrid/ProductGrid.module.css
Normal file
4
components/product/ProductGrid/ProductGrid.module.css
Normal file
@ -0,0 +1,4 @@
|
||||
.root {
|
||||
@apply grid grid-cols-1 lg:grid-cols-3 lg:grid-rows-4 w-full h-96;
|
||||
min-height: calc((100vh - 80px - 56px) * 2);
|
||||
}
|
25
components/product/ProductGrid/ProductGrid.tsx
Normal file
25
components/product/ProductGrid/ProductGrid.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import cn from "classnames";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import s from "./ProductGrid.module.css";
|
||||
import ProductCard from "@components/ProductCard";
|
||||
interface Props {
|
||||
className?: string;
|
||||
children?: any;
|
||||
products: [any];
|
||||
}
|
||||
|
||||
const ProductView: FunctionComponent<Props> = ({ products, className }) => {
|
||||
const rootClassName = cn(s.root, className);
|
||||
return (
|
||||
<div className={rootClassName}>
|
||||
<div className="row-span-2 lg:col-span-2 bg-violet h-full"></div>
|
||||
<div className="row-span-1 lg:col-span-1 bg-black h-full"></div>
|
||||
<div className="row-span-1 lg:col-span-1 bg-pink"></div>
|
||||
<div className="row-span-1 lg:col-span-1 bg-black h-full"></div>
|
||||
<div className="row-span-2 lg:col-span-2 bg-blue h-full"></div>
|
||||
<div className="row-span-1 lg:col-span-1 bg-cyan"></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductView;
|
1
components/product/ProductGrid/index.ts
Normal file
1
components/product/ProductGrid/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from "./ProductGrid";
|
@ -3,14 +3,6 @@ import React, { FunctionComponent } from "react";
|
||||
import s from "./ProductView.module.css";
|
||||
import { Button } from "@components/ui";
|
||||
import { Swatch } from "@components/product";
|
||||
import { Colors } from "@components/types";
|
||||
interface ProductData {
|
||||
title: string;
|
||||
price: string;
|
||||
description: string;
|
||||
colors: [Colors];
|
||||
sizes: [string];
|
||||
}
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import cn from "classnames";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import s from "./Swatch.module.css";
|
||||
import { Colors } from "@components/types";
|
||||
import { Colors } from "@components/ui/types";
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
|
@ -1,2 +1,4 @@
|
||||
export { default as ProductView } from "./ProductView";
|
||||
export { default as Swatch } from "./Swatch";
|
||||
export { default as ProductView } from "./ProductView";
|
||||
export { default as ProductCard } from "./ProductCard";
|
||||
export { default as ProductGrid } from "./ProductGrid";
|
||||
|
10
components/product/types.ts
Normal file
10
components/product/types.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Colors } from "@components/ui/types";
|
||||
export { Product } from "@lib/bigcommerce";
|
||||
|
||||
// export type ProductData = {
|
||||
// title: string;
|
||||
// price: string;
|
||||
// description: string;
|
||||
// colors: [Colors];
|
||||
// sizes: [string];
|
||||
// };
|
51
components/ui/ClickOutside/ClickOutside.tsx
Normal file
51
components/ui/ClickOutside/ClickOutside.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import React, {
|
||||
FunctionComponent,
|
||||
MutableRefObject,
|
||||
useEffect,
|
||||
useRef,
|
||||
} from "react";
|
||||
|
||||
import { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export interface ClickOutsideProps {
|
||||
onClickOutside: (e?: MouseEvent) => void;
|
||||
children: React.ReactNode | any;
|
||||
render: () => void;
|
||||
}
|
||||
|
||||
export default class ClickOutside extends Component<ClickOutsideProps> {
|
||||
public domNode: Element | null = null;
|
||||
|
||||
handleRef = (element) => {
|
||||
this.domNode = element;
|
||||
};
|
||||
|
||||
public componentDidMount() {
|
||||
document.addEventListener("click", this.handleClick, true);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
document.removeEventListener("mousedown", this.handleClick, true);
|
||||
document.removeEventListener("touchstart", this.handleClick, true);
|
||||
}
|
||||
|
||||
public handleClick = (event) => {
|
||||
function hasParent(element, root) {
|
||||
return root && root.contains(element);
|
||||
}
|
||||
|
||||
if (!hasParent(event.target, this.domNode)) {
|
||||
if (typeof this.props.onClickOutside === "function") {
|
||||
this.props.onClickOutside(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return null;
|
||||
// return this.props.render({
|
||||
// innerRef: this.handleRef,
|
||||
// });
|
||||
}
|
||||
}
|
1
components/ui/ClickOutside/index.ts
Normal file
1
components/ui/ClickOutside/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from "./ClickOutside";
|
6710
package-lock.json
generated
6710
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@
|
||||
"classnames": "^2.2.6",
|
||||
"lodash": "^4.17.20",
|
||||
"next": "^9.5.4-canary.20",
|
||||
"postcss-nested": "^5.0.0",
|
||||
"postcss-nested": "^5.0.1",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"swr": "^0.3.3"
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { GetStaticPropsContext, InferGetStaticPropsType } from 'next';
|
||||
import getAllProducts from 'lib/bigcommerce/api/operations/get-all-products';
|
||||
import { Layout } from '@components/core';
|
||||
import { GetStaticPropsContext, InferGetStaticPropsType } from "next";
|
||||
import getAllProducts from "lib/bigcommerce/api/operations/get-all-products";
|
||||
import { Layout } from "@components/core";
|
||||
import { ProductGrid } from "@components/product";
|
||||
|
||||
export async function getStaticProps({ preview }: GetStaticPropsContext) {
|
||||
const { products } = await getAllProducts();
|
||||
|
||||
return {
|
||||
props: { products },
|
||||
};
|
||||
@ -13,15 +13,10 @@ export async function getStaticProps({ preview }: GetStaticPropsContext) {
|
||||
export default function Home({
|
||||
products,
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
console.log('PRODUCTS', products);
|
||||
|
||||
console.log("PRODUCTS", products);
|
||||
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>
|
||||
<ProductGrid products={products} />
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { GetStaticPropsContext, InferGetStaticPropsType } from 'next';
|
||||
import { useRouter } from 'next/router';
|
||||
import getProduct from 'lib/bigcommerce/api/operations/get-product';
|
||||
import { Layout } from '@components/core';
|
||||
import { ProductView } from '@components/product';
|
||||
import { GetStaticPropsContext, InferGetStaticPropsType } from "next";
|
||||
import { useRouter } from "next/router";
|
||||
import getProduct from "lib/bigcommerce/api/operations/get-product";
|
||||
import { Layout } from "@components/core";
|
||||
import { ProductView } from "@components/product";
|
||||
|
||||
export async function getStaticProps({
|
||||
params,
|
||||
}: GetStaticPropsContext<{ slug: string }>) {
|
||||
const { product } = await getProduct({ variables: { slug: params!.slug } });
|
||||
|
||||
console.log('PRODUCT', product);
|
||||
console.log("PRODUCT", product);
|
||||
|
||||
const productData = {
|
||||
title: 'T-Shirt',
|
||||
title: "T-Shirt",
|
||||
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.
|
||||
@ -21,9 +21,9 @@ export async function getStaticProps({
|
||||
run. Printing starts when the drop ends. Reminder: Bad Boys For
|
||||
Life. Shipping may take 10+ days due to COVID-19.
|
||||
`,
|
||||
price: '$50',
|
||||
colors: ['black', 'white', 'pink'],
|
||||
sizes: ['s', 'm', 'l', 'xl', 'xxl'],
|
||||
price: "$50",
|
||||
colors: ["black", "white", "pink"],
|
||||
sizes: ["s", "m", "l", "xl", "xxl"],
|
||||
};
|
||||
return {
|
||||
props: {
|
||||
@ -36,7 +36,7 @@ export async function getStaticProps({
|
||||
export async function getStaticPaths() {
|
||||
return {
|
||||
paths: [],
|
||||
fallback: 'unstable_blocking',
|
||||
fallback: "unstable_blocking",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
'tailwindcss',
|
||||
'postcss-flexbugs-fixes',
|
||||
"tailwindcss",
|
||||
"postcss-flexbugs-fixes",
|
||||
[
|
||||
'postcss-preset-env',
|
||||
"postcss-preset-env",
|
||||
{
|
||||
autoprefixer: {
|
||||
flexbox: 'no-2009',
|
||||
flexbox: "no-2009",
|
||||
},
|
||||
stage: 3,
|
||||
features: {
|
||||
'custom-properties': false,
|
||||
"custom-properties": false,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -15,6 +15,7 @@ module.exports = {
|
||||
violet: "#7928CA",
|
||||
pink: "#FF0080",
|
||||
cyan: "#50E3C2",
|
||||
blue: "#0070F3",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -15,8 +15,9 @@
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"paths": {
|
||||
"@components/*": ["components/*"],
|
||||
"@assets/*": ["assets/*"]
|
||||
"@lib/*": ["lib/*"],
|
||||
"@assets/*": ["assets/*"],
|
||||
"@components/*": ["components/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
|
20
yarn.lock
20
yarn.lock
@ -5712,12 +5712,12 @@ postcss-nested@^4.1.1:
|
||||
postcss "^7.0.32"
|
||||
postcss-selector-parser "^6.0.2"
|
||||
|
||||
postcss-nested@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.0.tgz#0d05bb93578ec42919bdbda7d4eb419d5f58fe07"
|
||||
integrity sha512-jQVUwMOkDJPHyY1o3bxLErHnxIFsO3yDgdDsL/rjSkUHrWNdtNGhP50O0P+vUjEwPo+ekCRhLXTe8TziARoS0w==
|
||||
postcss-nested@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.1.tgz#e7a77f7a806a09c8de0f2c163d8e3d09f00f3139"
|
||||
integrity sha512-ZHNSAoHrMtbEzjq+Qs4R0gHijpXc6F1YUv4TGmGaz7rtfMvVJBbu5hMOH+CrhEaljQpEmx5N/P8i1pXTkbVAmg==
|
||||
dependencies:
|
||||
postcss-selector-parser "^6.0.2"
|
||||
postcss-selector-parser "^6.0.4"
|
||||
|
||||
postcss-nesting@^7.0.0:
|
||||
version "7.0.1"
|
||||
@ -5848,6 +5848,16 @@ postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2:
|
||||
uniq "^1.0.1"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
postcss-selector-parser@^6.0.4:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3"
|
||||
integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==
|
||||
dependencies:
|
||||
cssesc "^3.0.0"
|
||||
indexes-of "^1.0.1"
|
||||
uniq "^1.0.1"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
postcss-value-parser@^3.3.0:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
|
||||
|
Loading…
x
Reference in New Issue
Block a user