diff --git a/client/index.html b/client/index.html
index 6b04374..bbfd12d 100644
--- a/client/index.html
+++ b/client/index.html
@@ -1,5 +1,5 @@
-
+
diff --git a/client/src/index.tsx b/client/src/index.tsx
index cf78bc1..dca4763 100644
--- a/client/src/index.tsx
+++ b/client/src/index.tsx
@@ -4,6 +4,7 @@ import { createRouter, RouterProvider } from "@tanstack/solid-router";
import { render } from "solid-js/web";
import { routeTree } from "./routeTree.gen";
+import UserContext from "./userContext";
// Keep polyfill out of the bundle. You can see this as vite generates two js bundles, one with only the polyfill and one without.
if (!("Temporal" in globalThis)) {
@@ -29,4 +30,11 @@ declare module "@tanstack/solid-router" {
}
}
-render(() => , document.body);
+render(
+ () => (
+
+
+
+ ),
+ document.body,
+);
diff --git a/client/src/routes/index.tsx b/client/src/routes/index.tsx
index b46075b..7fd997a 100644
--- a/client/src/routes/index.tsx
+++ b/client/src/routes/index.tsx
@@ -1,7 +1,16 @@
import { createFileRoute, Navigate } from "@tanstack/solid-router";
+import { useContext } from "solid-js";
+
+import UserContext from "../userContext";
export const Route = createFileRoute("/")({
component() {
- return ;
+ const userContext = useContext(UserContext);
+
+ if (userContext.isSignedIn) {
+ return ;
+ }
+
+ return ;
},
});
diff --git a/client/src/routes/login.tsx b/client/src/routes/login.tsx
new file mode 100644
index 0000000..31d339b
--- /dev/null
+++ b/client/src/routes/login.tsx
@@ -0,0 +1,111 @@
+import { createFileRoute, useNavigate } from "@tanstack/solid-router";
+import { useContext } from "solid-js";
+
+import Body from "../Body";
+import UserContext from "../userContext";
+
+export const Route = createFileRoute("/login")({
+ component: Login,
+});
+//
+
+//TODO remove this with sign in and Passkey implementation (see sign-in page)
+// Template from Tailwind Plus component
+function Login() {
+ const navigate = useNavigate();
+ const userContext = useContext(UserContext);
+
+ async function handleSubmit(event: SubmitEvent) {
+ event.preventDefault();
+ const formData = new FormData(event.target as HTMLFormElement);
+ const username = formData.get("username");
+ const password = formData.get("password");
+
+ const value = btoa(`${username}:${password}`);
+ const response = await fetch("/api/login", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Basic ${value}`,
+ },
+ });
+
+ console.debug("Login response", response);
+
+ if (!response.ok) {
+ //TODO
+ alert("Login failed");
+ return;
+ }
+
+ // Simple state management for now
+ userContext.isSignedIn = true;
+ await navigate({ to: "/times" });
+ }
+
+ return (
+
+
+
+ );
+}
diff --git a/client/src/routes/sign-in.tsx b/client/src/routes/sign-in.tsx
index c974f5d..38a7157 100644
--- a/client/src/routes/sign-in.tsx
+++ b/client/src/routes/sign-in.tsx
@@ -8,13 +8,38 @@ export const Route = createFileRoute("/sign-in")({
});
function SignIn() {
+ async function handleSignIn() {
+ console.debug("Signing in...");
+
+ const user = "yealch";
+ const password = "password";
+ const value = btoa(`${user}:${password}`);
+ const response = await fetch("/api/login", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Basic ${value}`,
+ },
+ });
+
+ console.debug("Login response", response, await response.json());
+
+ const getUsersResponse = await fetch("/api/users", {
+ method: "GET",
+ });
+
+ console.debug("Get users response", getUsersResponse, await getUsersResponse.json());
+ }
return (
Welcome
{/* TODO: Button states styles */}
-