diff --git a/client/.env b/client/.env new file mode 100644 index 0000000..84ead9b --- /dev/null +++ b/client/.env @@ -0,0 +1,4 @@ +VITE_VARIABLE_BACKEND=http://localhost:8000 +VITE_VARIABLE_IPFS=http://localhost:8001 +VITE_VARIABLE_ID_STORE=654074c904cf9f8ebc076631 +VITE_VARIABLE_PORT=8002 diff --git a/client/package-lock.json b/client/package-lock.json index 1ae119e..affb8de 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,7 +9,10 @@ "version": "0.0.0", "license": "MIT", "dependencies": { + "@solid-primitives/graphql": "^2.0.1", "@solidjs/router": "^0.8.2", + "@urql/core": "^4.2.0", + "@urql/exchange-retry": "^1.2.0", "aos": "^2.3.4", "axios": "^1.4.0", "babel-preset-solid": "^1.7.4", @@ -28,6 +31,19 @@ "vite-plugin-solid": "^2.5.0" } }, + "node_modules/@0no-co/graphql.web": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.4.tgz", + "integrity": "sha512-W3ezhHGfO0MS1PtGloaTpg0PbaT8aZSmmaerL7idtU5F7oCI+uu25k+MsMS31BVFlp4aMkHSrNRxiD72IlK8TA==", + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "graphql": { + "optional": true + } + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -936,6 +952,15 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "peer": true, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -1055,6 +1080,27 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@solid-primitives/graphql": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@solid-primitives/graphql/-/graphql-2.0.1.tgz", + "integrity": "sha512-wrSnZQFmM+rv233h07XRKZmJEtvabTzKGxa7UIKudyA7mZNIctVRc0cZdcqHvzkOCHLGrlLuYn5qlfTwehrPVg==", + "dependencies": { + "@solid-primitives/utils": "^6.2.1" + }, + "peerDependencies": { + "@graphql-typed-document-node/core": "^3.2.0", + "graphql": "^16.6.0", + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/utils": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.1.tgz", + "integrity": "sha512-TsecNzxiO5bLfzqb4OOuzfUmdOROcssuGqgh5rXMMaasoFZ3GoveUgdY1wcf17frMJM7kCNGNuK34EjErneZkg==", + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, "node_modules/@solidjs/router": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/@solidjs/router/-/router-0.8.2.tgz", @@ -1115,6 +1161,24 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@urql/core": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@urql/core/-/core-4.2.0.tgz", + "integrity": "sha512-GRkZ4kECR9UohWAjiSk2UYUetco6/PqSrvyC4AH6g16tyqEShA63M232cfbE1J9XJPaGNjia14Gi+oOqzp144w==", + "dependencies": { + "@0no-co/graphql.web": "^1.0.1", + "wonka": "^6.3.2" + } + }, + "node_modules/@urql/exchange-retry": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-1.2.0.tgz", + "integrity": "sha512-1O/biKiVhhn0EtvDF4UOvz325K4RrLupfL8rHcmqD2TBLv4qVDWQuzx4JGa1FfqjjRb+C9TNZ6w19f32Mq85Ug==", + "dependencies": { + "@urql/core": ">=4.0.0", + "wonka": "^6.3.2" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -3207,6 +3271,15 @@ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, + "node_modules/graphql": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -5742,6 +5815,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wonka": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz", + "integrity": "sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg==" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/client/package.json b/client/package.json index 6a0ad66..a6160b3 100644 --- a/client/package.json +++ b/client/package.json @@ -20,7 +20,10 @@ "vite-plugin-solid": "^2.5.0" }, "dependencies": { + "@solid-primitives/graphql": "^2.0.1", "@solidjs/router": "^0.8.2", + "@urql/core": "^4.2.0", + "@urql/exchange-retry": "^1.2.0", "aos": "^2.3.4", "axios": "^1.4.0", "babel-preset-solid": "^1.7.4", diff --git a/client/src/App.tsx b/client/src/App.tsx index 43ad42c..16694e0 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -22,7 +22,7 @@ import Reset from "./pages/reset"; const App: Component = () => { const location = useLocation(); return ( -
+
{location.pathname !== "/login" && location.pathname !== "/register" && location.pathname !== "/reset" && } diff --git a/client/src/components/cards/Cards.tsx b/client/src/components/cards/Cards.tsx index a198ba0..3d754dd 100644 --- a/client/src/components/cards/Cards.tsx +++ b/client/src/components/cards/Cards.tsx @@ -2,21 +2,10 @@ import { Component, Show } from "solid-js"; import { useCartContext } from "../../context/CartContext"; import { useNavigate } from "@solidjs/router"; -export type Product = { - id: string; - name: string; - image: string; - rating: number; - brand: string; - price: number; - category: string; - quantity: number; -}; - -const Cards: Component<{ product: Product }> = (props) => { +const Cards: Component<{ product: ProductType }> = (props) => { const { cartItems, addToCart } = useCartContext(); const navigate = useNavigate(); - const handleAddTocart = (product: Product) => { + const handleAddTocart = (product: ProductType) => { addToCart(product); }; const isInCart = () => { @@ -66,7 +55,9 @@ const Cards: Component<{ product: Product }> = (props) => {
product image
@@ -123,12 +114,12 @@ const Cards: Component<{ product: Product }> = (props) => {
- {props?.product?.name} + {props?.product?.title}
35 ? "mt-1" : "mt-7" + props?.product?.title?.length > 35 ? "mt-1" : "mt-7" }`} > diff --git a/client/src/components/layouts/Navbar.tsx b/client/src/components/layouts/Navbar.tsx index 76ecc91..f42ff24 100644 --- a/client/src/components/layouts/Navbar.tsx +++ b/client/src/components/layouts/Navbar.tsx @@ -1,7 +1,8 @@ -import { Component } from "solid-js"; +import { Component, createResource } from "solid-js"; import { A } from "@solidjs/router"; import { useCartContext } from "../../context/CartContext"; import NavActive from "./NavActive"; +import { read } from "../../utils/theme"; export type Nav = { title: string; @@ -12,13 +13,15 @@ export type Nav = { const Navbar: Component<{}> = () => { const { cartItems } = useCartContext(); - + const logo = read("logo"); + const name = read("name"); + return (
@@ -218,7 +226,7 @@ export const MainProducts: Component<{}> = () => {

Show More

- +
diff --git a/client/src/types/product.ts b/client/src/types/product.ts new file mode 100644 index 0000000..c9b3a4d --- /dev/null +++ b/client/src/types/product.ts @@ -0,0 +1,10 @@ +type ProductType = { + id: string; + title: string; + thumbnail: string; + rating: number; + brand: string; + price: number; + category: string; + quantity: number; +}; diff --git a/client/src/utils/theme.ts b/client/src/utils/theme.ts new file mode 100644 index 0000000..ec2f8a8 --- /dev/null +++ b/client/src/utils/theme.ts @@ -0,0 +1,12 @@ +import { createResource } from "solid-js"; +import { readTheme } from "../../theme"; + +const theme = async (name: string) => { + const theme = await readTheme(); + return theme(name); +}; + +export const read = (name: string) => { + const [data] = createResource(name, theme); + return data; +}; diff --git a/client/tailwind.config.js b/client/tailwind.config.js index 5d12b0c..6b6d5c3 100644 --- a/client/tailwind.config.js +++ b/client/tailwind.config.js @@ -1,18 +1,10 @@ +import themes from './themes/theme.json'; + module.exports = { content: ["./src/**/*.{js,jsx,ts,tsx}", "./node_modules/flowbite/**/*.js"], theme: { colors: { - primary: "#3674B7", - danger: "#de1414", - secondary: "#E11D48", - accent: "#1dcdbc", - neutral: "#2b3440", - "base-100": "#F5F5F5", - "base-200": "#fff", - info: "#3abff8", - success: "#36d399", - warning: "#fbbd23", - error: "#f87272", + ...themes.color }, screens: { sm: "640px", diff --git a/client/theme.ts b/client/theme.ts new file mode 100644 index 0000000..b617119 --- /dev/null +++ b/client/theme.ts @@ -0,0 +1,24 @@ +// export const names = ["store-123"] as const; +// export type ValidName = (typeof names)[number]; + +export const readTheme = async () => { + let theme_json = (await import(`./themes/store-${import.meta.env.VITE_VARIABLE_ID_STORE}.json`).then( + (module) => module.default + )) as any; + + + return (key: string, params?: { [key: string]: string | number }) => { + let theme = key + .split(".") + .reduce((obj, key) => obj && obj[key], theme_json); + if (!theme) { + return key; + } + if (params && Object.entries(params).length) { + Object.entries(params).forEach(([key, value]) => { + theme = theme!.replace(`{{ ${key} }}`, String(value)); + }); + } + return theme; + }; +}; diff --git a/client/themes/store-654074c904cf9f8ebc076631.json b/client/themes/store-654074c904cf9f8ebc076631.json new file mode 100644 index 0000000..ee71fe9 --- /dev/null +++ b/client/themes/store-654074c904cf9f8ebc076631.json @@ -0,0 +1,4 @@ +{ + "name": "CAM TECH", + "logo": "https://www.shutterstock.com/image-vector/pepsi-logo-on-white-background-260nw-2304484783.jpg" +} diff --git a/client/themes/theme.json b/client/themes/theme.json new file mode 100644 index 0000000..9e4535c --- /dev/null +++ b/client/themes/theme.json @@ -0,0 +1,18 @@ +{ + "color": { + "primary": "#3674B7", + "danger": "#de1414", + "secondary": "#E11D48", + "accent": "#1dcdbc", + "neutral": "#2b3440", + "base-100": "#27F24C", + "base-200": "#fff", + "info": "#3abff8", + "success": "#36d399", + "warning": "#fbbd23", + "error": "#f87272" + }, + "background": { + "hero-pattern": "url('https://img.freepik.com/free-photo/painting-mountain-lake-with-mountain-background_188544-9126.jpg?size=626&ext=jpg&ga=GA1.1.34264412.1699315200&semt=sph')" + } +} diff --git a/client/tsconfig.json b/client/tsconfig.json index a867f40..a4513e0 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -6,6 +6,7 @@ "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true, + "resolveJsonModule": true, "jsx": "preserve", "jsxImportSource": "solid-js", "types": ["vite/client"], diff --git a/client/vite.config.ts b/client/vite.config.ts index a0ae3be..30fd1e0 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -4,7 +4,7 @@ import solidPlugin from "vite-plugin-solid"; export default defineConfig({ plugins: [solidPlugin()], server: { - port: 8000, + port: import.meta.env.VITE_VARIABLE_PORT, }, build: { target: "esnext",