Scaffolded Springboard page

This commit is contained in:
2024-06-25 00:31:19 +08:00
parent 94a62f43b2
commit 29ab8c0422
7 changed files with 160 additions and 4 deletions

View File

@@ -2,6 +2,7 @@ import { Route, Routes } from "react-router-dom";
import HomePage from "./pages/HomePage";
import SignUpPage from "./pages/SignUpPage";
import SignInPage from "./pages/SignInPage";
import SpringboardPage from "./pages/SpringboardPage";
function App() {
return (
@@ -9,6 +10,7 @@ function App() {
<Route element={<HomePage />} path="/" />
<Route element={<SignUpPage />} path="/signup" />
<Route element={<SignInPage />} path="/signin" />
<Route element={<SpringboardPage />} path="/springboard/:accessToken" />
</Routes>
);
}

View File

@@ -39,7 +39,7 @@ export default function SignInModule() {
config.serverAddress + "/users/login",
values
);
console.log(response.data.accessToken);
navigate("/springboard/" + response.data.accessToken);
} catch (error) {
console.error("Error logging in:", error);
}

View File

@@ -0,0 +1,18 @@
import { Button } from "@nextui-org/react";
export default function SpringboardButton({
title,
subtitle,
}: {
title: string;
subtitle: string;
}) {
return (
<Button className="border-4 border-red-500 bg-neutral-700 hover:bg-red-500 text-white">
<div className="flex flex-col justify-between w-full h-full py-4 px-2 text-left *:text-wrap mr-16">
<p className="text-2xl font-semibold">{title}</p>
<p>{subtitle}</p>
</div>
</Button>
);
}

View File

@@ -16,3 +16,22 @@ export const ChevronLeftIcon = () => {
</svg>
);
};
export const PencilSquareIcon = () => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="size-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"
/>
</svg>
);
};

View File

@@ -0,0 +1,106 @@
import { useParams } from "react-router-dom";
import DefaultLayout from "../layouts/default";
import { useEffect, useState } from "react";
import axios from "axios";
import config from "../config";
import { Button, Link } from "@nextui-org/react";
import { PencilSquareIcon } from "../icons";
import SpringboardButton from "../components/SpringboardButton";
import { getTimeOfDay } from "../utilities";
export default function SpringboardPage() {
let { accessToken } = useParams(); // TODO: Replace AT from props with AT from localstorage
let [userInformation, setUserInformation] = useState<any>();
let timeOfDay = getTimeOfDay();
let greeting = "";
if (timeOfDay === 0) {
greeting = "Good morning";
} else if (timeOfDay === 1) {
greeting = "Good afternoon";
} else if (timeOfDay === 2) {
greeting = "Good evening";
}
const retrieveUserInformation = () => {
axios
.get(`${config.serverAddress}/users/auth`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
.then((response) => {
axios
.get(`${config.serverAddress}/users/individual/${response.data.id}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
.then((response) => {
setUserInformation(response.data);
})
.catch((error) => {
console.error("Error retrieving user information:", error);
});
})
.catch((error) => {
console.error("Error retrieving user ID:", error);
});
};
useEffect(() => {
retrieveUserInformation();
}, []);
return (
<DefaultLayout>
{userInformation && (
<div className="flex flex-col w-full">
<div className="flex flex-row justify-between p-8 *:my-auto">
<div className="flex flex-col gap-4">
<p className="text-3xl font-bold">
{greeting}, {userInformation.firstName}.
</p>
<p>
Resident of <Link>Bishan-Toa Payoh Town Council</Link>
</p>
<Button
className="w-max"
size="sm"
variant="flat"
color="primary"
startContent={
<div className="scale-80">
<PencilSquareIcon />
</div>
}
>
Manage your account
</Button>
</div>
<div className="bg-red-500 w-40 h-40 rounded-full"></div>
</div>
<div className="flex flex-row justify-stretch *:w-full *:h-56 w-full p-4 pt-0 gap-4">
<SpringboardButton
title="Community Forums"
subtitle="Be involved in discussions among your neighbourhood"
></SpringboardButton>
<SpringboardButton
title="Events"
subtitle="Participate in exciting upcoming events around Singapore"
></SpringboardButton>
<SpringboardButton
title="Home Bill Contest"
subtitle="Save resources, win vouchers!"
></SpringboardButton>
<SpringboardButton
title="Karang Guni Scheduling"
subtitle="Arrange doorstep sales for your old gears with Karang Guni"
></SpringboardButton>
</div>
<div className="w-full h-[600px] bg-red-500"></div>
</div>
)}
</DefaultLayout>
);
}

11
client/src/utilities.ts Normal file
View File

@@ -0,0 +1,11 @@
export function getTimeOfDay(): number {
const currentHour = new Date().getHours();
if (currentHour >= 6 && currentHour < 12) {
return 0; // Morning
} else if (currentHour >= 12 && currentHour < 18) {
return 1; // Afternoon
} else {
return 2; // Evening
}
}

View File

@@ -67,7 +67,7 @@ router.get("/all", async (req, res) => {
res.json(list);
});
router.get("/individual/:id", async (req, res) => {
router.get("/individual/:id", validateToken, async (req, res) => {
let id = req.params.id;
let user = await User.findByPk(id);
if (!user) {
@@ -77,7 +77,7 @@ router.get("/individual/:id", async (req, res) => {
res.json(user);
});
router.put("/individual/:id", async (req, res) => {
router.put("/individual/:id", validateToken, async (req, res) => {
let id = req.params.id;
let user = await User.findByPk(id);
@@ -109,7 +109,7 @@ router.put("/individual/:id", async (req, res) => {
}
});
router.delete("/individual/:id", async (req, res) => {
router.delete("/individual/:id", validateToken, async (req, res) => {
let id = req.params.id;
let user = await User.findByPk(id);