initialize foundational styles, dashboard layout, and hospital network module
This commit is contained in:
+40
-39
@@ -9,45 +9,46 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
/* Brand Colors */
|
/* Brand Colors — Cream-compatible blue palette */
|
||||||
--primary-50: #eef6ff;
|
--primary-50: #fcfbfa;
|
||||||
--primary-100: #d9ecff;
|
--primary-100: #f7f5f0;
|
||||||
--primary-200: #bcdcff;
|
--primary-200: #f1ebd8;
|
||||||
--primary-300: #8ec5fe;
|
--primary-300: #e2d3af;
|
||||||
--primary-400: #5aa5fb;
|
--primary-400: #d0c098;
|
||||||
--primary-500: #3b82f6;
|
--primary-500: #2563eb;
|
||||||
--primary-600: #2563eb;
|
--primary-600: #1d4ed8;
|
||||||
--primary-700: #1d4ed8;
|
--primary-700: #1e3a8a;
|
||||||
--primary-800: #1e40af;
|
--primary-800: #172554;
|
||||||
--primary-900: #1e3a8a;
|
--primary-900: #0f172a;
|
||||||
|
|
||||||
--teal-400: #2dd4bf;
|
/* Cream-compatible teal palette */
|
||||||
--teal-500: #14b8a6;
|
--teal-400: #0d9488;
|
||||||
--teal-600: #0d9488;
|
--teal-500: #0f766e;
|
||||||
|
--teal-600: #115e59;
|
||||||
|
|
||||||
/* Dark palette */
|
/* Cream & White surface palette (was Dark palette) */
|
||||||
--dark-900: #050d1a;
|
--dark-900: #faf7f0; /* Page Background (soft creamy ivory) */
|
||||||
--dark-800: #0a1628;
|
--dark-800: #ffffff; /* Primary Card/Sidebar surface (crisp white) */
|
||||||
--dark-700: #0f2040;
|
--dark-700: #f5eedc; /* Darker cream for borders / card hovers */
|
||||||
--dark-600: #162a52;
|
--dark-600: #eae1cc; /* Soft warm beige for borders/inputs */
|
||||||
--dark-500: #1e3a6e;
|
--dark-500: #d5c8ab; /* Deep beige for inactive borders/dividers */
|
||||||
|
|
||||||
/* Neutrals */
|
/* Neutrals — soft dark brown/charcoal for text (was light neutrals) */
|
||||||
--gray-50: #f8fafc;
|
--gray-50: #1e1b18; /* Body/Primary Text (soft espresso) */
|
||||||
--gray-100: #f1f5f9;
|
--gray-100: #29241f; /* Primary titles */
|
||||||
--gray-200: #e2e8f0;
|
--gray-200: #3b342c; /* Secondary text */
|
||||||
--gray-300: #cbd5e1;
|
--gray-300: #52493e; /* Medium description text */
|
||||||
--gray-400: #94a3b8;
|
--gray-400: #6f6354; /* Muted text */
|
||||||
--gray-500: #64748b;
|
--gray-500: #887b6a; /* Placeholders */
|
||||||
--gray-600: #475569;
|
--gray-600: #a29584; /* Soft dividers */
|
||||||
--gray-700: #334155;
|
--gray-700: #c1b5a5;
|
||||||
--gray-800: #1e293b;
|
--gray-800: #e2dbcd;
|
||||||
--gray-900: #0f172a;
|
--gray-900: #f3efe3;
|
||||||
|
|
||||||
/* Semantic */
|
/* Semantic */
|
||||||
--danger: #ef4444;
|
--danger: #ef4444;
|
||||||
--success: #22c55e;
|
--success: #16a34a;
|
||||||
--warning: #f59e0b;
|
--warning: #d97706;
|
||||||
|
|
||||||
/* Typography */
|
/* Typography */
|
||||||
--font-primary: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif;
|
--font-primary: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif;
|
||||||
@@ -60,12 +61,12 @@
|
|||||||
--radius-xl: 24px;
|
--radius-xl: 24px;
|
||||||
--radius-full: 9999px;
|
--radius-full: 9999px;
|
||||||
|
|
||||||
/* Shadows */
|
/* Shadows — soft warm ambient shadows */
|
||||||
--shadow-sm: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
--shadow-sm: 0 2px 4px rgba(47, 43, 36, 0.04), 0 1px 2px rgba(47, 43, 36, 0.03);
|
||||||
--shadow-md: 0 4px 16px rgba(0,0,0,0.25);
|
--shadow-md: 0 6px 16px rgba(47, 43, 36, 0.06);
|
||||||
--shadow-lg: 0 10px 40px rgba(0,0,0,0.35);
|
--shadow-lg: 0 12px 32px rgba(47, 43, 36, 0.08);
|
||||||
--shadow-glow: 0 0 40px rgba(59, 130, 246, 0.4);
|
--shadow-glow: 0 0 30px rgba(37, 99, 235, 0.1);
|
||||||
--shadow-teal: 0 0 30px rgba(20, 184, 166, 0.3);
|
--shadow-teal: 0 0 30px rgba(13, 148, 136, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
|||||||
+70
-63
@@ -15,7 +15,7 @@
|
|||||||
.sidebar {
|
.sidebar {
|
||||||
width: 280px;
|
width: 280px;
|
||||||
background: var(--dark-800);
|
background: var(--dark-800);
|
||||||
border-right: 1px solid rgba(255, 255, 255, 0.05);
|
border-right: 1px solid var(--dark-600);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
padding: 8px 12px 24px 12px;
|
padding: 8px 12px 24px 12px;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
border-bottom: 1px solid var(--dark-600);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo-icon-wrapper {
|
.logo-icon-wrapper {
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
.logo-brand {
|
.logo-brand {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +97,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:hover {
|
.nav-item:hover {
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
background: rgba(255, 255, 255, 0.03);
|
background: rgba(0, 0, 0, 0.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:hover svg {
|
.nav-item:hover svg {
|
||||||
@@ -106,10 +106,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-item.active {
|
.nav-item.active {
|
||||||
color: #fff;
|
color: var(--primary-600);
|
||||||
background: linear-gradient(135deg, rgba(37, 99, 235, 0.15) 0%, rgba(20, 184, 166, 0.05) 100%);
|
background: linear-gradient(135deg, rgba(37, 99, 235, 0.08) 0%, rgba(20, 184, 166, 0.02) 100%);
|
||||||
border: 1px solid rgba(37, 99, 235, 0.25);
|
border: 1px solid rgba(37, 99, 235, 0.15);
|
||||||
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.1);
|
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item.active svg {
|
.nav-item.active svg {
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-footer {
|
.sidebar-footer {
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
border-top: 1px solid var(--dark-600);
|
||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
.user-name {
|
.user-name {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-role {
|
.user-role {
|
||||||
@@ -198,9 +198,9 @@
|
|||||||
/* ── Topbar ── */
|
/* ── Topbar ── */
|
||||||
.topbar {
|
.topbar {
|
||||||
height: 70px;
|
height: 70px;
|
||||||
background: rgba(10, 22, 40, 0.5);
|
background: var(--dark-800);
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
border-bottom: 1px solid var(--dark-700);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -220,8 +220,8 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
font-size: 12.5px;
|
font-size: 12.5px;
|
||||||
color: var(--gray-400);
|
color: var(--gray-400);
|
||||||
background: rgba(255, 255, 255, 0.03);
|
background: var(--dark-900);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
border: 1px solid var(--dark-600);
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: var(--radius-full);
|
border-radius: var(--radius-full);
|
||||||
}
|
}
|
||||||
@@ -256,8 +256,8 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--gray-400);
|
color: var(--gray-400);
|
||||||
background: rgba(255, 255, 255, 0.03);
|
background: var(--dark-900);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: var(--radius-full);
|
border-radius: var(--radius-full);
|
||||||
}
|
}
|
||||||
@@ -286,7 +286,7 @@
|
|||||||
.pane-title {
|
.pane-title {
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,8 +326,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.metric-card {
|
.metric-card {
|
||||||
background: rgba(255, 255, 255, 0.03);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -355,8 +355,8 @@
|
|||||||
.glow-yellow .card-glass-glow { background: var(--warning); }
|
.glow-yellow .card-glass-glow { background: var(--warning); }
|
||||||
|
|
||||||
.metric-card:hover {
|
.metric-card:hover {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: var(--dark-700);
|
||||||
border-color: rgba(255, 255, 255, 0.12);
|
border-color: var(--dark-500);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +374,7 @@
|
|||||||
.metric-value {
|
.metric-value {
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
margin: 12px 0 6px 0;
|
margin: 12px 0 6px 0;
|
||||||
letter-spacing: -0.03em;
|
letter-spacing: -0.03em;
|
||||||
}
|
}
|
||||||
@@ -392,8 +392,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.detail-panel {
|
.detail-panel {
|
||||||
background: rgba(10, 22, 40, 0.4);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
@@ -401,7 +401,7 @@
|
|||||||
.panel-title {
|
.panel-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: var(--gray-100);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,8 +416,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background: rgba(255, 255, 255, 0.02);
|
background: var(--dark-900);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
border: 1px solid var(--dark-600);
|
||||||
padding: 14px 18px;
|
padding: 14px 18px;
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
}
|
}
|
||||||
@@ -431,7 +431,7 @@
|
|||||||
.pinger-name {
|
.pinger-name {
|
||||||
font-size: 13.5px;
|
font-size: 13.5px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pinger-value {
|
.pinger-value {
|
||||||
@@ -474,7 +474,7 @@
|
|||||||
.kpi-num {
|
.kpi-num {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kpi-label {
|
.kpi-label {
|
||||||
@@ -497,7 +497,10 @@
|
|||||||
padding: 14px 16px;
|
padding: 14px 16px;
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
border-left: 4px solid transparent;
|
border-left: 4px solid transparent;
|
||||||
background: rgba(255, 255, 255, 0.02);
|
background: var(--dark-900);
|
||||||
|
border-top: 1px solid var(--dark-600);
|
||||||
|
border-right: 1px solid var(--dark-600);
|
||||||
|
border-bottom: 1px solid var(--dark-600);
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-critical {
|
.alert-critical {
|
||||||
@@ -533,9 +536,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.resolve-btn {
|
.resolve-btn {
|
||||||
background: rgba(255, 255, 255, 0.06);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid var(--dark-600);
|
||||||
color: var(--gray-300);
|
color: var(--gray-200);
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@@ -575,13 +578,13 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--gray-500);
|
color: var(--gray-500);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
border-bottom: 1px solid var(--dark-600);
|
||||||
}
|
}
|
||||||
|
|
||||||
.telemetry-table td {
|
.telemetry-table td {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
font-size: 13.5px;
|
font-size: 13.5px;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.03);
|
border-bottom: 1px solid var(--dark-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hr-badge {
|
.hr-badge {
|
||||||
@@ -609,12 +612,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.status-indicator-tag {
|
.status-indicator-tag {
|
||||||
background: rgba(255, 255, 255, 0.03);
|
background: var(--dark-700);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
border: 1px solid var(--dark-600);
|
||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
border-radius: var(--radius-full);
|
border-radius: var(--radius-full);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: var(--gray-400);
|
color: var(--gray-300);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Admin Provisioning & Roster Cards ── */
|
/* ── Admin Provisioning & Roster Cards ── */
|
||||||
@@ -625,20 +628,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cg-card {
|
.cg-card {
|
||||||
background: rgba(255, 255, 255, 0.02);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
transition: all 0.25s ease;
|
transition: all 0.25s ease;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cg-card:hover {
|
.cg-card:hover {
|
||||||
background: rgba(255, 255, 255, 0.04);
|
background: var(--dark-700);
|
||||||
border-color: rgba(59, 130, 246, 0.2);
|
border-color: var(--primary-400);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cg-header {
|
.cg-header {
|
||||||
@@ -651,8 +656,8 @@
|
|||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: rgba(59, 130, 246, 0.15);
|
background: rgba(59, 130, 246, 0.1);
|
||||||
color: var(--primary-300);
|
color: var(--primary-600);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -663,7 +668,7 @@
|
|||||||
.cg-name {
|
.cg-name {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cg-role {
|
.cg-role {
|
||||||
@@ -673,8 +678,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cg-body {
|
.cg-body {
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
border-top: 1px solid var(--dark-600);
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
border-bottom: 1px solid var(--dark-600);
|
||||||
padding: 12px 0;
|
padding: 12px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -753,8 +758,8 @@
|
|||||||
|
|
||||||
/* ── Settings Options List ── */
|
/* ── Settings Options List ── */
|
||||||
.settings-options-list {
|
.settings-options-list {
|
||||||
background: rgba(255, 255, 255, 0.02);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
@@ -765,7 +770,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 20px 24px;
|
padding: 20px 24px;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.03);
|
border-bottom: 1px solid var(--dark-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-row:last-child {
|
.setting-row:last-child {
|
||||||
@@ -782,7 +787,7 @@
|
|||||||
.setting-label {
|
.setting-label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: var(--gray-100);
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-description {
|
.setting-description {
|
||||||
@@ -809,7 +814,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: var(--dark-700);
|
||||||
transition: .3s;
|
transition: .3s;
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
}
|
}
|
||||||
@@ -854,10 +859,12 @@ input:checked + .slider:before {
|
|||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
background: var(--dark-800);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 480px;
|
max-width: 480px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
padding: 28px;
|
padding: 28px;
|
||||||
box-shadow: var(--shadow-lg);
|
box-shadow: var(--shadow-lg);
|
||||||
animation: modalSlideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
animation: modalSlideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||||
@@ -878,7 +885,7 @@ input:checked + .slider:before {
|
|||||||
.modal-header h3 {
|
.modal-header h3 {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-btn {
|
.close-btn {
|
||||||
@@ -891,7 +898,7 @@ input:checked + .slider:before {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.close-btn:hover {
|
.close-btn:hover {
|
||||||
color: #fff;
|
color: var(--gray-100);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-form {
|
.modal-form {
|
||||||
@@ -914,11 +921,11 @@ input:checked + .slider:before {
|
|||||||
|
|
||||||
.form-group input,
|
.form-group input,
|
||||||
.form-group select {
|
.form-group select {
|
||||||
background: rgba(255, 255, 255, 0.04);
|
background: var(--dark-900);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
font-size: 13.5px;
|
font-size: 13.5px;
|
||||||
font-family: var(--font-primary);
|
font-family: var(--font-primary);
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -940,7 +947,7 @@ input:checked + .slider:before {
|
|||||||
|
|
||||||
.cancel-btn {
|
.cancel-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
border: 1px solid var(--dark-600);
|
||||||
color: var(--gray-300);
|
color: var(--gray-300);
|
||||||
padding: 10px 18px;
|
padding: 10px 18px;
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
@@ -949,8 +956,8 @@ input:checked + .slider:before {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cancel-btn:hover {
|
.cancel-btn:hover {
|
||||||
background: rgba(255, 255, 255, 0.03);
|
background: var(--dark-700);
|
||||||
color: #fff;
|
color: var(--gray-100);
|
||||||
}
|
}
|
||||||
|
|
||||||
.submit-btn {
|
.submit-btn {
|
||||||
@@ -1000,7 +1007,7 @@ input:checked + .slider:before {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
border-bottom: 1px solid var(--dark-600);
|
||||||
}
|
}
|
||||||
.nav-menu {
|
.nav-menu {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|||||||
@@ -23,18 +23,19 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
background: rgba(10, 22, 40, 0.6);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.analytics-card:hover {
|
.analytics-card:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
border-color: rgba(59, 130, 246, 0.2);
|
border-color: rgba(59, 130, 246, 0.2);
|
||||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
|
box-shadow: var(--shadow-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.analytics-card.glow-card {
|
.analytics-card.glow-card {
|
||||||
@@ -83,7 +84,7 @@
|
|||||||
.card-val {
|
.card-val {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@
|
|||||||
width: 320px;
|
width: 320px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
background: var(--dark-800);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -119,7 +120,7 @@
|
|||||||
.section-pane-title {
|
.section-pane-title {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-search-row {
|
.header-search-row {
|
||||||
@@ -168,10 +169,10 @@
|
|||||||
.search-input-wrap input {
|
.search-input-wrap input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: var(--dark-900);
|
background: var(--dark-900);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 8px 10px 8px 32px;
|
padding: 8px 10px 8px 32px;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
@@ -192,8 +193,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.group-item-card {
|
.group-item-card {
|
||||||
background: rgba(255, 255, 255, 0.02);
|
background: var(--dark-900);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -201,14 +202,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.group-item-card:hover {
|
.group-item-card:hover {
|
||||||
background: rgba(255, 255, 255, 0.04);
|
background: var(--dark-700);
|
||||||
border-color: rgba(255, 255, 255, 0.1);
|
border-color: var(--dark-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-item-card.selected {
|
.group-item-card.selected {
|
||||||
background: rgba(59, 130, 246, 0.08);
|
background: rgba(59, 130, 246, 0.06);
|
||||||
border-color: var(--primary-500);
|
border-color: var(--primary-500);
|
||||||
box-shadow: 0 0 12px rgba(59, 130, 246, 0.1);
|
box-shadow: 0 0 12px rgba(59, 130, 246, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-item-header {
|
.group-item-header {
|
||||||
@@ -221,12 +222,12 @@
|
|||||||
.group-name {
|
.group-name {
|
||||||
font-size: 13.5px;
|
font-size: 13.5px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-badge {
|
.group-badge {
|
||||||
font-size: 10.5px;
|
font-size: 10.5px;
|
||||||
background: rgba(255, 255, 255, 0.06);
|
background: var(--dark-600);
|
||||||
color: var(--gray-300);
|
color: var(--gray-300);
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -269,7 +270,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon-link-btn:hover {
|
.icon-link-btn:hover {
|
||||||
color: #fff;
|
color: var(--primary-600);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,9 +286,10 @@
|
|||||||
.network-main-content {
|
.network-main-content {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
background: var(--dark-800);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-details-pane {
|
.group-details-pane {
|
||||||
@@ -301,14 +303,14 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
border-bottom: 1px solid var(--dark-600);
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-title-label {
|
.group-title-label {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
letter-spacing: -0.01em;
|
letter-spacing: -0.01em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,8 +346,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hospital-detail-card {
|
.hospital-detail-card {
|
||||||
background: rgba(255, 255, 255, 0.02);
|
background: var(--dark-900);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -357,8 +359,8 @@
|
|||||||
|
|
||||||
.hospital-detail-card:hover {
|
.hospital-detail-card:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
border-color: rgba(20, 184, 166, 0.25);
|
border-color: var(--teal-500);
|
||||||
background: rgba(255, 255, 255, 0.03);
|
background: var(--dark-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hospital-card-header {
|
.hospital-card-header {
|
||||||
@@ -371,7 +373,7 @@
|
|||||||
.hospital-card-name {
|
.hospital-card-name {
|
||||||
font-size: 14.5px;
|
font-size: 14.5px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +403,7 @@
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--gray-400);
|
color: var(--gray-400);
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.04);
|
border-bottom: 1px solid var(--dark-600);
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,8 +424,8 @@
|
|||||||
|
|
||||||
.m-stat {
|
.m-stat {
|
||||||
font-size: 10.5px;
|
font-size: 10.5px;
|
||||||
background: rgba(255, 255, 255, 0.04);
|
background: var(--dark-600);
|
||||||
color: var(--gray-300);
|
color: var(--gray-100);
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@@ -436,8 +438,8 @@
|
|||||||
|
|
||||||
.mini-action-btn {
|
.mini-action-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
border: 1px solid var(--dark-500);
|
||||||
color: var(--gray-300);
|
color: var(--gray-200);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -446,9 +448,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mini-action-btn:hover {
|
.mini-action-btn:hover {
|
||||||
background: rgba(255, 255, 255, 0.08);
|
background: var(--dark-700);
|
||||||
color: #fff;
|
color: var(--gray-100);
|
||||||
border-color: rgba(255, 255, 255, 0.3);
|
border-color: var(--dark-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mini-action-btn.danger:hover {
|
.mini-action-btn.danger:hover {
|
||||||
@@ -489,7 +491,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
color: var(--gray-400);
|
color: var(--gray-400);
|
||||||
border: 1px dashed rgba(255, 255, 255, 0.08);
|
border: 1px dashed var(--dark-500);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
font-size: 13.5px;
|
font-size: 13.5px;
|
||||||
}
|
}
|
||||||
@@ -498,9 +500,11 @@
|
|||||||
.modal-wide .modal-content {
|
.modal-wide .modal-content {
|
||||||
max-width: 900px;
|
max-width: 900px;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
background: var(--dark-800);
|
background: var(--dark-800);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
border: 1px solid var(--dark-600);
|
||||||
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
|
box-shadow: var(--shadow-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-super-title {
|
.modal-super-title {
|
||||||
@@ -545,7 +549,7 @@
|
|||||||
background: var(--dark-900);
|
background: var(--dark-900);
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
}
|
}
|
||||||
|
|
||||||
.roster-tab-btn {
|
.roster-tab-btn {
|
||||||
@@ -561,13 +565,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.roster-tab-btn:hover {
|
.roster-tab-btn:hover {
|
||||||
color: #fff;
|
color: var(--gray-100);
|
||||||
}
|
}
|
||||||
|
|
||||||
.roster-tab-btn.active {
|
.roster-tab-btn.active {
|
||||||
background: var(--primary-600);
|
background: var(--primary-600);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
|
box-shadow: var(--shadow-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.roster-action-group {
|
.roster-action-group {
|
||||||
@@ -579,9 +583,9 @@
|
|||||||
|
|
||||||
.roster-dropdown {
|
.roster-dropdown {
|
||||||
background: var(--dark-900);
|
background: var(--dark-900);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
padding: 7px 12px;
|
padding: 7px 12px;
|
||||||
font-size: 12.5px;
|
font-size: 12.5px;
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -594,7 +598,7 @@
|
|||||||
|
|
||||||
/* Roster Table Styling */
|
/* Roster Table Styling */
|
||||||
.roster-table-container {
|
.roster-table-container {
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-height: 380px;
|
max-height: 380px;
|
||||||
@@ -619,7 +623,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.staff-cell-name {
|
.staff-cell-name {
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,11 +687,51 @@
|
|||||||
|
|
||||||
.cancel-btn {
|
.cancel-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid var(--dark-600);
|
||||||
color: var(--gray-300);
|
color: var(--gray-300);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cancel-btn:hover {
|
.cancel-btn:hover {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: var(--dark-700);
|
||||||
color: #fff;
|
color: var(--gray-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── TWO-COLUMN FORM LAYOUT ── */
|
||||||
|
.form-grid-two-col {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 24px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section-title {
|
||||||
|
font-size: 13.5px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--primary-600);
|
||||||
|
border-bottom: 1px solid var(--dark-600);
|
||||||
|
padding-bottom: 6px;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-info-box {
|
||||||
|
background: var(--dark-900);
|
||||||
|
border-left: 3px solid var(--teal-500);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
font-size: 11.5px;
|
||||||
|
color: var(--gray-300);
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions-grid-span {
|
||||||
|
grid-column: span 2;
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
+394
-32
@@ -67,7 +67,29 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
|
|
||||||
// Form States
|
// Form States
|
||||||
const [groupForm, setGroupForm] = useState({ name: '', hq: '', established: '', description: '' })
|
const [groupForm, setGroupForm] = useState({ name: '', hq: '', established: '', description: '' })
|
||||||
const [hospitalForm, setHospitalForm] = useState({ name: '', city: '', beds: '', phone: '', email: '', address: '', rating: '5.0' })
|
const [hospitalForm, setHospitalForm] = useState({
|
||||||
|
name: '',
|
||||||
|
reg_no: '',
|
||||||
|
beds: '50',
|
||||||
|
phone: '',
|
||||||
|
email: '',
|
||||||
|
address: '',
|
||||||
|
city: '',
|
||||||
|
state: '',
|
||||||
|
zip: '',
|
||||||
|
country: 'India',
|
||||||
|
website: '',
|
||||||
|
logoUrl: 'https://example.com/primecare-logo.png',
|
||||||
|
logoPath: '/uploads/logos/primecare-medical-center.png',
|
||||||
|
specialities: 'Cardiology, Neurology, Urology, Orthopedics, Emergency Medicine',
|
||||||
|
adminFirstName: '',
|
||||||
|
adminLastName: '',
|
||||||
|
adminEmail: '',
|
||||||
|
adminMobile: '',
|
||||||
|
adminCountryCode: '+91',
|
||||||
|
adminPassword: '',
|
||||||
|
adminUsername: '',
|
||||||
|
})
|
||||||
const [staffForm, setStaffForm] = useState({ type: 'doctor', name: '', specialty: '', role: 'Registered Nurse', experience: '1 Yr', certification: '', status: 'On Duty', phone: '', email: '' })
|
const [staffForm, setStaffForm] = useState({ type: 'doctor', name: '', specialty: '', role: 'Registered Nurse', experience: '1 Yr', certification: '', status: 'On Duty', phone: '', email: '' })
|
||||||
|
|
||||||
// Synchronize with LocalStorage
|
// Synchronize with LocalStorage
|
||||||
@@ -97,6 +119,20 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
fetchedGroups = groupsRes
|
fetchedGroups = groupsRes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Normalize backend shape → frontend shape
|
||||||
|
// Backend uses additional_info.city for HQ, reg_no as identifier, no established/description fields
|
||||||
|
fetchedGroups = fetchedGroups.map(g => {
|
||||||
|
const info = g.additional_info
|
||||||
|
? (typeof g.additional_info === 'string' ? JSON.parse(g.additional_info) : g.additional_info)
|
||||||
|
: {}
|
||||||
|
return {
|
||||||
|
...g,
|
||||||
|
hq: g.hq || (info.city && info.state ? `${info.city}, ${info.state}` : info.city || info.hq || 'N/A'),
|
||||||
|
established: g.established || (g.created_at ? g.created_at.substring(0, 4) : 'N/A'),
|
||||||
|
description: g.description || info.website || `Reg No: ${g.reg_no || 'N/A'}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
if (fetchedGroups.length > 0) {
|
if (fetchedGroups.length > 0) {
|
||||||
setGroups(fetchedGroups)
|
setGroups(fetchedGroups)
|
||||||
// Automatically select the first fetched group ID
|
// Automatically select the first fetched group ID
|
||||||
@@ -114,6 +150,22 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
} else if (Array.isArray(hospitalsRes)) {
|
} else if (Array.isArray(hospitalsRes)) {
|
||||||
fetchedHospitals = hospitalsRes
|
fetchedHospitals = hospitalsRes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fetchedHospitals = fetchedHospitals.map(h => {
|
||||||
|
const info = h.additional_info
|
||||||
|
? (typeof h.additional_info === 'string' ? JSON.parse(h.additional_info) : h.additional_info)
|
||||||
|
: {}
|
||||||
|
return {
|
||||||
|
...h,
|
||||||
|
city: h.city || info.city || 'N/A',
|
||||||
|
beds: h.beds || info.beds || 50,
|
||||||
|
phone: h.phone || info.phone || 'N/A',
|
||||||
|
email: h.email || info.contact_email || info.email || 'N/A',
|
||||||
|
address: h.address || info.address || 'N/A',
|
||||||
|
rating: h.rating || info.rating || '5.0'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
if (fetchedHospitals.length > 0) {
|
if (fetchedHospitals.length > 0) {
|
||||||
setHospitals(fetchedHospitals)
|
setHospitals(fetchedHospitals)
|
||||||
}
|
}
|
||||||
@@ -173,7 +225,7 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
const filteredGroups = useMemo(() => {
|
const filteredGroups = useMemo(() => {
|
||||||
return groups.filter(g =>
|
return groups.filter(g =>
|
||||||
g.name.toLowerCase().includes(groupQuery.toLowerCase()) ||
|
g.name.toLowerCase().includes(groupQuery.toLowerCase()) ||
|
||||||
g.hq.toLowerCase().includes(groupQuery.toLowerCase())
|
(g.hq || '').toLowerCase().includes(groupQuery.toLowerCase())
|
||||||
)
|
)
|
||||||
}, [groups, groupQuery])
|
}, [groups, groupQuery])
|
||||||
|
|
||||||
@@ -285,18 +337,66 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
setModalType('hospital')
|
setModalType('hospital')
|
||||||
if (mode === 'edit' && item) {
|
if (mode === 'edit' && item) {
|
||||||
setEditItem(item)
|
setEditItem(item)
|
||||||
|
const info = item.additional_info
|
||||||
|
? (typeof item.additional_info === 'string' ? JSON.parse(item.additional_info) : item.additional_info)
|
||||||
|
: {}
|
||||||
|
const logo = item.logo
|
||||||
|
? (typeof item.logo === 'string' ? JSON.parse(item.logo) : item.logo)
|
||||||
|
: {}
|
||||||
|
const specialities = item.hospital_speciality && Array.isArray(item.hospital_speciality)
|
||||||
|
? item.hospital_speciality.map(s => s.speciality || s).join(', ')
|
||||||
|
: (item.hospitalSpeciality && Array.isArray(item.hospitalSpeciality)
|
||||||
|
? item.hospitalSpeciality.map(s => s.speciality || s).join(', ')
|
||||||
|
: 'Cardiology, Neurology, Urology, Orthopedics, Emergency Medicine')
|
||||||
|
|
||||||
setHospitalForm({
|
setHospitalForm({
|
||||||
name: item.name,
|
name: item.name || '',
|
||||||
city: item.city,
|
reg_no: item.reg_no || '',
|
||||||
beds: item.beds,
|
beds: item.beds || info.beds || '50',
|
||||||
phone: item.phone,
|
phone: item.phone || info.phone || '',
|
||||||
email: item.email,
|
email: item.email || info.contact_email || info.email || '',
|
||||||
address: item.address,
|
address: item.address || info.address || '',
|
||||||
rating: item.rating
|
city: item.city || info.city || '',
|
||||||
|
state: info.state || '',
|
||||||
|
zip: info.zip || '',
|
||||||
|
country: info.country || 'India',
|
||||||
|
website: info.website || '',
|
||||||
|
logoUrl: logo.url || 'https://example.com/primecare-logo.png',
|
||||||
|
logoPath: logo.path || '/uploads/logos/primecare-medical-center.png',
|
||||||
|
specialities: specialities,
|
||||||
|
adminFirstName: item.primaryStaff?.user?.first_name || '',
|
||||||
|
adminLastName: item.primaryStaff?.user?.last_name || '',
|
||||||
|
adminEmail: item.primaryStaff?.user?.email || '',
|
||||||
|
adminMobile: item.primaryStaff?.user?.mobile || '',
|
||||||
|
adminCountryCode: item.primaryStaff?.user?.country_code || '+91',
|
||||||
|
adminPassword: '',
|
||||||
|
adminUsername: item.primaryStaff?.user?.username || '',
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
setEditItem(null)
|
setEditItem(null)
|
||||||
setHospitalForm({ name: '', city: '', beds: '', phone: '', email: '', address: '', rating: '5.0' })
|
setHospitalForm({
|
||||||
|
name: '',
|
||||||
|
reg_no: '',
|
||||||
|
beds: '50',
|
||||||
|
phone: '',
|
||||||
|
email: '',
|
||||||
|
address: '',
|
||||||
|
city: '',
|
||||||
|
state: '',
|
||||||
|
zip: '',
|
||||||
|
country: 'India',
|
||||||
|
website: '',
|
||||||
|
logoUrl: 'https://example.com/primecare-logo.png',
|
||||||
|
logoPath: '/uploads/logos/primecare-medical-center.png',
|
||||||
|
specialities: 'Cardiology, Neurology, Urology, Orthopedics, Emergency Medicine',
|
||||||
|
adminFirstName: '',
|
||||||
|
adminLastName: '',
|
||||||
|
adminEmail: '',
|
||||||
|
adminMobile: '',
|
||||||
|
adminCountryCode: '+91',
|
||||||
|
adminPassword: '',
|
||||||
|
adminUsername: '',
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,20 +404,100 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (!hospitalForm.name.trim()) return notify('Hospital Name is required', true)
|
if (!hospitalForm.name.trim()) return notify('Hospital Name is required', true)
|
||||||
|
|
||||||
|
try {
|
||||||
if (modalMode === 'create') {
|
if (modalMode === 'create') {
|
||||||
const newHospital = {
|
const payload = {
|
||||||
id: 'H' + Date.now().toString().slice(-4),
|
name: hospitalForm.name,
|
||||||
groupId: selectedGroupId,
|
group_id: parseInt(selectedGroupId) || null,
|
||||||
...hospitalForm,
|
reg_no: hospitalForm.reg_no,
|
||||||
beds: parseInt(hospitalForm.beds) || 50
|
additional_info: {
|
||||||
|
contact_email: hospitalForm.email,
|
||||||
|
phone: hospitalForm.phone,
|
||||||
|
address: hospitalForm.address,
|
||||||
|
city: hospitalForm.city,
|
||||||
|
state: hospitalForm.state,
|
||||||
|
zip: hospitalForm.zip,
|
||||||
|
country: hospitalForm.country,
|
||||||
|
website: hospitalForm.website,
|
||||||
|
beds: parseInt(hospitalForm.beds) || 50,
|
||||||
|
rating: '5.0'
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
url: hospitalForm.logoUrl,
|
||||||
|
path: hospitalForm.logoPath
|
||||||
|
},
|
||||||
|
hospital_speciality: hospitalForm.specialities.split(',').map(s => s.trim()).filter(Boolean),
|
||||||
|
user: {
|
||||||
|
role: 'hospital',
|
||||||
|
first_name: hospitalForm.adminFirstName,
|
||||||
|
last_name: hospitalForm.adminLastName,
|
||||||
|
email: hospitalForm.adminEmail,
|
||||||
|
mobile: hospitalForm.adminMobile,
|
||||||
|
country_code: hospitalForm.adminCountryCode,
|
||||||
|
password: hospitalForm.adminPassword,
|
||||||
|
gender: 'male',
|
||||||
|
dob: '1980-01-01',
|
||||||
|
username: hospitalForm.adminUsername || (hospitalForm.adminFirstName.toLowerCase() + '_' + hospitalForm.adminLastName.toLowerCase()),
|
||||||
|
timezone_id: 1,
|
||||||
|
is_2fa: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await adminService.hospitalNetwork.saveHospital(payload)
|
||||||
|
if (res?.success || res?.status === 201) {
|
||||||
|
notify(`Hospital "${hospitalForm.name}" created successfully.`)
|
||||||
|
await syncWithApi()
|
||||||
|
} else {
|
||||||
|
notify(res?.message || 'Failed to create hospital', true)
|
||||||
}
|
}
|
||||||
setHospitals(prev => [...prev, newHospital])
|
|
||||||
notify(`Hospital "${hospitalForm.name}" added to group.`)
|
|
||||||
} else if (modalMode === 'edit' && editItem) {
|
} else if (modalMode === 'edit' && editItem) {
|
||||||
setHospitals(prev => prev.map(h => h.id === editItem.id ? { ...h, ...hospitalForm, beds: parseInt(hospitalForm.beds) || 50 } : h))
|
const payload = {
|
||||||
notify(`Hospital "${hospitalForm.name}" updated.`)
|
id: editItem.id,
|
||||||
|
name: hospitalForm.name,
|
||||||
|
group_id: parseInt(selectedGroupId) || null,
|
||||||
|
reg_no: hospitalForm.reg_no,
|
||||||
|
additional_info: {
|
||||||
|
contact_email: hospitalForm.email,
|
||||||
|
phone: hospitalForm.phone,
|
||||||
|
address: hospitalForm.address,
|
||||||
|
city: hospitalForm.city,
|
||||||
|
state: hospitalForm.state,
|
||||||
|
zip: hospitalForm.zip,
|
||||||
|
country: hospitalForm.country,
|
||||||
|
website: hospitalForm.website,
|
||||||
|
beds: parseInt(hospitalForm.beds) || 50,
|
||||||
|
rating: editItem.rating || '5.0'
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
url: hospitalForm.logoUrl,
|
||||||
|
path: hospitalForm.logoPath
|
||||||
|
},
|
||||||
|
hospital_speciality: hospitalForm.specialities.split(',').map(s => s.trim()).filter(Boolean),
|
||||||
|
user: {
|
||||||
|
id: editItem.primaryStaff?.user?.id || editItem.user_id,
|
||||||
|
role: 'hospital',
|
||||||
|
first_name: hospitalForm.adminFirstName,
|
||||||
|
last_name: hospitalForm.adminLastName,
|
||||||
|
email: hospitalForm.adminEmail,
|
||||||
|
mobile: hospitalForm.adminMobile,
|
||||||
|
country_code: hospitalForm.adminCountryCode,
|
||||||
|
username: hospitalForm.adminUsername || (hospitalForm.adminFirstName.toLowerCase() + '_' + hospitalForm.adminLastName.toLowerCase()),
|
||||||
|
...(hospitalForm.adminPassword ? { password: hospitalForm.adminPassword } : {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await adminService.hospitalNetwork.saveHospital(payload)
|
||||||
|
if (res?.success || res?.status === 200) {
|
||||||
|
notify(`Hospital "${hospitalForm.name}" updated successfully.`)
|
||||||
|
await syncWithApi()
|
||||||
|
} else {
|
||||||
|
notify(res?.message || 'Failed to update hospital', true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setModalType(null)
|
setModalType(null)
|
||||||
|
} catch (err) {
|
||||||
|
notify(err.message || 'An error occurred during submission', true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDeleteHospital = (hospitalId, name) => {
|
const handleDeleteHospital = (hospitalId, name) => {
|
||||||
@@ -467,7 +647,7 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
<div className="network-left-sidebar">
|
<div className="network-left-sidebar">
|
||||||
<div className="pane-header">
|
<div className="pane-header">
|
||||||
<div className="header-search-row">
|
<div className="header-search-row">
|
||||||
<h3 className="section-pane-title">Provider Groups</h3>
|
<h3 className="section-pane-title">Hospital Groups</h3>
|
||||||
<button className="add-mini-btn" title="Create New Hospital Group" onClick={() => handleOpenGroupModal('create')}>
|
<button className="add-mini-btn" title="Create New Hospital Group" onClick={() => handleOpenGroupModal('create')}>
|
||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||||
<line x1="12" y1="5" x2="12" y2="19" />
|
<line x1="12" y1="5" x2="12" y2="19" />
|
||||||
@@ -788,7 +968,7 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
|
|
||||||
{/* ── DYNAMIC ADD / EDIT MODALS ── */}
|
{/* ── DYNAMIC ADD / EDIT MODALS ── */}
|
||||||
{modalType && (
|
{modalType && (
|
||||||
<div className="modal-overlay modal-front" onClick={() => setModalType(null)}>
|
<div className={`modal-overlay modal-front ${modalType === 'hospital' ? 'modal-wide' : ''}`} onClick={() => setModalType(null)}>
|
||||||
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h3>
|
<h3>
|
||||||
@@ -852,26 +1032,31 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
|
|
||||||
{/* 2. Hospital Form */}
|
{/* 2. Hospital Form */}
|
||||||
{modalType === 'hospital' && (
|
{modalType === 'hospital' && (
|
||||||
<form onSubmit={handleHospitalSubmit} className="modal-form">
|
<form onSubmit={handleHospitalSubmit} className="modal-form form-grid-two-col">
|
||||||
|
{/* Column 1: Facility Info */}
|
||||||
|
<div className="form-column">
|
||||||
|
<h4 className="form-section-title">Facility Details</h4>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>Facility Name *</label>
|
<label>Facility Name *</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
placeholder="e.g., City Medical Clinic Center"
|
placeholder="e.g., PrimeCare Medical Center"
|
||||||
value={hospitalForm.name}
|
value={hospitalForm.name}
|
||||||
onChange={(e) => setHospitalForm(prev => ({ ...prev, name: e.target.value }))}
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, name: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-row-double">
|
<div className="form-row-double">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>City *</label>
|
<label>Registration Number *</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
placeholder="e.g., Boston"
|
placeholder="e.g., HOSP-369258147"
|
||||||
value={hospitalForm.city}
|
value={hospitalForm.reg_no}
|
||||||
onChange={(e) => setHospitalForm(prev => ({ ...prev, city: e.target.value }))}
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, reg_no: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
@@ -884,12 +1069,13 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-row-double">
|
<div className="form-row-double">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>Contact Phone</label>
|
<label>Contact Phone</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="e.g., +1 (555) 123-4567"
|
placeholder="e.g., 1800-321-6547"
|
||||||
value={hospitalForm.phone}
|
value={hospitalForm.phone}
|
||||||
onChange={(e) => setHospitalForm(prev => ({ ...prev, phone: e.target.value }))}
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, phone: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
@@ -898,24 +1084,200 @@ export default function HospitalNetwork({ notify }) {
|
|||||||
<label>Public Email Address</label>
|
<label>Public Email Address</label>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="e.g., contact@hospital.com"
|
placeholder="e.g., info@primecare.com"
|
||||||
value={hospitalForm.email}
|
value={hospitalForm.email}
|
||||||
onChange={(e) => setHospitalForm(prev => ({ ...prev, email: e.target.value }))}
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, email: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>Complete Street Address</label>
|
<label>Complete Street Address</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="e.g., 400 Beacon Dr, Boston, MA"
|
placeholder="e.g., 214 Lakeview Medical Avenue"
|
||||||
value={hospitalForm.address}
|
value={hospitalForm.address}
|
||||||
onChange={(e) => setHospitalForm(prev => ({ ...prev, address: e.target.value }))}
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, address: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-actions">
|
|
||||||
|
<div className="form-row-double">
|
||||||
|
<div className="form-group">
|
||||||
|
<label>City *</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="e.g., Hyderabad"
|
||||||
|
value={hospitalForm.city}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, city: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>State / Province</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="e.g., Telangana"
|
||||||
|
value={hospitalForm.state}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, state: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-row-double">
|
||||||
|
<div className="form-group">
|
||||||
|
<label>ZIP / Postal Code</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="e.g., 500001"
|
||||||
|
value={hospitalForm.zip}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, zip: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Country</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="e.g., India"
|
||||||
|
value={hospitalForm.country}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, country: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Website URL</label>
|
||||||
|
<input
|
||||||
|
type="url"
|
||||||
|
placeholder="e.g., https://www.primecare.com"
|
||||||
|
value={hospitalForm.website}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, website: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-row-double">
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Logo URL</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="URL to logo image"
|
||||||
|
value={hospitalForm.logoUrl}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, logoUrl: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Logo Path</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Server upload path"
|
||||||
|
value={hospitalForm.logoPath}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, logoPath: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Hospital Specialities (comma separated)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Cardiology, Neurology, Urology"
|
||||||
|
value={hospitalForm.specialities}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, specialities: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Column 2: Admin Account Credentials */}
|
||||||
|
<div className="form-column">
|
||||||
|
<h4 className="form-section-title">Administrator Account</h4>
|
||||||
|
|
||||||
|
<div className="form-row-double">
|
||||||
|
<div className="form-group">
|
||||||
|
<label>First Name *</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="e.g., David"
|
||||||
|
value={hospitalForm.adminFirstName}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, adminFirstName: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Last Name *</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="e.g., Wilson"
|
||||||
|
value={hospitalForm.adminLastName}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, adminLastName: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Admin Email *</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
placeholder="e.g., david.wilson@primecare.com"
|
||||||
|
value={hospitalForm.adminEmail}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, adminEmail: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-row-double">
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Country Code</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="e.g., +91"
|
||||||
|
value={hospitalForm.adminCountryCode}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, adminCountryCode: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Mobile Number *</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="e.g., 9123456780"
|
||||||
|
value={hospitalForm.adminMobile}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, adminMobile: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Username *</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="e.g., dwilson_primecare"
|
||||||
|
value={hospitalForm.adminUsername}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, adminUsername: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Password {modalMode === 'create' ? '*' : '(Leave blank to keep current)'}</label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
required={modalMode === 'create'}
|
||||||
|
placeholder="e.g., PrimeCare@2026"
|
||||||
|
value={hospitalForm.adminPassword}
|
||||||
|
onChange={(e) => setHospitalForm(prev => ({ ...prev, adminPassword: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-info-box">
|
||||||
|
<p>💡 Setting up an Administrator Account registers this user as the primary contact and grants them control to manage this facility.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-actions form-actions-grid-span">
|
||||||
<button type="button" className="action-btn cancel-btn" onClick={() => setModalType(null)}>Cancel</button>
|
<button type="button" className="action-btn cancel-btn" onClick={() => setModalType(null)}>Cancel</button>
|
||||||
<button type="submit" className="action-btn-primary">Save Facility</button>
|
<button type="submit" className="action-btn-primary">
|
||||||
|
{modalMode === 'create' ? 'Create Facility' : 'Save Changes'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
|
|||||||
+19
-19
@@ -133,7 +133,7 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
letter-spacing: -0.03em;
|
letter-spacing: -0.03em;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-title-accent {
|
.hero-title-accent {
|
||||||
@@ -158,8 +158,8 @@
|
|||||||
|
|
||||||
.stat-card {
|
.stat-card {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: rgba(255,255,255,0.04);
|
background: rgba(255,255,255,0.65);
|
||||||
border: 1px solid rgba(255,255,255,0.08);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
padding: 18px 14px;
|
padding: 18px 14px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -176,7 +176,7 @@
|
|||||||
.stat-value {
|
.stat-value {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,8 +216,8 @@
|
|||||||
.hero-icon-center {
|
.hero-icon-center {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
background: rgba(15, 32, 64, 0.8);
|
background: rgba(255, 255, 255, 0.9);
|
||||||
border: 1px solid rgba(59,130,246,0.3);
|
border: 1px solid rgba(59,130,246,0.2);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
width: 80px; height: 80px;
|
width: 80px; height: 80px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -245,10 +245,10 @@
|
|||||||
padding: 40px 48px;
|
padding: 40px 48px;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
background: rgba(10, 22, 40, 0.7);
|
background: rgba(255, 255, 255, 0.55);
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
-webkit-backdrop-filter: blur(20px);
|
-webkit-backdrop-filter: blur(20px);
|
||||||
border-left: 1px solid rgba(255,255,255,0.06);
|
border-left: 1px solid var(--dark-600);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateX(30px);
|
transform: translateX(30px);
|
||||||
transition: opacity 0.7s ease 0.15s, transform 0.7s ease 0.15s;
|
transition: opacity 0.7s ease 0.15s, transform 0.7s ease 0.15s;
|
||||||
@@ -300,7 +300,7 @@
|
|||||||
.card-title {
|
.card-title {
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +326,7 @@
|
|||||||
content: '';
|
content: '';
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background: rgba(255,255,255,0.07);
|
background: var(--dark-600);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error banner */
|
/* Error banner */
|
||||||
@@ -391,13 +391,13 @@
|
|||||||
.field-input {
|
.field-input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
background: rgba(255,255,255,0.04);
|
background: rgba(255,255,255,0.8);
|
||||||
border: 1px solid rgba(255,255,255,0.1);
|
border: 1px solid var(--dark-600);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
padding: 0 48px 0 46px;
|
padding: 0 48px 0 46px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: var(--font-primary);
|
font-family: var(--font-primary);
|
||||||
color: #fff;
|
color: var(--gray-50);
|
||||||
transition: border-color 0.25s, background 0.25s, box-shadow 0.25s;
|
transition: border-color 0.25s, background 0.25s, box-shadow 0.25s;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
@@ -413,8 +413,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.field-input:hover:not(:focus) {
|
.field-input:hover:not(:focus) {
|
||||||
border-color: rgba(255,255,255,0.18);
|
border-color: var(--dark-500);
|
||||||
background: rgba(255,255,255,0.06);
|
background: rgba(255,255,255,0.95);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Password toggle */
|
/* Password toggle */
|
||||||
@@ -461,9 +461,9 @@
|
|||||||
.custom-check {
|
.custom-check {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
border: 1.5px solid rgba(255,255,255,0.2);
|
border: 1.5px solid var(--dark-500);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: rgba(255,255,255,0.04);
|
background: #ffffff;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -586,7 +586,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.demo-hint .hint-icon { font-size: 14px; flex-shrink: 0; margin-top: 1px; }
|
.demo-hint .hint-icon { font-size: 14px; flex-shrink: 0; margin-top: 1px; }
|
||||||
.demo-hint strong { color: var(--primary-300); font-weight: 600; }
|
.demo-hint strong { color: var(--primary-600); font-weight: 600; }
|
||||||
|
|
||||||
/* ── Security badge ── */
|
/* ── Security badge ── */
|
||||||
.security-badge {
|
.security-badge {
|
||||||
@@ -615,7 +615,7 @@
|
|||||||
padding: 40px 28px 32px;
|
padding: 40px 28px 32px;
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
border-bottom: 1px solid var(--dark-600);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-graphic { display: none; }
|
.hero-graphic { display: none; }
|
||||||
|
|||||||
Reference in New Issue
Block a user