diff --git a/.github/workflows/lint-check.yml b/.github/workflows/lint-check.yml index cc2ed80..3d43592 100644 --- a/.github/workflows/lint-check.yml +++ b/.github/workflows/lint-check.yml @@ -16,16 +16,6 @@ jobs: run: | npm ci npm run lint-check - frontend: - name: Frontend lint and style check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - - working-directory: dfm-sideline-sidekick-app # Change this to the name of your frontend directory - run: | - npm ci - npm run lint-check admin-portal-frontend: name: Admin portal frontend lint and style check runs-on: ubuntu-latest diff --git a/admin-portal-frontend/next.config.mjs b/admin-portal-frontend/next.config.mjs index b26145e..2f61a7d 100644 --- a/admin-portal-frontend/next.config.mjs +++ b/admin-portal-frontend/next.config.mjs @@ -5,7 +5,6 @@ const nextConfig = { env: { API_URL: process.env.API_URL, }, - output: "export", images: { unoptimized: true, }, diff --git a/admin-portal-frontend/src/app/pages/EmergencyFlowStyles.tsx b/admin-portal-frontend/src/app/add-emergency/EmergencyFlowStyles.tsx similarity index 100% rename from admin-portal-frontend/src/app/pages/EmergencyFlowStyles.tsx rename to admin-portal-frontend/src/app/add-emergency/EmergencyFlowStyles.tsx diff --git a/admin-portal-frontend/src/app/pages/EmergencyFlow.tsx b/admin-portal-frontend/src/app/add-emergency/page.tsx similarity index 97% rename from admin-portal-frontend/src/app/pages/EmergencyFlow.tsx rename to admin-portal-frontend/src/app/add-emergency/page.tsx index b52b8a4..4ba563e 100644 --- a/admin-portal-frontend/src/app/pages/EmergencyFlow.tsx +++ b/admin-portal-frontend/src/app/add-emergency/page.tsx @@ -1,8 +1,5 @@ "use client"; -// import searchIcon from "../icons/ic_search_grey.png"; -// import Image from "next/image"; -import { useRouter } from "next/navigation"; import React from "react"; import { CreateEmergencyRequest, createEmergency } from "../../../emergencies"; @@ -58,7 +55,6 @@ const EmergencyFlow: React.FC = () => { const [acuteManagement, setAcuteManagement] = React.useState(""); const [dispo, setDispo] = React.useState(""); const [considerations, setConsiderations] = React.useState(""); - const router = useRouter(); const handlePublish = () => { //make an object of type CreateEmergencyRequest @@ -120,7 +116,6 @@ const EmergencyFlow: React.FC = () => { setDispo(""); setConsiderations(""); //redirect to homepage/main page - router.push("/"); } else { // You should always clearly inform the user when something goes wrong. // In this case, we're just doing an `alert()` for brevity, but you'd diff --git a/admin-portal-frontend/src/app/api/Categories.ts b/admin-portal-frontend/src/app/api/Categories.ts index 837706c..9d6ca14 100644 --- a/admin-portal-frontend/src/app/api/Categories.ts +++ b/admin-portal-frontend/src/app/api/Categories.ts @@ -1,3 +1,5 @@ +import { updateVersion } from "./Version"; + export type Category = { _id: string; title: string; @@ -44,6 +46,8 @@ export const deleteCategory = async (itemId: string) => { await fetch(url, { method: "DELETE", }); + + await updateVersion(); } catch (error) { console.log("Error delete category", error); } @@ -65,6 +69,35 @@ export const deletePage = async (itemId: string, title: string) => { await fetch(url, { method: "PUT", }); + + await updateVersion(); + } catch (error) { + console.log("Error deleting page", error); + } +}; + +// Add a page (title) to a category +export const addPage = async (itemId: string, title: string) => { + try { + if (!process.env.API_URL) { + throw new Error("API URL is not defined"); + } + + const url = `${process.env.API_URL}/categories/${itemId}`; + + if (!url) { + throw new Error("API URL is not defined"); + } + + await fetch(url, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ title }), + }); + + await updateVersion(); } catch (error) { console.log("Error deleting page", error); } diff --git a/admin-portal-frontend/src/app/api/Version.ts b/admin-portal-frontend/src/app/api/Version.ts new file mode 100644 index 0000000..ecc8c53 --- /dev/null +++ b/admin-portal-frontend/src/app/api/Version.ts @@ -0,0 +1,15 @@ +export const updateVersion = async (): Promise => { + try { + if (!process.env.API_URL) { + throw new Error("API URL is not defined"); + } + + const url = `${process.env.API_URL}/version`; + + await fetch(url, { + method: "PUT", + }); + } catch (error) { + console.log("Error updating version", error); + } +}; diff --git a/admin-portal-frontend/src/app/category/page.tsx b/admin-portal-frontend/src/app/category/page.tsx new file mode 100644 index 0000000..0128124 --- /dev/null +++ b/admin-portal-frontend/src/app/category/page.tsx @@ -0,0 +1,18 @@ +"use client"; + +import { useSearchParams } from "next/navigation"; + +import { Category } from "../api/Categories"; + +const CategoryDetail: React.FC = () => { + const searchParams = useSearchParams(); + const categoryString = searchParams.get("category"); + const category = categoryString ? (JSON.parse(categoryString) as Category) : null; + return ( +
+

Category Detail: {category.title}

+
+ ); +}; + +export default CategoryDetail; diff --git a/admin-portal-frontend/src/app/components/CategoryContainer.tsx b/admin-portal-frontend/src/app/components/CategoryContainer.tsx index 90e0440..a288cf6 100644 --- a/admin-portal-frontend/src/app/components/CategoryContainer.tsx +++ b/admin-portal-frontend/src/app/components/CategoryContainer.tsx @@ -110,7 +110,6 @@ export const CategoryContainer: React.FC<{ {categories - // gets only either emergency or general principle .filter((category) => category.type === type) .map((category: Category) => { return ( diff --git a/admin-portal-frontend/src/app/components/VerticalNavBar.tsx b/admin-portal-frontend/src/app/components/VerticalNavBar.tsx index 1af841d..83cffe8 100644 --- a/admin-portal-frontend/src/app/components/VerticalNavBar.tsx +++ b/admin-portal-frontend/src/app/components/VerticalNavBar.tsx @@ -1,9 +1,12 @@ "use client"; -import React, { ReactNode } from "react"; +import React, { ReactNode, useEffect, useState } from "react"; import "bootstrap/dist/css/bootstrap.css"; import { Card } from "react-bootstrap"; import Accordion from "react-bootstrap/Accordion"; +import Link from "next/link"; + +import { Category, getAllCategories } from "../api/Categories"; import GpComponent from "./GPComponent"; import HomeComponent from "./HomeComponent"; @@ -11,6 +14,21 @@ import SearchComponent from "./SearchComponent"; import styles from "./VerticalNavBarStyles"; const VerticalNavBar: React.FC = () => { + const [categories, setCategories] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + const fetchedCategories = await getAllCategories(); + setCategories(fetchedCategories as never); + } catch (error) { + console.log("Fetch categories failed."); + } + }; + + void fetchData(); + }, [categories]); + type CustomAccordionProps = { children: ReactNode; }; @@ -24,8 +42,6 @@ const VerticalNavBar: React.FC = () => { return (
diff --git a/admin-portal-frontend/src/app/components/VerticalNavBarStyles.tsx b/admin-portal-frontend/src/app/components/VerticalNavBarStyles.tsx index 294a603..9de15e5 100644 --- a/admin-portal-frontend/src/app/components/VerticalNavBarStyles.tsx +++ b/admin-portal-frontend/src/app/components/VerticalNavBarStyles.tsx @@ -1,7 +1,7 @@ const VerticalNavBarStyles = { container: { display: "flex", - height: "100vh", + height: "100%", }, nav: { width: "350px", diff --git a/admin-portal-frontend/src/app/layout.tsx b/admin-portal-frontend/src/app/layout.tsx index 3cb6942..ab040f2 100644 --- a/admin-portal-frontend/src/app/layout.tsx +++ b/admin-portal-frontend/src/app/layout.tsx @@ -1,13 +1,13 @@ -import { Inter } from "next/font/google"; - import type { Metadata } from "next"; -import "./globals.css"; -const inter = Inter({ subsets: ["latin"] }); +import "./globals.css"; +import HorizontalNavBar from "./components/HorizontalNavbar"; +import VerticalNavBar from "./components/VerticalNavBar"; +import styles from "./pageStyles"; export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Sideline Sidekick Admin", + description: "Admin portal for Sideline Sidekick App", }; export default function RootLayout({ @@ -17,7 +17,20 @@ export default function RootLayout({ }>) { return ( - {children} + + +
+
+ +
+
+
+ +
+ {children} +
+
+ ); } diff --git a/admin-portal-frontend/src/app/page.tsx b/admin-portal-frontend/src/app/page.tsx index 6494e43..0422578 100644 --- a/admin-portal-frontend/src/app/page.tsx +++ b/admin-portal-frontend/src/app/page.tsx @@ -1,20 +1,11 @@ import React from "react"; -import HorizontalNavBar from "./components/HorizontalNavbar"; -import VerticalNavBar from "./components/VerticalNavBar"; -import styles from "./pageStyles"; - -const AnotherPage: React.FC = () => { +const Home: React.FC = () => { return (
-
- -
-
- -
+

Home

); }; -export default AnotherPage; +export default Home; diff --git a/admin-portal-frontend/src/app/pageStyles.tsx b/admin-portal-frontend/src/app/pageStyles.tsx index 3fc8506..49c914e 100644 --- a/admin-portal-frontend/src/app/pageStyles.tsx +++ b/admin-portal-frontend/src/app/pageStyles.tsx @@ -8,10 +8,9 @@ type Styles = { const styles: Styles = { verticalNavBar: { - position: "fixed", + position: "relative", top: 0, left: 0, - width: "100%", zIndex: 0, }, horizontalNavBar: { diff --git a/backend/controllers/versionController.js b/backend/controllers/versionController.js index 5e54e5c..137fb0c 100644 --- a/backend/controllers/versionController.js +++ b/backend/controllers/versionController.js @@ -24,6 +24,8 @@ export const updatedVersion = async (req, res) => { res.status(404).json({ message: "Version not found" }); } + console.log("Updated Version: ", updatedVersion); + // Respond with the updated version data res.status(200).json(updatedVersion); } catch (error) { diff --git a/dfm-sideline-sidekick-app/package-lock.json b/dfm-sideline-sidekick-app/package-lock.json index 382b94a..ac71128 100644 --- a/dfm-sideline-sidekick-app/package-lock.json +++ b/dfm-sideline-sidekick-app/package-lock.json @@ -6213,6 +6213,18 @@ "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.72.0.tgz", "integrity": "sha512-285lfdqSXaqKuBbbtP9qL2tDrfxdOFtIMvkKadtleRQkdOxx+uzGvFr82KHmc/sSiMtfXGp7JnFYWVh4sFl7Yw==" }, + "node_modules/@react-native/virtualized-lists": { + "version": "0.72.8", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz", + "integrity": "sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw==", + "dependencies": { + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" + }, + "peerDependencies": { + "react-native": "*" + } + }, "node_modules/@react-navigation/core": { "version": "6.4.10", "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.10.tgz", @@ -6246,9 +6258,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/@react-navigation/elements": { - "version": "1.3.30", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.30.tgz", - "integrity": "sha512-plhc8UvCZs0UkV+sI+3bisIyn78wz9O/BiWZXpounu72k/R/Sj5PuZYFJ1fi6psvriUveMCGh4LeZckAZu2qiQ==", + "version": "1.3.22", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.22.tgz", + "integrity": "sha512-HYKucs0TwQT8zMvgoZbJsY/3sZfzeP8Dk9IDv4agst3zlA7ReTx4+SROCG6VGC7JKqBCyQykHIwkSwxhapoc+Q==", "peerDependencies": { "@react-navigation/native": "^6.0.0", "react": "*", @@ -15612,18 +15624,6 @@ "node": ">=10" } }, - "node_modules/react-native/node_modules/@react-native/virtualized-lists": { - "version": "0.72.8", - "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz", - "integrity": "sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw==", - "dependencies": { - "invariant": "^2.2.4", - "nullthrows": "^1.1.1" - }, - "peerDependencies": { - "react-native": "*" - } - }, "node_modules/react-native/node_modules/promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", @@ -22307,6 +22307,15 @@ "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.72.0.tgz", "integrity": "sha512-285lfdqSXaqKuBbbtP9qL2tDrfxdOFtIMvkKadtleRQkdOxx+uzGvFr82KHmc/sSiMtfXGp7JnFYWVh4sFl7Yw==" }, + "@react-native/virtualized-lists": { + "version": "0.72.8", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz", + "integrity": "sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw==", + "requires": { + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" + } + }, "@react-navigation/core": { "version": "6.4.10", "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.10.tgz", @@ -22333,9 +22342,9 @@ } }, "@react-navigation/elements": { - "version": "1.3.30", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.30.tgz", - "integrity": "sha512-plhc8UvCZs0UkV+sI+3bisIyn78wz9O/BiWZXpounu72k/R/Sj5PuZYFJ1fi6psvriUveMCGh4LeZckAZu2qiQ==", + "version": "1.3.22", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.22.tgz", + "integrity": "sha512-HYKucs0TwQT8zMvgoZbJsY/3sZfzeP8Dk9IDv4agst3zlA7ReTx4+SROCG6VGC7JKqBCyQykHIwkSwxhapoc+Q==", "requires": {} }, "@react-navigation/native": { @@ -29145,15 +29154,6 @@ "yargs": "^17.6.2" }, "dependencies": { - "@react-native/virtualized-lists": { - "version": "0.72.8", - "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz", - "integrity": "sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw==", - "requires": { - "invariant": "^2.2.4", - "nullthrows": "^1.1.1" - } - }, "promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", diff --git a/dfm-sideline-sidekick-app/package.json b/dfm-sideline-sidekick-app/package.json index 23e64ca..3793890 100644 --- a/dfm-sideline-sidekick-app/package.json +++ b/dfm-sideline-sidekick-app/package.json @@ -47,7 +47,9 @@ "react-navigation": "^5.0.0", "react-router-dom": "^6.22.0", "react-router-native": "^6.22.1", - "typescript": "^5.1.3" + "typescript": "^5.1.3", + "react-native-web": "~0.19.6", + "@expo/webpack-config": "^19.0.0" }, "devDependencies": { "@babel/core": "^7.20.0",