Skip to content

Commit 1c3517e

Browse files
committed
fix: corrected hook dependency issues and remove any keyword
1 parent 1b9bce4 commit 1c3517e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+942
-474
lines changed

apps/web-app/Dockerfile

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,60 @@
1-
# BUILD STAGE
2-
FROM node:18-slim AS builder
1+
# # BUILD STAGE
2+
# FROM node:18-slim AS builder
33

4-
WORKDIR /app
4+
# WORKDIR /app
5+
6+
# RUN npm install -g pnpm
7+
8+
# COPY . .
9+
10+
# RUN pnpm install
11+
12+
# RUN pnpm --filter web-app build
13+
14+
# # NGINX STAGE
15+
# FROM nginx:alpine
16+
17+
# RUN apk add --no-cache curl
18+
19+
# COPY apps/web-app/dist /usr/share/nginx/html
20+
# COPY infra/nginx/default.conf /etc/nginx/conf.d/default.conf
521

6-
RUN npm install -g pnpm
22+
# EXPOSE 80
723

24+
# HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
25+
# CMD curl -f http://localhost/ || exit 1
26+
FROM node:18-slim AS base
27+
WORKDIR /app
28+
RUN npm install -g pnpm turbo
29+
30+
# BUILDER
31+
FROM base AS builder
32+
WORKDIR /app
833
COPY . .
34+
RUN turbo prune --scope=web-app --docker
35+
36+
# INSTALLER / BUILD
37+
FROM base AS installer
38+
WORKDIR /app
39+
40+
COPY --from=builder /app/out/json/ .
41+
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
42+
43+
RUN pnpm install --frozen-lockfile
944

10-
RUN pnpm install
45+
COPY --from=builder /app/out/full/ .
1146

12-
RUN pnpm --filter web-app build
47+
RUN pnpm turbo run build --filter=web-app
1348

14-
# NGINX STAGE
15-
FROM nginx:alpine
49+
# NGINX RUNNER
50+
FROM nginx:alpine AS runner
1651

1752
RUN apk add --no-cache curl
1853

19-
COPY apps/web-app/dist /usr/share/nginx/html
54+
COPY --from=installer /app/apps/web-app/dist /usr/share/nginx/html
2055
COPY infra/nginx/default.conf /etc/nginx/conf.d/default.conf
2156

2257
EXPOSE 80
2358

2459
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
25-
CMD curl -f http://localhost/ || exit 1
60+
CMD curl -f http://localhost/ || exit 1

apps/web-app/src/app/layout/Sidebar.tsx

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ import {
1212
House,
1313
FileText,
1414
Clock,
15+
Hospital,
16+
X,
1517
} from 'lucide-react';
1618

1719
export default function Sidebar() {
1820
const user = useAuthStore((s) => s.user);
1921
const location = useLocation();
2022
const [collapsed, setCollapsed] = useState(false);
23+
const [mobileOpen , setMobileOpen] = useState(false);
2124

2225
const isActive = (path: string) => location.pathname.startsWith(path);
2326

@@ -30,20 +33,56 @@ export default function Sidebar() {
3033
const isDoctor = user?.roles.includes("doctor");
3134
const isPatient = user?.roles.includes("patient")
3235
return (
36+
37+
<>
38+
39+
<button
40+
className="fixed top-4 left-4 z-50 sm:hidden bg-card border p-2 rounded-md"
41+
onClick={() => setMobileOpen(true)}
42+
>
43+
<Menu size={20} />
44+
</button>
45+
46+
{mobileOpen && (
47+
<div
48+
className="fixed inset-0 bg-black/40 z-40 sm:hidden"
49+
onClick={() => setMobileOpen(false)}
50+
/>
51+
)}
3352
<aside
34-
className={`bg-sidebar text-sidebar-foreground ${
35-
collapsed ? 'w-20' : 'w-64'
36-
} flex flex-col`}
37-
>
38-
{/* Header */}
53+
className={`
54+
sidebar fixed sm:static z-50 h-full
55+
${collapsed ? "w-20" : "w-64"}
56+
${mobileOpen ? "translate-x-0" : "-translate-x-full"}
57+
sm:translate-x-0
58+
transition-transform duration-300
59+
`}
60+
>
61+
3962
<div className="sidebar-header justify-between">
4063
{!collapsed && (
4164
<span className="font-semibold text-lg">Clinical System</span>
4265
)}
43-
<button onClick={() => setCollapsed(!collapsed)}>
44-
<Menu size={20} />
45-
</button>
46-
</div>
66+
67+
<div className="flex items-center gap-2">
68+
{/* collapse button (desktop) */}
69+
<button
70+
onClick={() => setCollapsed(!collapsed)}
71+
className="hidden sm:block"
72+
>
73+
<Menu size={20} />
74+
</button>
75+
76+
{/* close button (mobile) */}
77+
<button
78+
onClick={() => setMobileOpen(false)}
79+
className="sm:hidden"
80+
>
81+
<X size={20} />
82+
</button>
83+
</div>
84+
</div>
85+
4786

4887
<nav className="sidebar-nav overflow-y-auto">
4988
{isAdmin && (
@@ -72,11 +111,16 @@ export default function Sidebar() {
72111
{!collapsed && 'Create Admin'}
73112
</Link>
74113

75-
<Link to="/admin/patient" className={linkClass('/admin/patient')}>
114+
<Link to="/admin/patient/patient-search" className={linkClass('/admin/patient/patient-search')}>
76115
<Users size={18} />
77116
{!collapsed && 'Patients'}
78117
</Link>
79118

119+
<Link to="/admin/patient/doctor-search" className={linkClass('/admin/patient/doctor-search')}>
120+
<Hospital size={18} />
121+
{!collapsed && 'Doctors'}
122+
</Link>
123+
80124
<Link
81125
to="/admin/appointments"
82126
className={linkClass('/admin/appointments')}
@@ -184,5 +228,6 @@ export default function Sidebar() {
184228
)}
185229
</nav>
186230
</aside>
231+
</>
187232
);
188233
}

apps/web-app/src/app/layout/TopNavbar.tsx

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from "react";
1+
import { useEffect, useRef, useState } from "react";
22
import { useNavigate } from "react-router-dom";
33
import { useAuthStore } from "@/store/auth/auth.store";
44
import { AuthService } from "@/services/auth.service";
@@ -17,6 +17,7 @@ export default function TopNavbar() {
1717
);
1818

1919
const [open, setOpen] = useState(false);
20+
const menuRef = useRef<HTMLDivElement | null>(null)
2021

2122
async function handleLogout() {
2223
await AuthService.logout();
@@ -29,15 +30,38 @@ export default function TopNavbar() {
2930
setDark(!dark);
3031
}
3132

33+
useEffect(() => {
34+
function handleClickOutside(e: MouseEvent) {
35+
if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
36+
setOpen(false);
37+
}
38+
}
39+
40+
function handleKeyDown(e: KeyboardEvent) {
41+
if (e.key === "Escape") {
42+
setOpen(false);
43+
}
44+
}
45+
46+
document.addEventListener("mousedown", handleClickOutside);
47+
document.addEventListener("keydown", handleKeyDown);
48+
49+
return () => {
50+
document.removeEventListener("mousedown", handleClickOutside);
51+
document.removeEventListener("keydown", handleKeyDown);
52+
};
53+
}, []);
54+
55+
3256
return (
3357
<header className="navbar sticky top-0 z-50">
34-
<div className="navbar-left">
35-
<h1 className="navbar-title">
58+
<div className="navbar-left min-w-0">
59+
<h1 className="navbar-title truncate">
3660
Clinical Intelligence System
3761
</h1>
3862

3963
{role && (
40-
<span className="role-badge">
64+
<span className="role-badge hidden sm:inline">
4165
{role.toUpperCase()}
4266
</span>
4367
)}
@@ -46,46 +70,47 @@ export default function TopNavbar() {
4670
<div className="navbar-right">
4771

4872
<NotificationBell />
49-
{/* <button className="navbar-icon-btn">
50-
<Bell size={18} />
51-
</button> */}
52-
53-
<button onClick={toggleTheme} className="navbar-icon-btn">
73+
<button
74+
onClick={toggleTheme}
75+
className="navbar-icon-btn"
76+
aria-label="Toggle theme"
77+
>
5478
{dark ? <Sun size={18} /> : <Moon size={18} />}
5579
</button>
5680

57-
<div className="relative">
81+
<div className="relative" ref={menuRef}>
5882
<button
59-
onClick={() => setOpen(!open)}
83+
onClick={() => setOpen((prev) => !prev)}
6084
className="flex items-center gap-2"
85+
aria-label="Open user menu"
6186
>
62-
<span className="navbar-email">
87+
<span className="navbar-email hidden sm:block">
6388
{user?.email}
6489
</span>
6590
<ChevronDown size={16} />
6691
</button>
6792

6893
{open && (
69-
<div className="absolute right-0 mt-2 w-40 dropdown-menu">
70-
<div
71-
className="dropdown-item"
94+
<div className="absolute right-0 mt-2 w-40 sm:w-48 dropdown-menu">
95+
<button
96+
className="dropdown-item w-full text-left"
7297
onClick={() => {
7398
setOpen(false);
7499
navigate("/profile");
75100
}}
76101
>
77102
Profile
78-
</div>
103+
</button>
79104

80-
<div
81-
className="dropdown-item"
105+
<button
106+
className="dropdown-item w-full text-left"
82107
onClick={() => {
83108
setOpen(false);
84109
handleLogout();
85110
}}
86111
>
87112
Logout
88-
</div>
113+
</button>
89114
</div>
90115
)}
91116
</div>

apps/web-app/src/features/admin/pages/AdminClinicalRecords.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export default function AdminRecordsPage() {
2121
to,
2222
sortBy,
2323
sortOrder,
24+
loading,
2425
setPage,
2526
setSearch,
2627
setFrom,
@@ -29,15 +30,14 @@ export default function AdminRecordsPage() {
2930
fetchAdminRecords
3031
} = useClinicalStore()
3132

32-
const [loading, setLoading] = useState(false)
3333
const [selectedNote, setSelectedNote] = useState<ConsultationNote | null>(null)
3434
const [drawerOpen, setDrawerOpen] = useState(false)
3535

3636

3737
useEffect(() => {
38-
setLoading(true)
39-
fetchAdminRecords().finally(() => setLoading(false))
40-
}, [page, search,from, to, sortBy, sortOrder])
38+
39+
fetchAdminRecords()
40+
}, [fetchAdminRecords,page, search,from, to, sortBy, sortOrder])
4141

4242
const openDrawer = (note: ConsultationNote) => {
4343

apps/web-app/src/features/admin/pages/AppointmentList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default function AdminAppointments() {
3737

3838
useEffect(() => {
3939
fetchAdminAppointments()
40-
}, [page, search, status, fromDate, toDate, sortBy, sortOrder])
40+
}, [fetchAdminAppointments,page, search, status, fromDate, toDate, sortBy, sortOrder])
4141

4242
const columns = [
4343

apps/web-app/src/features/admin/pages/CreateAdmin.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ export default function CreateAdmin() {
3939
});
4040

4141
reset();
42-
} catch (err: any) {
42+
} catch (error: unknown) {
43+
const message= error instanceof Error ? error.message: "Failed to create admin"
4344
toast({
4445
variant: 'destructive',
4546
title: 'Error',
46-
description: err.message,
47+
description: message,
4748
});
4849
}
4950
}

apps/web-app/src/features/admin/pages/CreateDoctor.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ export default function CreateDoctor() {
3939
});
4040

4141
reset();
42-
} catch (err: any) {
42+
} catch (error: unknown) {
43+
const message= error instanceof Error ? error.message: "Failed to create doctor"
4344
toast({
4445
variant: 'destructive',
4546
title: 'Error',
46-
description: err.message,
47+
description: message,
4748
});
4849
}
4950
}

0 commit comments

Comments
 (0)