diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2dbc5e9..6ac3547 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,5 +27,5 @@ jobs: cache: "yarn" - run: yarn install - run: yarn build - - run: yarn prettier -c . + - run: yarn reformat:check # - run: yarn test diff --git a/eslint.config.mjs b/eslint.config.mjs index 4d4fafe..38b8bb7 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -112,6 +112,7 @@ export default [ "react/react-in-jsx-scope": "off", "no-plusplus": "off", "react/no-array-index-key": "off", + "@typescript-eslint/no-explicit-any": "warn", }, }, ]; diff --git a/package.json b/package.json index 4421291..c53f752 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "reformat-all": "prettier --write .", "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"", "lint:fix": "eslint --fix \"src/**/*.{js,jsx,ts,tsx}\"", - "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,md}\" --config ./.prettierrc.json" + "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,md}\" --config ./.prettierrc.json", + "reformat:check": "prettier -c ." }, "eslintConfig": { "extends": [ diff --git a/src/App.css b/src/App.css index 78b8850..6f73220 100644 --- a/src/App.css +++ b/src/App.css @@ -1,5 +1,5 @@ .App { - text-align: center; + /* text-align: center; */ } .App-logo { diff --git a/src/App.tsx b/src/App.tsx index f08ee3c..2a3aa38 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,24 +1,17 @@ -import React from "react"; import "./App.css"; -import Board from "./components/TicTacToe/Board"; +import { ConfigProvider, theme } from "antd"; +import FilterableProductTable from "./components/FilterableProductTable"; function App() { - // const [count, setCount] = React.useState(0); - - // function handleClick(){ - // setCount(count+1); - // console.log(`Button clicked ${count} times`); - // } return (
- {/*

Welcome to my App!

- -
- - -
*/} - {/* */} - + + +
); } diff --git a/src/components/FilterableProductTable/ProductTable/ProductCategoryRow/index.tsx b/src/components/FilterableProductTable/ProductTable/ProductCategoryRow/index.tsx new file mode 100644 index 0000000..ae39d00 --- /dev/null +++ b/src/components/FilterableProductTable/ProductTable/ProductCategoryRow/index.tsx @@ -0,0 +1,29 @@ +export default function ProductCategoryRow({ category }: { category: string }) { + return ( +
+
+ + {category} + + + Name + + + Price + + + In Stock + +
+
+ ); +} diff --git a/src/components/FilterableProductTable/ProductTable/ProductRow/index.tsx b/src/components/FilterableProductTable/ProductTable/ProductRow/index.tsx new file mode 100644 index 0000000..b1ddf26 --- /dev/null +++ b/src/components/FilterableProductTable/ProductTable/ProductRow/index.tsx @@ -0,0 +1,30 @@ +import { IProduct } from "../../model"; + +export default function ProductRow({ product }: { product: IProduct }) { + console.log(product); + return ( +
+ + {product.category} + + + {product.name} + + + {product.price} + + + {product.stocked ? "True" : "False"} + +
+ ); +} diff --git a/src/components/FilterableProductTable/ProductTable/index.tsx b/src/components/FilterableProductTable/ProductTable/index.tsx new file mode 100644 index 0000000..9bd55ed --- /dev/null +++ b/src/components/FilterableProductTable/ProductTable/index.tsx @@ -0,0 +1,51 @@ +import { uniq } from "lodash-es"; +import ProductCategoryRow from "./ProductCategoryRow"; +import ProductRow from "./ProductRow"; +import { IProduct } from "../model"; + +interface IProductCategoryRow { + categoryComponent: React.ReactElement; + productComponents: React.ReactElement[]; +} + +export default function ProductTable({ + ProductData, +}: { + ProductData: IProduct[]; +}) { + const categories: string[] = ProductData.map((product) => product.category); + const uniqCategories: string[] = uniq(categories); + + const productsByCategory = new Map(); + + uniqCategories.forEach((category) => { + productsByCategory.set( + category, + ProductData.filter((product) => product.category === category) + ); + }); + + const productCaregoriesComponents: Map = + new Map(); + + const tableRows: JSX.Element[] = []; + + productsByCategory.forEach((value, key) => { + productCaregoriesComponents.set(key, { + categoryComponent: , + productComponents: value.map((product, index) => ( + + )), + }); + tableRows.push(); + tableRows.push( + ...value.map((product, index) => ( + + )) + ); + }); + + console.log("hellooo", Object.fromEntries(productCaregoriesComponents)); + + return
{tableRows}
; +} diff --git a/src/components/FilterableProductTable/SearchBar/index.tsx b/src/components/FilterableProductTable/SearchBar/index.tsx new file mode 100644 index 0000000..ed8fc88 --- /dev/null +++ b/src/components/FilterableProductTable/SearchBar/index.tsx @@ -0,0 +1,57 @@ +import { Button, Checkbox, Input } from "antd"; +import { useState } from "react"; +import type { ButtonProps, CheckboxProps, InputProps } from "antd"; + +export default function SearchTable() { + const [checked, setChecked] = useState(false); + + const [searchVal, setSearchVal] = useState(""); + + const onChange: CheckboxProps["onChange"] = (e) => { + setChecked(e.target.checked); + }; + + const OnSearchClicked: ButtonProps["onClick"] = () => { + console.log(checked); + }; + + const OnSearchInput: InputProps["onInput"] = (e: any) => { + console.log(e.target.value); + setSearchVal(e.target.value); + }; + + return ( +
+
+ + +
+ + Only show products in stock + +
+ ); +} diff --git a/src/components/FilterableProductTable/index.tsx b/src/components/FilterableProductTable/index.tsx new file mode 100644 index 0000000..0b211ec --- /dev/null +++ b/src/components/FilterableProductTable/index.tsx @@ -0,0 +1,25 @@ +import { IProduct } from "./model"; +import ProductTable from "./ProductTable"; +import SearchTable from "./SearchBar"; + +const ProductData: IProduct[] = [ + { category: "Fruits", price: "$1", stocked: true, name: "Apple" }, + { category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit" }, + { category: "Fruits", price: "$2", stocked: false, name: "Passionfruit" }, + { category: "Vegetables", price: "$2", stocked: true, name: "Spinach" }, + { category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin" }, + { category: "Vegetables", price: "$1", stocked: true, name: "Peas" }, +]; + +export default function FilterableProductTable() { + return ( +
+ + +
+ ); +} diff --git a/src/components/FilterableProductTable/model.ts b/src/components/FilterableProductTable/model.ts new file mode 100644 index 0000000..0f72e08 --- /dev/null +++ b/src/components/FilterableProductTable/model.ts @@ -0,0 +1,6 @@ +export interface IProduct { + category: string; + price: string; + stocked: boolean; + name: string; +} diff --git a/src/components/ProfileCard/index.tsx b/src/components/ProfileCard/index.tsx index cc10dbd..9aa91d2 100644 --- a/src/components/ProfileCard/index.tsx +++ b/src/components/ProfileCard/index.tsx @@ -1,5 +1,3 @@ -// import { Card } from "antd"; - const user = { name: "Iron Man", imgSrc: "https://www.shutterstock.com/shutterstock/photos/2061533240/display_1500/stock-photo-mountain-view-california-october-iron-man-cardstock-mask-of-marvel-book-character-2061533240.jpg", diff --git a/src/index.css b/src/index.css index 98556d7..dca8484 100644 --- a/src/index.css +++ b/src/index.css @@ -11,3 +11,8 @@ code { font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; } +/* html, body { + padding: 0; + margin: 0; + background: #000; +} */ diff --git a/tsconfig.json b/tsconfig.json index c0555cb..1696f33 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,8 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "react-jsx" + "jsx": "react-jsx", + "baseUrl": "./" }, "include": ["src"] }