From 278498123d1d59010feee057cfd13f8592fa100a Mon Sep 17 00:00:00 2001 From: mahdahar <89adham@gmail.com> Date: Fri, 13 Feb 2026 16:07:59 +0700 Subject: [PATCH] Add containers and tests master data modules - Add containers management page with CRUD operations - Add tests management page with test configuration - Add organization API client - Update SelectDropdown and Sidebar components - Enhance PatientFormModal and VisitListModal - Add VisitFormModal for visit management --- src/lib/api/containers.js | 39 + src/lib/api/organization.js | 21 + src/lib/api/tests.js | 41 ++ src/lib/components/SelectDropdown.svelte | 40 +- src/lib/components/Sidebar.svelte | 21 +- src/routes/(app)/master-data/+page.svelte | 18 +- .../(app)/master-data/containers/+page.svelte | 261 +++++++ .../(app)/master-data/tests/+page.svelte | 389 ++++++++++ .../(app)/patients/PatientFormModal.svelte | 693 +++++++++--------- .../(app)/patients/VisitFormModal.svelte | 389 ++++++++++ .../(app)/patients/VisitListModal.svelte | 93 ++- 11 files changed, 1630 insertions(+), 375 deletions(-) create mode 100644 src/lib/api/containers.js create mode 100644 src/lib/api/organization.js create mode 100644 src/lib/api/tests.js create mode 100644 src/routes/(app)/master-data/containers/+page.svelte create mode 100644 src/routes/(app)/master-data/tests/+page.svelte create mode 100644 src/routes/(app)/patients/VisitFormModal.svelte diff --git a/src/lib/api/containers.js b/src/lib/api/containers.js new file mode 100644 index 0000000..4dfb7c4 --- /dev/null +++ b/src/lib/api/containers.js @@ -0,0 +1,39 @@ +import { get, post, patch, del } from './client.js'; + +export async function fetchContainers(params = {}) { + const query = new URLSearchParams(params).toString(); + return get(query ? `/api/specimen/container?${query}` : '/api/specimen/container'); +} + +export async function fetchContainer(id) { + return get(`/api/specimen/container/${id}`); +} + +export async function createContainer(data) { + const payload = { + ConCode: data.ConCode, + ConName: data.ConName, + ConDesc: data.ConDesc, + ConClass: data.ConClass, + Additive: data.Additive, + Color: data.Color, + }; + return post('/api/specimen/container', payload); +} + +export async function updateContainer(data) { + const payload = { + ConDefID: data.ConDefID, + ConCode: data.ConCode, + ConName: data.ConName, + ConDesc: data.ConDesc, + ConClass: data.ConClass, + Additive: data.Additive, + Color: data.Color, + }; + return patch('/api/specimen/container', payload); +} + +export async function deleteContainer(id) { + return del('/api/specimen/container', { body: JSON.stringify({ ConDefID: id }) }); +} diff --git a/src/lib/api/organization.js b/src/lib/api/organization.js new file mode 100644 index 0000000..ccb212d --- /dev/null +++ b/src/lib/api/organization.js @@ -0,0 +1,21 @@ +import { get, post, patch, del } from './client.js'; + +// Disciplines +export async function fetchDisciplines(params = {}) { + const query = new URLSearchParams(params).toString(); + return get(query ? `/api/organization/discipline?${query}` : '/api/organization/discipline'); +} + +export async function fetchDiscipline(id) { + return get(`/api/organization/discipline/${id}`); +} + +// Departments +export async function fetchDepartments(params = {}) { + const query = new URLSearchParams(params).toString(); + return get(query ? `/api/organization/department?${query}` : '/api/organization/department'); +} + +export async function fetchDepartment(id) { + return get(`/api/organization/department/${id}`); +} diff --git a/src/lib/api/tests.js b/src/lib/api/tests.js new file mode 100644 index 0000000..ba99823 --- /dev/null +++ b/src/lib/api/tests.js @@ -0,0 +1,41 @@ +import { get, post, patch } from './client.js'; + +export async function fetchTests(params = {}) { + const query = new URLSearchParams(params).toString(); + return get(query ? `/api/tests?${query}` : '/api/tests'); +} + +export async function fetchTest(id) { + return get(`/api/tests/${id}`); +} + +export async function createTest(data) { + const payload = { + TestSiteCode: data.TestSiteCode, + TestSiteName: data.TestSiteName, + TestType: data.TestType, + DisciplineID: data.DisciplineID, + DepartmentID: data.DepartmentID, + SeqScr: data.SeqScr, + SeqRpt: data.SeqRpt, + VisibleScr: data.VisibleScr ? '1' : '0', + VisibleRpt: data.VisibleRpt ? '1' : '0', + }; + return post('/api/tests', payload); +} + +export async function updateTest(data) { + const payload = { + TestSiteID: data.TestSiteID, + TestSiteCode: data.TestSiteCode, + TestSiteName: data.TestSiteName, + TestType: data.TestType, + DisciplineID: data.DisciplineID, + DepartmentID: data.DepartmentID, + SeqScr: data.SeqScr, + SeqRpt: data.SeqRpt, + VisibleScr: data.VisibleScr ? '1' : '0', + VisibleRpt: data.VisibleRpt ? '1' : '0', + }; + return patch('/api/tests', payload); +} diff --git a/src/lib/components/SelectDropdown.svelte b/src/lib/components/SelectDropdown.svelte index 32ed546..39f8e37 100644 --- a/src/lib/components/SelectDropdown.svelte +++ b/src/lib/components/SelectDropdown.svelte @@ -64,9 +64,9 @@ } }); - // Check if current value exists in options + // Check if current value exists in options (empty string is always valid) let hasValidValue = $derived( - !value || dropdownOptions.some(opt => opt.value === value) + value === '' || value === null || value === undefined || dropdownOptions.some(opt => opt.value === value) ); @@ -81,25 +81,23 @@
Manage specimen containers and tubes
++ Are you sure you want to delete {deleteItem?.ConName}? +
+This action cannot be undone.
+Manage laboratory tests and panels
+