diff --git a/dashboard_js/app/app.css b/dashboard_js/app/app.css index f2168f3..ffd4898 100644 --- a/dashboard_js/app/app.css +++ b/dashboard_js/app/app.css @@ -1,8 +1,19 @@ -@import "tailwindcss"; +@import 'tailwindcss'; @theme { - --font-sans: "Roboto", ui-sans-serif, system-ui, sans-serif, - "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-sans: 'Roboto', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', + 'Noto Color Emoji'; + + --color-yellow-primary: #ffcf82; + --color-yellow-secondary: #f2ebe1; + --color-yellow-terciary: #f9f7e8; + + --color-green-primary: #2e3524; + --color-green-secondary: #8cd366; + --color-green-terciary: #83926d; + --color-green-support: #c9fcad; + --color-green-pastel: #f9fff6; + --color-green-light: #cad9b4; } html, diff --git a/dashboard_js/app/components/logo.jsx b/dashboard_js/app/components/logo.jsx new file mode 100644 index 0000000..cde6b75 --- /dev/null +++ b/dashboard_js/app/components/logo.jsx @@ -0,0 +1,73 @@ +export function Regular({ ...props }) { + return ( + + + + + + + + + + + + + + + + + + + + + ) +} + +export function Smallest({ ...props }) { + return ( + + + + + + + + + + + + ) +} diff --git a/dashboard_js/app/hooks/use-auth.jsx b/dashboard_js/app/hooks/use-auth.jsx new file mode 100644 index 0000000..ccff976 --- /dev/null +++ b/dashboard_js/app/hooks/use-auth.jsx @@ -0,0 +1,50 @@ +import { useMemo, useCallback, createContext, useState } from 'react' +import * as Auth from 'aws-amplify/auth' + +const AuthContext = createContext(null) + +export function useAuth() { + return useContext(AuthContext) +} + +export function AuthProvider({ children }) { + const [authUser, setAuthUser] = useState(null) + + const currentUser = useCallback(async () => { + try { + const currentUser = await Auth.fetchUserAttributes() + + setAuthUser(currentUser) + return currentUser + } catch { + setAuthUser(null) + } + }, []) + + const signIn = useCallback(async ({ username, password }) => { + const signInOut = await Auth.signIn({ + username, + password, + options: { + clientMetadata: {}, + }, + }) + + if (signInOut?.isSignedIn) { + setAuthUser(await Auth.fetchUserAttributes()) + } + + return signInOut + }, []) + + const ctxValue = useMemo( + () => ({ + authUser, + signIn, + currentUser, + }), + [authUser] + ) + + return {children} +} diff --git a/dashboard_js/app/pages/welcome/logo-dark.svg b/dashboard_js/app/pages/welcome/logo-dark.svg new file mode 100644 index 0000000..dd82028 --- /dev/null +++ b/dashboard_js/app/pages/welcome/logo-dark.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard_js/app/pages/welcome/logo-light.svg b/dashboard_js/app/pages/welcome/logo-light.svg new file mode 100644 index 0000000..7328492 --- /dev/null +++ b/dashboard_js/app/pages/welcome/logo-light.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard_js/app/pages/welcome/welcome.tsx b/dashboard_js/app/pages/welcome/welcome.tsx new file mode 100644 index 0000000..8ac6e1d --- /dev/null +++ b/dashboard_js/app/pages/welcome/welcome.tsx @@ -0,0 +1,89 @@ +import logoDark from "./logo-dark.svg"; +import logoLight from "./logo-light.svg"; + +export function Welcome() { + return ( +
+
+
+
+ React Router + React Router +
+
+
+ +
+
+
+ ); +} + +const resources = [ + { + href: "https://reactrouter.com/docs", + text: "React Router Docs", + icon: ( + + + + ), + }, + { + href: "https://rmx.as/discord", + text: "Join Discord", + icon: ( + + + + ), + }, +]; diff --git a/dashboard_js/app/root.tsx b/dashboard_js/app/root.tsx index 3668c2a..dd3ac86 100644 --- a/dashboard_js/app/root.tsx +++ b/dashboard_js/app/root.tsx @@ -1,27 +1,22 @@ -import { - isRouteErrorResponse, - Links, - Meta, - Outlet, - Scripts, - ScrollRestoration, -} from "react-router"; +import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router' -import type { Route } from "./+types/root"; -import "./app.css"; +import type { Route } from './+types/root' +import './app.css' + +import { Smallest as Logo } from './components/logo' export const links: Route.LinksFunction = () => [ - { rel: "preconnect", href: "https://fonts.googleapis.com" }, + { rel: 'preconnect', href: 'https://fonts.googleapis.com' }, { - rel: "preconnect", - href: "https://fonts.gstatic.com", - crossOrigin: "anonymous", + rel: 'preconnect', + href: 'https://fonts.gstatic.com', + crossOrigin: 'anonymous', }, { - rel: "stylesheet", - href: "https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap", + rel: 'stylesheet', + href: 'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap', }, -]; +] export function Layout({ children }: { children: React.ReactNode }) { return ( @@ -39,27 +34,28 @@ export function Layout({ children }: { children: React.ReactNode }) { - ); + ) +} + +export function HydrateFallback() { + return } export default function App() { - return ; + return } export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { - let message = "Oops!"; - let details = "An unexpected error occurred."; - let stack: string | undefined; + let message = 'Oops!' + let details = 'An unexpected error occurred.' + let stack: string | undefined if (isRouteErrorResponse(error)) { - message = error.status === 404 ? "404" : "Error"; - details = - error.status === 404 - ? "The requested page could not be found." - : error.statusText || details; + message = error.status === 404 ? '404' : 'Error' + details = error.status === 404 ? 'The requested page could not be found.' : error.statusText || details } else if (import.meta.env.DEV && error && error instanceof Error) { - details = error.message; - stack = error.stack; + details = error.message + stack = error.stack } return ( @@ -72,5 +68,5 @@ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { )} - ); + ) }