Skip to content

Commit

Permalink
Merge pull request #11 from moevm/admin-page
Browse files Browse the repository at this point in the history
Admin page
  • Loading branch information
10023r authored Dec 24, 2023
2 parents e3c16f5 + d94bf6e commit 818028c
Show file tree
Hide file tree
Showing 15 changed files with 276 additions and 5 deletions.
1 change: 1 addition & 0 deletions .idea/httpRequests/http-client.cookies

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/httpRequests/http-requests-log.http

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion backend/src/controllers/AdminController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
// @ts-ignore
import express from "express";
import {adminService} from "../services/AdminService";

export class AdminController {
static async getAdminInfo(req: express.Request, res: express.Response) {
static async getAppointments(req: express.Request, res: express.Response) {
try {
const admin = await adminService.getAppointments(req.params.id)

res.json(admin)
} catch (error) {
if (error instanceof Error) {
res.status(400).send(error.message)
}
}
}
}
1 change: 1 addition & 0 deletions backend/src/controllers/PatientController.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-ignore
import express from "express";
import { patientService } from "../services/PatientsService";

Expand Down
1 change: 1 addition & 0 deletions backend/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ router.get('/doctors/:id', DoctorController.getDoctorById)
router.get('/patients/:id', PatientController.getPatientById)
router.get('/patients', PatientController.getAllPatients)

router.get('/appointments', AdminController.getAppointments)

export default router;
34 changes: 34 additions & 0 deletions backend/src/services/AdminService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import mongoose from "mongoose";
import {AdminsMongoCollection} from "../models/mongoose/AdminModel";
import {AppoitmentMongoCollection} from "../models/mongoose/AppoitmentModel";
import {ProceduresMongoCollection} from "../models/mongoose/ProcedureModel";
import {PatientsMongoCollection} from "../models/mongoose/PatientModel";
import {DoctorMongoCollection} from "../models/mongoose/DoctorModel";

class AdminService {
public async getAppointments(id: string) {

const appointments = await AppoitmentMongoCollection.find({})

let myAppointments: { [key: string]: any }[] = [];

for(const appointment of appointments) {
const procedure = await ProceduresMongoCollection.findOne({_id: appointment?.procedure_id})
const patient = await PatientsMongoCollection.findOne({_id: appointment?.patient_id})
const date = appointment?.date
const doctor = await DoctorMongoCollection.findOne({_id: appointment?.doctor_id})
const appointmentDetails = {
"date": date,
"procedure": procedure?.name,
"patient": patient?.name + " " + patient?.surname,
"doctor": doctor?.name + " " + doctor?.surname
};
myAppointments.push(appointmentDetails);
}


return {"appointments": myAppointments}
}
}

export const adminService = new AdminService()
6 changes: 5 additions & 1 deletion backend/test.rest
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ GET http://localhost:1234/api/patients/658705e53b786ef1006e04fb

###

GET http://localhost:1234/api/patients
GET http://localhost:1234/api/patients

###

GET http://localhost:1234/api/admin/65880207e075c93418fd6619
16 changes: 16 additions & 0 deletions frontend/src/Components/PatientCard/PatientCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@


function PatientCard({name, age, cardNumber, phone}: any) {
return (
<>
<div className="bg-base2 rounded-3xl p-3 leading-loose px-8">
<p>Name: {name}</p>
<p>Age: {age}</p>
<p>Card number: {cardNumber}</p>
<p>Phone: {phone}</p>
</div>
</>
)
}

export default PatientCard
6 changes: 4 additions & 2 deletions frontend/src/Config/routeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export enum AppRoutes {
// REGISTER = "register",
LOGIN = "login",
PATIENT = "patient",
DOCTOR = "doctor"
DOCTOR = "doctor",
ADMIN = "admin"
// FEED = "feed",
// POST = "post",
// NOT_FOUND = "notFound",
Expand All @@ -26,7 +27,8 @@ export const RoutePaths: Record<AppRoutes, string> = {
// [AppRoutes.REGISTER]: "/register",
[AppRoutes.LOGIN]: "/login",
[AppRoutes.PATIENT]: "/patient",
[AppRoutes.DOCTOR]: "/doctor"
[AppRoutes.DOCTOR]: "/doctor",
[AppRoutes.ADMIN]: "/admin"
// [AppRoutes.FEED]: "/feed",
// [AppRoutes.POST]: "/post/" + RouteParams.POST_ID,
// [AppRoutes.NOT_FOUND]: "*",
Expand Down
60 changes: 60 additions & 0 deletions frontend/src/Pages/AdminPage/AdminPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import Header from "../../Widgets/Header/Header.tsx";
import SignOutButton from "../../Components/SignOutButton/SignOutButton.tsx";
import {useEffect, useState} from "react";
import PatientRecords from "./PatientRecords/PatientRecords.tsx";
import Schedule from "./Schedule/Schedule.tsx";
import {useSelector} from "react-redux";
import {useNavigate} from "react-router-dom";


function AdminPage(){
const role = useSelector((state: any) => state.role)
const navigate = useNavigate()
const [curSubPage, setCurSubPage] = useState("patientRecords")
const [curStyle, setCurStyle] = useState(["bg-base1", "bg-base2"])
useEffect(() => {
if (role != "admin") {
navigate("/")
}
}, []);
console.log("role", role)
const subPages = {
'patientRecords': <PatientRecords />,
'schedule': <Schedule />
}
function onClick(e: any) {
const name = e.target.name
setCurSubPage(name)
if (name == 'patientRecords') {
setCurStyle(["bg-base1", "bg-base2"])
} else if (name == "schedule") {
setCurStyle(["bg-base2", "bg-base1"])
}
}

return (
<>
<Header signOutButton={<SignOutButton />} />
<div className=" mx-10">
<header className="text-2xl font-bold">
<h3 className="my-7 ">
Administrator Dashboard
</h3>
<nav className="flex justify-around text-center w-5/12 min-w-fit">
<a onClick={onClick} name="patientRecords" className={`${curStyle[0]} rounded-2xl p-4 w-56 mr-2 cursor-pointer`}>
Patient records
</a>
<a onClick={onClick} name="schedule" className={`${curStyle[1]} rounded-2xl p-4 w-56 cursor-pointer`}>
Schedule
</a>
</nav>
<hr className="mt-3 opacity-30"/>
</header>
{subPages[curSubPage]}
</div>

</>
)
}

export default AdminPage
51 changes: 51 additions & 0 deletions frontend/src/Pages/AdminPage/PatientRecords/PatientRecords.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import FilterCard from "../../../Widgets/FilterCard/FilterCard.tsx";
import FormInput from "../../../Components/FormInput/FormInput.tsx";
import PatientCard from "../../../Components/PatientCard/PatientCard.tsx";
import {useEffect, useState} from "react";
import {getPatientsList} from "../../../api/requests.ts";

function PatientRecords() {
const [patients, setPatients] = useState([])
const [filteredPatients, setFilteredPatients] = useState([])

useEffect(() => {
getPatientsList()
.then(res => {
setFilteredPatients(res.data)
setPatients(res.data)
})
.catch(err => {
console.log(err)
})
}, []);

const [filter, setFilter] = useState('')
const dropFilter = () => {
setFilter('')
setFilteredPatients(patients)
}
const onChange = (e: any) => {
const value: any = e.target.value
// @ts-ignore
setFilter(value)
const tmp = patients.filter((x: any) => x.name.includes(value) || String(x.age).includes(value) || x.card.includes(value) || x.phone.includes(value))
setFilteredPatients(tmp)
}
return (
<>
<div className="font-bold text-xl">
<FilterCard onChange={onChange} dropFilter={dropFilter}
theme="primary">
<FormInput name={"filter_input"} type="text" value={filter}/>
</FilterCard>
<div className="grid grid-cols-3 gap-x-4">
{filteredPatients.map(
(x: any, idx: number) => <PatientCard key={idx} name={x.name} cardNumber={x.card} age={x.age} phone={x.phone} />
)}
</div>
</div>
</>
)
}

export default PatientRecords
63 changes: 63 additions & 0 deletions frontend/src/Pages/AdminPage/Schedule/Schedule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import FilterCard from "../../../Widgets/FilterCard/FilterCard.tsx";
import FormInput from "../../../Components/FormInput/FormInput.tsx";
import RecordsStand from "../../../Widgets/RecordsStand/RecordsStand.tsx";
import {useEffect, useState} from "react";
import {getAppointments} from "../../../api/requests.ts";

function Schedule() {
const [appointments, setAppointments] =useState([])
const [filteredAppointments, setFilteredAppointments] = useState([])
useEffect(() => {
getAppointments()
.then(res => {
setAppointments(res.data.appointments)
setFilteredAppointments(res.data.appointments)
})
.catch(err => console.log(err))
}, []);

const [filter, setFilter] = useState('')
const dropFilter = () => {
setFilter('')
setFilteredAppointments(appointments)
}
const onChange = (e: any) => {
const value: any = e.target.value
// @ts-ignore
setFilter(value)
const tmp = appointments.filter((x: any) => x.date.includes(value) || x.procedure.includes(value) || x.patient.includes(value) || x.doctor.includes(value))
setFilteredAppointments(tmp)
}

const gridCol4 = "w-full grid grid-cols-4 justify-items-center"

return (
<>
<div className="font-bold text-xl">
<FilterCard onChange={onChange} dropFilter={dropFilter} theme="primary">
<FormInput name={"filter_input"} type="text" value={filter}/>
</FilterCard>
<RecordsStand name={"Registered Schedules"} theme="primary">
<div className={`${gridCol4} text-2xl my-4`}>
<h4>Date</h4>
<h4>Procedure</h4>
<h4>Doctor</h4>
<h4>Patient</h4>
</div>
<ul className="w-full">
{filteredAppointments.map((currentValue: any, idx) =>
<div key={idx} className={`${gridCol4} text-lg font-medium mb-7`}>
<li>{currentValue.date}</li>
<li>{currentValue.procedure}</li>
<li>{currentValue.doctor}</li>
<li>{currentValue.patient}</li>
</div>)}
</ul>
</RecordsStand>

</div>
</>
)
}

export default Schedule
5 changes: 5 additions & 0 deletions frontend/src/Router/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Route, Routes, RouteProps } from "react-router-dom";
import LoginPage from "../Pages/LoginPage/LoginPage.tsx";
import PatientPage from "../Pages/PatientPage/PatientPage.tsx";
import DoctorPage from "../Pages/DoctorPage/DoctorPage.tsx";
import AdminPage from "../Pages/AdminPage/AdminPage.tsx";

const routes: Record<AppRoutes, RouteProps> = {
[AppRoutes.MAIN]: {
Expand All @@ -29,6 +30,10 @@ const routes: Record<AppRoutes, RouteProps> = {
[AppRoutes.DOCTOR]: {
path: RoutePaths.doctor,
element: <DoctorPage />
},
[AppRoutes.ADMIN]: {
path: RoutePaths.admin,
element: <AdminPage />
}
// [AppRoutes.FEED]: {
// path: RoutePaths.feed,
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/api/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
export enum Endpoints {
LOGIN = "login",
GET_DOCTOR_BY_ID = "doctors",
GET_PATIENTS = "patients"
GET_PATIENTS = "patients",
GET_APPOINTMENTS = "appointments"
}
13 changes: 13 additions & 0 deletions frontend/src/api/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,17 @@ export const getPatientById = (id: string) => {
url: API_URL + Endpoints.GET_PATIENTS + "/" + id,
method: "GET"
})
}
export const getPatientsList = () => {
return axios({
url: API_URL + Endpoints.GET_PATIENTS,
method: "GET"
})
}

export const getAppointments = () => {
return axios({
url: API_URL + Endpoints.GET_APPOINTMENTS,
method: "GET"
})
}

0 comments on commit 818028c

Please sign in to comment.