From 1e9a52850d09f5fb863e852dabe986d8255def1a Mon Sep 17 00:00:00 2001
From: s223060317 <142484345+s223060317@users.noreply.github.com>
Date: Fri, 12 Sep 2025 17:40:32 +1000
Subject: [PATCH] Add files via upload
hardcode for admin dashboard
---
guardian-admin-dashboard/src/App.css | 153 ++++++++++++--
guardian-admin-dashboard/src/App.jsx | 136 +++++--------
guardian-admin-dashboard/src/Assignments.jsx | 117 +++++++++++
guardian-admin-dashboard/src/Dashboard.jsx | 50 +++++
guardian-admin-dashboard/src/Login.jsx | 63 ++++++
guardian-admin-dashboard/src/Patients.jsx | 51 +++++
.../src/ProtectedRoute.jsx | 15 ++
guardian-admin-dashboard/src/Sidebar.jsx | 46 +++++
guardian-admin-dashboard/src/Staff.jsx | 52 +++++
guardian-admin-dashboard/src/index.css | 186 +++++++++++++-----
guardian-admin-dashboard/src/main.jsx | 20 +-
11 files changed, 719 insertions(+), 170 deletions(-)
create mode 100644 guardian-admin-dashboard/src/Assignments.jsx
create mode 100644 guardian-admin-dashboard/src/Dashboard.jsx
create mode 100644 guardian-admin-dashboard/src/Login.jsx
create mode 100644 guardian-admin-dashboard/src/Patients.jsx
create mode 100644 guardian-admin-dashboard/src/ProtectedRoute.jsx
create mode 100644 guardian-admin-dashboard/src/Sidebar.jsx
create mode 100644 guardian-admin-dashboard/src/Staff.jsx
diff --git a/guardian-admin-dashboard/src/App.css b/guardian-admin-dashboard/src/App.css
index 83c74d68..fb513ed8 100644
--- a/guardian-admin-dashboard/src/App.css
+++ b/guardian-admin-dashboard/src/App.css
@@ -1,43 +1,158 @@
+/* General Styles */
body {
- margin: 0;
font-family: 'Segoe UI', sans-serif;
- background: #f0f2f5;
+ margin: 0;
+ padding: 0;
+ background-color: #f4f6f8;
+ color: #333;
}
+/* Login Page */
.login-container {
- max-width: 400px;
+ width: 320px;
margin: 100px auto;
- padding: 30px;
+ padding: 25px;
background: #fff;
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
- border-radius: 8px;
+ border-radius: 12px;
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
text-align: center;
}
-.login-container h2 {
- margin-bottom: 20px;
-}
-
.login-form input {
- width: 100%;
- padding: 10px;
+ width: 90%;
margin: 10px 0;
+ padding: 12px;
+ border-radius: 6px;
border: 1px solid #ccc;
- border-radius: 4px;
}
.login-form button {
- width: 100%;
- padding: 10px;
- background-color: #3f51b5;
+ background-color: #0066cc;
+ color: white;
+ border: none;
+ padding: 12px 25px;
+ margin-top: 10px;
+ border-radius: 6px;
+ cursor: pointer;
+}
+
+.login-form button:hover {
+ background-color: #004d99;
+}
+
+/* Dashboard Layout */
+.dashboard {
+ display: flex;
+ height: 100vh;
+}
+
+/* Sidebar */
+.sidebar {
+ width: 240px;
+ background-color: #0d47a1;
color: white;
+ padding: 30px 20px;
+}
+
+.sidebar h2 {
+ font-size: 22px;
+ margin-bottom: 40px;
+}
+
+.sidebar nav button {
+ display: block;
+ width: 100%;
+ background: none;
border: none;
+ color: white;
+ font-size: 16px;
+ padding: 12px 0;
+ text-align: left;
+ cursor: pointer;
+}
+
+.sidebar nav button:hover {
+ background-color: #1565c0;
border-radius: 4px;
+}
+
+/* Main Content */
+.main-content {
+ flex: 1;
+ padding: 30px 40px;
+ overflow-y: auto;
+ background-color: #f9f9f9;
+}
+
+.main-content h2 {
+ margin-bottom: 20px;
+}
+
+/* Card Grid */
+.card-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 20px;
+ margin-bottom: 30px;
+}
+
+.card {
+ background-color: #ffffff;
+ padding: 20px;
+ border-radius: 10px;
+ box-shadow: 0 2px 6px rgba(0,0,0,0.05);
+ text-align: center;
font-weight: bold;
+}
+
+/* Assignment Button */
+.create-button {
+ background-color: #009688;
+ color: white;
+ padding: 12px 20px;
+ border: none;
+ border-radius: 6px;
+ font-size: 14px;
+ margin-bottom: 20px;
cursor: pointer;
- transition: background 0.3s;
}
-.login-form button:hover {
- background-color: #303f9f;
+.create-button:hover {
+ background-color: #00796b;
+}
+
+/* Assignment Form */
+.assignment-form {
+ background-color: #fff;
+ padding: 20px;
+ border-radius: 10px;
+ width: 100%;
+ max-width: 600px;
+ box-shadow: 0 2px 6px rgba(0,0,0,0.05);
+}
+
+.assignment-form h3 {
+ margin-bottom: 20px;
+}
+
+.assignment-form select,
+.assignment-form input {
+ width: 100%;
+ padding: 10px;
+ margin-bottom: 15px;
+ border-radius: 6px;
+ border: 1px solid #ccc;
+}
+
+.assignment-form button {
+ background-color: #4caf50;
+ color: white;
+ padding: 10px 18px;
+ border: none;
+ border-radius: 6px;
+ cursor: pointer;
+}
+
+.assignment-form button:hover {
+ background-color: #388e3c;
}
diff --git a/guardian-admin-dashboard/src/App.jsx b/guardian-admin-dashboard/src/App.jsx
index f9354860..e2832127 100644
--- a/guardian-admin-dashboard/src/App.jsx
+++ b/guardian-admin-dashboard/src/App.jsx
@@ -1,92 +1,52 @@
-import React, { useState } from 'react';
-import './App.css';
-
-function App() {
- const [email, setEmail] = useState('');
- const [password, setPassword] = useState('');
- const [otp, setOtp] = useState('');
- const [step, setStep] = useState('login'); // login → otp → dashboard
- const [isAuthenticated, setIsAuthenticated] = useState(false);
-
- const handleLogin = (e) => {
- e.preventDefault();
- // Simulate backend login credentials (admin only)
- if (email === 'dominicdiona@gmail.com' && password === 'admin123') {
- setStep('otp'); // Go to 2FA step
- } else {
- alert('Invalid credentials. Please contact backend for admin login.');
- }
- };
-
-
- const handleOTPVerify = (e) => {
- e.preventDefault();
- // Simulated OTP check (normally generated backend)
- if (otp === '123456') {
- setIsAuthenticated(true);
- } else {
- alert('Invalid OTP');
- }
- };
-
- if (isAuthenticated) {
- return (
-
-

-
Admin Dashboard
-
Welcome, {email}
- {/* Add admin dashboard components here */}
-
- );
- }
-
+import React from "react";
+import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
+import Login from "./Login";
+import Dashboard from "./Dashboard";
+import Patients from "./Patients";
+import Staff from "./Staff";
+import Assignments from "./Assignments";
+import ProtectedRoute from "./ProtectedRoute";
+
+const App = () => {
return (
-
-

-
Guardian Admin Login
-
- {step === 'login' && (
-
- )}
-
- {step === 'otp' && (
-
- )}
-
+
+
+ } />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
);
-}
+};
export default App;
diff --git a/guardian-admin-dashboard/src/Assignments.jsx b/guardian-admin-dashboard/src/Assignments.jsx
new file mode 100644
index 00000000..b23e274f
--- /dev/null
+++ b/guardian-admin-dashboard/src/Assignments.jsx
@@ -0,0 +1,117 @@
+import React, { useState } from 'react';
+
+const Assignments = () => {
+ const [selectedPatient, setSelectedPatient] = useState('');
+ const [selectedStaff, setSelectedStaff] = useState('');
+ const [notes, setNotes] = useState('');
+ const [assignments, setAssignments] = useState([
+ { id: 1, patient: 'Patient A', staff: 'Nurse Emma', notes: 'Checkup daily' },
+ { id: 2, patient: 'Patient B', staff: 'Doctor James', notes: 'Blood test' },
+ { id: 3, patient: 'Patient C', staff: 'Nurse Liam', notes: 'Vitals monitoring' },
+ ]);
+ const [successMessage, setSuccessMessage] = useState('');
+
+ const handleCreateAssignment = () => {
+ if (!selectedPatient || !selectedStaff) return;
+
+ const newAssignment = {
+ id: assignments.length + 1,
+ patient: selectedPatient,
+ staff: selectedStaff,
+ notes: notes,
+ };
+
+ setAssignments([...assignments, newAssignment]);
+ setSelectedPatient('');
+ setSelectedStaff('');
+ setNotes('');
+ setSuccessMessage('Assignment created successfully!');
+
+ setTimeout(() => setSuccessMessage(''), 3000);
+ };
+
+ return (
+
+
Assignments
+
+ {/* Success message */}
+ {successMessage && (
+
+ {successMessage}
+
+ )}
+
+ {/* Form */}
+
+
Create New Assignment
+
+
+
+
+
+ setNotes(e.target.value)}
+ className="w-full p-2 mb-4 border border-gray-300 rounded"
+ />
+
+
+
+
+ {/* Table */}
+
+
+
+
+ | ID |
+ Patient |
+ Staff |
+ Notes |
+
+
+
+ {assignments.map((a) => (
+
+ | {a.id} |
+ {a.patient} |
+ {a.staff} |
+ {a.notes} |
+
+ ))}
+
+
+
+
+ );
+};
+
+export default Assignments;
diff --git a/guardian-admin-dashboard/src/Dashboard.jsx b/guardian-admin-dashboard/src/Dashboard.jsx
new file mode 100644
index 00000000..7c241ae2
--- /dev/null
+++ b/guardian-admin-dashboard/src/Dashboard.jsx
@@ -0,0 +1,50 @@
+// src/Dashboard.jsx
+import React from 'react';
+import './App.css';
+
+const Dashboard = () => {
+ return (
+
+
+
+
+ Dashboard Overview
+
+
+
Total Patients: 5
+
Active Staff: 4
+
Assignments: 3
+
Unassigned: 2
+
+
+
+
+
+
Create New Assignment
+
+
+
+
+
+
+
+ );
+};
+
+export default Dashboard;
diff --git a/guardian-admin-dashboard/src/Login.jsx b/guardian-admin-dashboard/src/Login.jsx
new file mode 100644
index 00000000..c26951c0
--- /dev/null
+++ b/guardian-admin-dashboard/src/Login.jsx
@@ -0,0 +1,63 @@
+// src/Login.jsx
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import './App.css';
+
+const Login = () => {
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [pin, setPin] = useState('');
+ const navigate = useNavigate();
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+
+ // Hardcoded admin credentials and 2FA
+ const adminEmail = 'admin@guardian.com';
+ const adminPassword = 'admin@123';
+ const adminPin = '123456';
+
+ if (
+ email.trim() === adminEmail &&
+ password === adminPassword &&
+ pin === adminPin
+ ) {
+ localStorage.setItem('isAuthenticated', 'true');
+ navigate('/dashboard');
+ } else {
+ alert('Invalid email, password or 2FA PIN');
+ }
+ };
+
+ return (
+
+
Admin Login
+
+
+ );
+};
+
+export default Login;
diff --git a/guardian-admin-dashboard/src/Patients.jsx b/guardian-admin-dashboard/src/Patients.jsx
new file mode 100644
index 00000000..800532d4
--- /dev/null
+++ b/guardian-admin-dashboard/src/Patients.jsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import './App.css'; // reuse same styles
+import { useNavigate } from 'react-router-dom';
+
+const Patients = () => {
+ const navigate = useNavigate();
+
+ const patients = [
+ { id: 1, name: 'Patient A', age: 78, condition: 'Diabetes' },
+ { id: 2, name: 'Patient B', age: 85, condition: 'Dementia' },
+ { id: 3, name: 'Patient C', age: 72, condition: 'Hypertension' },
+ ];
+
+ const handleLogout = () => {
+ localStorage.removeItem('isAuthenticated');
+ navigate('/');
+ };
+
+ return (
+
+
+
+
Patient List
+
+
+
+
+ | ID |
+ Name |
+ Age |
+ Condition |
+
+
+
+ {patients.map((patient) => (
+
+ | {patient.id} |
+ {patient.name} |
+ {patient.age} |
+ {patient.condition} |
+
+ ))}
+
+
+
+ );
+};
+
+export default Patients;
diff --git a/guardian-admin-dashboard/src/ProtectedRoute.jsx b/guardian-admin-dashboard/src/ProtectedRoute.jsx
new file mode 100644
index 00000000..0b441f57
--- /dev/null
+++ b/guardian-admin-dashboard/src/ProtectedRoute.jsx
@@ -0,0 +1,15 @@
+// src/ProtectedRoute.jsx
+import React from 'react';
+import { Navigate } from 'react-router-dom';
+
+const ProtectedRoute = ({ children }) => {
+ const isAuthenticated = localStorage.getItem('isAuthenticated') === 'true';
+
+ if (!isAuthenticated) {
+ return ;
+ }
+
+ return children;
+};
+
+export default ProtectedRoute;
diff --git a/guardian-admin-dashboard/src/Sidebar.jsx b/guardian-admin-dashboard/src/Sidebar.jsx
new file mode 100644
index 00000000..a0630738
--- /dev/null
+++ b/guardian-admin-dashboard/src/Sidebar.jsx
@@ -0,0 +1,46 @@
+import React from "react";
+import { useNavigate, useLocation } from "react-router-dom";
+import "./index.css";
+
+const Sidebar = () => {
+ const navigate = useNavigate();
+ const location = useLocation();
+
+ const isActive = (path) => location.pathname === path;
+
+ return (
+
+ );
+};
+
+export default Sidebar;
diff --git a/guardian-admin-dashboard/src/Staff.jsx b/guardian-admin-dashboard/src/Staff.jsx
new file mode 100644
index 00000000..320c3a14
--- /dev/null
+++ b/guardian-admin-dashboard/src/Staff.jsx
@@ -0,0 +1,52 @@
+import React from 'react';
+import './App.css';
+import { useNavigate } from 'react-router-dom';
+
+const Staff = () => {
+ const navigate = useNavigate();
+
+ const staffMembers = [
+ { id: 1, name: 'Nurse 1', role: 'Nurse', shift: 'Morning' },
+ { id: 2, name: 'Doctor 2', role: 'Doctor', shift: 'Evening' },
+ { id: 3, name: 'Caretaker 3', role: 'Caretaker', shift: 'Night' },
+ { id: 4, name: 'Doctor 4', role: 'Doctor', shift: 'Morning' },
+ ];
+
+ const handleLogout = () => {
+ localStorage.removeItem('isAuthenticated');
+ navigate('/');
+ };
+
+ return (
+
+
+
+
Staff List
+
+
+
+
+ | ID |
+ Name |
+ Role |
+ Shift |
+
+
+
+ {staffMembers.map((staff) => (
+
+ | {staff.id} |
+ {staff.name} |
+ {staff.role} |
+ {staff.shift} |
+
+ ))}
+
+
+
+ );
+};
+
+export default Staff;
diff --git a/guardian-admin-dashboard/src/index.css b/guardian-admin-dashboard/src/index.css
index 08a3ac9e..583e3db3 100644
--- a/guardian-admin-dashboard/src/index.css
+++ b/guardian-admin-dashboard/src/index.css
@@ -1,68 +1,146 @@
-:root {
- font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
+/* Reset and Base Styles */
+body {
+ margin: 0;
+ padding: 0;
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ background-color: #f4f6f8;
+ color: #333;
+}
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
+h1, h2, h3 {
+ margin-bottom: 10px;
+}
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+button {
+ cursor: pointer;
+ border: none;
+ border-radius: 6px;
+ padding: 10px 15px;
+ background-color: #0066cc;
+ color: white;
+ font-weight: bold;
+ transition: background-color 0.3s ease;
}
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
+button:hover {
+ background-color: #004999;
}
-a:hover {
- color: #535bf2;
+
+/* Login Page */
+.login-container {
+ width: 350px;
+ margin: 100px auto;
+ padding: 30px;
+ background-color: #ffffff;
+ border-radius: 12px;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+ text-align: center;
}
-body {
- margin: 0;
+.login-form input {
+ width: 100%;
+ padding: 12px;
+ margin-bottom: 15px;
+ border-radius: 6px;
+ border: 1px solid #ccc;
+}
+
+/* Dashboard Layout */
+.dashboard {
display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
+ height: 100vh;
}
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
+.sidebar {
+ width: 220px;
+ background-color: #1f2a40;
+ color: white;
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
}
-button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
+.sidebar h2 {
+ font-size: 20px;
+ margin-bottom: 30px;
+ line-height: 1.2;
}
-button:hover {
- border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
-
-@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
+
+.sidebar nav button {
+ margin: 10px 0;
+ width: 100%;
+ background-color: #1f2a40;
+ border: none;
+ text-align: left;
+ padding: 12px;
+ border-radius: 6px;
+ color: #eee;
+}
+
+.sidebar nav button:hover,
+.sidebar nav button.active {
+ background-color: #2e4a76;
+}
+
+/* Main Content Area */
+.main-content {
+ flex: 1;
+ padding: 40px;
+ background-color: #f4f6f8;
+ overflow-y: auto;
+}
+
+.card-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 20px;
+ margin-top: 20px;
+ margin-bottom: 40px;
+}
+
+.card {
+ background-color: #ffffff;
+ padding: 20px;
+ border-radius: 10px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
+ font-weight: bold;
+ text-align: center;
+}
+
+/* Assignment Form */
+.assignment-form {
+ background-color: #ffffff;
+ padding: 20px;
+ border-radius: 10px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
+}
+
+.assignment-form select,
+.assignment-form input {
+ display: block;
+ width: 100%;
+ padding: 10px;
+ margin: 12px 0;
+ border-radius: 6px;
+ border: 1px solid #ccc;
+}
+
+/* Table Style */
+.data-table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-top: 20px;
+}
+
+.data-table th,
+.data-table td {
+ padding: 12px 15px;
+ border: 1px solid #ccc;
+ text-align: left;
+ background-color: #fff;
+}
+
+.data-table th {
+ background-color: #f0f0f0;
+ font-weight: 600;
}
diff --git a/guardian-admin-dashboard/src/main.jsx b/guardian-admin-dashboard/src/main.jsx
index b9a1a6de..56a3bfaf 100644
--- a/guardian-admin-dashboard/src/main.jsx
+++ b/guardian-admin-dashboard/src/main.jsx
@@ -1,10 +1,12 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import './index.css'
-import App from './App.jsx'
+// main.jsx
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+import './index.css';
-createRoot(document.getElementById('root')).render(
-
-
- ,
-)
+
+ReactDOM.createRoot(document.getElementById('root')).render(
+
+
+
+);
\ No newline at end of file