diff --git a/assets/js/react/components/Button.tsx b/assets/js/react/components/Button.tsx
new file mode 100644
index 0000000..8305dde
--- /dev/null
+++ b/assets/js/react/components/Button.tsx
@@ -0,0 +1,30 @@
+import * as React from "react"
+import clsx from "clsx"
+import { Button as BaseButton, ButtonProps } from "@mui/base/Button"
+
+export const Button = React.forwardRef<
+ HTMLButtonElement,
+ ButtonProps & { invert?: boolean; href?: string }
+>(function Button(props, ref) {
+ const { invert, className, href, ...other } = props
+
+ const button = (
+
+ )
+
+ if (href === undefined) {
+ return button
+ }
+
+ return {button}
+})
diff --git a/assets/js/react/components/CaptionImage.tsx b/assets/js/react/components/CaptionImage.tsx
new file mode 100644
index 0000000..e0b6fe7
--- /dev/null
+++ b/assets/js/react/components/CaptionImage.tsx
@@ -0,0 +1,27 @@
+import * as React from "react"
+
+interface CaptionImageProps {
+ title?: string
+ subtitle?: string
+ src: string
+}
+
+export function CaptionImage({ title, subtitle, src }: CaptionImageProps) {
+ return (
+
+
+
+ {title && (
+
+ {title}
+
+ )}
+ {subtitle &&
{subtitle}
}
+
+
+ )
+}
diff --git a/assets/js/react/components/FadeIn.tsx b/assets/js/react/components/FadeIn.tsx
new file mode 100644
index 0000000..6f4c68f
--- /dev/null
+++ b/assets/js/react/components/FadeIn.tsx
@@ -0,0 +1,43 @@
+import * as React from "react"
+import { motion, useReducedMotion } from "framer-motion"
+
+const FadeInStaggerContext = React.createContext(false)
+
+const viewport = { once: true, margin: "0px 0px -200px" }
+
+export function FadeIn({ ...props }) {
+ let shouldReduceMotion = useReducedMotion()
+ let isInStaggerGroup = React.useContext(FadeInStaggerContext)
+
+ return (
+
+ )
+}
+
+export function FadeInStagger({ faster = false, ...props }) {
+ return (
+
+
+
+ )
+}
diff --git a/assets/js/react/components/FallbackMessage.tsx b/assets/js/react/components/FallbackMessage.tsx
new file mode 100644
index 0000000..518ec39
--- /dev/null
+++ b/assets/js/react/components/FallbackMessage.tsx
@@ -0,0 +1,28 @@
+import * as React from "react"
+import clsx from "clsx"
+
+import { FadeIn } from "./FadeIn"
+
+export type FallbackMessageProps = React.ComponentPropsWithoutRef<"div"> & {
+ title: string
+ body: string
+}
+
+export const FallbackMessage = React.forwardRef(function FallbackMessage(
+ props: FallbackMessageProps,
+ ref: React.ForwardedRef
+) {
+ const { title, body, className, ...other } = props
+ return (
+
+
+ {title}
+
+ {body}
+
+ )
+})
diff --git a/assets/js/react/components/FilterScroll.tsx b/assets/js/react/components/FilterScroll.tsx
new file mode 100644
index 0000000..b79c544
--- /dev/null
+++ b/assets/js/react/components/FilterScroll.tsx
@@ -0,0 +1,118 @@
+import * as React from "react"
+import clsx from "clsx"
+
+import type { Query } from "../types/Query"
+
+import FilterIcon from "../icons/Filter"
+import RightArrowIcon from "../icons/RightArrow"
+import RisingGraphIcon from "../icons/RisingGraph"
+import { Button } from "./Button"
+
+interface FilterOption {
+ title: string
+ Icon: ({ ...props }: { [x: string]: any }) => React.JSX.Element
+ enable: (q: Query) => Query
+ isEnabled: (q: Query) => boolean
+}
+
+const filters: FilterOption[] = [
+ {
+ title: "FIDE 2000+",
+ Icon: RisingGraphIcon,
+ enable: (q) => {
+ q.fideRating[0] = Math.max(2000, q.fideRating[0])
+ return q
+ },
+ isEnabled: (q) => q.fideRating[0] >= 2000,
+ },
+]
+
+enum Direction {
+ LEFT,
+ RIGHT,
+}
+
+interface FilterScrollProps {
+ query: Query
+ onModal: () => void
+ onEnable: (q: Query) => void
+}
+
+export function FilterScroll({ query, onModal, onEnable }: FilterScrollProps) {
+ const viewport = React.useRef(null)
+ const [isFlush, setIsFlush] = React.useState([true, false])
+
+ const scrollDir = (dir: Direction) => {
+ const v = viewport.current
+ if (!v) {
+ return
+ }
+ const delta = v.clientWidth / 2
+ const left = v.scrollLeft + (dir == Direction.RIGHT ? delta : -delta)
+ v.scroll({ left, behavior: "smooth" })
+
+ const isFlushLeft = left <= 1
+ const isFlushRight = left + v.clientWidth >= v.scrollWidth
+ setIsFlush([isFlushLeft, isFlushRight])
+ }
+
+ return (
+
+
+
+ {[...filters].map((e) => (
+
onEnable(e.enable({ ...query }))}
+ >
+
+ {e.title}
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/assets/js/react/components/Loading.tsx b/assets/js/react/components/Loading.tsx
new file mode 100644
index 0000000..b6cfa23
--- /dev/null
+++ b/assets/js/react/components/Loading.tsx
@@ -0,0 +1,27 @@
+import * as React from "react"
+
+import LogoMark from "../icons/LogoMark"
+
+function Fallback() {
+ return (
+
+
+ Loading...
+
+ )
+}
+
+type LoadingProps = React.ComponentPropsWithoutRef<"div"> & {
+ loading: boolean
+}
+
+export const Loading = React.forwardRef(
+ function Loading(props, ref) {
+ const { loading, children, ...other } = props
+ return (
+
+ {loading ? : children}
+
+ )
+ }
+)
diff --git a/assets/js/react/components/Logo.tsx b/assets/js/react/components/Logo.tsx
index 2fb76fc..41c0533 100644
--- a/assets/js/react/components/Logo.tsx
+++ b/assets/js/react/components/Logo.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
import clsx from "clsx"
-import LogoMark from "../icons/Logomark"
+import LogoMark from "../icons/LogoMark"
export function Logo({
invert = false,
diff --git a/assets/js/react/icons/Filter.tsx b/assets/js/react/icons/Filter.tsx
new file mode 100644
index 0000000..32478ae
--- /dev/null
+++ b/assets/js/react/icons/Filter.tsx
@@ -0,0 +1,14 @@
+import * as React from "react"
+
+const SvgComponent = ({ ...props }) => (
+
+)
+
+export default SvgComponent
diff --git a/assets/js/react/icons/Logomark.tsx b/assets/js/react/icons/LogoMark.tsx
similarity index 100%
rename from assets/js/react/icons/Logomark.tsx
rename to assets/js/react/icons/LogoMark.tsx
diff --git a/assets/js/react/icons/RightArrow.tsx b/assets/js/react/icons/RightArrow.tsx
new file mode 100644
index 0000000..a3dd5fd
--- /dev/null
+++ b/assets/js/react/icons/RightArrow.tsx
@@ -0,0 +1,19 @@
+import * as React from "react"
+
+const SvgComponent = ({ ...props }) => (
+
+)
+
+export default SvgComponent
diff --git a/assets/js/react/icons/RisingGraph.tsx b/assets/js/react/icons/RisingGraph.tsx
new file mode 100644
index 0000000..6101fce
--- /dev/null
+++ b/assets/js/react/icons/RisingGraph.tsx
@@ -0,0 +1,15 @@
+import * as React from "react"
+
+const SvgComponent = ({ ...props }) => (
+
+)
+
+export default SvgComponent
diff --git a/assets/js/react/pages/Search.tsx b/assets/js/react/pages/Search.tsx
new file mode 100644
index 0000000..5efee9b
--- /dev/null
+++ b/assets/js/react/pages/Search.tsx
@@ -0,0 +1,63 @@
+import * as React from "react"
+
+import type { Query } from "../types/Query"
+
+import { CaptionImage } from "../components/CaptionImage"
+import { Container } from "../components/Container"
+import { FadeIn, FadeInStagger } from "../components/FadeIn"
+import { FallbackMessage } from "../components/FallbackMessage"
+import { FilterScroll } from "../components/FilterScroll"
+import { Loading } from "../components/Loading"
+
+const FIDE_RATING_MIN = 1500
+const FIDE_RATING_MAX = 3200
+
+interface Coach {
+ id: string
+ imageUrl: string
+ name: string
+ title: string
+ slug: string
+}
+
+const defaultQuery: Query = {
+ fideRating: [FIDE_RATING_MIN, FIDE_RATING_MAX],
+}
+
+export function Search() {
+ const [query, setQuery] = React.useState(defaultQuery)
+ const [loading, setLoading] = React.useState(true)
+ const [coaches, setCoaches] = React.useState([])
+
+ return (
+
+ {}} />
+
+ {coaches.length > 0 ? (
+
+ {coaches.map((coach, index) => (
+
+
+
+ ))}
+
+ ) : (
+
+ )}
+
+
+ )
+}
diff --git a/assets/js/react/router.tsx b/assets/js/react/router.tsx
index 50cfea6..7ac7b9d 100644
--- a/assets/js/react/router.tsx
+++ b/assets/js/react/router.tsx
@@ -1,9 +1,11 @@
import * as React from "react"
import { createBrowserRouter } from "react-router-dom"
+import { Search } from "./pages/Search"
+
export const router = createBrowserRouter([
{
path: "/",
- element: ,
+ element: ,
},
])
diff --git a/assets/js/react/types/Query.ts b/assets/js/react/types/Query.ts
new file mode 100644
index 0000000..0dcb14a
--- /dev/null
+++ b/assets/js/react/types/Query.ts
@@ -0,0 +1,3 @@
+export type Query = {
+ fideRating: [number, number]
+}
diff --git a/assets/package-lock.json b/assets/package-lock.json
index 6945322..0153a92 100644
--- a/assets/package-lock.json
+++ b/assets/package-lock.json
@@ -8,6 +8,7 @@
"name": "boardwise",
"version": "0.1.0",
"dependencies": {
+ "@mui/base": "^5.0.0-beta.25",
"clsx": "^2.0.0",
"framer-motion": "^10.16.12",
"react": "^18.2.0",
@@ -43,6 +44,17 @@
"node_modules/.pnpm/scheduler@0.23.0": {
"extraneous": true
},
+ "node_modules/@babel/runtime": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz",
+ "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
@@ -58,6 +70,120 @@
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
},
+ "node_modules/@floating-ui/core": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.1.tgz",
+ "integrity": "sha512-QgcKYwzcc8vvZ4n/5uklchy8KVdjJwcOeI+HnnTNclJjs2nYsy23DOCf+sSV1kBwD9yDAoVKCkv/gEPzgQU3Pw==",
+ "dependencies": {
+ "@floating-ui/utils": "^0.1.3"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz",
+ "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==",
+ "dependencies": {
+ "@floating-ui/core": "^1.4.2",
+ "@floating-ui/utils": "^0.1.3"
+ }
+ },
+ "node_modules/@floating-ui/react-dom": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz",
+ "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==",
+ "dependencies": {
+ "@floating-ui/dom": "^1.5.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
+ "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
+ },
+ "node_modules/@mui/base": {
+ "version": "5.0.0-beta.25",
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.25.tgz",
+ "integrity": "sha512-Iiv+IcappRRv6IBlknIVmLkXxfp51NEX1+l9f+dIbBuPU4PaRULegr1lCeHKsC45KU5ruxM5xMg4R/de03aJQg==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.4",
+ "@floating-ui/react-dom": "^2.0.4",
+ "@mui/types": "^7.2.10",
+ "@mui/utils": "^5.14.19",
+ "@popperjs/core": "^2.11.8",
+ "clsx": "^2.0.0",
+ "prop-types": "^15.8.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui-org"
+ },
+ "peerDependencies": {
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/types": {
+ "version": "7.2.10",
+ "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.10.tgz",
+ "integrity": "sha512-wX1vbDC+lzF7FlhT6A3ffRZgEoKWPF8VqRoTu4lZwouFX2t90KyCMsgepMw5DxLak1BSp/KP86CmtZttikb/gQ==",
+ "peerDependencies": {
+ "@types/react": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/utils": {
+ "version": "5.14.19",
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.19.tgz",
+ "integrity": "sha512-qAHvTXzk7basbyqPvhgWqN6JbmI2wLB/mf97GkSlz5c76MiKYV6Ffjvw9BjKZQ1YRb8rDX9kgdjRezOcoB91oQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.4",
+ "@types/prop-types": "^15.7.11",
+ "prop-types": "^15.8.1",
+ "react-is": "^18.2.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui-org"
+ },
+ "peerDependencies": {
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@remix-run/router": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.1.tgz",
@@ -75,14 +201,13 @@
"node_modules/@types/prop-types": {
"version": "15.7.11",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
- "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==",
- "dev": true
+ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
},
"node_modules/@types/react": {
"version": "18.2.40",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.40.tgz",
"integrity": "sha512-H+BUhb9C1zBtogDLAk+KCNRKiHDrqSwQT/0z0PVTwMFBxqg3011ByLomADtgkgMkfwj4AMOiXBReyLTUBg681g==",
- "dev": true,
+ "devOptional": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@@ -123,7 +248,7 @@
"version": "0.16.8",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
- "dev": true
+ "devOptional": true
},
"node_modules/clsx": {
"version": "2.0.0",
@@ -137,7 +262,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
- "dev": true
+ "devOptional": true
},
"node_modules/framer-motion": {
"version": "10.16.12",
@@ -178,6 +303,29 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/prop-types/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
"node_modules/react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
@@ -201,6 +349,11 @@
"react": "^18.2.0"
}
},
+ "node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ },
"node_modules/react-router": {
"version": "6.20.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.1.tgz",
@@ -231,6 +384,11 @@
"react-dom": ">=16.8"
}
},
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+ },
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@@ -246,6 +404,14 @@
}
},
"dependencies": {
+ "@babel/runtime": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz",
+ "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==",
+ "requires": {
+ "regenerator-runtime": "^0.14.0"
+ }
+ },
"@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
@@ -261,6 +427,72 @@
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
},
+ "@floating-ui/core": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.1.tgz",
+ "integrity": "sha512-QgcKYwzcc8vvZ4n/5uklchy8KVdjJwcOeI+HnnTNclJjs2nYsy23DOCf+sSV1kBwD9yDAoVKCkv/gEPzgQU3Pw==",
+ "requires": {
+ "@floating-ui/utils": "^0.1.3"
+ }
+ },
+ "@floating-ui/dom": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz",
+ "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==",
+ "requires": {
+ "@floating-ui/core": "^1.4.2",
+ "@floating-ui/utils": "^0.1.3"
+ }
+ },
+ "@floating-ui/react-dom": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz",
+ "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==",
+ "requires": {
+ "@floating-ui/dom": "^1.5.1"
+ }
+ },
+ "@floating-ui/utils": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
+ "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
+ },
+ "@mui/base": {
+ "version": "5.0.0-beta.25",
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.25.tgz",
+ "integrity": "sha512-Iiv+IcappRRv6IBlknIVmLkXxfp51NEX1+l9f+dIbBuPU4PaRULegr1lCeHKsC45KU5ruxM5xMg4R/de03aJQg==",
+ "requires": {
+ "@babel/runtime": "^7.23.4",
+ "@floating-ui/react-dom": "^2.0.4",
+ "@mui/types": "^7.2.10",
+ "@mui/utils": "^5.14.19",
+ "@popperjs/core": "^2.11.8",
+ "clsx": "^2.0.0",
+ "prop-types": "^15.8.1"
+ }
+ },
+ "@mui/types": {
+ "version": "7.2.10",
+ "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.10.tgz",
+ "integrity": "sha512-wX1vbDC+lzF7FlhT6A3ffRZgEoKWPF8VqRoTu4lZwouFX2t90KyCMsgepMw5DxLak1BSp/KP86CmtZttikb/gQ==",
+ "requires": {}
+ },
+ "@mui/utils": {
+ "version": "5.14.19",
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.19.tgz",
+ "integrity": "sha512-qAHvTXzk7basbyqPvhgWqN6JbmI2wLB/mf97GkSlz5c76MiKYV6Ffjvw9BjKZQ1YRb8rDX9kgdjRezOcoB91oQ==",
+ "requires": {
+ "@babel/runtime": "^7.23.4",
+ "@types/prop-types": "^15.7.11",
+ "prop-types": "^15.8.1",
+ "react-is": "^18.2.0"
+ }
+ },
+ "@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
+ },
"@remix-run/router": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.1.tgz",
@@ -275,14 +507,13 @@
"@types/prop-types": {
"version": "15.7.11",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
- "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==",
- "dev": true
+ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
},
"@types/react": {
"version": "18.2.40",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.40.tgz",
"integrity": "sha512-H+BUhb9C1zBtogDLAk+KCNRKiHDrqSwQT/0z0PVTwMFBxqg3011ByLomADtgkgMkfwj4AMOiXBReyLTUBg681g==",
- "dev": true,
+ "devOptional": true,
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@@ -323,7 +554,7 @@
"version": "0.16.8",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
- "dev": true
+ "devOptional": true
},
"clsx": {
"version": "2.0.0",
@@ -334,7 +565,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
- "dev": true
+ "devOptional": true
},
"framer-motion": {
"version": "10.16.12",
@@ -358,6 +589,28 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+ },
+ "prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ }
+ }
+ },
"react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
@@ -375,6 +628,11 @@
"scheduler": "^0.23.0"
}
},
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ },
"react-router": {
"version": "6.20.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.1.tgz",
@@ -392,6 +650,11 @@
"react-router": "6.20.1"
}
},
+ "regenerator-runtime": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+ },
"scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
diff --git a/assets/package.json b/assets/package.json
index e1b2d69..140081e 100644
--- a/assets/package.json
+++ b/assets/package.json
@@ -2,6 +2,7 @@
"name": "boardwise",
"version": "0.1.0",
"dependencies": {
+ "@mui/base": "^5.0.0-beta.25",
"clsx": "^2.0.0",
"framer-motion": "^10.16.12",
"react": "^18.2.0",