Add settings UI page (#171)
* Add theme colors from Figma * Rough-in of AppHeader * Add styled ActionButton * Add react-router and placeholder Settings page * Add ability to set persistent defaultDir * Add react-hot-toast for save success message * Add defaultProjectName setting * Handle case of stale empty defaultDir in storage * Wrap app in BrowserRouter * Wrap test App in BrowserRouter * Don't need BrowserRouter outside of testing because we use RouterProvider
This commit is contained in:
@ -4,6 +4,9 @@
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@codemirror/lang-javascript": "^6.1.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"@headlessui/react": "^1.7.13",
|
||||
"@tauri-apps/api": "^1.3.0",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
@ -19,8 +22,10 @@
|
||||
"http-server": "^14.1.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"react-json-view": "^1.21.3",
|
||||
"react-modal-promise": "^1.0.2",
|
||||
"react-router-dom": "^6.14.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"sketch-helpers": "^0.0.3",
|
||||
"swr": "^2.0.4",
|
||||
|
37
public/kitt-8bit-winking.svg
Normal file
37
public/kitt-8bit-winking.svg
Normal file
@ -0,0 +1,37 @@
|
||||
<svg width="25" height="34" viewBox="0 0 25 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 31V30H1V29H0V8H1V7H2V6H3V5H4V4H21V5H22V6H23V7H24V8H25V29H24V30H22V31H19V32H20V34H14V32H15V31H10V32H11V34H5V32H6V31H3Z" fill="#101412"/>
|
||||
<path d="M6 31V29.5H10V31H9V32H10V33H6V32H7V31H6Z" fill="#4B4862"/>
|
||||
<path d="M15 31V29.5H19V31H18V32H19V33H15V32H16V31H15Z" fill="#4B4862"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 24.5V29H3V30H22V29H24V24.5H1ZM9 29V27H16V29H9Z" fill="#9BADB7"/>
|
||||
<path d="M1 25V23H24V25H1Z" fill="#BECAD0"/>
|
||||
<path d="M2 27V26H7V27H2Z" fill="#2B3E48"/>
|
||||
<path d="M4 29V28H7V29H4Z" fill="#2B3E48"/>
|
||||
<path d="M18 27V26H19V27H18Z" fill="#2B3E48"/>
|
||||
<path d="M20 27V26H21V27H20Z" fill="#2B3E48"/>
|
||||
<path d="M22 27V26H23V27H22Z" fill="#2B3E48"/>
|
||||
<path d="M18 29V28H21V29H18Z" fill="#2B3E48"/>
|
||||
<path d="M22 7V6H21V5H4V6H3V7H2V8H1V10H24V8H23V7H22Z" fill="#FBF580"/>
|
||||
<path d="M1 24V22H24V24H1Z" fill="#AEAA4C"/>
|
||||
<path d="M24 9H1V23H24V9Z" fill="#E5E3A1"/>
|
||||
<path d="M4 12V11H21V12H22V20H21V21H4V20H3V12H4Z" fill="#1F2320"/>
|
||||
<rect x="10" y="5" width="5" height="2" fill="#AEAA4C"/>
|
||||
<path d="M16 13V12H18V16H17L16 13Z" fill="#DBFF3C"/>
|
||||
<path d="M11 16H14V17H13V19H16V18H17V19H16V20H9V19H8V18H9V19H12V17H11V16Z" fill="#DBFF3C"/>
|
||||
<path d="M9 15V14H6V15H5V14H6V13H9V14H10V15H9Z" fill="#DBFF3C"/>
|
||||
<path d="M4 7V6H5V4H6V2H7V1H8V2H9V4H10V6H11V7H4Z" fill="#DBFF3C"/>
|
||||
<path d="M21 6V7H14V6H15V4H16V2H17V1H18V2H19V4H20V6H21Z" fill="#DBFF3C"/>
|
||||
<path d="M16 2V0H19V2H20V4H21V5.5H20V4H19V2H18V1H17V2H16V4H15V5.5H14V4H15V2H16Z" fill="#92C51B"/>
|
||||
<path d="M6 2V0H9V2H10V4H11V5.5H10V4H9V2H8V1H7V2H6V4H5V5.5H4V4H5V2H6Z" fill="#92C51B"/>
|
||||
<rect x="11" y="6" width="3" height="1" fill="#D0CC6A"/>
|
||||
<path d="M16 7V6H17V5H18V6H19V7H16Z" fill="#76AA1D"/>
|
||||
<path d="M7 6V5H8V6H9V7H6V6H7Z" fill="#76AA1D"/>
|
||||
<path d="M21 7V6H20V5H21V6H22V7H21Z" fill="#76AA1D"/>
|
||||
<path d="M4 6V7H3V6H4V5H5V6H4Z" fill="#76AA1D"/>
|
||||
<path d="M10 5H11V6H12V7H11V6H10V5Z" fill="#76AA1D"/>
|
||||
<path d="M14 5H15V6H14V7H13V6H14V5Z" fill="#76AA1D"/>
|
||||
<path d="M17 13H16V16H17V13Z" fill="#92C51B"/>
|
||||
<path d="M2 25V23H1V25H2Z" fill="#D0CC6A"/>
|
||||
<path d="M23 25V23H24V25H23Z" fill="#D0CC6A"/>
|
||||
<path d="M4 24V23H7V24H4Z" fill="#D56161"/>
|
||||
<path d="M4 25V24H7V25H4Z" fill="#AC3232"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
18
public/kitt-arcade-winking.svg
Normal file
18
public/kitt-arcade-winking.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<svg width="25" height="34" viewBox="0 0 25 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 31V30H1V29H0V8H1V7H2V6H3V5H4V3H5V2H6V1H7V0H8V1H9V2H10V3H11V4H14V3H15V2H16V1H17V0H18V1H19V2H20V3H21V5H22V6H23V7H24V8H25V29H24V30H22V31H19V32H20V34H14V32H15V31H10V32H11V34H5V32H6V31H3Z" fill="#101412"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 5H14V4H15V3H16V2H17V1H18V2H19V3H20V5H21V6H22V7H23V8H24V9V10V23V24V25V29H22V30H18V31V32H19V33H15V32H16V31V30H9V31V32H10V33H6V32H7V31V30H3V29H1V25V24V23V10V9V8H2V7H3V6H4V5H5V3H6V2H7V1H8V2H9V3H10V4H11V5ZM2 26V27H7V26H2ZM4 28V29H7V28H4ZM18 27V26H19V27H18ZM20 26V27H21V26H20ZM22 27V26H23V27H22ZM18 28V29H21V28H18ZM9 27H16V29H9V27Z" fill="#D0FF00"/>
|
||||
<path d="M1 24V23H24V24H1Z" fill="#B1E515"/>
|
||||
<path d="M4 12V11H21V12H22V20H21V21H4V20H3V12H4Z" fill="#1F2320"/>
|
||||
<path d="M16 16V12H18V16H16Z" fill="#D0FF00"/>
|
||||
<path d="M11 16H14V17H13V19H16V18H17V19H16V20H9V19H8V18H9V19H12V17H11V16Z" fill="#D0FF00"/>
|
||||
<path d="M9 15V14H6V15H5V14H6V13H9V14H10V15H9Z" fill="#D0FF00"/>
|
||||
<path d="M22 8V7H23V8H22Z" fill="#B1E515"/>
|
||||
<path d="M3 8V7H2V8H3Z" fill="#B1E515"/>
|
||||
<path d="M21 7V6H22V7H21Z" fill="#92C51B"/>
|
||||
<path d="M4 7V6H3V7H4Z" fill="#92C51B"/>
|
||||
<rect x="12" y="5" width="1" height="2" fill="#B1E515"/>
|
||||
<path d="M16 7V6H17V5H18V6H19V7H16Z" fill="#101412"/>
|
||||
<path d="M7 6V5H8V6H9V7H6V6H7Z" fill="#101412"/>
|
||||
<path d="M4 24V23H7V24H4Z" fill="#92C51B"/>
|
||||
<rect x="11" y="5" width="3" height="1" fill="#92C51B"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
@ -1,5 +1,6 @@
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import { App } from './App'
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
|
||||
let listener: ((rect: any) => void) | undefined = undefined
|
||||
;(global as any).ResizeObserver = class ResizeObserver {
|
||||
@ -12,7 +13,9 @@ let listener: ((rect: any) => void) | undefined = undefined
|
||||
}
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />)
|
||||
render(<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>)
|
||||
const linkElement = screen.getByText(/Variables/i)
|
||||
expect(linkElement).toBeInTheDocument()
|
||||
})
|
||||
|
@ -21,6 +21,7 @@ import ModalContainer from 'react-modal-promise'
|
||||
import { EngineCommandManager } from './lang/std/engineConnection'
|
||||
import { isOverlap } from './lib/utils'
|
||||
import { SetToken } from './components/TokenInput'
|
||||
import { AppHeader } from './components/AppHeader'
|
||||
|
||||
export function App() {
|
||||
const cam = useRef()
|
||||
@ -253,6 +254,7 @@ export function App() {
|
||||
}, [code, isStreamReady])
|
||||
return (
|
||||
<div className="h-screen">
|
||||
<AppHeader />
|
||||
<ModalContainer />
|
||||
<Allotment snap={true}>
|
||||
|
||||
@ -285,9 +287,6 @@ export function App() {
|
||||
<Logs />
|
||||
</Allotment>
|
||||
<Allotment vertical defaultSizes={[40, 400]} minSize={20}>
|
||||
<div>
|
||||
<Toolbar />
|
||||
</div>
|
||||
<Stream />
|
||||
</Allotment>
|
||||
</Allotment>
|
||||
|
20
src/Auth.tsx
20
src/Auth.tsx
@ -4,6 +4,24 @@ import withBaseUrl from './lib/withBaseURL'
|
||||
import { App } from './App'
|
||||
import { SetToken } from './components/TokenInput'
|
||||
import { useStore } from './useStore'
|
||||
import {
|
||||
createBrowserRouter,
|
||||
RouterProvider,
|
||||
} from "react-router-dom"
|
||||
import { ErrorPage } from './components/ErrorPage'
|
||||
import { Settings } from './routes/Settings'
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: "/",
|
||||
element: <App />,
|
||||
errorElement: <ErrorPage />,
|
||||
},
|
||||
{
|
||||
path: "/settings",
|
||||
element: <Settings />,
|
||||
}
|
||||
])
|
||||
|
||||
export const Auth = () => {
|
||||
const { data: user } = useSWR(withBaseUrl('/user'), fetcher) as any
|
||||
@ -37,5 +55,5 @@ export const Auth = () => {
|
||||
)
|
||||
}
|
||||
|
||||
return <App />
|
||||
return <RouterProvider router={router} />
|
||||
}
|
||||
|
263
src/colors.css
Normal file
263
src/colors.css
Normal file
@ -0,0 +1,263 @@
|
||||
:root {
|
||||
/*
|
||||
Generated using Catmosphere Theme Builder
|
||||
by KittyCAD
|
||||
https://catmosphere-theme-builder.vercel.app/?colors=%5B%7B%22from%22:%7B%22l%22:1,%22c%22:0.01,%22h%22:78%7D,%22to%22:%7B%22l%22:0.065,%22c%22:0.05,%22h%22:182.6%7D,%22stops%22:10,%22steps%22:12%7D,%7B%22from%22:%7B%22l%22:1,%22c%22:0.45,%22h%22:122.4%7D,%22to%22:%7B%22l%22:0.13,%22c%22:0.031,%22h%22:137.2%7D,%22stops%22:10,%22steps%22:12%7D,%7B%22from%22:%7B%22l%22:1,%22c%22:0.13,%22h%22:176%7D,%22to%22:%7B%22l%22:0.116,%22c%22:0.097,%22h%22:213.1%7D,%22stops%22:10,%22steps%22:12%7D,%7B%22from%22:%7B%22l%22:1,%22c%22:0.169,%22h%22:144.4%7D,%22to%22:%7B%22l%22:0.12,%22c%22:0.45,%22h%22:132.7%7D,%22steps%22:12%7D,%7B%22from%22:%7B%22l%22:1,%22c%22:0.087,%22h%22:261.6%7D,%22to%22:%7B%22l%22:0.22,%22c%22:0.084,%22h%22:275.5%7D,%22steps%22:12,%22uuid%22:%227tpx9pf1zd6%22%7D,%7B%22from%22:%7B%22l%22:0.954,%22c%22:0.108,%22h%22:280.6%7D,%22to%22:%7B%22l%22:0.166,%22c%22:0.188,%22h%22:263.8%7D,%22steps%22:12,%22uuid%22:%22vu652mebd3%22%7D,%7B%22from%22:%7B%22l%22:1,%22c%22:0.115,%22h%22:0%7D,%22to%22:%7B%22l%22:0.096,%22c%22:0.261,%22h%22:302%7D,%22steps%22:12%7D,%7B%22from%22:%7B%22l%22:1,%22c%22:0.185,%22h%22:19.8%7D,%22to%22:%7B%22l%22:0.368,%22c%22:0.45,%22h%22:9.4%7D,%22steps%22:8,%22uuid%22:%22g05inkd34l%22%7D,%7B%22from%22:%7B%22l%22:0.912,%22c%22:0.139,%22h%22:87%7D,%22to%22:%7B%22l%22:0.502,%22c%22:0.45,%22h%22:97.7%7D,%22steps%22:8,%22uuid%22:%22l892hcw4ef%22%7D,%7B%22from%22:%7B%22l%22:0.89,%22c%22:0.16,%22h%22:143.4%7D,%22to%22:%7B%22l%22:0.466,%22c%22:0.208,%22h%22:147.7%7D,%22steps%22:8,%22uuid%22:%22hkd09y9ov4h%22%7D%5D
|
||||
*/
|
||||
/* Chalkboard */
|
||||
--chalkboard-10: oklch(99.70% 0.008766 102.8deg);
|
||||
--chalkboard-20: oklch(91.34% 0.009353 109.0deg);
|
||||
--chalkboard-30: oklch(82.99% 0.009940 115.2deg);
|
||||
--chalkboard-40: oklch(74.63% 0.01053 121.4deg);
|
||||
--chalkboard-50: oklch(66.27% 0.01111 127.6deg);
|
||||
--chalkboard-60: oklch(57.92% 0.01170 133.9deg);
|
||||
--chalkboard-70: oklch(49.56% 0.01229 140.1deg);
|
||||
--chalkboard-80: oklch(41.21% 0.01288 146.3deg);
|
||||
--chalkboard-90: oklch(32.85% 0.01346 152.5deg);
|
||||
--chalkboard-100: oklch(24.49% 0.01405 158.7deg);
|
||||
--chalkboard-110: oklch(16.14% 0.01464 164.9deg);
|
||||
--chalkboard-120: oklch(7.783% 0.01522 171.1deg);
|
||||
|
||||
/* Energy */
|
||||
--energy-10: oklch(93.31% 0.2270 122.3deg);
|
||||
--energy-20: oklch(86.01% 0.2092 123.6deg);
|
||||
--energy-30: oklch(78.71% 0.1914 125.0deg);
|
||||
--energy-40: oklch(71.41% 0.1736 126.3deg);
|
||||
--energy-50: oklch(64.10% 0.1557 127.7deg);
|
||||
--energy-60: oklch(56.80% 0.1379 129.1deg);
|
||||
--energy-70: oklch(49.50% 0.1201 130.4deg);
|
||||
--energy-80: oklch(42.20% 0.1023 131.8deg);
|
||||
--energy-90: oklch(34.90% 0.08446 133.1deg);
|
||||
--energy-100: oklch(27.60% 0.06664 134.5deg);
|
||||
--energy-110: oklch(20.30% 0.04882 135.8deg);
|
||||
--energy-120: oklch(13.00% 0.03100 137.2deg);
|
||||
|
||||
/* Liquid */
|
||||
--liquid-10: oklch(93.45% 0.1002 193.1deg);
|
||||
--liquid-20: oklch(86.21% 0.09511 198.7deg);
|
||||
--liquid-30: oklch(78.97% 0.09003 204.2deg);
|
||||
--liquid-40: oklch(71.74% 0.08495 209.8deg);
|
||||
--liquid-50: oklch(64.50% 0.07988 215.3deg);
|
||||
--liquid-60: oklch(57.26% 0.07480 220.9deg);
|
||||
--liquid-70: oklch(50.03% 0.06972 226.4deg);
|
||||
--liquid-80: oklch(42.79% 0.06465 232.0deg);
|
||||
--liquid-90: oklch(35.56% 0.05957 237.5deg);
|
||||
--liquid-100: oklch(28.32% 0.05450 243.1deg);
|
||||
--liquid-110: oklch(21.08% 0.04942 248.6deg);
|
||||
--liquid-120: oklch(13.85% 0.04434 254.2deg);
|
||||
|
||||
/* Fern */
|
||||
--fern-10: oklch(93.22% 0.1243 144.8deg);
|
||||
--fern-20: oklch(86.59% 0.1193 144.6deg);
|
||||
--fern-30: oklch(79.97% 0.1143 144.4deg);
|
||||
--fern-40: oklch(73.34% 0.1093 144.2deg);
|
||||
--fern-50: oklch(66.71% 0.1043 144.0deg);
|
||||
--fern-60: oklch(60.09% 0.09927 143.8deg);
|
||||
--fern-70: oklch(53.46% 0.09425 143.6deg);
|
||||
--fern-80: oklch(46.83% 0.08924 143.3deg);
|
||||
--fern-90: oklch(40.21% 0.08422 143.1deg);
|
||||
--fern-100: oklch(33.58% 0.07920 142.9deg);
|
||||
--fern-110: oklch(26.95% 0.07419 142.7deg);
|
||||
--fern-120: oklch(20.33% 0.06917 142.5deg);
|
||||
|
||||
/* Cool */
|
||||
--cool-10: oklch(97.71% 0.03321 196.6deg);
|
||||
--cool-20: oklch(90.82% 0.03783 203.8deg);
|
||||
--cool-30: oklch(83.94% 0.04245 211.0deg);
|
||||
--cool-40: oklch(77.06% 0.04706 218.1deg);
|
||||
--cool-50: oklch(70.18% 0.05168 225.3deg);
|
||||
--cool-60: oklch(63.29% 0.05630 232.5deg);
|
||||
--cool-70: oklch(56.41% 0.06091 239.6deg);
|
||||
--cool-80: oklch(49.53% 0.06553 246.8deg);
|
||||
--cool-90: oklch(42.65% 0.07015 254.0deg);
|
||||
--cool-100: oklch(35.76% 0.07477 261.2deg);
|
||||
--cool-110: oklch(28.88% 0.07938 268.3deg);
|
||||
--cool-120: oklch(22.00% 0.08400 275.5deg);
|
||||
|
||||
/* River */
|
||||
--river-10: oklch(93.35% 0.03169 273.4deg);
|
||||
--river-20: oklch(86.91% 0.04221 273.1deg);
|
||||
--river-30: oklch(80.46% 0.05274 272.7deg);
|
||||
--river-40: oklch(74.01% 0.06326 272.4deg);
|
||||
--river-50: oklch(67.57% 0.07378 272.0deg);
|
||||
--river-60: oklch(61.12% 0.08430 271.7deg);
|
||||
--river-70: oklch(54.67% 0.09483 271.4deg);
|
||||
--river-80: oklch(48.22% 0.1053 271.0deg);
|
||||
--river-90: oklch(41.78% 0.1159 270.7deg);
|
||||
--river-100: oklch(35.33% 0.1264 270.4deg);
|
||||
--river-110: oklch(28.88% 0.1369 270.0deg);
|
||||
--river-120: oklch(22.44% 0.1474 269.7deg);
|
||||
|
||||
/* Berry */
|
||||
--berry-10: oklch(93.77% 0.05212 329.0deg);
|
||||
--berry-20: oklch(87.30% 0.05912 325.3deg);
|
||||
--berry-30: oklch(80.82% 0.06612 321.6deg);
|
||||
--berry-40: oklch(74.34% 0.07313 317.8deg);
|
||||
--berry-50: oklch(67.86% 0.08013 314.1deg);
|
||||
--berry-60: oklch(61.39% 0.08713 310.3deg);
|
||||
--berry-70: oklch(54.91% 0.09413 306.6deg);
|
||||
--berry-80: oklch(48.43% 0.1011 302.8deg);
|
||||
--berry-90: oklch(41.95% 0.1081 299.1deg);
|
||||
--berry-100: oklch(35.47% 0.1151 295.4deg);
|
||||
--berry-110: oklch(29.00% 0.1221 291.6deg);
|
||||
--berry-120: oklch(22.52% 0.1291 287.9deg);
|
||||
|
||||
/* Destroy */
|
||||
--destroy-10: oklch(88.21% 0.06281 14.85deg);
|
||||
--destroy-20: oklch(83.23% 0.08511 16.91deg);
|
||||
--destroy-30: oklch(78.25% 0.1074 18.96deg);
|
||||
--destroy-40: oklch(73.27% 0.1297 21.01deg);
|
||||
--destroy-50: oklch(68.29% 0.1520 23.07deg);
|
||||
--destroy-60: oklch(63.31% 0.1743 25.12deg);
|
||||
--destroy-70: oklch(58.33% 0.1966 27.18deg);
|
||||
--destroy-80: oklch(53.35% 0.2189 29.23deg);
|
||||
|
||||
/* Warn */
|
||||
--warn-10: oklch(90.19% 0.1361 92.00deg);
|
||||
--warn-20: oklch(84.60% 0.1388 84.84deg);
|
||||
--warn-30: oklch(79.01% 0.1414 77.68deg);
|
||||
--warn-40: oklch(73.42% 0.1440 70.52deg);
|
||||
--warn-50: oklch(67.83% 0.1466 63.36deg);
|
||||
--warn-60: oklch(62.24% 0.1492 56.20deg);
|
||||
--warn-70: oklch(56.65% 0.1518 49.04deg);
|
||||
--warn-80: oklch(51.06% 0.1544 41.88deg);
|
||||
|
||||
/* Succeed */
|
||||
--succeed-10: oklch(89.00% 0.1600 143.4deg);
|
||||
--succeed-20: oklch(83.23% 0.1608 143.3deg);
|
||||
--succeed-30: oklch(77.46% 0.1616 143.1deg);
|
||||
--succeed-40: oklch(71.69% 0.1623 143.0deg);
|
||||
--succeed-50: oklch(65.92% 0.1631 142.9deg);
|
||||
--succeed-60: oklch(60.16% 0.1639 142.8deg);
|
||||
--succeed-70: oklch(54.39% 0.1647 142.6deg);
|
||||
--succeed-80: oklch(48.62% 0.1654 142.5deg);
|
||||
|
||||
/* Base values for use with Tailwind. */
|
||||
/* Chalkboard */
|
||||
--_chalkboard-10: 99.70% 0.008766 102.8deg;
|
||||
--_chalkboard-20: 91.34% 0.009353 109.0deg;
|
||||
--_chalkboard-30: 82.99% 0.009940 115.2deg;
|
||||
--_chalkboard-40: 74.63% 0.01053 121.4deg;
|
||||
--_chalkboard-50: 66.27% 0.01111 127.6deg;
|
||||
--_chalkboard-60: 57.92% 0.01170 133.9deg;
|
||||
--_chalkboard-70: 49.56% 0.01229 140.1deg;
|
||||
--_chalkboard-80: 41.21% 0.01288 146.3deg;
|
||||
--_chalkboard-90: 32.85% 0.01346 152.5deg;
|
||||
--_chalkboard-100: 24.49% 0.01405 158.7deg;
|
||||
--_chalkboard-110: 16.14% 0.01464 164.9deg;
|
||||
--_chalkboard-120: 7.783% 0.01522 171.1deg;
|
||||
|
||||
/* Energy */
|
||||
--_energy-10: 93.31% 0.2270 122.3deg;
|
||||
--_energy-20: 86.01% 0.2092 123.6deg;
|
||||
--_energy-30: 78.71% 0.1914 125.0deg;
|
||||
--_energy-40: 71.41% 0.1736 126.3deg;
|
||||
--_energy-50: 64.10% 0.1557 127.7deg;
|
||||
--_energy-60: 56.80% 0.1379 129.1deg;
|
||||
--_energy-70: 49.50% 0.1201 130.4deg;
|
||||
--_energy-80: 42.20% 0.1023 131.8deg;
|
||||
--_energy-90: 34.90% 0.08446 133.1deg;
|
||||
--_energy-100: 27.60% 0.06664 134.5deg;
|
||||
--_energy-110: 20.30% 0.04882 135.8deg;
|
||||
--_energy-120: 13.00% 0.03100 137.2deg;
|
||||
|
||||
/* Liquid */
|
||||
--_liquid-10: 93.45% 0.1002 193.1deg;
|
||||
--_liquid-20: 86.21% 0.09511 198.7deg;
|
||||
--_liquid-30: 78.97% 0.09003 204.2deg;
|
||||
--_liquid-40: 71.74% 0.08495 209.8deg;
|
||||
--_liquid-50: 64.50% 0.07988 215.3deg;
|
||||
--_liquid-60: 57.26% 0.07480 220.9deg;
|
||||
--_liquid-70: 50.03% 0.06972 226.4deg;
|
||||
--_liquid-80: 42.79% 0.06465 232.0deg;
|
||||
--_liquid-90: 35.56% 0.05957 237.5deg;
|
||||
--_liquid-100: 28.32% 0.05450 243.1deg;
|
||||
--_liquid-110: 21.08% 0.04942 248.6deg;
|
||||
--_liquid-120: 13.85% 0.04434 254.2deg;
|
||||
|
||||
/* Fern */
|
||||
--_fern-10: 93.22% 0.1243 144.8deg;
|
||||
--_fern-20: 86.59% 0.1193 144.6deg;
|
||||
--_fern-30: 79.97% 0.1143 144.4deg;
|
||||
--_fern-40: 73.34% 0.1093 144.2deg;
|
||||
--_fern-50: 66.71% 0.1043 144.0deg;
|
||||
--_fern-60: 60.09% 0.09927 143.8deg;
|
||||
--_fern-70: 53.46% 0.09425 143.6deg;
|
||||
--_fern-80: 46.83% 0.08924 143.3deg;
|
||||
--_fern-90: 40.21% 0.08422 143.1deg;
|
||||
--_fern-100: 33.58% 0.07920 142.9deg;
|
||||
--_fern-110: 26.95% 0.07419 142.7deg;
|
||||
--_fern-120: 20.33% 0.06917 142.5deg;
|
||||
|
||||
/* Cool */
|
||||
--_cool-10: 97.71% 0.03321 196.6deg;
|
||||
--_cool-20: 90.82% 0.03783 203.8deg;
|
||||
--_cool-30: 83.94% 0.04245 211.0deg;
|
||||
--_cool-40: 77.06% 0.04706 218.1deg;
|
||||
--_cool-50: 70.18% 0.05168 225.3deg;
|
||||
--_cool-60: 63.29% 0.05630 232.5deg;
|
||||
--_cool-70: 56.41% 0.06091 239.6deg;
|
||||
--_cool-80: 49.53% 0.06553 246.8deg;
|
||||
--_cool-90: 42.65% 0.07015 254.0deg;
|
||||
--_cool-100: 35.76% 0.07477 261.2deg;
|
||||
--_cool-110: 28.88% 0.07938 268.3deg;
|
||||
--_cool-120: 22.00% 0.08400 275.5deg;
|
||||
|
||||
/* River */
|
||||
--_river-10: 93.35% 0.03169 273.4deg;
|
||||
--_river-20: 86.91% 0.04221 273.1deg;
|
||||
--_river-30: 80.46% 0.05274 272.7deg;
|
||||
--_river-40: 74.01% 0.06326 272.4deg;
|
||||
--_river-50: 67.57% 0.07378 272.0deg;
|
||||
--_river-60: 61.12% 0.08430 271.7deg;
|
||||
--_river-70: 54.67% 0.09483 271.4deg;
|
||||
--_river-80: 48.22% 0.1053 271.0deg;
|
||||
--_river-90: 41.78% 0.1159 270.7deg;
|
||||
--_river-100: 35.33% 0.1264 270.4deg;
|
||||
--_river-110: 28.88% 0.1369 270.0deg;
|
||||
--_river-120: 22.44% 0.1474 269.7deg;
|
||||
|
||||
/* Berry */
|
||||
--_berry-10: 93.77% 0.05212 329.0deg;
|
||||
--_berry-20: 87.30% 0.05912 325.3deg;
|
||||
--_berry-30: 80.82% 0.06612 321.6deg;
|
||||
--_berry-40: 74.34% 0.07313 317.8deg;
|
||||
--_berry-50: 67.86% 0.08013 314.1deg;
|
||||
--_berry-60: 61.39% 0.08713 310.3deg;
|
||||
--_berry-70: 54.91% 0.09413 306.6deg;
|
||||
--_berry-80: 48.43% 0.1011 302.8deg;
|
||||
--_berry-90: 41.95% 0.1081 299.1deg;
|
||||
--_berry-100: 35.47% 0.1151 295.4deg;
|
||||
--_berry-110: 29.00% 0.1221 291.6deg;
|
||||
--_berry-120: 22.52% 0.1291 287.9deg;
|
||||
|
||||
/* Destroy */
|
||||
--_destroy-10: 88.21% 0.06281 14.85deg;
|
||||
--_destroy-20: 83.23% 0.08511 16.91deg;
|
||||
--_destroy-30: 78.25% 0.1074 18.96deg;
|
||||
--_destroy-40: 73.27% 0.1297 21.01deg;
|
||||
--_destroy-50: 68.29% 0.1520 23.07deg;
|
||||
--_destroy-60: 63.31% 0.1743 25.12deg;
|
||||
--_destroy-70: 58.33% 0.1966 27.18deg;
|
||||
--_destroy-80: 53.35% 0.2189 29.23deg;
|
||||
|
||||
/* Warn */
|
||||
--_warn-10: 90.19% 0.1361 92.00deg;
|
||||
--_warn-20: 84.60% 0.1388 84.84deg;
|
||||
--_warn-30: 79.01% 0.1414 77.68deg;
|
||||
--_warn-40: 73.42% 0.1440 70.52deg;
|
||||
--_warn-50: 67.83% 0.1466 63.36deg;
|
||||
--_warn-60: 62.24% 0.1492 56.20deg;
|
||||
--_warn-70: 56.65% 0.1518 49.04deg;
|
||||
--_warn-80: 51.06% 0.1544 41.88deg;
|
||||
|
||||
/* Succeed */
|
||||
--_succeed-10: 89.00% 0.1600 143.4deg;
|
||||
--_succeed-20: 83.23% 0.1608 143.3deg;
|
||||
--_succeed-30: 77.46% 0.1616 143.1deg;
|
||||
--_succeed-40: 71.69% 0.1623 143.0deg;
|
||||
--_succeed-50: 65.92% 0.1631 142.9deg;
|
||||
--_succeed-60: 60.16% 0.1639 142.8deg;
|
||||
--_succeed-70: 54.39% 0.1647 142.6deg;
|
||||
--_succeed-80: 48.62% 0.1654 142.5deg;
|
||||
}
|
35
src/components/ActionButton.tsx
Normal file
35
src/components/ActionButton.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import { Link } from 'react-router-dom'
|
||||
import { ActionIcon, ActionIconProps } from './ActionIcon'
|
||||
|
||||
interface ActionButtonProps extends React.PropsWithChildren {
|
||||
icon?: ActionIconProps
|
||||
className?: string
|
||||
onClick?: () => void
|
||||
to?: string
|
||||
as?: 'button' | 'link'
|
||||
}
|
||||
|
||||
export const ActionButton = ({
|
||||
icon,
|
||||
className,
|
||||
onClick,
|
||||
to = '/',
|
||||
as = 'button',
|
||||
children,
|
||||
}: ActionButtonProps) => {
|
||||
const classNames = `group mono flex items-center gap-2 text-chalkboard-110 rounded-sm border border-chalkboard-40 hover:border-liquid-40 p-[3px] ${
|
||||
icon ? 'pr-2' : 'px-2'
|
||||
} ${className}`
|
||||
|
||||
return as === 'button' ? (
|
||||
<button onClick={onClick} className={classNames}>
|
||||
{icon && <ActionIcon {...icon} />}
|
||||
{children}
|
||||
</button>
|
||||
) : (
|
||||
<Link to={to} className={classNames}>
|
||||
{icon && <ActionIcon {...icon} />}
|
||||
{children}
|
||||
</Link>
|
||||
)
|
||||
}
|
48
src/components/ActionIcon.tsx
Normal file
48
src/components/ActionIcon.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
import {
|
||||
IconDefinition,
|
||||
faCircleExclamation,
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
|
||||
const iconSizes = {
|
||||
sm: 12,
|
||||
md: 14.4,
|
||||
lg: 18,
|
||||
}
|
||||
|
||||
export interface ActionIconProps extends React.PropsWithChildren {
|
||||
icon?: IconDefinition
|
||||
bgClassName?: string
|
||||
iconClassName?: string
|
||||
size?: keyof typeof iconSizes
|
||||
}
|
||||
|
||||
export const ActionIcon = ({
|
||||
icon,
|
||||
bgClassName,
|
||||
iconClassName,
|
||||
size = 'md',
|
||||
children,
|
||||
}: ActionIconProps) => {
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
'p-1 w-fit inline-grid place-content-center ' +
|
||||
(bgClassName ||
|
||||
'bg-chalkboard-100 group-hover:bg-chalkboard-90 hover:bg-chalkboard-90')
|
||||
}
|
||||
>
|
||||
{children || (
|
||||
<FontAwesomeIcon
|
||||
icon={icon || faCircleExclamation}
|
||||
width={iconSizes[size]}
|
||||
height={iconSizes[size]}
|
||||
className={
|
||||
iconClassName ||
|
||||
'text-liquid-20 group-hover:text-liquid-10 hover:text-liquid-10'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
37
src/components/AppHeader.tsx
Normal file
37
src/components/AppHeader.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import { faGear } from '@fortawesome/free-solid-svg-icons'
|
||||
import { Toolbar } from '../Toolbar'
|
||||
import { ActionButton } from './ActionButton'
|
||||
|
||||
interface AppHeaderProps extends React.PropsWithChildren {
|
||||
showToolbar?: boolean
|
||||
}
|
||||
|
||||
export const AppHeader = ({ showToolbar = true, children }: AppHeaderProps) => {
|
||||
return (
|
||||
<header className="py-1 px-5 bg-chalkboard-10 border-b border-chalkboard-30 flex justify-between items-center">
|
||||
<a href="/project-settings">
|
||||
<img
|
||||
src="/kitt-arcade-winking.svg"
|
||||
alt="KittyCAD App"
|
||||
className="h-9 w-auto"
|
||||
/>
|
||||
<span className="sr-only">KittyCAD App</span>
|
||||
</a>
|
||||
{/* Toolbar if the context deems it */}
|
||||
{showToolbar && (
|
||||
<div className="max-w-4xl">
|
||||
<Toolbar />
|
||||
</div>
|
||||
)}
|
||||
{/* If there are children, show them, otherwise... */}
|
||||
{children || (
|
||||
// TODO: If signed out, show the token paste field
|
||||
|
||||
// If signed in, show the account avatar
|
||||
<ActionButton as="link" icon={{ icon: faGear }} to="/settings">
|
||||
Settings
|
||||
</ActionButton>
|
||||
)}
|
||||
</header>
|
||||
)
|
||||
}
|
8
src/components/ErrorPage.tsx
Normal file
8
src/components/ErrorPage.tsx
Normal file
@ -0,0 +1,8 @@
|
||||
export const ErrorPage = () => {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center h-screen">
|
||||
<h1 className="text-4xl font-bold">404</h1>
|
||||
<p className="text-2xl font-bold">Page not found</p>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
@tailwind utilities;
|
||||
|
||||
@import '../node_modules/allotment/dist/style.css';
|
||||
@import './colors.css';
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
@ -13,6 +14,11 @@ body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.mono {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
|
@ -2,11 +2,13 @@ import ReactDOM from 'react-dom/client'
|
||||
import './index.css'
|
||||
import { Auth } from './Auth'
|
||||
import reportWebVitals from './reportWebVitals'
|
||||
import { Toaster } from 'react-hot-toast'
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
|
||||
root.render(
|
||||
root.render(<>
|
||||
<Auth />
|
||||
)
|
||||
<Toaster position='bottom-center' />
|
||||
</>)
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
|
143
src/routes/Settings.tsx
Normal file
143
src/routes/Settings.tsx
Normal file
@ -0,0 +1,143 @@
|
||||
import { faCheck, faFolder, faXmark } from '@fortawesome/free-solid-svg-icons'
|
||||
import { ActionButton } from '../components/ActionButton'
|
||||
import { AppHeader } from '../components/AppHeader'
|
||||
import { open } from '@tauri-apps/api/dialog'
|
||||
import { useStore } from '../useStore'
|
||||
import { useState } from 'react'
|
||||
import { toast } from 'react-hot-toast'
|
||||
|
||||
export const Settings = () => {
|
||||
const {
|
||||
defaultDir: originalDefaultDir,
|
||||
setDefaultDir: saveDefaultDir,
|
||||
defaultProjectName: originalDefaultProjectName,
|
||||
setDefaultProjectName: saveDefaultProjectName,
|
||||
} = useStore((s) => ({
|
||||
defaultDir: s.defaultDir,
|
||||
setDefaultDir: s.setDefaultDir,
|
||||
defaultProjectName: s.defaultProjectName,
|
||||
setDefaultProjectName: s.setDefaultProjectName,
|
||||
}))
|
||||
const [defaultDir, setDefaultDir] = useState(originalDefaultDir)
|
||||
const [defaultProjectName, setDefaultProjectName] = useState(
|
||||
originalDefaultProjectName
|
||||
)
|
||||
|
||||
async function handleDirectorySelection() {
|
||||
const newDirectory = await open({
|
||||
directory: true,
|
||||
defaultPath: (defaultDir.base || '') + (defaultDir.dir || '/'),
|
||||
title: 'Choose a new default directory',
|
||||
})
|
||||
|
||||
if (newDirectory && newDirectory !== null && !Array.isArray(newDirectory)) {
|
||||
setDefaultDir({ base: defaultDir.base, dir: newDirectory })
|
||||
}
|
||||
}
|
||||
|
||||
const handleSaveClick = () => {
|
||||
saveDefaultDir(defaultDir)
|
||||
saveDefaultProjectName(defaultProjectName)
|
||||
toast.success('Settings saved!')
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<AppHeader showToolbar={false}>
|
||||
<ActionButton
|
||||
as="link"
|
||||
to="/"
|
||||
icon={{
|
||||
icon: faXmark,
|
||||
bgClassName: 'bg-destroy-80',
|
||||
iconClassName:
|
||||
'text-destroy-20 group-hover:text-destroy-10 hover:text-destroy-10',
|
||||
}}
|
||||
className="hover:border-destroy-40"
|
||||
>
|
||||
Close
|
||||
</ActionButton>
|
||||
</AppHeader>
|
||||
<div className="mt-24 max-w-5xl mx-auto">
|
||||
<h1 className="text-4xl font-bold">User Settings</h1>
|
||||
{(window as any).__TAURI__ && (
|
||||
<SettingsSection
|
||||
title="Default Directory"
|
||||
description="Where newly-created projects are saved on your local computer"
|
||||
>
|
||||
<div className="w-full flex gap-4 p-1 rounded border border-chalkboard-30">
|
||||
<input
|
||||
className="flex-1 px-2 bg-transparent"
|
||||
value={defaultDir.dir}
|
||||
onChange={(e) =>
|
||||
setDefaultDir({
|
||||
base: originalDefaultDir.base,
|
||||
dir: e.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<ActionButton
|
||||
as="button"
|
||||
className="bg-chalkboard-100 hover:bg-chalkboard-90 text-chalkboard-10 border-chalkboard-100 hover:border-chalkboard-70"
|
||||
onClick={handleDirectorySelection}
|
||||
icon={{
|
||||
icon: faFolder,
|
||||
bgClassName:
|
||||
'bg-liquid-20 group-hover:bg-liquid-10 hover:bg-liquid-10',
|
||||
iconClassName:
|
||||
'text-liquid-90 group-hover:text-liquid-90 hover:text-liquid-90',
|
||||
}}
|
||||
>
|
||||
Choose a folder
|
||||
</ActionButton>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
)}
|
||||
<SettingsSection
|
||||
title="Default Project Name"
|
||||
description="Name template for new projects. Use $n to include an incrementing index"
|
||||
>
|
||||
<input
|
||||
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
|
||||
value={defaultProjectName}
|
||||
onChange={(e) => setDefaultProjectName(e.target.value)}
|
||||
/>
|
||||
</SettingsSection>
|
||||
<ActionButton
|
||||
className="hover:border-succeed-50"
|
||||
onClick={handleSaveClick}
|
||||
icon={{
|
||||
icon: faCheck,
|
||||
bgClassName:
|
||||
'bg-succeed-80 group-hover:bg-succeed-70 hover:bg-succeed-70',
|
||||
iconClassName:
|
||||
'text-succeed-20 group-hover:text-succeed-10 hover:text-succeed-10',
|
||||
}}
|
||||
>
|
||||
Save Settings
|
||||
</ActionButton>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
interface SettingsSectionProps extends React.PropsWithChildren {
|
||||
title: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
function SettingsSection({
|
||||
title,
|
||||
description,
|
||||
children,
|
||||
}: SettingsSectionProps) {
|
||||
return (
|
||||
<section className="my-8 first-of-type:mt-16 last-of-type:mb-16 flex gap-12 items-start">
|
||||
<div className="w-80">
|
||||
<h2 className="text-2xl">{title}</h2>
|
||||
<p className="mt-2 text-sm">{description}</p>
|
||||
</div>
|
||||
{children}
|
||||
</section>
|
||||
)
|
||||
}
|
@ -155,6 +155,8 @@ export interface StoreState {
|
||||
// tauri specific app settings
|
||||
defaultDir: DefaultDir
|
||||
setDefaultDir: (dir: DefaultDir) => void
|
||||
defaultProjectName: string
|
||||
setDefaultProjectName: (defaultProjectName: string) => void
|
||||
showHomeMenu: boolean
|
||||
setHomeShowMenu: (showMenu: boolean) => void
|
||||
homeMenuItems: {
|
||||
@ -310,9 +312,11 @@ export const useStore = create<StoreState>()(
|
||||
|
||||
// tauri specific app settings
|
||||
defaultDir: {
|
||||
dir: '',
|
||||
dir: '~/Documents/',
|
||||
},
|
||||
setDefaultDir: (dir) => set({ defaultDir: dir }),
|
||||
defaultProjectName: 'new-project-$n',
|
||||
setDefaultProjectName: (defaultProjectName) => set({ defaultProjectName }),
|
||||
showHomeMenu: true,
|
||||
setHomeShowMenu: (showHomeMenu) => set({ showHomeMenu }),
|
||||
homeMenuItems: [],
|
||||
@ -324,7 +328,12 @@ export const useStore = create<StoreState>()(
|
||||
name: 'store',
|
||||
partialize: (state) =>
|
||||
Object.fromEntries(
|
||||
Object.entries(state).filter(([key]) => ['code', 'defaultDir', 'token'].includes(key))
|
||||
Object.entries(state).filter(([key]) => [
|
||||
'code',
|
||||
'defaultDir',
|
||||
'defaultProjectName',
|
||||
'token',
|
||||
].includes(key))
|
||||
),
|
||||
}
|
||||
)
|
||||
|
@ -1,10 +1,42 @@
|
||||
const themeColorRamps = [
|
||||
{ name: 'chalkboard', stops: 12 },
|
||||
{ name: 'energy', stops: 12 },
|
||||
{ name: 'liquid', stops: 12 },
|
||||
{ name: 'fern', stops: 12 },
|
||||
{ name: 'cool', stops: 12 },
|
||||
{ name: 'river', stops: 12 },
|
||||
{ name: 'berry', stops: 12 },
|
||||
{ name: 'destroy', stops: 8 },
|
||||
{ name: 'warn', stops: 8 },
|
||||
{ name: 'succeed', stops: 8 },
|
||||
]
|
||||
const toOKLCHVar = val => `oklch(var(${val}) / <alpha-value>) `
|
||||
|
||||
const themeColors = Object.fromEntries(
|
||||
themeColorRamps.map(({name, stops}) => [
|
||||
name,
|
||||
Object.fromEntries(
|
||||
new Array(stops)
|
||||
.fill(0)
|
||||
.map((_, i) => [
|
||||
(i + 1) * 10,
|
||||
toOKLCHVar(`--_${name}-${(i + 1) * 10}`),
|
||||
])
|
||||
),
|
||||
])
|
||||
)
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./src/**/*.{js,jsx,ts,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
extend: {
|
||||
colors: {
|
||||
...themeColors,
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
58
yarn.lock
58
yarn.lock
@ -1539,6 +1539,32 @@
|
||||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@fortawesome/fontawesome-common-types@6.4.0":
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz#88da2b70d6ca18aaa6ed3687832e11f39e80624b"
|
||||
integrity sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ==
|
||||
|
||||
"@fortawesome/fontawesome-svg-core@^6.4.0":
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.0.tgz#3727552eff9179506e9203d72feb5b1063c11a21"
|
||||
integrity sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw==
|
||||
dependencies:
|
||||
"@fortawesome/fontawesome-common-types" "6.4.0"
|
||||
|
||||
"@fortawesome/free-solid-svg-icons@^6.4.0":
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz#48c0e790847fa56299e2f26b82b39663b8ad7119"
|
||||
integrity sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ==
|
||||
dependencies:
|
||||
"@fortawesome/fontawesome-common-types" "6.4.0"
|
||||
|
||||
"@fortawesome/react-fontawesome@^0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4"
|
||||
integrity sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==
|
||||
dependencies:
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@headlessui/react@^1.7.13":
|
||||
version "1.7.13"
|
||||
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.13.tgz#fd150b394954e9f1d86ed2340cffd1217d6e7628"
|
||||
@ -1958,6 +1984,11 @@
|
||||
schema-utils "^3.0.0"
|
||||
source-map "^0.7.3"
|
||||
|
||||
"@remix-run/router@1.7.1":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.7.1.tgz#fea7ac35ae4014637c130011f59428f618730498"
|
||||
integrity sha512-bgVQM4ZJ2u2CM8k1ey70o1ePFXsEzYVZoWghh6WjM8p59jQ7HxzbHW4SbnWFG7V9ig9chLawQxDTZ3xzOF8MkQ==
|
||||
|
||||
"@rollup/plugin-babel@^5.2.0":
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
|
||||
@ -5568,6 +5599,11 @@ globby@^11.0.4, globby@^11.1.0:
|
||||
merge2 "^1.4.1"
|
||||
slash "^3.0.0"
|
||||
|
||||
goober@^2.1.10:
|
||||
version "2.1.13"
|
||||
resolved "https://registry.yarnpkg.com/goober/-/goober-2.1.13.tgz#e3c06d5578486212a76c9eba860cbc3232ff6d7c"
|
||||
integrity sha512-jFj3BQeleOoy7t93E9rZ2de+ScC4lQICLwiAQmKMg9F6roKGaLSHoCDYKkWlSafg138jejvq/mTdvmnwDQgqoQ==
|
||||
|
||||
gopd@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
|
||||
@ -8802,6 +8838,13 @@ react-error-overlay@^6.0.11:
|
||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb"
|
||||
integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==
|
||||
|
||||
react-hot-toast@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/react-hot-toast/-/react-hot-toast-2.4.1.tgz#df04295eda8a7b12c4f968e54a61c8d36f4c0994"
|
||||
integrity sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==
|
||||
dependencies:
|
||||
goober "^2.1.10"
|
||||
|
||||
react-is@^16.13.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
@ -8842,6 +8885,21 @@ react-refresh@^0.11.0:
|
||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046"
|
||||
integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==
|
||||
|
||||
react-router-dom@^6.14.1:
|
||||
version "6.14.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.14.1.tgz#0ad7ba7abdf75baa61169d49f096f0494907a36f"
|
||||
integrity sha512-ssF6M5UkQjHK70fgukCJyjlda0Dgono2QGwqGvuk7D+EDGHdacEN3Yke2LTMjkrpHuFwBfDFsEjGVXBDmL+bWw==
|
||||
dependencies:
|
||||
"@remix-run/router" "1.7.1"
|
||||
react-router "6.14.1"
|
||||
|
||||
react-router@6.14.1:
|
||||
version "6.14.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.14.1.tgz#5e82bcdabf21add859dc04b1859f91066b3a5810"
|
||||
integrity sha512-U4PfgvG55LdvbQjg5Y9QRWyVxIdO1LlpYT7x+tMAxd9/vmiPuJhIwdxZuIQLN/9e3O4KFDHYfR9gzGeYMasW8g==
|
||||
dependencies:
|
||||
"@remix-run/router" "1.7.1"
|
||||
|
||||
react-scripts@5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003"
|
||||
|
Reference in New Issue
Block a user