diff --git a/client-solid/src/GlobalState.tsx b/client-solid/src/GlobalState.tsx new file mode 100644 index 0000000..0929729 --- /dev/null +++ b/client-solid/src/GlobalState.tsx @@ -0,0 +1,59 @@ +import { + Accessor, + JSXElement, + createContext, + createSignal, + onMount, +} from "solid-js"; + +// Representing the state of varoious modals. +// So far we only have one modal, but we can add more later +// by adding more fields to this interface, or maybe an enum +interface ModalContextType { + loginModalOpen: Accessor; + setLoginModalOpen: (value: boolean) => void; +} + +interface LoginContextType { + token: Accessor; + setToken: (value: string) => void; + username: Accessor; + setUsername: (value: string) => void; + loggedIn: () => boolean; +} + +// It is unclear to me if this is the idiomatic way to do this in Solid +export const ModalContext = createContext(); +export const LoginContext = createContext(); + +export function GlobalStateProvider(props: { + children: JSXElement; +}): JSXElement { + // All of these are passed into context providers + const [loginModalOpen, setLoginModalOpen] = createSignal(false); + const [token, setToken] = createSignal(""); + const [username, setUsername] = createSignal(""); + + onMount(() => { + // This may not be the best place to do this. + localStorage.getItem("token") && setToken(localStorage.getItem("token")!); + localStorage.getItem("username") && + setUsername(localStorage.getItem("username")!); + }); + + function loggedIn(): boolean { + return token() != "" && username() != ""; + } + + return ( + <> + + + {props.children} + + + + ); +} diff --git a/client-solid/src/LoginModal.tsx b/client-solid/src/LoginModal.tsx index 152044c..4266145 100644 --- a/client-solid/src/LoginModal.tsx +++ b/client-solid/src/LoginModal.tsx @@ -1,8 +1,8 @@ import { JSXElement, Show, onCleanup, useContext } from "solid-js"; +import { ModalContext } from "./GlobalState"; import { LoginForm } from "./RegLogin/Login"; import { RegisterForm } from "./RegLogin/Register"; -import { ModalContext } from "./Root"; export function LoginModal(): JSXElement { const modal_ctx = useContext(ModalContext)!; diff --git a/client-solid/src/Navbar.tsx b/client-solid/src/Navbar.tsx index 3e2fdd6..2803a87 100644 --- a/client-solid/src/Navbar.tsx +++ b/client-solid/src/Navbar.tsx @@ -1,8 +1,8 @@ import { A } from "@solidjs/router"; import { JSXElement, Show, useContext } from "solid-js"; +import { LoginContext, ModalContext } from "./GlobalState"; import { Flake, Home, Plus, UserCircle } from "./Icons"; -import { LoginContext, ModalContext } from "./Root"; // Represents a single list item in the menu bar function MenuItem(props: { href: string; children: JSXElement }): JSXElement { diff --git a/client-solid/src/NewPost.tsx b/client-solid/src/NewPost.tsx index 40d6a63..baace22 100644 --- a/client-solid/src/NewPost.tsx +++ b/client-solid/src/NewPost.tsx @@ -1,13 +1,15 @@ import { useNavigate } from "@solidjs/router"; import { JSXElement, Show, createSignal, onMount, useContext } from "solid-js"; -import { LoginContext } from "./Root"; +import { LoginContext } from "./GlobalState"; import { NewPost, createPost } from "./api"; export function NewPostInputArea(): JSXElement { const [content, setContent] = createSignal(""); const [waiting, setWaiting] = createSignal(false); - const login_ctx = useContext(LoginContext); + + // We assumte this context is always available + const login_ctx = useContext(LoginContext)!; const nav = useNavigate(); @@ -16,7 +18,7 @@ export function NewPostInputArea(): JSXElement { const response = createPost({ content: content(), - token: login_ctx?.token(), + token: login_ctx.token(), } as NewPost); if (response) { @@ -28,8 +30,9 @@ export function NewPostInputArea(): JSXElement { } }; + // Bail out if not logged in onMount(() => { - if (login_ctx?.token() == "") nav("/"); + if (!login_ctx.loggedIn()) nav("/"); }); return ( diff --git a/client-solid/src/RegLogin/Login.tsx b/client-solid/src/RegLogin/Login.tsx index 1436f26..6548b2e 100644 --- a/client-solid/src/RegLogin/Login.tsx +++ b/client-solid/src/RegLogin/Login.tsx @@ -1,6 +1,6 @@ import { JSXElement, createSignal, useContext } from "solid-js"; -import { LoginContext, ModalContext } from "../Root"; +import { LoginContext, ModalContext } from "../GlobalState"; export function LoginForm(): JSXElement { const modal_ctx = useContext(ModalContext); diff --git a/client-solid/src/RegLogin/Register.tsx b/client-solid/src/RegLogin/Register.tsx index 33c15f5..0e09d10 100644 --- a/client-solid/src/RegLogin/Register.tsx +++ b/client-solid/src/RegLogin/Register.tsx @@ -1,6 +1,6 @@ import { JSXElement, createSignal, useContext } from "solid-js"; -import { LoginContext, ModalContext } from "../Root"; +import { LoginContext, ModalContext } from "../GlobalState"; export function RegisterForm(): JSXElement { const modal_ctx = useContext(ModalContext); diff --git a/client-solid/src/Root.tsx b/client-solid/src/Root.tsx index 6a04063..717d224 100644 --- a/client-solid/src/Root.tsx +++ b/client-solid/src/Root.tsx @@ -1,55 +1,23 @@ -import { Accessor, JSXElement, createContext, createSignal } from "solid-js"; +import { JSXElement } from "solid-js"; +import { GlobalStateProvider } from "./GlobalState"; import { LoginModal } from "./LoginModal"; import { Navbar } from "./Navbar"; import { Primary } from "./Primary"; -// Representing the state of varoious modals. -// So far we only have one modal, but we can add more later -// by adding more fields to this interface, or maybe an enum -interface ModalContextType { - loginModalOpen: Accessor; - setLoginModalOpen: (value: boolean) => void; -} - -interface LoginContextType { - token: Accessor; - setToken: (value: string) => void; - username: Accessor; - setUsername: (value: string) => void; -} - -// It is unclear to me if this is the idiomatic way to do this in Solid -export const ModalContext = createContext(); -export const LoginContext = createContext(); - function Root(): JSXElement { - // All of these are passed into context providers - const [loginModalOpen, setLoginModalOpen] = createSignal(false); - const [token, setToken] = createSignal(""); - const [username, setUsername] = createSignal(""); - - // This may not be the best place to do this. - localStorage.getItem("token") && setToken(localStorage.getItem("token")!); - localStorage.getItem("username") && - setUsername(localStorage.getItem("username")!); - return ( <> - - - -
- - -
- -
+ + +
+ + +
+
- - +
+
); }