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,18 +26,29 @@ 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) => {
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,7 +41,6 @@ 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">
@@ -65,16 +63,13 @@ export default function AdministratorSpringboard() {
</div>
}
onPress={() => {
navigate("/manage-account/");
navigate("/manage-account");
}}
>
Manage your account
</Button>
</div>
<UserProfilePicture
userId={userInformation.id}
editable={false}
/>
<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">
@@ -107,7 +102,6 @@ export default function AdministratorSpringboard() {
</div>
</Card>
</div>
</AdministratorLayout>
)}
</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,14 +1,18 @@
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() {
let navigate = useNavigate();
const navigate = useNavigate();
return (
<DefaultLayout>
<div className="w-full h-full">
<section>
<Card className="max-w-[800px] bg-red-50 mx-auto">
<CardHeader className="flex gap-3">
@@ -18,17 +22,24 @@ export default function HBContestPage() {
</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>
<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>
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>
@@ -38,7 +49,7 @@ export default function HBContestPage() {
className=" bg-red-500 dark:bg-red-700 text-white"
size="lg"
onPress={() => {
navigate("/hbcform");
navigate("new-submission");
}}
>
<p className="font-bold">Join</p>
@@ -48,7 +59,6 @@ export default function HBContestPage() {
</CardFooter>
</Card>
</section>
</DefaultLayout>
)
</div>
);
}

View File

@@ -1,39 +1,38 @@
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')
.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')
.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')
.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')
.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;
@@ -44,46 +43,49 @@ export default function HBFormPage() {
ebPicture: File | null;
wbPicture: File | null;
} = {
id: '',
electricalBill: '',
waterBill: '',
totalBill: '',
noOfDependents: '',
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);
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);
formData.append("ebPicture", values.ebPicture);
}
if (values.wbPicture) {
formData.append('wbPicture', values.wbPicture);
formData.append("wbPicture", values.wbPicture);
}
try {
const response = await axios.post(config.serverAddress + "/hbcform", formData, {
const response = await axios.post(
config.serverAddress + "/hbcform",
formData,
{
headers: {
'Content-Type': 'multipart/form-data'
"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");
setFieldValue("ebPicture", null);
setFieldValue("wbPicture", null);
navigate(-1);
} else {
console.error("Error creating form:", response.statusText);
}
@@ -102,12 +104,9 @@ export default function HBFormPage() {
};
return (
<DefaultLayout>
<div className="w-full h-full">
<section className="w-7/12 mx-auto">
<Button
variant="light"
onPress={() => navigate(-1)}
>
<Button variant="light" onPress={() => navigate(-1)}>
<ArrowUTurnLeftIcon />
</Button>
</section>
@@ -154,12 +153,12 @@ export default function HBFormPage() {
<div className="flex flex-row gap-8 max-w-xs h-[500px]">
<InsertImage
onImageSelected={(file) => {
setFieldValue('ebPicture', file);
setFieldValue("ebPicture", file);
}}
/>
<InsertImage
onImageSelected={(file) => {
setFieldValue('wbPicture', file);
setFieldValue("wbPicture", file);
}}
/>
</div>
@@ -178,6 +177,6 @@ export default function HBFormPage() {
)}
</Formik>
</section>
</DefaultLayout>
</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,6 +1,5 @@
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 {
@@ -18,12 +17,12 @@ import {
ModalFooter,
useDisclosure,
Spinner,
} from "@nextui-org/react";
} from "@nextui-org/react";
import {
ChatBubbleOvalLeftEllipsisIcon,
EllipsisHorizontalIcon,
HandThumbsUpIcon,
ArrowUTurnLeftIcon,
ChatBubbleOvalLeftEllipsisIcon,
EllipsisHorizontalIcon,
HandThumbsUpIcon,
ArrowUTurnLeftIcon,
} from "../icons";
interface Post {
@@ -50,7 +49,11 @@ const PostPage: React.FC = () => {
}, [id]);
if (!post) {
return <div className="flex justify-center min-h-screen"><Spinner label="Loading..." color="danger" /></div>;
return (
<div className="flex justify-center min-h-screen">
<Spinner label="Loading..." color="danger" />
</div>
);
}
const handleDeleteClick = (post: Post) => {
@@ -71,7 +74,7 @@ const PostPage: React.FC = () => {
};
return (
<DefaultLayout>
<div className="w-full h-full">
<section className="flex">
<div className="w-2/12 flex justify-end">
<Button
@@ -88,7 +91,8 @@ const PostPage: React.FC = () => {
<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}>
key={post.id}
>
<div>
<Avatar
src="https://pbs.twimg.com/media/GOva9x5a0AAK8Bn?format=jpg&name=large"
@@ -113,8 +117,9 @@ const PostPage: React.FC = () => {
<DropdownItem
key="edit"
onClick={() => {
navigate(`/editPost/${post.id}`);
}}>
navigate(`edit/${post.id}`);
}}
>
Edit
</DropdownItem>
<DropdownItem
@@ -164,8 +169,7 @@ const PostPage: React.FC = () => {
</div>
</div>
</div>
<div className="w-2/12">
</div>
<div className="w-2/12"></div>
</section>
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
<ModalContent>
@@ -189,8 +193,8 @@ const PostPage: React.FC = () => {
)}
</ModalContent>
</Modal>
</DefaultLayout>
</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}`;
}