mirror of
https://github.com/vercel/commerce.git
synced 2025-04-24 03:47:52 +00:00
ProductGrid
This commit is contained in:
parent
ba4b3b765c
commit
de949095d7
@ -38,7 +38,7 @@ const CartSidebarView: FunctionComponent = () => {
|
|||||||
<span>-</span>
|
<span>-</span>
|
||||||
<input
|
<input
|
||||||
className="w-6 border-gray-300 border mx-3 rounded text-center text-sm"
|
className="w-6 border-gray-300 border mx-3 rounded text-center text-sm"
|
||||||
value="1"
|
defaultValue="1"
|
||||||
/>
|
/>
|
||||||
<span>+</span>
|
<span>+</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,7 @@ interface Props {
|
|||||||
|
|
||||||
const Layout: FunctionComponent<Props> = ({ className, children }) => {
|
const Layout: FunctionComponent<Props> = ({ className, children }) => {
|
||||||
const rootClassName = cn(s.root, className);
|
const rootClassName = cn(s.root, className);
|
||||||
const { displaySidebar, closeSidebar } = useUI();
|
const { displaySidebar } = useUI();
|
||||||
return (
|
return (
|
||||||
<div className={rootClassName}>
|
<div className={rootClassName}>
|
||||||
<Featurebar
|
<Featurebar
|
||||||
@ -25,7 +25,7 @@ const Layout: FunctionComponent<Props> = ({ className, children }) => {
|
|||||||
<main className="h-screen">{children}</main>
|
<main className="h-screen">{children}</main>
|
||||||
</Container>
|
</Container>
|
||||||
{displaySidebar && (
|
{displaySidebar && (
|
||||||
<Sidebar closeSidebar={closeSidebar}>
|
<Sidebar>
|
||||||
<CartSidebarView />
|
<CartSidebarView />
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
)}
|
)}
|
||||||
|
@ -4,9 +4,9 @@ const Cross = ({ ...props }) => {
|
|||||||
return (
|
return (
|
||||||
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" {...props}>
|
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" {...props}>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke-linejoin="round"
|
strokeLinejoin="round"
|
||||||
stroke-width="2"
|
strokeWidth="2"
|
||||||
d="M6 18L18 6M6 6l12 12"
|
d="M6 18L18 6M6 6l12 12"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</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 flex flex-row px-2;
|
||||||
|
}
|
29
components/product/ProductCard/ProductCard.tsx
Normal file
29
components/product/ProductCard/ProductCard.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import cn from "classnames";
|
||||||
|
import s from "./ProductCard.module.css";
|
||||||
|
import React, { FunctionComponent } from "react";
|
||||||
|
|
||||||
|
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-violet text-white font-bold text-3xl">
|
||||||
|
{/* {productData.title} */}
|
||||||
|
</h1>
|
||||||
|
<div className="px-6 py-2 pb-4 bg-violet text-white font-semibold inline-block">
|
||||||
|
{/* {productData.price} */}
|
||||||
|
</div>
|
||||||
|
</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";
|
||||||
|
|
||||||
|
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 s from "./ProductView.module.css";
|
||||||
import { Button } from "@components/ui";
|
import { Button } from "@components/ui";
|
||||||
import { Swatch } from "@components/product";
|
import { Swatch } from "@components/product";
|
||||||
import { Colors } from "@components/types";
|
|
||||||
interface ProductData {
|
|
||||||
title: string;
|
|
||||||
price: string;
|
|
||||||
description: string;
|
|
||||||
colors: [Colors];
|
|
||||||
sizes: [string];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import React, { FunctionComponent } from "react";
|
import React, { FunctionComponent } from "react";
|
||||||
import s from "./Swatch.module.css";
|
import s from "./Swatch.module.css";
|
||||||
import { Colors } from "@components/types";
|
import { Colors } from "@components/ui/types";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
export { default as ProductView } from "./ProductView";
|
|
||||||
export { default as Swatch } from "./Swatch";
|
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];
|
||||||
|
// };
|
@ -4,35 +4,48 @@ import React, {
|
|||||||
useEffect,
|
useEffect,
|
||||||
useRef,
|
useRef,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { findDOMNode } from "react-dom";
|
|
||||||
|
import { Component } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
export interface ClickOutsideProps {
|
export interface ClickOutsideProps {
|
||||||
onClickOutside: (e?: MouseEvent) => void;
|
onClickOutside: (e?: MouseEvent) => void;
|
||||||
children: React.ReactNode | any;
|
children: React.ReactNode | any;
|
||||||
|
render: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClickOutside: FunctionComponent<ClickOutsideProps> = ({
|
export default class ClickOutside extends Component<ClickOutsideProps> {
|
||||||
children,
|
public domNode: Element | null = null;
|
||||||
onClickOutside,
|
|
||||||
}) => {
|
|
||||||
let node = useRef(null);
|
|
||||||
|
|
||||||
const handleClick = (e: MouseEvent) => {
|
handleRef = (element) => {
|
||||||
console.log("eeee");
|
this.domNode = element;
|
||||||
if (!e || !node.current.contains(e.target as HTMLInputElement)) {
|
};
|
||||||
console.log("eeee");
|
|
||||||
// onClickOutside && onClickOutside(e);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
render() {
|
||||||
document.addEventListener("click", handleClick, true);
|
return null;
|
||||||
return () => {
|
// return this.props.render({
|
||||||
document.removeEventListener("click", handleClick);
|
// innerRef: this.handleRef,
|
||||||
};
|
// });
|
||||||
});
|
}
|
||||||
|
}
|
||||||
return children;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ClickOutside;
|
|
||||||
|
@ -5,21 +5,13 @@ import s from "./Sidebar.module.css";
|
|||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
children?: any;
|
children?: any;
|
||||||
closeSidebar: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Sidebar: FunctionComponent<Props> = ({
|
const Sidebar: FunctionComponent<Props> = ({ className, children }) => {
|
||||||
className,
|
|
||||||
children,
|
|
||||||
closeSidebar,
|
|
||||||
}) => {
|
|
||||||
const rootClassName = cn(s.root, className);
|
const rootClassName = cn(s.root, className);
|
||||||
return (
|
return (
|
||||||
<div className={rootClassName}>
|
<div className={rootClassName}>
|
||||||
<div
|
<div className="fixed inset-0 overflow-hidden shadow-sm bg-black bg-opacity-25">
|
||||||
className="fixed inset-0 overflow-hidden shadow-sm bg-black bg-opacity-25"
|
|
||||||
onClick={closeSidebar}
|
|
||||||
>
|
|
||||||
<div className="absolute inset-0 overflow-hidden">
|
<div className="absolute inset-0 overflow-hidden">
|
||||||
<section className="absolute inset-y-0 right-0 pl-10 max-w-full flex sm:pl-16 ">
|
<section className="absolute inset-y-0 right-0 pl-10 max-w-full flex sm:pl-16 ">
|
||||||
<div className="w-screen max-w-2xl">
|
<div className="w-screen max-w-2xl">
|
||||||
|
@ -2,4 +2,3 @@ export { default as Button } from "./Button";
|
|||||||
export { default as Container } from "./Container";
|
export { default as Container } from "./Container";
|
||||||
export { default as Sidebar } from "./Sidebar";
|
export { default as Sidebar } from "./Sidebar";
|
||||||
export { default as Logo } from "./Logo";
|
export { default as Logo } from "./Logo";
|
||||||
export { default as ClickOutside } from "./ClickOutside";
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
GetAllProductsQuery,
|
GetAllProductsQuery,
|
||||||
GetAllProductsQueryVariables,
|
GetAllProductsQueryVariables,
|
||||||
} from 'lib/bigcommerce/schema';
|
} from "lib/bigcommerce/schema";
|
||||||
import { getConfig, Images, ProductImageVariables } from '..';
|
import { getConfig, Images, ProductImageVariables } from "..";
|
||||||
import { RecursivePartial } from '../types';
|
import { RecursivePartial } from "../types";
|
||||||
|
|
||||||
export const getAllProductsQuery = /* GraphQL */ `
|
export const getAllProductsQuery = /* GraphQL */ `
|
||||||
query getAllProducts(
|
query getAllProducts(
|
||||||
@ -104,7 +104,7 @@ export const getAllProductsQuery = /* GraphQL */ `
|
|||||||
|
|
||||||
export interface GetAllProductsResult<T> {
|
export interface GetAllProductsResult<T> {
|
||||||
products: T extends GetAllProductsQuery
|
products: T extends GetAllProductsQuery
|
||||||
? T['site']['products']['edges']
|
? T["site"]["products"]["edges"]
|
||||||
: unknown;
|
: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { GetStaticPropsContext, InferGetStaticPropsType } from 'next';
|
import { GetStaticPropsContext, InferGetStaticPropsType } from "next";
|
||||||
import getAllProducts from 'lib/bigcommerce/api/operations/get-all-products';
|
import getAllProducts from "lib/bigcommerce/api/operations/get-all-products";
|
||||||
import { Layout } from '@components/core';
|
import { Layout } from "@components/core";
|
||||||
|
import { ProductGrid } from "@components/product";
|
||||||
|
|
||||||
export async function getStaticProps({ preview }: GetStaticPropsContext) {
|
export async function getStaticProps({ preview }: GetStaticPropsContext) {
|
||||||
const { products } = await getAllProducts();
|
const { products } = await getAllProducts();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: { products },
|
props: { products },
|
||||||
};
|
};
|
||||||
@ -13,15 +13,10 @@ export async function getStaticProps({ preview }: GetStaticPropsContext) {
|
|||||||
export default function Home({
|
export default function Home({
|
||||||
products,
|
products,
|
||||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||||
console.log('PRODUCTS', products);
|
console.log("PRODUCTS", products);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<div className="h-full grid grid-cols-1 h-full lg:grid-cols-3 lg:grid-rows-2">
|
<ProductGrid products={products} />
|
||||||
<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>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ module.exports = {
|
|||||||
violet: "#7928CA",
|
violet: "#7928CA",
|
||||||
pink: "#FF0080",
|
pink: "#FF0080",
|
||||||
cyan: "#50E3C2",
|
cyan: "#50E3C2",
|
||||||
|
blue: "#0070F3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@components/*": ["components/*"],
|
"@lib/*": ["lib/*"],
|
||||||
"@assets/*": ["assets/*"]
|
"@assets/*": ["assets/*"],
|
||||||
|
"@components/*": ["components/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user