Revamped routing system

This commit is contained in:
2024-07-26 14:49:40 +08:00
parent 4d1b623ec6
commit 9b293660bf
26 changed files with 666 additions and 601 deletions

View File

@@ -8,7 +8,7 @@ import ManageUserAccountPage from "./pages/ManageUserAccountPage";
import CommunityPage from "./pages/CommunityPage";
import CreatePostPage from "./pages/CreatePostPage";
import EditPostPage from "./pages/EditPostPage";
import PostPage from './pages/PostPage';
import PostPage from "./pages/PostPage";
import SchedulePage from "./pages/SchedulePage";
import EventsPage from "./pages/EventsPage";
import CreateEventsPage from "./pages/CreateEventsPage";
@@ -17,28 +17,57 @@ import AdministratorSpringboard from "./pages/AdministratorSpringboard";
import HBContestPage from "./pages/HBContestPage";
import HBFormPage from "./pages/HBFormPage";
import EditEventsPage from "./pages/EditEventsPage";
import DefaultLayout from "./layouts/default";
import AdministratorLayout from "./layouts/administrator";
function App() {
return (
<Routes>
<Route element={<HomePage />} path="/" />
<Route element={<SignUpPage />} path="/signup" />
<Route element={<SignInPage />} path="/signin" />
<Route element={<SpringboardPage />} path="/springboard" />
<Route element={<ManageUserAccountPage />} path="/manage-account" />
<Route element={<AdministratorSpringboard />} path="/admin" />
{/* User Routes */}
<Route path="/" element={<DefaultLayout />}>
{/* General Routes */}
<Route index element={<HomePage />} />
<Route element={<SignUpPage />} path="signup" />
<Route element={<SignInPage />} path="signin" />
<Route element={<SpringboardPage />} path="springboard" />
<Route element={<ManageUserAccountPage />} path="manage-account" />
<Route element={<CommunityPage />} path="/community" />
<Route element={<CreatePostPage />} path="/createPost" />
<Route element={<EditPostPage />} path="/editPost/:id" />
<Route element={<PostPage />} path="/post/:id" />
<Route element={<SchedulePage />} path="/schedule" />
<Route element={<EventsPage />} path="/events" />
<Route element={<HBContestPage />} path="/contest" />
<Route element={<HBFormPage />} path="/hbcform" />
<Route element={<CreateEventsPage />} path="/createEvent" />
<Route element={<ManageEventsPage />} path="/manageEvent" />
<Route element={<EditEventsPage />} path="/editEvent/:id" />
{/* Events Route */}
<Route path="events">
<Route index element={<EventsPage />} />
</Route>
{/* Karang Guni Schedules Route */}
<Route path="karang-guni-schedules">
<Route index element={<SchedulePage />} />
</Route>
{/* Home Bill Contest Route */}
<Route path="home-bill-contest">
<Route index element={<HBContestPage />} />
<Route element={<HBFormPage />} path="new-submission" />
</Route>
{/* Community Posts Route */}
<Route path="community-posts">
<Route index element={<CommunityPage />} />
<Route element={<CreatePostPage />} path="create" />
<Route element={<PostPage />} path="post/:id" />
<Route element={<EditPostPage />} path="edit/:id" />
</Route>
</Route>
{/* Admin Routes */}
<Route path="/admin" element={<AdministratorLayout />}>
<Route index element={<AdministratorSpringboard />} />
{/* Events */}
<Route path="events">
<Route index element={<ManageEventsPage />} />
<Route element={<CreateEventsPage />} path="create" />
<Route element={<EditEventsPage />} path="edit/:id" />
</Route>
</Route>
</Routes>
);
}

View File

@@ -26,19 +26,30 @@ import { useEffect, useState } from "react";
import config from "../config";
import AdministratorNavigationPanelNavigationButton from "./AdministratorNavigationPanelNavigationButton";
import EcoconnectLogo from "./EcoconnectLogo";
import { useNavigate } from "react-router-dom";
export default function AdministratorNavigationPanel() {
const [userInformation, setUserInformation] = useState<any>();
const [userProfileImageURL, setUserProfileImageURL] = useState("");
const [panelVisible, setPanelVisible] = useState(true);
const [isScrolled, setIsScrolled] = useState(false);
const navigate = useNavigate();
useEffect(() => {
retrieveUserInformation().then((value) => {
setUserInformation(value);
setUserProfileImageURL(
`${config.serverAddress}/users/profile-image/${value.id}`
);
});
retrieveUserInformation()
.then((value) => {
if (!value || value.accountType != 2) {
navigate("/");
}
setUserInformation(value);
setUserProfileImageURL(
`${config.serverAddress}/users/profile-image/${value.id}`
);
})
.catch(() => {
navigate("/signin");
});
const handleScroll = () => {
setIsScrolled(window.scrollY > 10);
};

View File

@@ -21,23 +21,23 @@ import { useNavigate } from "react-router-dom";
import EcoconnectFullLogo from "./EcoconnectFullLogo";
export default function NavigationBar() {
let [userProfileImageURL, setUserProfileImageURL] = useState("");
let [userInformation, setUserInformation] = useState<any>();
let [doneLoading, setDoneLoading] = useState(false);
const [userProfileImageURL, setUserProfileImageURL] = useState("");
const [userInformation, setUserInformation] = useState<any>();
const [doneLoading, setDoneLoading] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
let navigate = useNavigate();
const navigate = useNavigate();
useEffect(() => {
retrieveUserInformation()
.then((value) => {
if (value.accountType == 2) navigate("/admin");
setUserProfileImageURL(
`${config.serverAddress}/users/profile-image/${value.id}`
);
setUserInformation(value);
})
.catch((err) => {
console.log(err);
return;
.catch(() => {
navigate("/signin");
})
.finally(() => {
setDoneLoading(true);
@@ -86,7 +86,7 @@ export default function NavigationBar() {
variant="light"
size="sm"
onPress={() => {
navigate("/schedule");
navigate("/karang-guni-schedules");
}}
>
<p className="text-lg">Schedules</p>
@@ -95,7 +95,7 @@ export default function NavigationBar() {
variant="light"
size="sm"
onPress={() => {
navigate("/contest");
navigate("/home-bill-contest");
}}
>
<p className="text-lg">HB Contest</p>
@@ -104,7 +104,7 @@ export default function NavigationBar() {
variant="light"
size="sm"
onPress={() => {
navigate("/community");
navigate("/community-posts");
}}
>
<p className="text-lg">Community Forums</p>

View File

@@ -8,6 +8,7 @@ import { useNavigate } from "react-router-dom";
import { ChevronLeftIcon } from "../icons";
import { popErrorToast } from "../utilities";
import { retrieveUserInformation } from "../security/users";
import instance from "../security/http";
const validationSchema = Yup.object({
email: Yup.string()
@@ -36,7 +37,7 @@ export default function SignInModule() {
};
const handleSubmit = (values: any): void => {
axios
instance
.post(config.serverAddress + "/users/login", values)
.then((response) => {
localStorage.setItem("accessToken", response.data.accessToken);
@@ -44,7 +45,7 @@ export default function SignInModule() {
if (value.accountType == 2) {
navigate("/admin");
} else {
navigate("/springboard/");
navigate("/springboard");
}
});
})

View File

@@ -8,8 +8,8 @@ export default function SignedInStatusVerifier({
}: {
children: React.JSX.Element;
}) {
let navigate = useNavigate();
let [isLoading, setIsLoading] = useState(true);
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
retrieveUserInformation()
.then((value) => {

View File

@@ -23,7 +23,7 @@ import instance from "../security/http";
export default function UpdateAccountModule() {
const navigate = useNavigate();
let [userInformation, setUserInformation] = useState<any>();
const [userInformation, setUserInformation] = useState<any>();
const { isOpen, onOpen, onOpenChange } = useDisclosure();
@@ -33,7 +33,7 @@ export default function UpdateAccountModule() {
setUserInformation(response);
})
.catch(() => {
navigate("/springboard/");
navigate("/signin");
});
}, []);
@@ -72,7 +72,7 @@ export default function UpdateAccountModule() {
values
);
console.log("User updated successfully:", response.data);
navigate("/springboard/");
navigate("/springboard");
} catch (error) {
popErrorToast(error);
}
@@ -127,7 +127,7 @@ export default function UpdateAccountModule() {
<Button
variant="light"
onPress={() => {
navigate("/springboard/");
navigate("/springboard");
}}
>
Cancel

View File

@@ -1,12 +1,9 @@
import { Toaster } from "react-hot-toast";
import SingaporeAgencyStrip from "../components/SingaporeAgencyStrip";
import AdministratorNavigationPanel from "../components/AdministratorNavigationPanel";
import { Outlet } from "react-router-dom";
export default function AdministratorLayout({
children,
}: {
children: React.ReactNode;
}) {
export default function AdministratorLayout() {
return (
<div className="relative flex flex-col h-full">
<SingaporeAgencyStrip />
@@ -14,7 +11,9 @@ export default function AdministratorLayout({
<div className="h-full z-50">
<AdministratorNavigationPanel />
</div>
<main className="flex-grow">{children}</main>
<main className="flex-grow">
<Outlet />
</main>
</div>
<Toaster />

View File

@@ -1,16 +1,15 @@
import { Toaster } from "react-hot-toast";
import SingaporeAgencyStrip from "../components/SingaporeAgencyStrip";
import NavigationBar from "../components/NavigationBar";
import { Outlet } from "react-router-dom";
export default function DefaultLayout({
children,
}: {
children: React.ReactNode;
}) {
export default function DefaultLayout() {
return (
<div className="relative flex flex-col h-screen">
<SingaporeAgencyStrip />
<main className="pt-16 flex-grow">{children}</main>
<main className="pt-16 flex-grow">
<Outlet />
</main>
<Toaster />
<NavigationBar />

View File

@@ -1,5 +1,4 @@
import { useNavigate } from "react-router-dom";
import AdministratorLayout from "../layouts/administrator";
import { useEffect, useState } from "react";
import { getTimeOfDay } from "../utilities";
import { retrieveUserInformation } from "../security/users";
@@ -14,7 +13,7 @@ export default function AdministratorSpringboard() {
if (!accessToken) {
navigate("/signin");
}
let [userInformation, setUserInformation] = useState<any>();
const [userInformation, setUserInformation] = useState<any>();
let timeOfDay = getTimeOfDay();
let greeting = "";
@@ -42,72 +41,67 @@ export default function AdministratorSpringboard() {
return (
<div>
{userInformation && (
<AdministratorLayout>
<div className="flex flex-col w-full pb-2">
<div className="flex flex-row justify-between p-8 pt-14 *:my-auto">
<div className="flex flex-col gap-3">
<p className="text-3xl font-bold">
{greeting}, {userInformation.firstName}.
</p>
<div className="flex flex-row gap-2 *:my-auto">
<p className="text-xl">A staff member of</p>
<EcoconnectFullLogo />
</div>
<p className="text-primary-500">{userInformation.email}</p>
<Button
className="w-max"
size="sm"
variant="flat"
color="primary"
startContent={
<div className="scale-80">
<PencilSquareIcon />
</div>
}
onPress={() => {
navigate("/manage-account/");
}}
>
Manage your account
</Button>
<div className="flex flex-col w-full pb-2">
<div className="flex flex-row justify-between p-8 pt-14 *:my-auto">
<div className="flex flex-col gap-3">
<p className="text-3xl font-bold">
{greeting}, {userInformation.firstName}.
</p>
<div className="flex flex-row gap-2 *:my-auto">
<p className="text-xl">A staff member of</p>
<EcoconnectFullLogo />
</div>
<UserProfilePicture
userId={userInformation.id}
editable={false}
/>
<p className="text-primary-500">{userInformation.email}</p>
<Button
className="w-max"
size="sm"
variant="flat"
color="primary"
startContent={
<div className="scale-80">
<PencilSquareIcon />
</div>
}
onPress={() => {
navigate("/manage-account");
}}
>
Manage your account
</Button>
</div>
<div className="flex flex-row justify-stretch *:w-full *:h-56 w-full p-4 pt-0 gap-4"></div>
<Card className="w-full bg-primary-500 p-8 text-white rounded-r-none">
<div className="flex flex-col gap-4">
<p className="font-bold text-4xl">Statistics Overview</p>
<div className="h-[500px] w-full bg-primary-600 rounded-2xl flex flex-row p-6">
<div className="w-60 flex flex-col justify-between">
<div className="flex flex-col">
<p className="text-2xl">User Count</p>
<p className="opacity-70">(past 30 days)</p>
</div>
<p className="text-lg">
Total: <span className="font-bold">2139</span> users
</p>
</div>
<div className="w-full h-full bg-white rounded-xl">
{/* TODO: Graph */}
<p className="text-black">GRAPH HERE</p>
<UserProfilePicture userId={userInformation.id} editable={false} />
</div>
<div className="flex flex-row justify-stretch *:w-full *:h-56 w-full p-4 pt-0 gap-4"></div>
<Card className="w-full bg-primary-500 p-8 text-white rounded-r-none">
<div className="flex flex-col gap-4">
<p className="font-bold text-4xl">Statistics Overview</p>
<div className="h-[500px] w-full bg-primary-600 rounded-2xl flex flex-row p-6">
<div className="w-60 flex flex-col justify-between">
<div className="flex flex-col">
<p className="text-2xl">User Count</p>
<p className="opacity-70">(past 30 days)</p>
</div>
<p className="text-lg">
Total: <span className="font-bold">2139</span> users
</p>
</div>
<div className="h-[500px] w-full bg-primary-600 rounded-2xl flex flex-row p-6">
<div className="w-60 flex flex-col justify-between">
<p className="text-2xl">Population Distribution</p>
</div>
<div className="w-full h-full bg-white rounded-xl">
{/* TODO: Graph */}
<p className="text-black">GRAPH HERE</p>
</div>
<div className="w-full h-full bg-white rounded-xl">
{/* TODO: Graph */}
<p className="text-black">GRAPH HERE</p>
</div>
</div>
</Card>
</div>
</AdministratorLayout>
<div className="h-[500px] w-full bg-primary-600 rounded-2xl flex flex-row p-6">
<div className="w-60 flex flex-col justify-between">
<p className="text-2xl">Population Distribution</p>
</div>
<div className="w-full h-full bg-white rounded-xl">
{/* TODO: Graph */}
<p className="text-black">GRAPH HERE</p>
</div>
</div>
</div>
</Card>
</div>
)}
</div>
);

View File

@@ -1,5 +1,4 @@
// import { title } from "@/components/primitives";
import DefaultLayout from "../layouts/default";
import { SetStateAction, useEffect, useState } from "react";
import {
Button,
@@ -117,20 +116,12 @@ export default function CommunityPage() {
}
};
// useEffect(() => {
// retrieveUserInformation()
// .then((response) => {
// setUserInformation(response);
// })
// return;
// }, []);
const handlePostClick = (id: number) => {
navigate(`/post/${id}`);
navigate(`post/${id}`);
};
return (
<DefaultLayout>
<div className="w-full h-full">
<div className="flex flex-row gap-4 m-10">
<div className="flex flex-col gap-8 w-full">
<div className="flex flex-col">
@@ -163,8 +154,10 @@ export default function CommunityPage() {
<div className="flex flex-row-reverse justify-center items-center">
<Dropdown>
<div>
<DropdownTrigger className="justify-center items-center"
onClick={(e) => e.stopPropagation()}>
<DropdownTrigger
className="justify-center items-center"
onClick={(e) => e.stopPropagation()}
>
<Button isIconOnly variant="light">
<EllipsisHorizontalIcon />
</Button>
@@ -174,7 +167,7 @@ export default function CommunityPage() {
<DropdownItem
key="edit"
onClick={() => {
navigate(`/editPost/${post.id}`);
navigate(`edit/${post.id}`);
}}
>
Edit
@@ -196,12 +189,6 @@ export default function CommunityPage() {
</div>
<div>
<p>Image</p>
{/* {userInformation && (
<UserPostImage
userId={userInformation}
editable={true}
/>
)} */}
</div>
</div>
<div className="flex flex-col gap-2">
@@ -210,19 +197,30 @@ export default function CommunityPage() {
<Chip>Tag 2</Chip>
</div>
<div className="flex flex-row">
<Button variant="light" isIconOnly onClick={(e) => e.stopPropagation()}>
<Button
variant="light"
isIconOnly
onClick={(e) => e.stopPropagation()}
>
<HandThumbsUpIcon />
</Button>
<Button variant="light" isIconOnly onClick={(e) => e.stopPropagation()}>
<Button
variant="light"
isIconOnly
onClick={(e) => e.stopPropagation()}
>
<ChatBubbleOvalLeftEllipsisIcon />
</Button>
<Button variant="light" isIconOnly onClick={(e) => e.stopPropagation()}>
<Button
variant="light"
isIconOnly
onClick={(e) => e.stopPropagation()}
>
<EllipsisHorizontalIcon />
</Button>
</div>
</div>
</div>
</section>
);
})}
@@ -234,7 +232,7 @@ export default function CommunityPage() {
className=" bg-primary-500 dark:bg-primary-700 text-white"
size="lg"
onPress={() => {
navigate("/createPost");
navigate("create");
}}
>
<p className="font-bold">Create a post!</p>
@@ -280,6 +278,6 @@ export default function CommunityPage() {
)}
</ModalContent>
</Modal>
</DefaultLayout>
</div>
);
}

View File

@@ -1,4 +1,3 @@
import DefaultLayout from "../layouts/default";
import { Button } from "@nextui-org/react";
import { Formik, Form } from "formik";
import * as Yup from "yup";
@@ -32,8 +31,12 @@ const validationSchema = Yup.object({
time: Yup.string().required("Time is required"),
location: Yup.string().required("Location is required"),
category: Yup.string().required("Category is required"),
slotsAvailable: Yup.number().integer().required("Slots Available is required"),
imageUrl: Yup.string().url("Invalid URL format").required("Image URL is required")
slotsAvailable: Yup.number()
.integer()
.required("Slots Available is required"),
imageUrl: Yup.string()
.url("Invalid URL format")
.required("Image URL is required"),
});
const CreateEventsPage = () => {
@@ -47,7 +50,7 @@ const CreateEventsPage = () => {
location: "",
category: "",
slotsAvailable: "",
imageUrl: ""
imageUrl: "",
};
const handleSubmit = async (
@@ -56,12 +59,15 @@ const CreateEventsPage = () => {
) => {
console.log("Submitting form with values:", values); // Debug log
try {
const response = await axios.post(config.serverAddress + "/events", values);
const response = await axios.post(
config.serverAddress + "/events",
values
);
console.log("Server response:", response); // Debug log
if (response.status === 200 || response.status === 201) {
console.log("Event created successfully:", response.data);
resetForm(); // Clear form after successful submit
navigate("/manageEvent");
navigate(-1);
} else {
console.error("Error creating event:", response.statusText);
}
@@ -77,7 +83,7 @@ const CreateEventsPage = () => {
};
return (
<DefaultLayout>
<div className="w-full h-full">
<section className="w-8/12 mx-auto">
<Button
variant="light"
@@ -163,7 +169,7 @@ const CreateEventsPage = () => {
)}
</Formik>
</section>
</DefaultLayout>
</div>
);
};

View File

@@ -1,4 +1,3 @@
import DefaultLayout from "../layouts/default";
import { Button } from "@nextui-org/react";
import { Formik, Form } from "formik";
import * as Yup from "yup";
@@ -48,7 +47,7 @@ function CreatePostPage() {
if (response.status === 200) {
console.log("Post created successfully:", response.data);
resetForm(); // Clear form after successful submit
navigate("/community");
navigate(-1);
} else {
console.error("Error creating post:", response.statusText);
}
@@ -64,7 +63,7 @@ function CreatePostPage() {
};
return (
<DefaultLayout>
<div className="w-full h-full">
<section className="w-8/12 mx-auto">
<Button
variant="light"
@@ -126,7 +125,7 @@ function CreatePostPage() {
)}
</Formik>
</section>
</DefaultLayout>
</div>
);
}

View File

@@ -1,5 +1,4 @@
import React, { useState, useEffect } from 'react';
import DefaultLayout from "../layouts/default";
import React, { useState, useEffect } from "react";
import { Button } from "@nextui-org/react";
import { Formik, Form } from "formik";
import * as Yup from "yup";
@@ -33,8 +32,12 @@ const validationSchema = Yup.object({
time: Yup.string().required("Time is required"),
location: Yup.string().required("Location is required"),
category: Yup.string().required("Category is required"),
slotsAvailable: Yup.number().integer().required("Slots Available is required"),
imageUrl: Yup.string().url("Invalid URL format").required("Image URL is required")
slotsAvailable: Yup.number()
.integer()
.required("Slots Available is required"),
imageUrl: Yup.string()
.url("Invalid URL format")
.required("Image URL is required"),
});
const EditEventsPage = () => {
@@ -48,13 +51,15 @@ const EditEventsPage = () => {
location: "",
category: "",
slotsAvailable: "",
imageUrl: ""
imageUrl: "",
});
useEffect(() => {
const fetchEvent = async () => {
try {
const response = await axios.get(`${config.serverAddress}/events/${id}`);
const response = await axios.get(
`${config.serverAddress}/events/${id}`
);
console.log("Fetched event data:", response.data); // Debug log
setInitialValues(response.data);
} catch (error) {
@@ -71,12 +76,15 @@ const EditEventsPage = () => {
) => {
console.log("Submitting form with values:", values); // Debug log
try {
const response = await axios.put(`${config.serverAddress}/events/${id}`, values);
const response = await axios.put(
`${config.serverAddress}/events/${id}`,
values
);
console.log("Server response:", response); // Debug log
if (response.status === 200 || response.status === 201) {
console.log("Event updated successfully:", response.data);
resetForm(); // Clear form after successful submit
navigate("/manageEvent");
navigate(-1);
} else {
console.error("Error updating event:", response.statusText);
}
@@ -92,7 +100,7 @@ const EditEventsPage = () => {
};
return (
<DefaultLayout>
<div className="w-full h-full">
<section className="w-8/12 mx-auto">
<Button
variant="light"
@@ -179,7 +187,7 @@ const EditEventsPage = () => {
)}
</Formik>
</section>
</DefaultLayout>
</div>
);
};

View File

@@ -1,4 +1,3 @@
import DefaultLayout from "../layouts/default";
import { Button } from "@nextui-org/react";
import { Formik, Form } from "formik";
import * as Yup from "yup";
@@ -60,7 +59,7 @@ function editPost() {
if (response.status === 200) {
console.log("Post updated successfully:", response.data);
resetForm();
navigate("/community");
navigate(-1);
} else {
console.error("Error updating post:", response.statusText);
}
@@ -76,7 +75,7 @@ function editPost() {
};
return (
<DefaultLayout>
<div className="w-full h-full">
<section className="w-8/12 mx-auto">
<Button
variant="light"
@@ -138,7 +137,7 @@ function editPost() {
</Formik>
)}
</section>
</DefaultLayout>
</div>
);
}

View File

@@ -1,9 +1,15 @@
import React, { useState, useEffect } from 'react';
import DefaultLayout from "../layouts/default";
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import instance from "../security/http";
import config from "../config";
import { Card, CardHeader, CardBody, CardFooter, Image, Button } from "@nextui-org/react";
import {
Card,
CardHeader,
CardBody,
CardFooter,
Image,
Button,
} from "@nextui-org/react";
const EventsPage = () => {
const [events, setEvents] = useState<any[]>([]);
@@ -24,7 +30,7 @@ const EventsPage = () => {
}, []);
return (
<DefaultLayout>
<div className="w-full h-full">
<div className="p-8">
<div className="mb-6">
<h2 className="text-3xl font-semibold text-primary-600">Events</h2>
@@ -65,7 +71,7 @@ const EventsPage = () => {
)}
</div>
</div>
</DefaultLayout>
</div>
);
};

View File

@@ -1,54 +1,64 @@
import { Card, CardHeader, CardBody, CardFooter, Divider, Button } from "@nextui-org/react";
import DefaultLayout from '../layouts/default';
import { useNavigate } from 'react-router-dom';
import {
Card,
CardHeader,
CardBody,
CardFooter,
Divider,
Button,
} from "@nextui-org/react";
import { useNavigate } from "react-router-dom";
export default function HBContestPage() {
const navigate = useNavigate();
let navigate = useNavigate();
return (
<DefaultLayout>
<section>
<Card className="max-w-[800px] bg-red-50 mx-auto">
<CardHeader className="flex gap-3">
<div className="flex flex-col">
<h2 className="text-md">Home Bill Contest</h2>
</div>
</CardHeader>
<Divider />
<CardBody>
<p>This contest is to encourage residents to reduce the use of electricity and water usage.
This contest would be won by the person with the lowest overall bill average.
Join us in this important effort to create a more sustainable future for everyone.
Participants would be required to input and upload their bills into the form to ensure integrity and honesty. </p>
</CardBody>
<Divider />
<CardFooter>
<div className="flex-col">
<div>
<h4>Winners</h4>
<p>There will 3 winners for each month. Each winner will receive random food vouchers.</p>
<p>1st: 3 vouchers</p>
<p>2nd: 2 vouchers</p>
<p>3rd: 1 voucher</p>
</div>
<div>
<Button
className=" bg-red-500 dark:bg-red-700 text-white"
size="lg"
onPress={() => {
navigate("/hbcform");
}}
>
<p className="font-bold">Join</p>
</Button>
</div>
</div>
</CardFooter>
</Card>
</section>
</DefaultLayout>
)
return (
<div className="w-full h-full">
<section>
<Card className="max-w-[800px] bg-red-50 mx-auto">
<CardHeader className="flex gap-3">
<div className="flex flex-col">
<h2 className="text-md">Home Bill Contest</h2>
</div>
</CardHeader>
<Divider />
<CardBody>
<p>
This contest is to encourage residents to reduce the use of
electricity and water usage. This contest would be won by the
person with the lowest overall bill average. Join us in this
important effort to create a more sustainable future for everyone.
Participants would be required to input and upload their bills
into the form to ensure integrity and honesty.{" "}
</p>
</CardBody>
<Divider />
<CardFooter>
<div className="flex-col">
<div>
<h4>Winners</h4>
<p>
There will 3 winners for each month. Each winner will receive
random food vouchers.
</p>
<p>1st: 3 vouchers</p>
<p>2nd: 2 vouchers</p>
<p>3rd: 1 voucher</p>
</div>
<div>
<Button
className=" bg-red-500 dark:bg-red-700 text-white"
size="lg"
onPress={() => {
navigate("new-submission");
}}
>
<p className="font-bold">Join</p>
</Button>
</div>
</div>
</CardFooter>
</Card>
</section>
</div>
);
}

View File

@@ -1,183 +1,182 @@
import DefaultLayout from '../layouts/default';
import { Button } from '@nextui-org/react';
import { ArrowUTurnLeftIcon } from '../icons';
import { useNavigate } from 'react-router-dom';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';
import config from '../config';
import NextUIFormikInput from '../components/NextUIFormikInput';
import { Button } from "@nextui-org/react";
import { ArrowUTurnLeftIcon } from "../icons";
import { useNavigate } from "react-router-dom";
import { Formik, Form } from "formik";
import * as Yup from "yup";
import config from "../config";
import NextUIFormikInput from "../components/NextUIFormikInput";
import axios from "axios";
import InsertImage from '../components/InsertImage';
import InsertImage from "../components/InsertImage";
const validationSchema = Yup.object({
electricalBill: Yup.number()
.typeError('Must be a number')
.positive("Must be a positive value")
.max(99999.99, "Value is too large")
.required(),
waterBill: Yup.number()
.typeError('Must be a number')
.positive("Must be a positive value")
.max(99999.99, "Value is too large")
.required(),
totalBill: Yup.number()
.typeError('Must be a number')
.positive("Must be a positive value")
.max(99999.99, "Value is too large")
.required(),
noOfDependents: Yup.number()
.typeError('Must be a number')
.integer("Must be a whole number")
.positive("Must be a positive value")
.required(),
electricalBill: Yup.number()
.typeError("Must be a number")
.positive("Must be a positive value")
.max(99999.99, "Value is too large")
.required(),
waterBill: Yup.number()
.typeError("Must be a number")
.positive("Must be a positive value")
.max(99999.99, "Value is too large")
.required(),
totalBill: Yup.number()
.typeError("Must be a number")
.positive("Must be a positive value")
.max(99999.99, "Value is too large")
.required(),
noOfDependents: Yup.number()
.typeError("Must be a number")
.integer("Must be a whole number")
.positive("Must be a positive value")
.required(),
});
export default function HBFormPage() {
let navigate = useNavigate();
const navigate = useNavigate();
const initialValues: {
id: string;
electricalBill: string;
waterBill: string;
totalBill: string;
noOfDependents: string;
ebPicture: File | null;
wbPicture: File | null;
} = {
id: '',
electricalBill: '',
waterBill: '',
totalBill: '',
noOfDependents: '',
ebPicture: null,
wbPicture: null,
};
const initialValues: {
id: string;
electricalBill: string;
waterBill: string;
totalBill: string;
noOfDependents: string;
ebPicture: File | null;
wbPicture: File | null;
} = {
id: "",
electricalBill: "",
waterBill: "",
totalBill: "",
noOfDependents: "",
ebPicture: null,
wbPicture: null,
};
const handleSubmit = async (
values: any,
{ setSubmitting, resetForm, setFieldError, setFieldValue }: any
) => {
const formData = new FormData();
formData.append("electricalBill", values.electricalBill);
formData.append("waterBill", values.waterBill);
formData.append("totalBill", values.totalBill);
formData.append("noOfDependents", values.noOfDependents);
const handleSubmit = async (
values: any,
{ setSubmitting, resetForm, setFieldError, setFieldValue }: any
) => {
const formData = new FormData();
formData.append('electricalBill', values.electricalBill);
formData.append('waterBill', values.waterBill);
formData.append('totalBill', values.totalBill);
formData.append('noOfDependents', values.noOfDependents);
if (values.ebPicture) {
formData.append("ebPicture", values.ebPicture);
}
if (values.ebPicture) {
formData.append('ebPicture', values.ebPicture);
if (values.wbPicture) {
formData.append("wbPicture", values.wbPicture);
}
try {
const response = await axios.post(
config.serverAddress + "/hbcform",
formData,
{
headers: {
"Content-Type": "multipart/form-data",
},
}
);
if (response.status === 200) {
console.log("Form created successfully:", response.data);
resetForm(); // Clear form after successful submit
setFieldValue("ebPicture", null);
setFieldValue("wbPicture", null);
navigate(-1);
} else {
console.error("Error creating form:", response.statusText);
}
} catch (error: any) {
if (error.response && error.response.data && error.response.data.errors) {
const errors = error.response.data.errors;
Object.keys(errors).forEach((key) => {
setFieldError(key, errors[key]);
});
} else {
console.error("Unexpected error:", error);
}
} finally {
setSubmitting(false);
}
};
if (values.wbPicture) {
formData.append('wbPicture', values.wbPicture);
}
try {
const response = await axios.post(config.serverAddress + "/hbcform", formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
if (response.status === 200) {
console.log("Form created successfully:", response.data);
resetForm(); // Clear form after successful submit
setFieldValue('ebPicture', null);
setFieldValue('wbPicture', null);
navigate("/contest");
} else {
console.error("Error creating form:", response.statusText);
}
} catch (error: any) {
if (error.response && error.response.data && error.response.data.errors) {
const errors = error.response.data.errors;
Object.keys(errors).forEach((key) => {
setFieldError(key, errors[key]);
});
} else {
console.error("Unexpected error:", error);
}
} finally {
setSubmitting(false);
}
};
return (
<DefaultLayout>
<section className="w-7/12 mx-auto">
<Button
variant="light"
onPress={() => navigate(-1)}
>
<ArrowUTurnLeftIcon />
</Button>
</section>
<section className="w-7/12 mx-auto p-5 bg-red-100 border border-none rounded-2xl h-600px">
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{({ isValid, dirty, isSubmitting, setFieldValue }) => (
<Form>
<div className="flex flex-col gap-5">
<div className="flex flex-row gap-10">
<div className="flex flex-col gap-5">
<NextUIFormikInput
label="Electrical Bill"
name="electricalBill"
type="text"
placeholder="$"
labelPlacement="inside"
/>
<NextUIFormikInput
label="Water Bill"
name="waterBill"
type="text"
placeholder="$"
labelPlacement="inside"
/>
<NextUIFormikInput
label="Total Bill"
name="totalBill"
type="text"
placeholder="$"
labelPlacement="inside"
/>
<NextUIFormikInput
label="Number of dependents"
name="noOfDependents"
type="text"
placeholder="0"
labelPlacement="inside"
/>
</div>
<div className="flex flex-row gap-8 max-w-xs h-[500px]">
<InsertImage
onImageSelected={(file) => {
setFieldValue('ebPicture', file);
}}
/>
<InsertImage
onImageSelected={(file) => {
setFieldValue('wbPicture', file);
}}
/>
</div>
</div>
<div>
<Button
type="submit"
className="bg-red-500 dark:bg-red-700 text-white"
isDisabled={!isValid || !dirty || isSubmitting}
>
<p>Submit</p>
</Button>
</div>
</div>
</Form>
)}
</Formik>
</section>
</DefaultLayout>
);
return (
<div className="w-full h-full">
<section className="w-7/12 mx-auto">
<Button variant="light" onPress={() => navigate(-1)}>
<ArrowUTurnLeftIcon />
</Button>
</section>
<section className="w-7/12 mx-auto p-5 bg-red-100 border border-none rounded-2xl h-600px">
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{({ isValid, dirty, isSubmitting, setFieldValue }) => (
<Form>
<div className="flex flex-col gap-5">
<div className="flex flex-row gap-10">
<div className="flex flex-col gap-5">
<NextUIFormikInput
label="Electrical Bill"
name="electricalBill"
type="text"
placeholder="$"
labelPlacement="inside"
/>
<NextUIFormikInput
label="Water Bill"
name="waterBill"
type="text"
placeholder="$"
labelPlacement="inside"
/>
<NextUIFormikInput
label="Total Bill"
name="totalBill"
type="text"
placeholder="$"
labelPlacement="inside"
/>
<NextUIFormikInput
label="Number of dependents"
name="noOfDependents"
type="text"
placeholder="0"
labelPlacement="inside"
/>
</div>
<div className="flex flex-row gap-8 max-w-xs h-[500px]">
<InsertImage
onImageSelected={(file) => {
setFieldValue("ebPicture", file);
}}
/>
<InsertImage
onImageSelected={(file) => {
setFieldValue("wbPicture", file);
}}
/>
</div>
</div>
<div>
<Button
type="submit"
className="bg-red-500 dark:bg-red-700 text-white"
isDisabled={!isValid || !dirty || isSubmitting}
>
<p>Submit</p>
</Button>
</div>
</div>
</Form>
)}
</Formik>
</section>
</div>
);
}

View File

@@ -1,11 +1,9 @@
import { Button } from "@nextui-org/react";
import { useNavigate } from "react-router-dom";
import DefaultLayout from "../layouts/default";
export default function HomePage() {
const navigate = useNavigate();
return (
<DefaultLayout>
<div className="w-full h-full">
<p>Home</p>
<Button
onPress={() => {
@@ -14,6 +12,6 @@ export default function HomePage() {
>
Sign up!
</Button>
</DefaultLayout>
</div>
);
}

View File

@@ -1,6 +1,14 @@
import React, { useEffect, useState } from 'react';
import DefaultLayout from "../layouts/default";
import { Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, Avatar, Button } from "@nextui-org/react";
import React, { useEffect, useState } from "react";
import {
Table,
TableHeader,
TableColumn,
TableBody,
TableRow,
TableCell,
Avatar,
Button,
} from "@nextui-org/react";
import { useNavigate } from "react-router-dom";
import { PencilSquareIcon, TrashIcon } from "../icons";
import axios from "axios";
@@ -38,7 +46,7 @@ const ManageEventsPage = () => {
};
return (
<DefaultLayout>
<div className="w-full h-full">
<div className="mb-6">
<h2 className="text-3xl font-semibold text-red-600">Manage Events</h2>
</div>
@@ -57,7 +65,10 @@ const ManageEventsPage = () => {
<TableRow key={event.id}>
<TableCell>
<div className="flex items-center">
<Avatar src={`${config.serverAddress}${event.imageUrl}`} className="mr-4" />
<Avatar
src={`${config.serverAddress}${event.imageUrl}`}
className="mr-4"
/>
{event.title}
</div>
</TableCell>
@@ -92,13 +103,12 @@ const ManageEventsPage = () => {
</Table>
<Button
className="mt-6 bg-red-600 text-white"
onPress={() => navigate("/CreateEvent")}
onPress={() => navigate("createEvent")}
>
Add events
</Button>
</DefaultLayout>
</div>
);
};
export default ManageEventsPage;

View File

@@ -1,4 +1,3 @@
import DefaultLayout from "../layouts/default";
import UpdateAccountModule from "../components/UpdateAccountModule";
import { useNavigate } from "react-router-dom";
@@ -10,12 +9,12 @@ export default function ManageUserAccountPage() {
}
return (
<DefaultLayout>
<div className="w-full h-full">
<div>
<div className="p-8 flex flex-col gap-8">
<UpdateAccountModule />
</div>
</div>
</DefaultLayout>
</div>
);
}

View File

@@ -1,196 +1,200 @@
import { useParams, useNavigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
import DefaultLayout from "../layouts/default";
import { useParams, useNavigate } from "react-router-dom";
import { useEffect, useState } from "react";
import instance from "../security/http";
import config from "../config";
import {
Button,
Avatar,
Dropdown,
DropdownTrigger,
DropdownMenu,
DropdownItem,
Chip,
Modal,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
useDisclosure,
Spinner,
} from "@nextui-org/react";
Button,
Avatar,
Dropdown,
DropdownTrigger,
DropdownMenu,
DropdownItem,
Chip,
Modal,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
useDisclosure,
Spinner,
} from "@nextui-org/react";
import {
ChatBubbleOvalLeftEllipsisIcon,
EllipsisHorizontalIcon,
HandThumbsUpIcon,
ArrowUTurnLeftIcon,
ChatBubbleOvalLeftEllipsisIcon,
EllipsisHorizontalIcon,
HandThumbsUpIcon,
ArrowUTurnLeftIcon,
} from "../icons";
interface Post {
title: string;
postImage: Blob;
content: string;
tags: string;
id: number;
title: string;
postImage: Blob;
content: string;
tags: string;
id: number;
}
const PostPage: React.FC = () => {
const navigate = useNavigate();
const { id } = useParams<{ id: string }>();
const [post, setPost] = useState<Post | null>(null);
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const [selectedPost, setSelectedPost] = useState<Post | null>(null);
const navigate = useNavigate();
const { id } = useParams<{ id: string }>();
const [post, setPost] = useState<Post | null>(null);
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const [selectedPost, setSelectedPost] = useState<Post | null>(null);
useEffect(() => {
if (id) {
instance.get(`${config.serverAddress}/post/${id}`).then((res) => {
setPost(res.data);
});
}
}, [id]);
if (!post) {
return <div className="flex justify-center min-h-screen"><Spinner label="Loading..." color="danger" /></div>;
useEffect(() => {
if (id) {
instance.get(`${config.serverAddress}/post/${id}`).then((res) => {
setPost(res.data);
});
}
}, [id]);
const handleDeleteClick = (post: Post) => {
setSelectedPost(post);
onOpen();
};
const handleDeleteConfirm = async () => {
if (selectedPost) {
try {
await instance.delete(
config.serverAddress + `/post/${selectedPost.id}`
);
onOpenChange();
} catch (error) {
console.error("Error deleting post:", error);
}
}
};
if (!post) {
return (
<DefaultLayout>
<section className="flex">
<div className="w-2/12 flex justify-end">
<Button
variant="light"
onPress={() => {
navigate(-1);
}}
>
<ArrowUTurnLeftIcon />
</Button>
<div className="flex justify-center min-h-screen">
<Spinner label="Loading..." color="danger" />
</div>
);
}
const handleDeleteClick = (post: Post) => {
setSelectedPost(post);
onOpen();
};
const handleDeleteConfirm = async () => {
if (selectedPost) {
try {
await instance.delete(
config.serverAddress + `/post/${selectedPost.id}`
);
onOpenChange();
} catch (error) {
console.error("Error deleting post:", error);
}
}
};
return (
<div className="w-full h-full">
<section className="flex">
<div className="w-2/12 flex justify-end">
<Button
variant="light"
onPress={() => {
navigate(-1);
}}
>
<ArrowUTurnLeftIcon />
</Button>
</div>
<div className="flex flex-row w-full gap-4 mx-auto ">
<div className="flex flex-col gap-8 w-full">
<div className="flex flex-col gap-4">
<section
className="flex flex-row gap-4 bg-primary-50 dark:bg-primary-950 border border-none rounded-2xl p-4"
key={post.id}
>
<div>
<Avatar
src="https://pbs.twimg.com/media/GOva9x5a0AAK8Bn?format=jpg&name=large"
size="lg"
/>
</div>
<div className="flex flex-row w-full gap-4 mx-auto ">
<div className="flex flex-col gap-8 w-full">
<div className="flex flex-col gap-4">
<section
className="flex flex-row gap-4 bg-primary-50 dark:bg-primary-950 border border-none rounded-2xl p-4"
key={post.id}>
<div>
<Avatar
src="https://pbs.twimg.com/media/GOva9x5a0AAK8Bn?format=jpg&name=large"
size="lg"
/>
</div>
<div className="flex flex-col gap-8 w-full">
<div className="h-full flex flex-col gap-4">
<div className="flex flex-row justify-between">
<div className="flex flex-col">
<p className="text-xl font-bold">{post.title}</p>
<p className="text-md text-neutral-500">Adam</p>
</div>
<div className="flex flex-row-reverse justify-center items-center">
<Dropdown>
<DropdownTrigger className="justify-center items-center">
<Button isIconOnly variant="light">
<EllipsisHorizontalIcon />
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Static Actions">
<DropdownItem
key="edit"
onClick={() => {
navigate(`/editPost/${post.id}`);
}}>
Edit
</DropdownItem>
<DropdownItem
key="delete"
className="text-danger"
color="danger"
onClick={() => handleDeleteClick(post)}
>
Delete
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
</div>
<div>
<p>{post.content}</p>
</div>
<div>
<p>Image</p>
{/* {userInformation && (
<div className="flex flex-col gap-8 w-full">
<div className="h-full flex flex-col gap-4">
<div className="flex flex-row justify-between">
<div className="flex flex-col">
<p className="text-xl font-bold">{post.title}</p>
<p className="text-md text-neutral-500">Adam</p>
</div>
<div className="flex flex-row-reverse justify-center items-center">
<Dropdown>
<DropdownTrigger className="justify-center items-center">
<Button isIconOnly variant="light">
<EllipsisHorizontalIcon />
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Static Actions">
<DropdownItem
key="edit"
onClick={() => {
navigate(`edit/${post.id}`);
}}
>
Edit
</DropdownItem>
<DropdownItem
key="delete"
className="text-danger"
color="danger"
onClick={() => handleDeleteClick(post)}
>
Delete
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
</div>
<div>
<p>{post.content}</p>
</div>
<div>
<p>Image</p>
{/* {userInformation && (
<UserPostImage
userId={userInformation}
editable={true}
/>
)} */}
</div>
</div>
<div className="flex flex-col gap-2">
<div className="flex flex-row gap-2">
<Chip>Tag 1</Chip>
<Chip>Tag 2</Chip>
</div>
<div className="flex flex-row">
<Button variant="light" isIconOnly>
<HandThumbsUpIcon />
</Button>
<Button variant="light" isIconOnly>
<ChatBubbleOvalLeftEllipsisIcon />
</Button>
<Button variant="light" isIconOnly>
<EllipsisHorizontalIcon />
</Button>
</div>
</div>
</div>
</section>
</div>
</div>
</div>
<div className="flex flex-col gap-2">
<div className="flex flex-row gap-2">
<Chip>Tag 1</Chip>
<Chip>Tag 2</Chip>
</div>
<div className="flex flex-row">
<Button variant="light" isIconOnly>
<HandThumbsUpIcon />
</Button>
<Button variant="light" isIconOnly>
<ChatBubbleOvalLeftEllipsisIcon />
</Button>
<Button variant="light" isIconOnly>
<EllipsisHorizontalIcon />
</Button>
</div>
</div>
</div>
</section>
</div>
<div className="w-2/12">
</div>
</section>
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">
Confirm Delete
</ModalHeader>
<ModalBody>
<p>Are you sure you want to delete this post?</p>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose}>
Close
</Button>
<Button color="primary" onPress={handleDeleteConfirm}>
Confirm
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</DefaultLayout>
);
}
</div>
</div>
<div className="w-2/12"></div>
</section>
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">
Confirm Delete
</ModalHeader>
<ModalBody>
<p>Are you sure you want to delete this post?</p>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose}>
Close
</Button>
<Button color="primary" onPress={handleDeleteConfirm}>
Confirm
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</div>
);
};
export default PostPage;

View File

@@ -12,7 +12,6 @@ import {
TableHeader,
TableRow,
} from "@nextui-org/react";
import DefaultLayout from "../layouts/default";
import { useEffect, useState } from "react";
import config from "../config";
import instance from "../security/http";
@@ -30,7 +29,7 @@ interface Schedule {
const statusColorMap: Record<string, ChipProps["color"]> = {
"On going": "success",
"Up coming": "danger",
"Ended": "default",
Ended: "default",
};
const getStatusColor = (status: string): ChipProps["color"] => {
@@ -97,7 +96,7 @@ export default function SchedulePage() {
};
return (
<DefaultLayout>
<div className="w-full h-full">
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
<h1>Karang Guni Schedule</h1>
<div className="flex gap-4">
@@ -201,6 +200,6 @@ export default function SchedulePage() {
</div>
</div>
</section>
</DefaultLayout>
</div>
);
}

View File

@@ -1,11 +1,10 @@
import SignInModule from "../components/SignInModule";
import DefaultLayout from "../layouts/default";
import SignedInStatusVerifier from "../components/SignedInStatusVerifier";
export default function SignInPage() {
return (
<SignedInStatusVerifier>
<DefaultLayout>
<div className="w-full h-full">
<div className="flex flex-col h-full">
<div className="flex flex-row h-full">
<div className="w-3/5 relative">
@@ -33,7 +32,7 @@ export default function SignInPage() {
</div>
</div>
</div>
</DefaultLayout>
</div>
</SignedInStatusVerifier>
);
}

View File

@@ -1,11 +1,10 @@
import SignUpModule from "../components/SignUpModule";
import DefaultLayout from "../layouts/default";
import SignedInStatusVerifier from "../components/SignedInStatusVerifier";
export default function SignUpPage() {
return (
<SignedInStatusVerifier>
<DefaultLayout>
<div className="w-full h-full">
<div className="flex flex-col h-full">
<div className="flex flex-row h-full">
<div className="w-3/5 relative">
@@ -33,7 +32,7 @@ export default function SignUpPage() {
</div>
</div>
</div>
</DefaultLayout>
</div>
</SignedInStatusVerifier>
);
}

View File

@@ -1,5 +1,4 @@
import { useNavigate } from "react-router-dom";
import DefaultLayout from "../layouts/default";
import { useEffect, useState } from "react";
import { Button, Card, Link } from "@nextui-org/react";
import { LockClosedIcon, PencilSquareIcon } from "../icons";
@@ -14,8 +13,8 @@ export default function SpringboardPage() {
if (!accessToken) {
navigate("/signin");
}
let [userInformation, setUserInformation] = useState<any>();
let [accountUnavailable, setAccountUnavaliable] = useState(false);
const [userInformation, setUserInformation] = useState<any>();
const [accountUnavailable, setAccountUnavaliable] = useState(false);
let timeOfDay = getTimeOfDay();
let greeting = "";
@@ -42,7 +41,7 @@ export default function SpringboardPage() {
}, []);
return (
<DefaultLayout>
<div className="w-full h-full">
<div>
{userInformation && (
<div className="flex flex-col w-full">
@@ -165,6 +164,6 @@ export default function SpringboardPage() {
</div>
)}
</div>
</DefaultLayout>
</div>
);
}

View File

@@ -9,7 +9,7 @@ const instance = axios.create({
instance.interceptors.request.use(
function (config) {
// Do something before request is sent
let accessToken = localStorage.getItem("accessToken");
const accessToken = localStorage.getItem("accessToken");
if (accessToken) {
config.headers["Authorization"] = `Bearer ${accessToken}`;
}