diff --git a/README.md b/README.md
index a77a4f0..3828d71 100644
--- a/README.md
+++ b/README.md
@@ -25,3 +25,4 @@ Run development Server
```bash
yarn start
```
+# keplr-example
diff --git a/package.json b/package.json
index 1aa17e9..7101b26 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"@types/react-dom": "^18.2.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-router-dom": "^6.21.3",
"react-scripts": "5.0.1",
"typescript": "^4.9.5"
},
@@ -42,12 +43,14 @@
"devDependencies": {
"buffer": "^6.0.3",
"crypto-browserify": "^3.12.0",
+ "daisyui": "^4.6.0",
"https-browserify": "^1.0.0",
"os-browserify": "^0.3.0",
"process": "^0.11.10",
"react-app-rewired": "^2.2.1",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
+ "tailwindcss": "^3.4.1",
"ts-proto": "^1.157.0",
"zx": "^7.2.3"
}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..8ff29e0
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,7 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+
+ autoprefixer: {},
+ },
+};
diff --git a/public/fakeData.json b/public/fakeData.json
new file mode 100644
index 0000000..3f7fd96
--- /dev/null
+++ b/public/fakeData.json
@@ -0,0 +1,23 @@
+[
+ {
+ "id": "1",
+ "name": "Widget A",
+ "description": "A high-quality widget with advanced features.",
+ "amount": 15,
+ "price": 29.99
+ },
+ {
+ "id": "2",
+ "name": "Gizmo B",
+ "description": "An innovative gizmo for everyday use.",
+ "amount": 8,
+ "price": 49.99
+ },
+ {
+ "id": "3",
+ "name": "Doohickey C",
+ "description": "The latest doohickey with cutting-edge technology.",
+ "amount": 20,
+ "price": 39.99
+ }
+]
diff --git a/public/index.html b/public/index.html
index 0e4f9c5..ae6d041 100644
--- a/public/index.html
+++ b/public/index.html
@@ -9,6 +9,7 @@
content="Web site created using create-react-app"
/>
Keplr Example App
+
diff --git a/src/App.tsx b/src/App.tsx
index 71d3871..0fce5b4 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,185 +1,9 @@
-import React, {useEffect} from 'react';
-import {getKeplrFromWindow} from "./util/getKeplrFromWindow";
-import {OsmosisChainInfo} from "./constants";
-import {Balances} from "./types/balance";
-import {Dec, DecUtils} from "@keplr-wallet/unit";
-import {sendMsgs} from "./util/sendMsgs";
-import {api} from "./util/api";
-import {simulateMsgs} from "./util/simulateMsgs";
-import {MsgSend} from "./proto-types-gen/src/cosmos/bank/v1beta1/tx";
import "./styles/container.css";
import "./styles/button.css";
import "./styles/item.css";
function App() {
- const [address, setAddress] = React.useState('');
- const [balance, setBalance] = React.useState('');
-
- const [recipient, setRecipient] = React.useState('');
- const [amount, setAmount] = React.useState('');
-
- useEffect(() => {
- init();
- }, []);
-
- const init = async () => {
- const keplr = await getKeplrFromWindow();
-
- if(keplr) {
- try {
- await keplr.experimentalSuggestChain(OsmosisChainInfo);
- } catch (e) {
- if (e instanceof Error) {
- console.log(e.message);
- }
- }
- }
- }
-
- const getKeyFromKeplr = async () => {
- const key = await window.keplr?.getKey(OsmosisChainInfo.chainId);
- if (key) {
- setAddress(key.bech32Address)
- }
- }
-
- const getBalance = async () => {
- const key = await window.keplr?.getKey(OsmosisChainInfo.chainId);
-
- if (key) {
- const uri = `${OsmosisChainInfo.rest}/cosmos/bank/v1beta1/balances/${key.bech32Address}?pagination.limit=1000`;
-
- const data = await api(uri);
- const balance = data.balances.find((balance) => balance.denom === "uosmo");
- const osmoDecimal = OsmosisChainInfo.currencies.find((currency) => currency.coinMinimalDenom === "uosmo")?.coinDecimals;
-
- if(balance) {
- const amount = new Dec(balance.amount, osmoDecimal);
- setBalance(`${amount.toString(osmoDecimal)} OSMO`)
- } else {
- setBalance(`0 OSMO`)
- }
- }
- }
-
- const sendBalance = async () => {
- if (window.keplr) {
- const key = await window.keplr.getKey(OsmosisChainInfo.chainId);
- const protoMsgs = {
- typeUrl: "/cosmos.bank.v1beta1.MsgSend",
- value: MsgSend.encode({
- fromAddress: key.bech32Address,
- toAddress: recipient,
- amount: [
- {
- denom: "uosmo",
- amount: DecUtils.getTenExponentN(6).mul(new Dec(amount)).truncate().toString(),
- },
- ],
- }).finish(),
- }
-
- try {
- const gasUsed = await simulateMsgs(
- OsmosisChainInfo,
- key.bech32Address,
- [protoMsgs],
- [{denom: "uosmo",
- amount: "236",}]
- );
-
- if(gasUsed) {
- await sendMsgs(
- window.keplr,
- OsmosisChainInfo,
- key.bech32Address,
- [protoMsgs],
- {
- amount: [{denom: "uosmo",
- amount: "236",}],
- gas: Math.floor(gasUsed * 1.5).toString(),
- })
- }
- } catch (e) {
- if (e instanceof Error) {
- console.log(e.message);
- }
- }
-
- }
- }
-
-
- return (
-
-
-
-
-
-
-
-
-
-
- Get OSMO Address
-
-
-
-
- Address: {address}
-
-
-
-
-
-
-
-
-
-
- Get OSMO Balance
-
-
-
- Balance: {balance}
-
-
-
-
-
-
-
- Send OSMO
-
-
-
-
- Recipient:
- setRecipient(e.target.value)} />
-
-
-
- Amount:
- setAmount(e.target.value)} />
-
-
-
-
-
-
-
-
- );
+ return ;
}
export default App;
diff --git a/src/components/Details/Details.tsx b/src/components/Details/Details.tsx
new file mode 100644
index 0000000..c765624
--- /dev/null
+++ b/src/components/Details/Details.tsx
@@ -0,0 +1,150 @@
+import React, { useEffect } from "react";
+import { getKeplrFromWindow } from "../../util/getKeplrFromWindow";
+import { OsmosisChainInfo } from "../../constants";
+import { MsgSend } from "../../proto-types-gen/src/cosmos/bank/v1beta1/tx";
+import { Dec, DecUtils } from "@keplr-wallet/unit";
+import { simulateMsgs } from "../../util/simulateMsgs";
+import { sendMsgs } from "../../util/sendMsgs";
+import { IData } from "../../types/ItemType";
+import { useParams } from "react-router-dom";
+import { fakeData } from "../../util/fakeData";
+import ProductQuantityProgressBar from "../Home/ProductQuantityProgressBar";
+
+type DetailsProps = {};
+
+const Details: React.FC = () => {
+ const { id } = useParams();
+ useEffect(() => {
+ init();
+ }, []);
+
+ const init = async () => {
+ const keplr = await getKeplrFromWindow();
+
+ if (keplr) {
+ try {
+ await keplr.experimentalSuggestChain(OsmosisChainInfo);
+ } catch (e) {
+ if (e instanceof Error) {
+ console.log(e.message);
+ }
+ }
+ }
+ };
+
+ const sendBalance = async (amount: string) => {
+ if (window.keplr) {
+ const key = await window.keplr.getKey(OsmosisChainInfo.chainId);
+ const protoMsgs = {
+ typeUrl: "/cosmos.bank.v1beta1.MsgSend",
+ value: MsgSend.encode({
+ fromAddress: key.bech32Address,
+ toAddress: "",
+ amount: [
+ {
+ denom: "uosmo",
+ amount: DecUtils.getTenExponentN(6)
+ .mul(new Dec(amount))
+ .truncate()
+ .toString(),
+ },
+ ],
+ }).finish(),
+ };
+
+ try {
+ const gasUsed = await simulateMsgs(
+ OsmosisChainInfo,
+ key.bech32Address,
+ [protoMsgs],
+ [{ denom: "uosmo", amount }]
+ );
+
+ if (gasUsed) {
+ await sendMsgs(
+ window.keplr,
+ OsmosisChainInfo,
+ key.bech32Address,
+ [protoMsgs],
+ {
+ amount: [{ denom: "uosmo", amount }],
+ gas: Math.floor(gasUsed * 1.5).toString(),
+ }
+ );
+ }
+ } catch (e) {
+ if (e instanceof Error) {
+ console.log(e.message);
+ }
+ }
+ }
+ };
+
+ return (
+
+
+
+ {fakeData
+ .filter((item: IData) => item.id === id)
+ .map((item: IData) => (
+
+
+
+
+
+
+
+
+
{item.name}
+
+
Price {item.price}
+
+
+
+
+
+
+ ))}
+
+
+
+ );
+};
+export default Details;
diff --git a/src/components/Home/AllData.tsx b/src/components/Home/AllData.tsx
new file mode 100644
index 0000000..0c491fe
--- /dev/null
+++ b/src/components/Home/AllData.tsx
@@ -0,0 +1,43 @@
+import React from "react";
+import { Link } from "react-router-dom";
+import { IData } from "../../types/ItemType";
+import { fakeData } from "../../util/fakeData";
+import ProductQuantityProgressBar from "./ProductQuantityProgressBar";
+
+type AllDataProps = {};
+
+const AllData: React.FC = () => {
+ return (
+
+
+ {fakeData.map((item: IData) => (
+
+
+
+
+
{item.name}
+
+
+
Price {item.price}
+
Quantity {item.quantity}
+
+
+
+
+
+
+
+
+ ))}
+
+
+ );
+};
+export default AllData;
diff --git a/src/components/Home/Home.tsx b/src/components/Home/Home.tsx
new file mode 100644
index 0000000..9eb353c
--- /dev/null
+++ b/src/components/Home/Home.tsx
@@ -0,0 +1,123 @@
+import React, { useEffect } from "react";
+import AllData from "./AllData";
+import { OsmosisChainInfo } from "../../constants";
+import { sendMsgs } from "../../util/sendMsgs";
+import { simulateMsgs } from "../../util/simulateMsgs";
+import { Dec, DecUtils } from "@keplr-wallet/unit";
+import { MsgSend } from "../../proto-types-gen/src/cosmos/bank/v1beta1/tx";
+import { api } from "../../util/api";
+import { Balances } from "../../types/balance";
+import { getKeplrFromWindow } from "../../util/getKeplrFromWindow";
+
+type HomeProps = {};
+
+const Home: React.FC = () => {
+ /* const [recipient, setRecipient] = React.useState("");
+ const [amount, setAmount] = React.useState("");
+ useEffect(() => {
+ init();
+ }, []);
+
+ const init = async () => {
+ const keplr = await getKeplrFromWindow();
+
+ if (keplr) {
+ try {
+ await keplr.experimentalSuggestChain(OsmosisChainInfo);
+ } catch (e) {
+ if (e instanceof Error) {
+ console.log(e.message);
+ }
+ }
+ }
+ };
+
+ const sendBalance = async () => {
+ if (window.keplr) {
+ const key = await window.keplr.getKey(OsmosisChainInfo.chainId);
+ const protoMsgs = {
+ typeUrl: "/cosmos.bank.v1beta1.MsgSend",
+ value: MsgSend.encode({
+ fromAddress: key.bech32Address,
+ toAddress: recipient,
+ amount: [
+ {
+ denom: "uosmo",
+ amount: DecUtils.getTenExponentN(6)
+ .mul(new Dec(amount))
+ .truncate()
+ .toString(),
+ },
+ ],
+ }).finish(),
+ };
+
+ try {
+ const gasUsed = await simulateMsgs(
+ OsmosisChainInfo,
+ key.bech32Address,
+ [protoMsgs],
+ [{ denom: "uosmo", amount: "236" }]
+ );
+
+ if (gasUsed) {
+ await sendMsgs(
+ window.keplr,
+ OsmosisChainInfo,
+ key.bech32Address,
+ [protoMsgs],
+ {
+ amount: [{ denom: "uosmo", amount: "236" }],
+ gas: Math.floor(gasUsed * 1.5).toString(),
+ }
+ );
+ }
+ } catch (e) {
+ if (e instanceof Error) {
+ console.log(e.message);
+ }
+ }
+ }
+ }; */
+ return (
+
+ {/*
+
+
Send OSMO
+
+
+
+
+ setRecipient(e.target.value)}
+ />
+
+
+
+ setAmount(e.target.value)}
+ />
+
+
+
+
+
+
*/}
+
+
+ );
+};
+export default Home;
diff --git a/src/components/Home/ProductQuantityProgressBar.tsx b/src/components/Home/ProductQuantityProgressBar.tsx
new file mode 100644
index 0000000..29bed87
--- /dev/null
+++ b/src/components/Home/ProductQuantityProgressBar.tsx
@@ -0,0 +1,41 @@
+import React from "react";
+
+interface ProductQuantityProgressBarProps {
+ currentQuantity: number;
+ maxQuantityPerBlock: number;
+}
+
+const ProductQuantityProgressBar: React.FC = ({
+ currentQuantity,
+ maxQuantityPerBlock,
+}) => {
+ const calculateProgress = (): number => {
+ const progress = (currentQuantity / maxQuantityPerBlock) * 100;
+ return Math.min(progress, 100); // Ensure progress does not exceed 100%
+ };
+
+ return (
+
+
Product Quantity Progress:
+
+
+
+ {currentQuantity}/{maxQuantityPerBlock}
+
+
+
+
+
+ );
+};
+
+export default ProductQuantityProgressBar;
diff --git a/src/components/Layout/Main.tsx b/src/components/Layout/Main.tsx
new file mode 100644
index 0000000..e82d5b9
--- /dev/null
+++ b/src/components/Layout/Main.tsx
@@ -0,0 +1,15 @@
+import React from "react";
+import Nav from "../shared/Nav";
+import { Outlet } from "react-router-dom";
+
+type MainProps = {};
+
+const Main: React.FC = () => {
+ return (
+
+
+
+
+ );
+};
+export default Main;
diff --git a/src/components/shared/Nav.tsx b/src/components/shared/Nav.tsx
new file mode 100644
index 0000000..83f3b43
--- /dev/null
+++ b/src/components/shared/Nav.tsx
@@ -0,0 +1,139 @@
+import React, { useEffect } from "react";
+import { OsmosisChainInfo } from "../../constants";
+import { Balances } from "../../types/balance";
+import { sendMsgs } from "../../util/sendMsgs";
+import { simulateMsgs } from "../../util/simulateMsgs";
+import { Dec, DecUtils } from "@keplr-wallet/unit";
+import { MsgSend } from "../../proto-types-gen/src/cosmos/bank/v1beta1/tx";
+import { api } from "../../util/api";
+import { getKeplrFromWindow } from "../../util/getKeplrFromWindow";
+import { Link } from "react-router-dom";
+
+type NavProps = {};
+
+const Nav: React.FC = () => {
+ const [address, setAddress] = React.useState("");
+ const [balance, setBalance] = React.useState("");
+
+ const [open, setOpen] = React.useState(false);
+ useEffect(() => {
+ init();
+ }, []);
+
+ const init = async () => {
+ const keplr = await getKeplrFromWindow();
+
+ if (keplr) {
+ try {
+ await keplr.experimentalSuggestChain(OsmosisChainInfo);
+ } catch (e) {
+ if (e instanceof Error) {
+ console.log(e.message);
+ }
+ }
+ }
+ };
+
+ const getKeyFromKeplr = async () => {
+ const key = await window.keplr?.getKey(OsmosisChainInfo.chainId);
+ if (key) {
+ setAddress(key.bech32Address);
+ }
+ };
+
+ const getBalance = async () => {
+ const key = await window.keplr?.getKey(OsmosisChainInfo.chainId);
+
+ if (key) {
+ const uri = `${OsmosisChainInfo.rest}/cosmos/bank/v1beta1/balances/${key.bech32Address}?pagination.limit=1000`;
+
+ const data = await api(uri);
+ const balance = data.balances.find(
+ (balance) => balance.denom === "uosmo"
+ );
+ const osmoDecimal = OsmosisChainInfo.currencies.find(
+ (currency) => currency.coinMinimalDenom === "uosmo"
+ )?.coinDecimals;
+
+ if (balance) {
+ const amount = new Dec(balance.amount, osmoDecimal);
+ setBalance(`${amount.toString(osmoDecimal)} OSMO`);
+ } else {
+ setBalance(`0 OSMO`);
+ }
+ }
+ };
+
+ return (
+
+ {/* header start */}
+
+
+
+
+
+
+
+
+
+
+
+ {open && (
+
+
+
+ Get OSMO Address
+
+
+
+
+ Address:
+ {address}
+
+
+
+
+
+
+
+
+
+ Get OSMO Balance
+
+
+
+
+ Balance:{" "}
+ {balance}
+
+
+
+
+
+ )}
+
+ {/* header end */}
+ {/* transfer */}
+
+ );
+};
+export default Nav;
diff --git a/src/index.tsx b/src/index.tsx
index 88e8a31..16a7fa1 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,12 +1,15 @@
-import React from 'react';
-import ReactDOM from 'react-dom/client';
-import App from './App';
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App";
+import "./styles/index.css";
+import { RouterProvider } from "react-router-dom";
+import { router } from "./util/Routes";
const root = ReactDOM.createRoot(
- document.getElementById('root') as HTMLElement
+ document.getElementById("root") as HTMLElement
);
root.render(
-
+
);
diff --git a/src/styles/index.css b/src/styles/index.css
new file mode 100644
index 0000000..969ba50
--- /dev/null
+++ b/src/styles/index.css
@@ -0,0 +1,7 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+body {
+ background: white;
+}
diff --git a/src/styles/item.css b/src/styles/item.css
index 456062f..e7190c5 100644
--- a/src/styles/item.css
+++ b/src/styles/item.css
@@ -1,31 +1,31 @@
.item {
- display: flex;
- flex-direction: column;
- justify-content: center;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
- border: 1px solid #ccc;
- border-radius: 5px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
}
.item-title {
- padding: 12px;
- font-size: 20px;
+ padding: 12px;
+ font-size: 20px;
- background: #F2F2F6;
+ background: #f2f2f6;
}
.item-content {
- display: flex;
- flex-direction: column;
+ display: flex;
+ flex-direction: column;
- gap: 12px;
- padding: 16px;
+ gap: 12px;
+ padding: 16px;
}
input {
- margin: 0;
- border: 1px solid #09090A;
- border-radius: 0.5rem;
+ margin: 0;
+ border: 1px solid #09090a;
+ border-radius: 0.5rem;
- padding: 0.75rem 0.75rem;
+ padding: 0.75rem 0.75rem;
}
diff --git a/src/types/ItemType.ts b/src/types/ItemType.ts
new file mode 100644
index 0000000..ba51014
--- /dev/null
+++ b/src/types/ItemType.ts
@@ -0,0 +1,10 @@
+export type IData = {
+ id: string;
+ name: string;
+ description: string;
+ amount: number;
+ price: number;
+ quantity: number;
+ totalQuantity: number;
+ image: string;
+};
diff --git a/src/util/Routes.tsx b/src/util/Routes.tsx
new file mode 100644
index 0000000..54750c9
--- /dev/null
+++ b/src/util/Routes.tsx
@@ -0,0 +1,22 @@
+import { ReactElement } from "react";
+import { createBrowserRouter } from "react-router-dom";
+import Home from "../components/Home/Home";
+import Main from "../components/Layout/Main";
+import Details from "../components/Details/Details";
+
+export const router = createBrowserRouter([
+ {
+ path: "/",
+ element: () as ReactElement,
+ children: [
+ {
+ path: "/",
+ element: () as ReactElement,
+ },
+ {
+ path: "details/:id",
+ element: ( ) as ReactElement,
+ },
+ ],
+ },
+]);
diff --git a/src/util/fakeData.ts b/src/util/fakeData.ts
new file mode 100644
index 0000000..b5facb0
--- /dev/null
+++ b/src/util/fakeData.ts
@@ -0,0 +1,37 @@
+import { IData } from "../types/ItemType";
+
+export const fakeData: IData[] = [
+ {
+ id: "1",
+ name: "Widget A",
+ description: "A high-quality widget with advanced features.",
+ amount: 15,
+ price: 29.99,
+ quantity: 10,
+ totalQuantity: 15,
+ image:
+ "https://images.unsplash.com/photo-1518546305927-5a555bb7020d?q=80&w=2069&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+ },
+ {
+ id: "2",
+ name: "Gizmo B",
+ description: "An innovative gizmo for everyday use.",
+ amount: 8,
+ price: 49.99,
+ quantity: 20,
+ totalQuantity: 50,
+ image:
+ "https://images.unsplash.com/photo-1518478021985-13055115e310?q=80&w=2069&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+ },
+ {
+ id: "3",
+ name: "Doohickey C",
+ description: "The latest doohickey with cutting-edge technology.",
+ amount: 20,
+ price: 39.99,
+ quantity: 21,
+ totalQuantity: 50,
+ image:
+ "https://images.unsplash.com/photo-1609554496796-c345a5335ceb?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+ },
+];
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..19973dd
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,8 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ["./src/**/*.{html,js}"],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+};
diff --git a/yarn.lock b/yarn.lock
index 32e49ed..ee69710 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1800,6 +1800,11 @@
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
+"@remix-run/router@1.14.2":
+ version "1.14.2"
+ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.14.2.tgz#4d58f59908d9197ba3179310077f25c88e49ed17"
+ integrity sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==
+
"@rollup/plugin-babel@^5.2.0":
version "5.3.1"
resolved "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz"
@@ -3838,6 +3843,14 @@ css-select@^4.1.3:
domutils "^2.8.0"
nth-check "^2.0.1"
+css-selector-tokenizer@^0.8:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz#88267ef6238e64f2215ea2764b3e2cf498b845dd"
+ integrity sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==
+ dependencies:
+ cssesc "^3.0.0"
+ fastparse "^1.1.2"
+
css-tree@1.0.0-alpha.37:
version "1.0.0-alpha.37"
resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz"
@@ -3952,6 +3965,21 @@ csstype@^3.0.2:
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
+culori@^3:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/culori/-/culori-3.3.0.tgz#e33530adbd124d53bd6550394397e695eaaed739"
+ integrity sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==
+
+daisyui@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/daisyui/-/daisyui-4.6.0.tgz#3b2d34ba2995633530b510ebaf9fbc6ed03374c1"
+ integrity sha512-B5ZB/sczXpp4LMdo/SZrtYY/U2hq+Vr9I15QawuWZ0VwgtSAbuZpAZUftKVryEsPuv3BM0yVlBED0nAmtis/dw==
+ dependencies:
+ css-selector-tokenizer "^0.8"
+ culori "^3"
+ picocolors "^1"
+ postcss-js "^4"
+
damerau-levenshtein@^1.0.8:
version "1.0.8"
resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz"
@@ -4855,6 +4883,11 @@ fast-levenshtein@^2.0.6:
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
+fastparse@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
+ integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
+
fastq@^1.6.0:
version "1.15.0"
resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz"
@@ -6427,6 +6460,11 @@ jiti@^1.18.2:
resolved "https://registry.npmjs.org/jiti/-/jiti-1.19.3.tgz"
integrity sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==
+jiti@^1.19.1:
+ version "1.21.0"
+ resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
+ integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
+
js-sha3@0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
@@ -7353,7 +7391,7 @@ picocolors@^0.2.1:
resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz"
integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==
-picocolors@^1.0.0:
+picocolors@^1, picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
@@ -7566,7 +7604,7 @@ postcss-initial@^4.0.1:
resolved "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz"
integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==
-postcss-js@^4.0.1:
+postcss-js@^4, postcss-js@^4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz"
integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
@@ -8225,6 +8263,21 @@ react-refresh@^0.11.0:
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz"
integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==
+react-router-dom@^6.21.3:
+ version "6.21.3"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.21.3.tgz#ef3a7956a3699c7b82c21fcb3dbc63c313ed8c5d"
+ integrity sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==
+ dependencies:
+ "@remix-run/router" "1.14.2"
+ react-router "6.21.3"
+
+react-router@6.21.3:
+ version "6.21.3"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.21.3.tgz#8086cea922c2bfebbb49c6594967418f1f167d70"
+ integrity sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==
+ dependencies:
+ "@remix-run/router" "1.14.2"
+
react-scripts@5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz"
@@ -9195,6 +9248,34 @@ tailwindcss@^3.0.2:
resolve "^1.22.2"
sucrase "^3.32.0"
+tailwindcss@^3.4.1:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.1.tgz#f512ca5d1dd4c9503c7d3d28a968f1ad8f5c839d"
+ integrity sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==
+ dependencies:
+ "@alloc/quick-lru" "^5.2.0"
+ arg "^5.0.2"
+ chokidar "^3.5.3"
+ didyoumean "^1.2.2"
+ dlv "^1.1.3"
+ fast-glob "^3.3.0"
+ glob-parent "^6.0.2"
+ is-glob "^4.0.3"
+ jiti "^1.19.1"
+ lilconfig "^2.1.0"
+ micromatch "^4.0.5"
+ normalize-path "^3.0.0"
+ object-hash "^3.0.0"
+ picocolors "^1.0.0"
+ postcss "^8.4.23"
+ postcss-import "^15.1.0"
+ postcss-js "^4.0.1"
+ postcss-load-config "^4.0.1"
+ postcss-nested "^6.0.1"
+ postcss-selector-parser "^6.0.11"
+ resolve "^1.22.2"
+ sucrase "^3.32.0"
+
tapable@^1.0.0:
version "1.1.3"
resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz"