diff --git a/src/pages/HospitalNetwork.css b/src/pages/HospitalNetwork.css index 94298ce..1f6ebb4 100644 --- a/src/pages/HospitalNetwork.css +++ b/src/pages/HospitalNetwork.css @@ -1,157 +1,193 @@ /* ============================================================ - HospitalNetwork.css — CureSelect Hospital Network UI/UX Styles + HospitalNetwork.css — CureSelect Hospital Network + Light Cream/Ivory Theme — Fully compatible with app palette ============================================================ */ +/* ── Base Container ── */ .hospital-network-tab { display: flex; flex-direction: column; gap: 24px; width: 100%; height: 100%; - padding-bottom: 40px; + padding-bottom: 48px; } -/* ── Analytics Overview Cards ── */ +/* ══════════════════════════════════════ + ANALYTICS OVERVIEW CARDS + ══════════════════════════════════════ */ .network-analytics-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); - gap: 16px; + grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); + gap: 14px; width: 100%; } .analytics-card { + position: relative; display: flex; align-items: center; gap: 16px; - background: var(--dark-800); - border: 1px solid var(--dark-600); - border-radius: var(--radius-md); - padding: 16px 20px; - backdrop-filter: blur(10px); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - box-shadow: var(--shadow-sm); + background: #ffffff; + border: 1.5px solid #eae1cc; + border-radius: 14px; + padding: 18px 20px; + transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 2px 8px rgba(47, 43, 36, 0.05); } .analytics-card:hover { - transform: translateY(-2px); - border-color: rgba(59, 130, 246, 0.2); - box-shadow: var(--shadow-md); + transform: translateY(-3px); + box-shadow: 0 8px 24px rgba(47, 43, 36, 0.1); + border-color: #d5c8ab; } .analytics-card.glow-card { - border-color: rgba(59, 130, 246, 0.2); - box-shadow: 0 0 20px rgba(59, 130, 246, 0.05); + border-color: rgba(37, 99, 235, 0.3); + box-shadow: 0 2px 12px rgba(37, 99, 235, 0.08); +} + +.analytics-card.glow-card:hover { + box-shadow: 0 8px 28px rgba(37, 99, 235, 0.14); } .card-icon-wrap { - width: 48px; - height: 48px; - border-radius: var(--radius-md); + width: 50px; + height: 50px; + border-radius: 13px; display: flex; align-items: center; justify-content: center; + flex-shrink: 0; } .primary-icon { - background: rgba(59, 130, 246, 0.1); - color: var(--primary-400); - border: 1px solid rgba(59, 130, 246, 0.2); + background: rgba(37, 99, 235, 0.09); + color: #1d4ed8; + border: 1.5px solid rgba(37, 99, 235, 0.18); } .teal-icon { - background: rgba(20, 184, 166, 0.1); - color: var(--teal-400); - border: 1px solid rgba(20, 184, 166, 0.2); + background: rgba(13, 148, 136, 0.09); + color: #0d9488; + border: 1.5px solid rgba(13, 148, 136, 0.2); } .info-icon { - background: rgba(14, 165, 233, 0.1); - color: #38bdf8; - border: 1px solid rgba(14, 165, 233, 0.2); + background: rgba(6, 182, 212, 0.09); + color: #0891b2; + border: 1.5px solid rgba(6, 182, 212, 0.2); } .success-icon { - background: rgba(34, 197, 94, 0.1); - color: var(--success); - border: 1px solid rgba(34, 197, 94, 0.2); + background: rgba(22, 163, 74, 0.09); + color: #16a34a; + border: 1.5px solid rgba(22, 163, 74, 0.18); } .card-data { display: flex; flex-direction: column; + min-width: 0; } .card-val { - font-size: 24px; + font-size: 26px; font-weight: 800; - color: var(--gray-50); - line-height: 1.2; + color: #1e1b18; + line-height: 1.1; + letter-spacing: -0.02em; } .card-title { - font-size: 12.5px; - color: var(--gray-400); + font-size: 11.5px; + color: #6f6354; font-weight: 600; - margin-top: 2px; + margin-top: 3px; + text-transform: uppercase; + letter-spacing: 0.05em; } -/* ── Split Panel Layout ── */ +/* ══════════════════════════════════════ + SPLIT PANEL LAYOUT + ══════════════════════════════════════ */ .network-split-panel { display: flex; - gap: 20px; + gap: 18px; width: 100%; - min-height: 520px; + min-height: 540px; align-items: flex-start; } -/* Left Sidebar (Provider Groups) */ +/* ── Left Sidebar ── */ .network-left-sidebar { - width: 320px; + width: 300px; flex-shrink: 0; - background: var(--dark-800); - border: 1px solid var(--dark-600); - border-radius: var(--radius-md); + background: #ffffff; + border: 1.5px solid #eae1cc; + border-radius: 16px; padding: 16px; display: flex; flex-direction: column; - gap: 16px; + gap: 12px; + box-shadow: 0 2px 8px rgba(47, 43, 36, 0.04); + position: sticky; + top: 0; +} + +.pane-header { + display: flex; + flex-direction: column; + gap: 10px; } .section-pane-title { - font-size: 15px; - font-weight: 700; - color: var(--gray-50); + font-size: 14px; + font-weight: 800; + color: #1e1b18; + letter-spacing: -0.01em; } .header-search-row { display: flex; - justify-content: justify; - align-items: center; justify-content: space-between; - margin-bottom: 8px; + align-items: center; + margin-bottom: 2px; } -.add-mini-btn { - background: rgba(59, 130, 246, 0.1); - border: 1px solid rgba(59, 130, 246, 0.2); - color: var(--primary-400); - width: 26px; - height: 26px; - border-radius: 6px; +/* Section Labels */ +.network-section-label { display: flex; align-items: center; - justify-content: center; - cursor: pointer; - transition: all 0.2s; + justify-content: space-between; + padding: 6px 8px 4px; + margin-bottom: 4px; + font-size: 10px; + font-weight: 700; + letter-spacing: 0.09em; + color: #887b6a; + text-transform: uppercase; } -.add-mini-btn:hover { - background: var(--primary-600); - color: #fff; - border-color: var(--primary-600); - transform: scale(1.05); +.network-section-label span:last-child { + min-width: 20px; + padding: 2px 7px; + border-radius: 20px; + background: #f1ebd8; + color: #52493e; + font-size: 10px; + font-weight: 700; + text-align: center; + border: 1px solid #eae1cc; } +.standalone-section-label { + margin-top: 10px; + padding-top: 12px; + border-top: 1.5px solid #eae1cc; +} + +/* Search Input */ .search-input-wrap { position: relative; width: 100%; @@ -162,54 +198,106 @@ left: 10px; top: 50%; transform: translateY(-50%); - color: var(--gray-500); + color: #887b6a; pointer-events: none; } .search-input-wrap input { width: 100%; - background: var(--dark-900); - border: 1px solid var(--dark-600); - border-radius: 8px; + background: #faf7f0; + border: 1.5px solid #eae1cc; + border-radius: 10px; padding: 8px 10px 8px 32px; - color: var(--gray-50); - font-size: 13px; - transition: all 0.2s; + color: #1e1b18; + font-size: 12.5px; + transition: all 0.2s ease; + outline: none; + font-family: inherit; +} + +.search-input-wrap input::placeholder { + color: #a29584; } .search-input-wrap input:focus { - border-color: var(--primary-500); - outline: none; - box-shadow: 0 0 10px rgba(59, 130, 246, 0.15); + border-color: #2563eb; + background: #ffffff; + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } +/* Add Mini Button */ +.add-mini-btn { + background: rgba(37, 99, 235, 0.08); + border: 1.5px solid rgba(37, 99, 235, 0.2); + color: #2563eb; + width: 28px; + height: 28px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 0.2s ease; + flex-shrink: 0; +} + +.add-mini-btn:hover { + background: #2563eb; + border-color: #2563eb; + color: #fff; + transform: rotate(90deg) scale(1.05); + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.25); +} + +/* Groups List */ .groups-list { display: flex; flex-direction: column; - gap: 10px; - max-height: 480px; + gap: 6px; + max-height: 500px; overflow-y: auto; - padding-right: 4px; + padding-right: 2px; } +.groups-list::-webkit-scrollbar { width: 4px; } +.groups-list::-webkit-scrollbar-track { background: transparent; } +.groups-list::-webkit-scrollbar-thumb { background: #d5c8ab; border-radius: 2px; } + +/* Group Cards */ .group-item-card { - background: var(--dark-900); - border: 1px solid var(--dark-600); - border-radius: 8px; - padding: 12px; + background: #faf7f0; + border: 1.5px solid #eae1cc; + border-radius: 11px; + padding: 12px 13px; cursor: pointer; - transition: all 0.2s ease; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + flex-shrink: 0; /* Prevents cards from shrinking and hiding buttons */ +} + +.group-item-card::before { + content: ''; + position: absolute; + left: 0; top: 0; bottom: 0; + width: 3px; + background: transparent; + transition: background 0.2s; } .group-item-card:hover { - background: var(--dark-700); - border-color: var(--dark-500); + background: #f5eedc; + border-color: #d5c8ab; + transform: translateX(2px); } .group-item-card.selected { - background: rgba(59, 130, 246, 0.06); - border-color: var(--primary-500); - box-shadow: 0 0 12px rgba(59, 130, 246, 0.05); + background: rgba(37, 99, 235, 0.05); + border-color: rgba(37, 99, 235, 0.4); + box-shadow: 0 2px 10px rgba(37, 99, 235, 0.08); +} + +.group-item-card.selected::before { + background: linear-gradient(180deg, #2563eb, #6366f1); } .group-item-header { @@ -220,76 +308,100 @@ } .group-name { - font-size: 13.5px; + font-size: 13px; font-weight: 700; - color: var(--gray-50); + color: #1e1b18; + line-height: 1.3; +} + +.group-item-card.selected .group-name { + color: #1d4ed8; } .group-badge { - font-size: 10.5px; - background: var(--dark-600); - color: var(--gray-300); - padding: 2px 6px; - border-radius: 4px; + font-size: 10px; + background: #f1ebd8; + color: #52493e; + padding: 2px 7px; + border-radius: 20px; white-space: nowrap; - font-weight: 500; + font-weight: 600; + border: 1px solid #eae1cc; + flex-shrink: 0; } .group-item-card.selected .group-badge { - background: rgba(59, 130, 246, 0.2); - color: var(--primary-300); + background: rgba(37, 99, 235, 0.1); + color: #1d4ed8; + border-color: rgba(37, 99, 235, 0.25); } .group-hq { - font-size: 11.5px; - color: var(--gray-400); + font-size: 11px; + color: #6f6354; margin-top: 4px; + line-height: 1.4; } .group-actions-inline { display: flex; - gap: 12px; - margin-top: 8px; - opacity: 0.7; - transition: opacity 0.2s; -} - -.group-item-card:hover .group-actions-inline { + gap: 14px; + margin-top: 10px; opacity: 1; } .icon-link-btn { background: none; border: none; - color: var(--primary-400); - font-size: 11px; - font-weight: 600; + color: #2563eb; + font-size: 11.5px; + font-weight: 700; cursor: pointer; padding: 0; - transition: color 0.15s; + transition: all 0.15s; + font-family: inherit; } .icon-link-btn:hover { - color: var(--primary-600); + color: #1d4ed8; text-decoration: underline; } .icon-link-btn.danger-link { - color: var(--danger); + color: #dc2626; } .icon-link-btn.danger-link:hover { - color: #ff6b6b; + color: #b91c1c; } -/* Main Content Panel (Selected Group View) */ +/* Standalone card */ +.standalone-card { + border-style: dashed; + border-color: #c1b5a5; +} + +.standalone-card.selected { + background: rgba(109, 40, 217, 0.04); + border-color: rgba(109, 40, 217, 0.35); + border-style: solid; +} + +.standalone-card.selected::before { + background: linear-gradient(180deg, #7c3aed, #db2777); +} + +/* ══════════════════════════════════════ + MAIN CONTENT PANEL + ══════════════════════════════════════ */ .network-main-content { flex-grow: 1; - background: var(--dark-800); - border: 1px solid var(--dark-600); - border-radius: var(--radius-md); - padding: 20px; - box-shadow: var(--shadow-sm); + background: #ffffff; + border: 1.5px solid #eae1cc; + border-radius: 16px; + padding: 22px; + box-shadow: 0 2px 8px rgba(47, 43, 36, 0.04); + min-width: 0; } .group-details-pane { @@ -303,24 +415,76 @@ justify-content: space-between; align-items: flex-start; gap: 20px; - border-bottom: 1px solid var(--dark-600); + border-bottom: 1.5px solid #eae1cc; padding-bottom: 16px; } .group-title-label { font-size: 20px; font-weight: 800; - color: var(--gray-50); - letter-spacing: -0.01em; + color: #1e1b18; + letter-spacing: -0.02em; + line-height: 1.2; } .group-desc-label { - font-size: 13px; - color: var(--gray-400); - margin-top: 4px; - max-width: 600px; + font-size: 12.5px; + color: #6f6354; + margin-top: 5px; + max-width: 560px; + line-height: 1.5; } +/* Action Buttons */ +.action-btn { + display: inline-flex; + align-items: center; + gap: 6px; + background: rgba(37, 99, 235, 0.07); + border: 1.5px solid rgba(37, 99, 235, 0.25); + color: #1d4ed8; + font-size: 12.5px; + font-weight: 600; + padding: 8px 16px; + border-radius: 10px; + cursor: pointer; + transition: all 0.2s ease; + white-space: nowrap; + font-family: inherit; +} + +.action-btn:hover { + background: #2563eb; + border-color: #2563eb; + color: #fff; + transform: translateY(-1px); + box-shadow: 0 6px 18px rgba(37, 99, 235, 0.22); +} + +.action-btn-primary { + display: inline-flex; + align-items: center; + gap: 6px; + background: linear-gradient(135deg, #2563eb, #4f46e5); + border: none; + color: #fff; + font-size: 12px; + font-weight: 700; + padding: 7px 14px; + border-radius: 8px; + cursor: pointer; + transition: all 0.2s ease; + font-family: inherit; + box-shadow: 0 3px 10px rgba(37, 99, 235, 0.28); +} + +.action-btn-primary:hover { + background: linear-gradient(135deg, #1d4ed8, #4338ca); + transform: translateY(-1px); + box-shadow: 0 6px 18px rgba(37, 99, 235, 0.35); +} + +/* ── Facility Filter Row ── */ .facility-filter-row { display: flex; justify-content: space-between; @@ -329,155 +493,210 @@ } .width-medium { - max-width: 300px; + max-width: 280px; } .section-sub-title { - font-size: 14.5px; + font-size: 14px; font-weight: 700; - color: var(--gray-200); + color: #29241f; + letter-spacing: -0.01em; } -/* Hospitals Cards Grid */ +/* ══════════════════════════════════════ + HOSPITAL CARDS GRID + ══════════════════════════════════════ */ .hospitals-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); - gap: 16px; + grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); + gap: 14px; } .hospital-detail-card { - background: var(--dark-900); - border: 1px solid var(--dark-600); - border-radius: var(--radius-md); - padding: 16px; + position: relative; + background: #faf7f0; + border: 1.5px solid #eae1cc; + border-radius: 14px; + padding: 18px; display: flex; flex-direction: column; - justify-content: space-between; - gap: 16px; - transition: all 0.25s ease; + gap: 13px; + transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); + overflow: hidden; +} + +.hospital-detail-card::after { + content: ''; + position: absolute; + top: 0; left: 0; right: 0; + height: 3px; + background: linear-gradient(90deg, #0d9488, #2563eb, #4f46e5); + opacity: 0; + transition: opacity 0.25s; + border-radius: 14px 14px 0 0; } .hospital-detail-card:hover { - transform: translateY(-2px); - border-color: var(--teal-500); - background: var(--dark-700); + transform: translateY(-3px); + border-color: #0d9488; + background: #ffffff; + box-shadow: 0 10px 30px rgba(13, 148, 136, 0.12); +} + +.hospital-detail-card:hover::after { + opacity: 1; } .hospital-card-header { display: flex; justify-content: space-between; align-items: flex-start; - gap: 8px; + gap: 10px; } .hospital-card-name { font-size: 14.5px; font-weight: 700; - color: var(--gray-50); + color: #1e1b18; line-height: 1.3; } .hospital-card-city { - font-size: 11px; - color: var(--teal-400); + font-size: 10.5px; + color: #0d9488; text-transform: uppercase; - font-weight: 600; - margin-top: 2px; + font-weight: 700; + margin-top: 3px; display: inline-block; + letter-spacing: 0.05em; } .beds-badge { font-size: 10px; - background: rgba(20, 184, 166, 0.15); - color: var(--teal-400); - border: 1px solid rgba(20, 184, 166, 0.2); - padding: 2px 6px; - border-radius: 4px; - font-weight: 600; + background: rgba(13, 148, 136, 0.1); + color: #0f766e; + border: 1px solid rgba(13, 148, 136, 0.22); + padding: 3px 8px; + border-radius: 20px; + font-weight: 700; white-space: nowrap; + flex-shrink: 0; } .hospital-card-info { display: flex; flex-direction: column; - gap: 4px; + gap: 5px; font-size: 12px; - color: var(--gray-400); - border-bottom: 1px solid var(--dark-600); - padding-bottom: 12px; + color: #52493e; + border-top: 1px solid #eae1cc; + border-bottom: 1px solid #eae1cc; + padding: 10px 0; } .info-desc { - line-height: 1.4; + line-height: 1.5; + display: flex; + align-items: baseline; + gap: 6px; +} + +.info-desc strong { + color: #3b342c; + font-weight: 600; + flex-shrink: 0; } .hospital-card-footer { display: flex; justify-content: space-between; align-items: center; + gap: 8px; + flex-wrap: wrap; } .staff-micro-stats { display: flex; - gap: 8px; + gap: 6px; } .m-stat { - font-size: 10.5px; - background: var(--dark-600); - color: var(--gray-100); - padding: 2px 6px; - border-radius: 4px; - font-weight: 500; + display: flex; + align-items: center; + gap: 4px; + font-size: 11px; + background: #f1ebd8; + color: #3b342c; + padding: 3px 8px; + border-radius: 6px; + font-weight: 600; + border: 1px solid #eae1cc; +} + +.m-stat strong { + color: #1e1b18; } .card-actions { display: flex; - gap: 8px; + gap: 6px; + align-items: center; + flex-wrap: wrap; } .mini-action-btn { - background: none; - border: 1px solid var(--dark-500); - color: var(--gray-200); + background: #ffffff; + border: 1.5px solid #d5c8ab; + color: #52493e; font-size: 11px; - padding: 4px 8px; - border-radius: 4px; + font-weight: 600; + padding: 4px 10px; + border-radius: 7px; cursor: pointer; - transition: all 0.15s; + transition: all 0.18s ease; + font-family: inherit; } .mini-action-btn:hover { - background: var(--dark-700); - color: var(--gray-100); - border-color: var(--dark-500); + background: #f5eedc; + color: #1e1b18; + border-color: #a29584; } .mini-action-btn.danger:hover { - border-color: var(--danger); - color: var(--danger); - background: rgba(239, 68, 68, 0.08); + border-color: rgba(220, 38, 38, 0.4); + color: #dc2626; + background: rgba(239, 68, 68, 0.06); } -.action-btn-primary { - background: var(--primary-600); - border: none; - color: #fff; +/* Manage Staff button */ +.manage-staff-btn { + display: inline-flex; + align-items: center; + gap: 5px; + background: linear-gradient(135deg, rgba(13,148,136,0.1), rgba(37,99,235,0.08)); + border: 1.5px solid rgba(13, 148, 136, 0.35); + color: #0f766e; font-size: 11px; - font-weight: 600; - padding: 5px 10px; - border-radius: 4px; + font-weight: 700; + padding: 5px 12px; + border-radius: 8px; cursor: pointer; - transition: background 0.15s; + transition: all 0.2s ease; + font-family: inherit; } -.action-btn-primary:hover { - background: var(--primary-500); +.manage-staff-btn:hover { + background: #0d9488; + border-color: #0d9488; + color: #fff; + transform: translateY(-1px); + box-shadow: 0 5px 16px rgba(13, 148, 136, 0.25); } -/* Empty states */ +/* Empty States */ .empty-state { - color: var(--gray-500); + color: #887b6a; font-size: 12.5px; text-align: center; padding: 16px; @@ -489,38 +708,46 @@ align-items: center; justify-content: center; text-align: center; - padding: 40px; - color: var(--gray-400); - border: 1px dashed var(--dark-500); - border-radius: var(--radius-md); + padding: 48px 40px; + color: #887b6a; + border: 2px dashed #d5c8ab; + border-radius: 14px; font-size: 13.5px; + background: #faf7f0; } -/* ── MODALS (Wide & Dialog styling) ── */ +/* ══════════════════════════════════════ + STAFF ROSTER MODAL + ══════════════════════════════════════ */ .modal-wide .modal-content { - max-width: 900px; - width: 90%; - max-height: 90vh; + max-width: 980px; + width: 94%; + max-height: 92vh; overflow-y: auto; - background: var(--dark-800); - border: 1px solid var(--dark-600); - box-shadow: var(--shadow-lg); + background: #ffffff; + border: 1.5px solid #eae1cc; + border-radius: 18px; + box-shadow: 0 20px 60px rgba(47, 43, 36, 0.14); } +.modal-wide .modal-content::-webkit-scrollbar { width: 5px; } +.modal-wide .modal-content::-webkit-scrollbar-thumb { background: #d5c8ab; border-radius: 3px; } + .modal-super-title { font-size: 10px; - color: var(--teal-400); + color: #0d9488; text-transform: uppercase; font-weight: 700; - letter-spacing: 0.08em; - margin-bottom: 2px; + letter-spacing: 0.12em; + margin-bottom: 3px; display: block; } .modal-sub-title-address { font-size: 12px; - color: var(--gray-400); - margin-top: 4px; + color: #6f6354; + margin-top: 5px; + line-height: 1.4; } .modal-inner-roster-body { @@ -530,10 +757,15 @@ margin-top: 20px; } +/* Roster Control Panel */ .roster-control-panel { display: flex; flex-direction: column; gap: 12px; + background: #faf7f0; + border: 1.5px solid #eae1cc; + border-radius: 12px; + padding: 14px; } @media (min-width: 768px) { @@ -544,194 +776,528 @@ } } +/* Tab Switcher */ .roster-tabs-switcher { display: flex; - background: var(--dark-900); + background: #ffffff; padding: 3px; - border-radius: 6px; - border: 1px solid var(--dark-600); + border-radius: 9px; + border: 1.5px solid #eae1cc; + gap: 2px; } .roster-tab-btn { background: none; border: none; - color: var(--gray-400); + color: #6f6354; font-size: 12px; font-weight: 600; - padding: 6px 14px; - border-radius: 4px; + padding: 7px 15px; + border-radius: 7px; cursor: pointer; - transition: all 0.2s; + transition: all 0.2s ease; + font-family: inherit; + white-space: nowrap; } .roster-tab-btn:hover { - color: var(--gray-100); + color: #1e1b18; + background: #f5eedc; } .roster-tab-btn.active { - background: var(--primary-600); + background: linear-gradient(135deg, #2563eb, #4f46e5); color: #fff; - box-shadow: var(--shadow-sm); + box-shadow: 0 3px 10px rgba(37, 99, 235, 0.3); } .roster-action-group { display: flex; - gap: 10px; + gap: 8px; align-items: center; flex-wrap: wrap; } .roster-dropdown { - background: var(--dark-900); - border: 1px solid var(--dark-600); + background: #ffffff; + border: 1.5px solid #eae1cc; border-radius: 8px; - color: var(--gray-50); + color: #29241f; padding: 7px 12px; font-size: 12.5px; outline: none; cursor: pointer; + font-family: inherit; + transition: border-color 0.2s; } .roster-dropdown:focus { - border-color: var(--primary-500); + border-color: #2563eb; + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } -/* Roster Table Styling */ -.roster-table-container { - border: 1px solid var(--dark-600); - border-radius: 8px; - overflow: hidden; - max-height: 380px; +/* ══════════════════════════════════════ + PROVIDER CARDS — Doctor Roster + ══════════════════════════════════════ */ +.providers-cards-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(265px, 1fr)); + gap: 13px; + padding: 2px 0; } +.provider-card { + position: relative; + background: #faf7f0; + border: 1.5px solid #eae1cc; + border-radius: 13px; + padding: 17px; + display: flex; + flex-direction: column; + gap: 13px; + transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1); + overflow: hidden; +} + +.provider-card::before { + content: ''; + position: absolute; + top: 0; left: 0; right: 0; + height: 3px; + background: linear-gradient(90deg, #2563eb, #6366f1); + opacity: 0; + transition: opacity 0.25s; +} + +.provider-card:hover { + background: #ffffff; + border-color: rgba(37, 99, 235, 0.3); + transform: translateY(-3px); + box-shadow: 0 10px 28px rgba(47, 43, 36, 0.09); +} + +.provider-card:hover::before { + opacity: 1; +} + +.provider-card-header { + display: flex; + align-items: center; + gap: 12px; +} + +.provider-avatar { + width: 46px; + height: 46px; + border-radius: 12px; + background: linear-gradient(135deg, #2563eb, #4f46e5); + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + font-weight: 800; + color: #fff; + flex-shrink: 0; + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.25); + letter-spacing: -0.02em; +} + +.provider-card-meta { + min-width: 0; + flex: 1; +} + +.provider-name { + font-size: 14px; + font-weight: 700; + color: #1e1b18; + line-height: 1.3; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.provider-email { + font-size: 11px; + color: #887b6a; + margin-top: 2px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.provider-card-body { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.provider-tag { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 11px; + font-weight: 600; + padding: 3px 9px; + border-radius: 20px; +} + +.tag-specialty { + background: rgba(37, 99, 235, 0.08); + color: #1d4ed8; + border: 1px solid rgba(37, 99, 235, 0.18); +} + +.tag-license { + background: rgba(217, 119, 6, 0.08); + color: #b45309; + border: 1px solid rgba(217, 119, 6, 0.2); +} + +.tag-since { + background: rgba(13, 148, 136, 0.08); + color: #0f766e; + border: 1px solid rgba(13, 148, 136, 0.2); +} + +.tag-mobile { + background: rgba(109, 40, 217, 0.07); + color: #6d28d9; + border: 1px solid rgba(109, 40, 217, 0.18); +} + +.provider-card-footer { + display: flex; + justify-content: space-between; + align-items: center; + border-top: 1px solid #eae1cc; + padding-top: 11px; +} + +.provider-status-dot { + display: flex; + align-items: center; + gap: 6px; + font-size: 11px; + font-weight: 700; + color: #16a34a; +} + +.provider-status-dot::before { + content: ''; + width: 7px; + height: 7px; + border-radius: 50%; + background: #16a34a; + box-shadow: 0 0 6px rgba(22, 163, 74, 0.5); + animation: pulse-dot 2s ease-in-out infinite; +} + +@keyframes pulse-dot { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.6; transform: scale(0.85); } +} + +.provider-actions { + display: flex; + gap: 6px; +} + +/* ── Roster Table (Caregivers) ── */ +.roster-table-container { + border: 1.5px solid #eae1cc; + border-radius: 12px; + overflow: hidden; + max-height: 400px; + overflow-y: auto; +} + +.roster-table-container::-webkit-scrollbar { width: 4px; } +.roster-table-container::-webkit-scrollbar-thumb { background: #d5c8ab; border-radius: 2px; } + .staff-avatar-cell { display: flex; align-items: center; gap: 12px; } +.cg-avatar { + display: flex; + align-items: center; + justify-content: center; + font-weight: 800; + color: #fff; + background: linear-gradient(135deg, #0d9488, #0891b2); + border-radius: 8px; +} + .mini-av { - width: 32px !important; - height: 32px !important; + width: 34px !important; + height: 34px !important; font-size: 10px !important; - border-radius: 6px !important; + border-radius: 9px !important; + flex-shrink: 0; } .staff-meta-details { display: flex; flex-direction: column; + min-width: 0; } .staff-cell-name { - color: var(--gray-50); + color: #1e1b18; font-size: 13px; + font-weight: 600; } .staff-cell-sub { font-size: 11px; - color: var(--gray-400); + color: #887b6a; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 180px; } .roster-actions-wrap { display: flex; - gap: 12px; + gap: 10px; } -/* Status Indicator tag pills */ +/* Loading State */ +.roster-loading { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + padding: 40px; + color: #6f6354; + font-size: 13px; + font-weight: 500; +} + +.roster-spinner { + width: 20px; + height: 20px; + border: 2.5px solid #eae1cc; + border-top-color: #2563eb; + border-radius: 50%; + animation: spin 0.7s linear infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +/* ══════════════════════════════════════ + STATUS INDICATOR PILLS + ══════════════════════════════════════ */ .status-indicator-tag { - display: inline-block; + display: inline-flex; + align-items: center; + gap: 5px; font-size: 10px; font-weight: 700; - padding: 2px 8px; - border-radius: 4px; + padding: 3px 9px; + border-radius: 20px; border: 1px solid transparent; text-transform: uppercase; - letter-spacing: 0.03em; + letter-spacing: 0.05em; +} + +.status-indicator-tag::before { + content: ''; + width: 5px; + height: 5px; + border-radius: 50%; + background: currentColor; } .status-on-duty, .status-active { - background: rgba(34, 197, 94, 0.1); - color: var(--success); - border-color: rgba(34, 197, 94, 0.2); + background: rgba(22, 163, 74, 0.09); + color: #15803d; + border-color: rgba(22, 163, 74, 0.22); } .status-off-duty, .status-on-leave { - background: rgba(239, 68, 68, 0.1); - color: var(--danger); - border-color: rgba(239, 68, 68, 0.2); + background: rgba(220, 38, 38, 0.08); + color: #dc2626; + border-color: rgba(220, 38, 38, 0.2); } .status-on-call { - background: rgba(245, 158, 11, 0.1); - color: var(--warning); - border-color: rgba(245, 158, 11, 0.2); + background: rgba(217, 119, 6, 0.09); + color: #b45309; + border-color: rgba(217, 119, 6, 0.2); } .status-scheduled { - background: rgba(59, 130, 246, 0.1); - color: var(--primary-400); - border-color: rgba(59, 130, 246, 0.2); + background: rgba(37, 99, 235, 0.08); + color: #1d4ed8; + border-color: rgba(37, 99, 235, 0.2); } -/* Form layouts */ +/* ══════════════════════════════════════ + FORM LAYOUTS + ══════════════════════════════════════ */ .form-row-double { display: grid; - grid-template-columns: 1fr 1fr; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; + width: 100%; + min-width: 0; + box-sizing: border-box; } -/* Ensure Front modals stack correctly */ +.form-column > .form-group { + min-width: 0; + width: 100%; +} + + + .modal-front { z-index: 110 !important; } .cancel-btn { - background: none; - border: 1px solid var(--dark-600); - color: var(--gray-300); + background: #faf7f0; + border: 1.5px solid #d5c8ab; + color: #52493e; } .cancel-btn:hover { - background: var(--dark-700); - color: var(--gray-100); + background: #f5eedc; + color: #1e1b18; + border-color: #a29584; } -/* ── TWO-COLUMN FORM LAYOUT ── */ +/* Two-column form grid */ .form-grid-two-col { display: grid; - grid-template-columns: 1fr 1fr; - gap: 24px; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 22px; align-items: start; + width: 100%; + box-sizing: border-box; } .form-column { display: flex; flex-direction: column; - gap: 14px; + gap: 12px; + min-width: 0; + width: 100%; + box-sizing: border-box; } .form-section-title { - font-size: 13.5px; - font-weight: 600; - color: var(--primary-600); - border-bottom: 1px solid var(--dark-600); - padding-bottom: 6px; + font-size: 13px; + font-weight: 700; + color: #1d4ed8; + border-bottom: 2px solid rgba(37, 99, 235, 0.12); + padding-bottom: 8px; margin-top: 0; - margin-bottom: 8px; + margin-bottom: 4px; } .form-info-box { - background: var(--dark-900); - border-left: 3px solid var(--teal-500); - padding: 10px; - border-radius: var(--radius-sm); + background: rgba(13, 148, 136, 0.05); + border-left: 3px solid #0d9488; + padding: 10px 12px; + border-radius: 0 10px 10px 0; font-size: 11.5px; - color: var(--gray-300); + color: #52493e; line-height: 1.5; - margin-top: 6px; + margin-top: 2px; } .form-actions-grid-span { - grid-column: span 2; - margin-top: 10px; + grid-column: span 1; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-top: 8px; + width: 100%; } + + +.form-actions-grid-span button { + width: 100%; + box-sizing: border-box; +} + +@media (max-width: 768px) { + .form-grid-two-col { + grid-template-columns: 1fr; + gap: 18px; + } + +} + +/* ── Provider count badge ── */ +.provider-count-pill { + display: inline-flex; + align-items: center; + gap: 5px; + background: rgba(37, 99, 235, 0.08); + border: 1px solid rgba(37, 99, 235, 0.2); + color: #1d4ed8; + font-size: 11px; + font-weight: 700; + padding: 3px 10px; + border-radius: 20px; +} + +/* Fade-in animation */ +.fade-in { + animation: fadeInUp 0.35s ease both; +} + +@keyframes fadeInUp { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +/* ── Generic Form Fields width/styling ── */ +.form-group { + display: flex; + flex-direction: column; + gap: 6px; + width: 100%; + min-width: 0; + box-sizing: border-box; +} +.form-group label { + font-size: 12.5px; + font-weight: 600; + color: #3b342c; +} + +.form-group input, +.form-group select, +.form-group textarea { + width: 100%; + max-width: 100%; + min-width: 0; + box-sizing: border-box; + + background: #faf7f0; + border: 1.5px solid #eae1cc; + border-radius: 8px; + padding: 9px 11px; + color: #1e1b18; + font-size: 13px; + font-family: inherit; + outline: none; + transition: all 0.2s ease; +} +.form-group input:focus, +.form-group select:focus, +.form-group textarea:focus { + border-color: #2563eb; + background: #ffffff; + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); +} + diff --git a/src/pages/HospitalNetwork.jsx b/src/pages/HospitalNetwork.jsx index 4f37d12..7b1c9f4 100644 --- a/src/pages/HospitalNetwork.jsx +++ b/src/pages/HospitalNetwork.jsx @@ -47,9 +47,13 @@ export default function HospitalNetwork({ notify }) { return saved ? JSON.parse(saved) : DEFAULT_STAFF }) + // Providers (Doctors) fetched from real API per hospital + const [providers, setProviders] = useState([]) + const [providersLoading, setProvidersLoading] = useState(false) + // Selection & UI States const [selectedGroupId, setSelectedGroupId] = useState('HG001') - const [activeHospitalStaffId, setActiveHospitalStaffId] = useState(null) // ID of hospital whose staff modal is open + const [activeHospitalStaffId, setActiveHospitalStaffId] = useState(null) const [staffTab, setStaffTab] = useState('doctor') // 'doctor' | 'caregiver' // Searches & Filters @@ -90,7 +94,17 @@ export default function HospitalNetwork({ notify }) { 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', + // Doctor-specific (API provider fields) + firstName: '', lastName: '', email: '', username: '', password: '', + mobile: '', isdCode: '+91', gender: 'male', dob: '', bloodGroup: '', + licenseNo: '', practicingSince: '', + providerSpeciality: '', // comma-separated input → array on submit + // Caregiver-specific (local only) + name: '', specialty: '', role: 'Registered Nurse', experience: '1 Yr', + certification: '', status: 'On Duty', phone: '', + }) // Synchronize with LocalStorage useEffect(() => { @@ -119,8 +133,6 @@ export default function HospitalNetwork({ notify }) { 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) @@ -135,7 +147,6 @@ export default function HospitalNetwork({ notify }) { if (fetchedGroups.length > 0) { setGroups(fetchedGroups) - // Automatically select the first fetched group ID setSelectedGroupId(fetchedGroups[0].id) } @@ -173,7 +184,7 @@ export default function HospitalNetwork({ notify }) { console.log('Hospitals API bypass') } - // Fetch staff + // Fetch caregiver staff try { const staffRes = await adminService.hospitalNetwork.getStaff() let fetchedStaff = [] @@ -196,10 +207,41 @@ export default function HospitalNetwork({ notify }) { } }, []) + // Fetch providers (doctors) for a specific hospital from the real API + const fetchProviders = useCallback(async (hospitalId) => { + if (!hospitalId) return + setProvidersLoading(true) + setProviders([]) + try { + const res = await adminService.hospitalNetwork.getProviders(hospitalId) + // Response shape: { success, data: { providers: [...], pagination: {...} } } + let list = [] + if (res?.data?.providers && Array.isArray(res.data.providers)) { + list = res.data.providers + } else if (res?.data && Array.isArray(res.data)) { + list = res.data + } else if (Array.isArray(res)) { + list = res + } + setProviders(list) + } catch (err) { + console.log('Providers fetch failed, showing local doctors') + setProviders([]) + } finally { + setProvidersLoading(false) + } + }, []) + useEffect(() => { syncWithApi() }, [syncWithApi]) + useEffect(() => { + if (activeHospitalStaffId) { + fetchProviders(activeHospitalStaffId) + } + }, [activeHospitalStaffId, fetchProviders]) + // Analytics Helpers const analytics = useMemo(() => { const totalGroups = groups.length @@ -230,16 +272,27 @@ export default function HospitalNetwork({ notify }) { }, [groups, groupQuery]) const selectedGroup = useMemo(() => { + if (selectedGroupId === 'standalone') { + return { + id: 'standalone', + name: 'Independent Facilities', + description: 'Standalone hospitals and clinic networks operating independently of corporate provider groups.' + } + } return groups.find(g => g.id === selectedGroupId) || groups[0] }, [groups, selectedGroupId]) const filteredHospitals = useMemo(() => { if (!selectedGroupId) return [] - return hospitals.filter(h => - (h.groupId === selectedGroupId || h.group_id === selectedGroupId || String(h.groupId) === String(selectedGroupId) || String(h.group_id) === String(selectedGroupId)) && - (h.name.toLowerCase().includes(hospitalQuery.toLowerCase()) || - h.city.toLowerCase().includes(hospitalQuery.toLowerCase())) - ) + return hospitals.filter(h => { + const matchesGroup = selectedGroupId === 'standalone' + ? (!h.groupId && !h.group_id) + : (h.groupId === selectedGroupId || h.group_id === selectedGroupId || String(h.groupId) === String(selectedGroupId) || String(h.group_id) === String(selectedGroupId)); + + return matchesGroup && + (h.name.toLowerCase().includes(hospitalQuery.toLowerCase()) || + (h.city || '').toLowerCase().includes(hospitalQuery.toLowerCase())) + }) }, [hospitals, selectedGroupId, hospitalQuery]) const activeHospital = useMemo(() => { @@ -265,11 +318,39 @@ export default function HospitalNetwork({ notify }) { }) }, [staff, activeHospitalStaffId, staffTab, staffQuery, specialtyFilter, roleFilter]) + // Unique list of providers (doctors) filtered from the API response + const filteredProviders = useMemo(() => { + if (staffTab !== 'doctor') return [] + return providers.filter(p => { + const user = p.user || {} + const fullName = `${user.first_name || ''} ${user.last_name || ''}`.toLowerCase() + const email = (user.email || '').toLowerCase() + const username = (user.username || '').toLowerCase() + const matchesSearch = fullName.includes(staffQuery.toLowerCase()) || + email.includes(staffQuery.toLowerCase()) || + username.includes(staffQuery.toLowerCase()) + + const specs = p.provider_speciality || [] + const specialtyNames = specs.map(s => s.speciality || '').filter(Boolean) + const matchesSpec = specialtyFilter === 'All' || + specialtyNames.some(sName => sName.toLowerCase() === specialtyFilter.toLowerCase()) + + return matchesSearch && matchesSpec + }) + }, [providers, staffTab, staffQuery, specialtyFilter]) + // Unique lists for filtering dropdowns const specialties = useMemo(() => { const list = staff.filter(s => s.type === 'doctor').map(s => s.specialty) - return ['All', ...new Set(list)] - }, [staff]) + providers.forEach(p => { + if (p.provider_speciality && Array.isArray(p.provider_speciality)) { + p.provider_speciality.forEach(s => { + if (s.speciality) list.push(s.speciality) + }) + } + }) + return ['All', ...new Set(list.filter(Boolean))] + }, [staff, providers]) const roles = useMemo(() => { const list = staff.filter(s => s.type === 'caregiver').map(s => s.role) @@ -516,19 +597,40 @@ export default function HospitalNetwork({ notify }) { setEditItem(item) setStaffForm({ type: item.type, - name: item.name, + // Doctor fields + firstName: item.user?.first_name || item.firstName || '', + lastName: item.user?.last_name || item.lastName || '', + email: item.user?.email || item.email || '', + username: item.user?.username || item.username || '', + password: '', + mobile: item.user?.mobile || item.mobile || '', + isdCode: item.user?.isd_code || item.isdCode || '+91', + gender: item.user?.gender || item.gender || 'male', + dob: item.user?.dob || item.dob || '', + bloodGroup: item.user?.blood_group || item.bloodGroup || '', + licenseNo: item.license_no || item.licenseNo || '', + practicingSince: item.practicing_since || item.practicingSince || '', + providerSpeciality: Array.isArray(item.provider_speciality) + ? item.provider_speciality.join(', ') + : (item.providerSpeciality || item.specialty || ''), + // Caregiver fields + name: item.name || '', specialty: item.specialty || '', role: item.role || 'Registered Nurse', experience: item.experience || '1 Yr', certification: item.certification || '', - status: item.status, - phone: item.phone, - email: item.email + status: item.status || 'On Duty', + phone: item.phone || '', }) } else { setEditItem(null) setStaffForm({ type: staffTab, + // Doctor fields + firstName: '', lastName: '', email: '', username: '', password: '', + mobile: '', isdCode: '+91', gender: 'male', dob: '', bloodGroup: '', + licenseNo: '', practicingSince: '', providerSpeciality: '', + // Caregiver fields name: '', specialty: '', role: 'Registered Nurse', @@ -536,30 +638,95 @@ export default function HospitalNetwork({ notify }) { certification: '', status: staffTab === 'doctor' ? 'On Duty' : 'Active', phone: '', - email: '' }) } } const handleStaffSubmit = async (e) => { e.preventDefault() - if (!staffForm.name.trim()) return notify('Provider Name is required', true) + + // ── DOCTOR: call the real provider API ── + if (staffForm.type === 'doctor') { + if (!staffForm.firstName.trim()) return notify('First Name is required', true) + if (!staffForm.lastName.trim()) return notify('Last Name is required', true) + if (!staffForm.email.trim()) return notify('Email is required', true) + if (modalMode === 'create' && !staffForm.password.trim()) return notify('Password is required', true) + if (!staffForm.mobile.trim()) return notify('Mobile number is required', true) + if (!staffForm.licenseNo.trim()) return notify('License number is required', true) + + try { + const providerPayload = { + user: { + role: 'provider', + first_name: staffForm.firstName, + last_name: staffForm.lastName, + email: staffForm.email, + username: staffForm.username || `${staffForm.firstName.toLowerCase()}_${staffForm.lastName.toLowerCase()}`, + password: staffForm.password, + mobile: staffForm.mobile, + isd_code: staffForm.isdCode, + gender: staffForm.gender, + dob: staffForm.dob || '1980-01-01', + blood_group: staffForm.bloodGroup || 'O+', + timezone_id: 1, + country_iso: 'IN', + is_active: 1, + }, + license_no: staffForm.licenseNo, + practicing_since: staffForm.practicingSince || '2010-01-01', + provider_speciality: staffForm.providerSpeciality + ? staffForm.providerSpeciality.split(',').map(s => s.trim()).filter(Boolean) + : [], + } + + const res = await adminService.hospitalNetwork.addProvider(activeHospitalStaffId, providerPayload) + + if (res?.success || res?.status === 201 || res?.data) { + notify(`Dr. ${staffForm.firstName} ${staffForm.lastName} registered successfully.`) + // Add optimistic local entry so table updates immediately + const localEntry = { + id: res?.data?.id || ('S' + Date.now().toString().slice(-4)), + hospitalId: activeHospitalStaffId, + hospital_id: activeHospitalStaffId, + type: 'doctor', + name: `Dr. ${staffForm.firstName} ${staffForm.lastName}`, + specialty: staffForm.providerSpeciality.split(',')[0]?.trim() || 'General Physician', + experience: staffForm.practicingSince + ? `${new Date().getFullYear() - new Date(staffForm.practicingSince).getFullYear()} Yrs` + : '1 Yr', + status: 'On Duty', + phone: `${staffForm.isdCode}${staffForm.mobile}`, + email: staffForm.email, + } + setStaff(prev => [...prev, localEntry]) + setModalType(null) + } else { + notify(res?.message || 'Failed to register provider', true) + } + } catch (err) { + notify(err.message || 'An error occurred while registering provider', true) + } + return + } + + // ── CAREGIVER: local state only ── + if (!staffForm.name.trim()) return notify('Caregiver Name is required', true) if (modalMode === 'create') { const newStaff = { id: 'S' + Date.now().toString().slice(-4), hospitalId: activeHospitalStaffId, - type: staffForm.type, + hospital_id: activeHospitalStaffId, + type: 'caregiver', name: staffForm.name, status: staffForm.status, phone: staffForm.phone, - email: staffForm.email, - ...(staffForm.type === 'doctor' - ? { specialty: staffForm.specialty || 'General Physician', experience: staffForm.experience } - : { role: staffForm.role, certification: staffForm.certification }) + email: staffForm.email || '', + role: staffForm.role, + certification: staffForm.certification, } setStaff(prev => [...prev, newStaff]) - notify(`${staffForm.type === 'doctor' ? 'Doctor' : 'Caregiver'} "${staffForm.name}" registered successfully.`) + notify(`Caregiver "${staffForm.name}" registered successfully.`) } else if (modalMode === 'edit' && editItem) { setStaff(prev => prev.map(s => s.id === editItem.id ? { ...s, @@ -647,8 +814,7 @@ export default function HospitalNetwork({ notify }) {
HQ: {hqVal} · Est: {estVal}
-+ HQ: {hqVal} · Est: {estVal} +
+ ++ Hospitals not affiliated with a hospital group +
+| Clinician Name | -Specialty | -Experience | -Contact Number | -Operations Status | -Actions | -||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Caregiver Name | Role category | @@ -915,52 +1233,52 @@ export default function HospitalNetwork({ notify }) {Work Status | Actions | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - No matching staff members enrolled at this facility. - | -|||||||||||||||||
|
-
-
- {s.type === 'doctor' ? 'DR' : (s.role ? s.role.substring(0, 2).toUpperCase() : 'CG')}
+
+
+ {filteredStaff.length === 0 ? (
+
+ No matching staff members enrolled at this facility.
+ |
+
+ |
+
+
-
+ {s.role ? s.role.substring(0, 2).toUpperCase() : 'CG'}
+
+
+ {s.name}
+ {s.email || 'N/A'}
+
- {s.name}
- {s.email || 'N/A'}
+ {s.role} |
+ {s.certification || 'Verified'} |
+ {s.phone || 'N/A'} |
+
+
+ {s.status}
+
+ |
+
+ |
-
+
-
- {s.type === 'doctor' ? s.specialty : s.role} |
- {s.type === 'doctor' ? s.experience : (s.certification || 'Verified')} |
- {s.phone || 'N/A'} |
-
-
- {s.status}
-
- |
-
- |
-
-
- | |||||