Skip to content

Commit

Permalink
final website changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Anthonyp0329 committed Oct 10, 2024
1 parent bd99103 commit f5a45a2
Show file tree
Hide file tree
Showing 50 changed files with 5,983 additions and 2,494 deletions.
Binary file modified .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,6 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
backend/service_credentials/
.firebase/
.firebase/
2 changes: 2 additions & 0 deletions admin-portal-frontend/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ public/
next.config.js
vite.config.ts
postcss.config.js
src/app/firebase-admin.tsx
src/app/AuthContext.js
2 changes: 2 additions & 0 deletions admin-portal-frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

dfm-sideline-sidekick-app-firebase-adminsdk-mqgtq-32d66e30cf.json
6,004 changes: 4,237 additions & 1,767 deletions admin-portal-frontend/package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions admin-portal-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2",
"bootstrap": "^5.3.3",
"dotenv": "^16.4.5",
"firebase": "^9.23.0",
"firebase-admin": "^12.6.0",
"next": "14.1.4",
"react": "^18",
"react-bootstrap": "^2.10.2",
Expand Down
44 changes: 39 additions & 5 deletions admin-portal-frontend/src/app/add-emergency/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
"use client";

import { useRouter, useSearchParams } from "next/navigation";
import React, { ChangeEvent, useEffect, useState } from "react";
import React, { ChangeEvent, Suspense, useEffect, useState } from "react";

import { Category, addPage } from "../api/Categories";
import { Category, addPage, deletePage } from "../api/Categories";
import { createEmergency, getEmergency, updateEmergency } from "../api/emergencies";
import ProtectedRoute from "../components/ProtectedRoute";
import PublishPopup from "../components/PublishPopup";
import Toast from "../components/Toast";
import CloseIcon from "../icons/close.svg";

type IconProps = {
"content-type": string;
src: string;
};

export default function AddEmergency() {
function AddEmergencyPage() {
const searchParams = useSearchParams();
const router = useRouter();
const categoryString = searchParams.get("category");
Expand All @@ -28,6 +30,7 @@ export default function AddEmergency() {
const [treatDetails, setTreatDetails] = useState([""]);
const [popupVisible, setPopupVisible] = useState(false);
const [prevEmergency, setPrevEmergency] = useState({ _id: "" });
const [toast, showToast] = useState(false);

const [page, setPage] = useState({
title: "",
Expand Down Expand Up @@ -72,20 +75,31 @@ export default function AddEmergency() {
const publishEmergency = async () => {
try {
setPopupVisible(false);
if (page.title === "" || page.subtitle === "") {
showToast(true);
return;
}
const newPage = { ...page };
newPage.overview = Object.fromEntries(
overviewHeaders.map((key, i) => [key, overviewDetails[i]]),
);
newPage.treatment = Object.fromEntries(treatHeaders.map((key, i) => [key, treatDetails[i]]));

const newCategory = { ...category };
if (title) {
const toAdd = { ...newPage, _id: prevEmergency._id };
if (newPage.title !== title) {
await deletePage(category._id, title);
await addPage(category._id, newPage.title);
newCategory.items = newCategory.items.filter((item) => item !== title);
newCategory.items.push(newPage.title);
}
await updateEmergency(toAdd);
} else {
await createEmergency(newPage);
await addPage(category._id, newPage.title);
newCategory.items.push(newPage.title);
}
const encodedCategory = encodeURIComponent(JSON.stringify(category));
const encodedCategory = encodeURIComponent(JSON.stringify(newCategory));
router.push(`/category?category=${encodedCategory}`);
} catch (error) {
console.error("Error deleting category:", error);
Expand Down Expand Up @@ -298,6 +312,26 @@ export default function AddEmergency() {
onCancel={handleCancel}
/>
)}
{toast && (
<Toast
backgroundColor={"#FF0000"}
message={"Title and subtitle must be non-empty"}
onClose={() => {
showToast(false);
}}
isError={true}
/>
)}
</div>
);
}

export default function AddEmergency() {
return (
<ProtectedRoute>
<Suspense>
<AddEmergencyPage />
</Suspense>
</ProtectedRoute>
);
}
44 changes: 39 additions & 5 deletions admin-portal-frontend/src/app/add-principle/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
"use client";

import { useRouter, useSearchParams } from "next/navigation";
import React, { ChangeEvent, useEffect, useState } from "react";
import React, { ChangeEvent, Suspense, useEffect, useState } from "react";

import { Category, addPage } from "../api/Categories";
import { Category, addPage, deletePage } from "../api/Categories";
import {
createGeneralPrinciple,
getGeneralPrinciple,
updateGeneralPrinciple,
} from "../api/principles";
import ProtectedRoute from "../components/ProtectedRoute";
import PublishPopup from "../components/PublishPopup";
import Toast from "../components/Toast";
import CloseIcon from "../icons/close.svg";

type IconProps = {
"content-type": string;
src: string;
};

export default function AddEmergency() {
function AddPrinciplePage() {
const searchParams = useSearchParams();
const router = useRouter();
const categoryString = searchParams.get("category");
Expand All @@ -30,6 +32,7 @@ export default function AddEmergency() {
const [contentDetails, setContentDetails] = useState([""]);
const [popupVisible, setPopupVisible] = useState(false);
const [prevPrinciple, setPrevPrinciple] = useState({ _id: "" });
const [toast, showToast] = useState(false);

const [page, setPage] = useState({
title: "",
Expand Down Expand Up @@ -70,19 +73,30 @@ export default function AddEmergency() {
const publishPrinciple = async () => {
try {
setPopupVisible(false);
if (page.title === "" || page.subtitle === "") {
showToast(true);
return;
}
const newPage = { ...page };
newPage.content = Object.fromEntries(
contentHeaders.map((key, i) => [key, contentDetails[i]]),
);

const newCategory = { ...category };
if (title) {
const toAdd = { ...newPage, _id: prevPrinciple._id };
if (newPage.title !== title) {
await deletePage(category._id, title);
await addPage(category._id, newPage.title);
newCategory.items = newCategory.items.filter((item) => item !== title);
newCategory.items.push(newPage.title);
}
await updateGeneralPrinciple(toAdd);
} else {
await createGeneralPrinciple(newPage);
await addPage(category._id, newPage.title);
newCategory.items.push(newPage.title);
}
const encodedCategory = encodeURIComponent(JSON.stringify(category));
const encodedCategory = encodeURIComponent(JSON.stringify(newCategory));
router.push(`/category?category=${encodedCategory}`);
} catch (error) {
console.error("Error deleting category:", error);
Expand Down Expand Up @@ -225,6 +239,26 @@ export default function AddEmergency() {
onCancel={handleCancel}
/>
)}
{toast && (
<Toast
backgroundColor={"#FF0000"}
message={"Title and subtitle must be non-empty"}
onClose={() => {
showToast(false);
}}
isError={true}
/>
)}
</div>
);
}

export default function AddPrinciple() {
return (
<ProtectedRoute>
<Suspense>
<AddPrinciplePage />
</Suspense>
</ProtectedRoute>
);
}
2 changes: 0 additions & 2 deletions admin-portal-frontend/src/app/api/Categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ export const addCategory = async (title: string, type: string) => {
if (!url) {
throw new Error("API URL is not defined");
}
console.log(title);
console.log(type);

await fetch(url, {
method: "POST",
Expand Down
111 changes: 111 additions & 0 deletions admin-portal-frontend/src/app/api/admins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { APIResult, handleAPIError } from "./requests";

export type Admin = {
email: string;
firstName: string;
lastName: string;
phoneNumber: string;
title: string;
superUser: boolean;
};

// addadmin, delete admin by email, get all admins
export async function checkAdmin(email: string): Promise<boolean> {
try {
if (!process.env.API_URL) {
throw new Error("API URL is not defined");
}

const url = `${process.env.API_URL}/admin/${email}`;

const response = await fetch(url, {
method: "GET",
});
const json = (await response.json()) as boolean;
return json;
} catch (error) {
console.log(error);
return false;
}
}

export async function addAdmin(admin: Admin): Promise<APIResult<Admin>> {
try {
if (!process.env.API_URL) {
throw new Error("API URL is not defined");
}

const url = `${process.env.API_URL}/admin`;

const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(admin),
});
const json = (await response.json()) as Admin;
return { success: true, data: json };
} catch (error) {
return handleAPIError(error);
}
}

export async function deleteAdminByEmail(email: string): Promise<APIResult<Admin>> {
try {
if (!process.env.API_URL) {
throw new Error("API URL is not defined");
}

const url = `${process.env.API_URL}/admin/${email}`;
const response = await fetch(url, {
method: "DELETE",
});
if (!response.ok) {
throw new Error("Admin cannot be deleted");
}
const json = (await response.json()) as Admin;
return { success: true, data: json };
} catch (error) {
console.log(error);
return handleAPIError(error);
}
}

export async function getAllAdmins(): Promise<Admin[]> {
try {
if (!process.env.API_URL) {
throw new Error("API URL is not defined");
}

const url = `${process.env.API_URL}/allAdmins`;
const response = await fetch(url, {
method: "GET",
});
const json = (await response.json()) as Admin[];

return json;
} catch (error) {
console.log(error);
return [];
}
}

export async function checkSuperAdmin(email: string): Promise<boolean> {
try {
if (!process.env.API_URL) {
throw new Error("API URL is not defined");
}

const url = `${process.env.API_URL}/isSuperAdmin/${email}`;

const response = await fetch(url, {
method: "GET",
});
const json = (await response.json()) as boolean;
return json;
} catch (error) {
console.log(error);
return false;
}
}
20 changes: 18 additions & 2 deletions admin-portal-frontend/src/app/api/emergencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export async function createEmergency(
}

const url = `${process.env.API_URL}/emergencies`;
console.log(emergency);
console.log(url);

const response = await fetch(url, {
method: "POST",
Expand Down Expand Up @@ -134,3 +132,21 @@ export async function updateEmergency(
return handleAPIError(error);
}
}

export async function deleteEmergency(title: string): Promise<APIResult<Emergency>> {
try {
if (!process.env.API_URL) {
throw new Error("API URL is not defined");
}

const url = `${process.env.API_URL}/emergencies/${title}`;
const response = await fetch(url, {
method: "DELETE",
});
const json = (await response.json()) as Emergency;
await updateVersion();
return { success: true, data: json };
} catch (error) {
return handleAPIError(error);
}
}
18 changes: 18 additions & 0 deletions admin-portal-frontend/src/app/api/principles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,21 @@ export async function updateGeneralPrinciple(
return handleAPIError(error);
}
}

export async function deleteGeneralPrinciple(title: string): Promise<APIResult<GeneralPrinciple>> {
try {
if (!process.env.API_URL) {
throw new Error("API URL is not defined");
}

const url = `${process.env.API_URL}/generalPrinciples/${title}`;
const response = await fetch(url, {
method: "DELETE",
});
const json = (await response.json()) as GeneralPrinciple;
await updateVersion();
return { success: true, data: json };
} catch (error) {
return handleAPIError(error);
}
}
Loading

0 comments on commit f5a45a2

Please sign in to comment.