From cb4181dbffef3ac6074677a2639eee5dee9d151e Mon Sep 17 00:00:00 2001
From: mahdahar <89adham@gmail.com>
Date: Mon, 29 Dec 2025 16:57:46 +0700
Subject: [PATCH] refactor: restructure application architecture and
consolidate controllers
- Consolidate page controllers into unified PagesController
- Remove deprecated V2 pages, layouts, and controllers (AuthPage, DashboardPage, V2Page)
- Add Edge resource with migration and model (EdgeResModel)
- Implement new main_layout.php for consistent page structure
- Reorganize patient views into dedicated module with dialog form
- Update routing configuration in Routes.php
- Enhance AuthFilter for improved authentication handling
- Clean up unused V2 assets (CSS, JS) and legacy images
- Update README.md with latest project information
This refactoring improves code organization, removes technical debt, and
establishes a cleaner foundation for future development.
---
README.md | 29 +-
app/Config/Routes.php | 54 +-
app/Controllers/Edge.php | 163 ++++
app/Controllers/Pages/AuthPage.php | 53 --
app/Controllers/Pages/DashboardPage.php | 49 --
app/Controllers/Pages/V2Page.php | 345 --------
app/Controllers/PagesController.php | 67 ++
.../Migrations/2025-12-29-150000_EdgeRes.php | 58 ++
app/Filters/AuthFilter.php | 36 +-
app/Models/EdgeResModel.php | 63 ++
app/Views/layout/main_layout.php | 188 +++++
app/Views/layouts/v2-login.php | 60 --
app/Views/layouts/v2.php | 387 ---------
app/Views/layouts/v2_auth.php | 218 -----
app/Views/pages/dashboard.php | 328 --------
app/Views/pages/login.php | 233 ------
app/Views/patients/dialog_form.php | 188 +++++
app/Views/patients/patients_index.php | 414 ++++++++++
app/Views/v2/README.md | 37 -
app/Views/v2/api-tester.php | 68 --
app/Views/v2/dashboard.php | 169 ----
app/Views/v2/db-browser.php | 80 --
app/Views/v2/jwt-decoder.php | 94 ---
app/Views/v2/login.php | 70 --
app/Views/v2/logs.php | 51 --
app/Views/v2/organization.php | 297 -------
app/Views/v2/patient-form.php | 456 -----------
app/Views/v2/patient-view.php | 305 -------
app/Views/v2/patients.php | 694 ----------------
app/Views/v2/valuesets.php | 390 ---------
public/assets/images/logo.png | Bin 549617 -> 0 bytes
public/assets/js/app.js | 90 ---
public/assets/js/lucide.min.js | 12 -
public/assets/v2/css/v2.css | 753 ------------------
public/assets/v2/js/v2.js | 194 -----
public/upload/meow.jpg | Bin 13753 -> 0 bytes
public/upload/panda.jpg | Bin 24331 -> 0 bytes
37 files changed, 1214 insertions(+), 5479 deletions(-)
create mode 100644 app/Controllers/Edge.php
delete mode 100644 app/Controllers/Pages/AuthPage.php
delete mode 100644 app/Controllers/Pages/DashboardPage.php
delete mode 100644 app/Controllers/Pages/V2Page.php
create mode 100644 app/Controllers/PagesController.php
create mode 100644 app/Database/Migrations/2025-12-29-150000_EdgeRes.php
create mode 100644 app/Models/EdgeResModel.php
create mode 100644 app/Views/layout/main_layout.php
delete mode 100644 app/Views/layouts/v2-login.php
delete mode 100644 app/Views/layouts/v2.php
delete mode 100644 app/Views/layouts/v2_auth.php
delete mode 100644 app/Views/pages/dashboard.php
delete mode 100644 app/Views/pages/login.php
create mode 100644 app/Views/patients/dialog_form.php
create mode 100644 app/Views/patients/patients_index.php
delete mode 100644 app/Views/v2/README.md
delete mode 100644 app/Views/v2/api-tester.php
delete mode 100644 app/Views/v2/dashboard.php
delete mode 100644 app/Views/v2/db-browser.php
delete mode 100644 app/Views/v2/jwt-decoder.php
delete mode 100644 app/Views/v2/login.php
delete mode 100644 app/Views/v2/logs.php
delete mode 100644 app/Views/v2/organization.php
delete mode 100644 app/Views/v2/patient-form.php
delete mode 100644 app/Views/v2/patient-view.php
delete mode 100644 app/Views/v2/patients.php
delete mode 100644 app/Views/v2/valuesets.php
delete mode 100644 public/assets/images/logo.png
delete mode 100644 public/assets/js/app.js
delete mode 100644 public/assets/js/lucide.min.js
delete mode 100644 public/assets/v2/css/v2.css
delete mode 100644 public/assets/v2/js/v2.js
delete mode 100644 public/upload/meow.jpg
delete mode 100644 public/upload/panda.jpg
diff --git a/README.md b/README.md
index c45a027..c19c308 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ The system is currently undergoing a strategic **Architectural Redesign** to con
| **Framework** | CodeIgniter 4 |
| **Security** | JWT (JSON Web Tokens) Authorization |
| **Database** | MySQL (Optimized Schema Migration in progress) |
-| **Dev Tools** | Internal utilities available at `/v2` |
+
---
@@ -50,6 +50,33 @@ Key documents:
---
+## 🔌 Edge API - Instrument Integration
+
+The **Edge API** provides endpoints for integrating laboratory instruments via the `tiny-edge` middleware. Results from instruments are staged in the `edgeres` table before processing into the main patient results (`patres`).
+
+### Endpoints
+
+| Method | Endpoint | Description |
+|--------|----------|-------------|
+| `POST` | `/api/edge/results` | Receive instrument results (stored in `edgeres`) |
+| `GET` | `/api/edge/orders` | Fetch pending orders for an instrument |
+| `POST` | `/api/edge/orders/:id/ack` | Acknowledge order delivery to instrument |
+| `POST` | `/api/edge/status` | Log instrument status updates |
+
+### Workflow
+
+```
+Instrument → tiny-edge → POST /api/edge/results → edgeres table → [Manual/Auto Processing] → patres table
+```
+
+**Key Features:**
+- **Staging Table:** All results land in `edgeres` first for validation
+- **Rerun Handling:** Duplicate `SampleID` + `TestSiteCode` increments `AspCnt` in `patres`
+- **Configurable Processing:** Auto or manual processing based on settings
+- **Status Tracking:** Full audit trail via `edgestatus` and `edgeack` tables
+
+---
+
### 📜 Usage Notice
This repository contains proprietary information intended for the 5Panda Team and authorized collaborators.
diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index 7e93957..0a1699f 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -6,16 +6,23 @@ use CodeIgniter\Router\RouteCollection;
* @var RouteCollection $routes
*/
$routes->options('(:any)', function() { return ''; });
-$routes->get('/', 'Pages\V2Page::index');
-
-// Frontend Pages
-$routes->get('/login', 'Pages\V2Page::login');
-$routes->get('/logout', 'Pages\AuthPage::logout');
-$routes->get('/dashboard', 'Pages\V2Page::index');
// Faker
$routes->get('faker/faker-patient/(:num)', 'faker\FakerPatient::sendMany/$1');
+// ===========================================
+// Page Routes (Protected - returns views)
+// ===========================================
+$routes->group('', ['filter' => 'auth'], function($routes) {
+ $routes->get('/', 'PagesController::dashboard');
+ $routes->get('/patients', 'PagesController::patients');
+ $routes->get('/requests', 'PagesController::requests');
+ $routes->get('/settings', 'PagesController::settings');
+});
+
+// Login page (public)
+$routes->get('/login', 'PagesController::login');
+
$routes->group('api', ['filter' => 'auth'], function($routes) {
$routes->get('dashboard', 'Dashboard::index');
$routes->get('result', 'Result::index');
@@ -166,6 +173,14 @@ $routes->patch('/api/tests', 'Tests::update');
$routes->get('/api/tests/(:any)', 'Tests::show/$1');
$routes->get('/api/tests', 'Tests::index');
+// Edge API - Integration with tiny-edge
+$routes->group('/api/edge', function($routes) {
+ $routes->post('results', 'Edge::results');
+ $routes->get('orders', 'Edge::orders');
+ $routes->post('orders/(:num)/ack', 'Edge::ack/$1');
+ $routes->post('status', 'Edge::status');
+});
+
// Khusus
/*
$routes->get('/api/zones', 'Zones::index');
@@ -173,30 +188,3 @@ $routes->get('/api/zones/synchronize', 'Zones::synchronize');
$routes->get('/api/zones/provinces', 'Zones::getProvinces');
$routes->get('/api/zones/cities', 'Zones::getCities');
*/
-
-// V2 Hidden Frontend
-$routes->group('v2', function($routes) {
- $routes->get('login', 'Pages\V2Page::login');
- $routes->get('/', 'Pages\V2Page::index');
- $routes->get('dashboard', 'Pages\V2Page::index');
- $routes->get('api-tester', 'Pages\V2Page::apiTester');
- $routes->get('db-browser', 'Pages\V2Page::dbBrowser');
- $routes->get('logs', 'Pages\V2Page::logs');
- $routes->get('jwt-decoder', 'Pages\V2Page::jwtDecoder');
-
- // Patient
- $routes->get('patients', 'Pages\V2Page::patients');
- $routes->get('patients/create', 'Pages\V2Page::patientCreate');
- $routes->get('patients/edit/(:num)', 'Pages\V2Page::patientEdit/$1');
- $routes->get('patients/(:num)', 'Pages\V2Page::patientView/$1');
-
- // System
- $routes->get('organization/(:segment)', 'Pages\V2Page::organization/$1');
- $routes->get('organization', 'Pages\V2Page::organization'); // Default redirect or view
- $routes->get('valuesets', 'Pages\V2Page::valuesets');
-
- // V2 API endpoints
- $routes->get('api/tables', 'Pages\V2Page::getTables');
- $routes->get('api/table/(:any)', 'Pages\V2Page::getTableData/$1');
- $routes->get('api/logs', 'Pages\V2Page::getLogs');
-});
\ No newline at end of file
diff --git a/app/Controllers/Edge.php b/app/Controllers/Edge.php
new file mode 100644
index 0000000..0951a67
--- /dev/null
+++ b/app/Controllers/Edge.php
@@ -0,0 +1,163 @@
+db = \Config\Database::connect();
+ $this->edgeResModel = new \App\Models\EdgeResModel();
+ }
+
+ /**
+ * POST /api/edge/results
+ * Receive results from tiny-edge
+ */
+ public function results() {
+ try {
+ $input = $this->request->getJSON(true);
+
+ if (empty($input)) {
+ return $this->failValidationErrors('Invalid JSON payload');
+ }
+
+ // Extract key fields from payload
+ $sampleId = $input['sample_id'] ?? null;
+ $instrumentId = $input['instrument_id'] ?? null;
+ $patientId = $input['patient_id'] ?? null;
+
+ // Store in edgeres table
+ $data = [
+ 'SiteID' => 1, // Default site, can be configured
+ 'InstrumentID' => $instrumentId,
+ 'SampleID' => $sampleId,
+ 'PatientID' => $patientId,
+ 'Payload' => json_encode($input),
+ 'Status' => 'pending',
+ 'AutoProcess' => 0, // Default to manual processing
+ 'CreateDate' => date('Y-m-d H:i:s')
+ ];
+
+ $id = $this->edgeResModel->insert($data);
+
+ if (!$id) {
+ return $this->failServerError('Failed to save result');
+ }
+
+ return $this->respondCreated([
+ 'status' => 'success',
+ 'message' => 'Result received and queued',
+ 'data' => [
+ 'edge_res_id' => $id,
+ 'sample_id' => $sampleId,
+ 'instrument_id' => $instrumentId
+ ]
+ ]);
+
+ } catch (\Throwable $e) {
+ return $this->failServerError('Error processing result: ' . $e->getMessage());
+ }
+ }
+
+ /**
+ * GET /api/edge/orders
+ * Return pending orders for an instrument
+ */
+ public function orders() {
+ try {
+ $instrumentId = $this->request->getGet('instrument');
+
+ if (!$instrumentId) {
+ return $this->failValidationErrors('instrument parameter is required');
+ }
+
+ // TODO: Implement order fetching logic
+ // For now, return empty array
+ return $this->respond([
+ 'status' => 'success',
+ 'message' => 'Orders fetched',
+ 'data' => []
+ ]);
+
+ } catch (\Throwable $e) {
+ return $this->failServerError('Error fetching orders: ' . $e->getMessage());
+ }
+ }
+
+ /**
+ * POST /api/edge/orders/:id/ack
+ * Acknowledge order delivery
+ */
+ public function ack($orderId = null) {
+ try {
+ if (!$orderId) {
+ return $this->failValidationErrors('Order ID is required');
+ }
+
+ $input = $this->request->getJSON(true);
+ $instrumentId = $input['instrument_id'] ?? null;
+
+ // Log acknowledgment
+ $this->db->table('edgeack')->insert([
+ 'OrderID' => $orderId,
+ 'InstrumentID' => $instrumentId,
+ 'AckDate' => date('Y-m-d H:i:s'),
+ 'CreateDate' => date('Y-m-d H:i:s')
+ ]);
+
+ return $this->respond([
+ 'status' => 'success',
+ 'message' => 'Order acknowledged',
+ 'data' => [
+ 'order_id' => $orderId
+ ]
+ ]);
+
+ } catch (\Throwable $e) {
+ return $this->failServerError('Error acknowledging order: ' . $e->getMessage());
+ }
+ }
+
+ /**
+ * POST /api/edge/status
+ * Log instrument status
+ */
+ public function status() {
+ try {
+ $input = $this->request->getJSON(true);
+
+ $instrumentId = $input['instrument_id'] ?? null;
+ $status = $input['status'] ?? null;
+ $lastActivity = $input['last_activity'] ?? null;
+ $timestamp = $input['timestamp'] ?? date('Y-m-d H:i:s');
+
+ if (!$instrumentId || !$status) {
+ return $this->failValidationErrors('instrument_id and status are required');
+ }
+
+ // Store status log
+ $this->db->table('edgestatus')->insert([
+ 'InstrumentID' => $instrumentId,
+ 'Status' => $status,
+ 'LastActivity' => $lastActivity,
+ 'Timestamp' => $timestamp,
+ 'CreateDate' => date('Y-m-d H:i:s')
+ ]);
+
+ return $this->respond([
+ 'status' => 'success',
+ 'message' => 'Status logged'
+ ]);
+
+ } catch (\Throwable $e) {
+ return $this->failServerError('Error logging status: ' . $e->getMessage());
+ }
+ }
+}
diff --git a/app/Controllers/Pages/AuthPage.php b/app/Controllers/Pages/AuthPage.php
deleted file mode 100644
index d8eb74f..0000000
--- a/app/Controllers/Pages/AuthPage.php
+++ /dev/null
@@ -1,53 +0,0 @@
-request->getCookie('token');
-
- if ($token) {
- // If token exists, redirect to dashboard
- return redirect()->to('/dashboard');
- }
-
- return view('pages/login', [
- 'title' => 'Login',
- 'description' => 'Sign in to your CLQMS account'
- ]);
- }
-
- /**
- * Handle logout - clear cookie and redirect
- */
- public function logout()
- {
- // Determine secure status matching Auth controller logic
- $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
-
- // Manually expire the cookie with matching attributes to ensure deletion
- $this->response->setCookie([
- 'name' => 'token',
- 'value' => '',
- 'expire' => time() - 3600,
- 'path' => '/',
- 'secure' => $isSecure,
- 'httponly' => true,
- 'samesite' => $isSecure ? 'None' : 'Lax'
- ]);
-
- return redirect()->to('/login')->withCookies();
- }
-}
diff --git a/app/Controllers/Pages/DashboardPage.php b/app/Controllers/Pages/DashboardPage.php
deleted file mode 100644
index 129561f..0000000
--- a/app/Controllers/Pages/DashboardPage.php
+++ /dev/null
@@ -1,49 +0,0 @@
-request->getCookie('token');
-
- if (!$token) {
- return redirect()->to('/login');
- }
-
- try {
- $key = getenv('JWT_SECRET');
- $decoded = JWT::decode($token, new Key($key, 'HS256'));
-
- return view('pages/dashboard', [
- 'title' => 'Dashboard',
- 'description' => 'CLQMS Dashboard - Overview',
- 'user' => $decoded
- ]);
- } catch (ExpiredException $e) {
- // Token expired, redirect to login
- $response = service('response');
- $response->deleteCookie('token');
- return redirect()->to('/login');
- } catch (\Exception $e) {
- // Invalid token
- $response = service('response');
- $response->deleteCookie('token');
- return redirect()->to('/login');
- }
- }
-}
diff --git a/app/Controllers/Pages/V2Page.php b/app/Controllers/Pages/V2Page.php
deleted file mode 100644
index 210b919..0000000
--- a/app/Controllers/Pages/V2Page.php
+++ /dev/null
@@ -1,345 +0,0 @@
-request->getCookie('token');
-
- // Debug: Log cookie status
- log_message('debug', 'V2Page checkAuth - token cookie: ' . ($token ? 'EXISTS (length: ' . strlen($token) . ')' : 'NOT FOUND'));
- log_message('debug', 'V2Page checkAuth - all cookies: ' . json_encode($_COOKIE));
-
- if (!$token) {
- return false;
- }
-
- try {
- // Use getenv() directly like Auth controller
- $key = getenv('JWT_SECRET');
-
- // Debug environment if key missing
- if (empty($key)) {
- log_message('error', 'V2Page checkAuth - JWT_SECRET missing. Env vars available: ' . implode(',', array_keys($_ENV)));
- log_message('error', 'V2Page checkAuth - getenv(JWT_SECRET): ' . (getenv('JWT_SECRET') ? 'FOUND' : 'EMPTY'));
- return false;
- }
-
- $this->user = JWT::decode($token, new Key($key, 'HS256'));
- return true;
- } catch (ExpiredException $e) {
- log_message('debug', 'V2Page checkAuth - token expired');
- return false;
- } catch (\Exception $e) {
- log_message('debug', 'V2Page checkAuth - token error: ' . $e->getMessage());
- return false;
- }
- }
-
- /**
- * Redirect to V2 login if not authenticated
- */
- protected function requireAuth()
- {
- if (!$this->checkAuth()) {
- return redirect()->to(site_url('v2/login'));
- }
- return null;
- }
-
- /**
- * V2 Login Page
- */
- public function login()
- {
- // If already authenticated, redirect to dashboard
- if ($this->checkAuth()) {
- return redirect()->to(site_url('v2'));
- }
-
- return view('v2/login', [
- 'title' => 'V2 Login'
- ]);
- }
-
- /**
- * V2 Dashboard
- */
- public function index()
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- return view('v2/dashboard', [
- 'title' => 'V2 Dashboard',
- 'user' => $this->user,
- 'activePage' => 'dashboard'
- ]);
- }
-
- /**
- * API Tester
- */
- public function apiTester()
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- return view('v2/api-tester', [
- 'title' => 'API Tester',
- 'user' => $this->user,
- 'activePage' => 'api-tester'
- ]);
- }
-
- /**
- * Database Browser
- */
- public function dbBrowser()
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- return view('v2/db-browser', [
- 'title' => 'DB Browser',
- 'user' => $this->user,
- 'activePage' => 'db-browser'
- ]);
- }
-
- /**
- * Logs Viewer
- */
- public function logs()
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- return view('v2/logs', [
- 'title' => 'Logs',
- 'user' => $this->user,
- 'activePage' => 'logs'
- ]);
- }
-
- /**
- * Organization Management
- */
- public function organization($type = 'account')
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- // Normalize type
- $type = strtolower($type);
- $validTypes = ['account', 'site', 'discipline', 'department', 'workstation'];
- if (!in_array($type, $validTypes)) {
- return redirect()->to(site_url('v2/organization/account'));
- }
-
- return view('v2/organization', [
- 'title' => 'Organization: ' . ucfirst($type) . 's',
- 'user' => $this->user,
- // activePage set below for sub-pages
- 'activePage' => 'organization-' . $type,
- 'type' => $type
- ]);
- }
-
- /**
- * Value Sets Management
- */
- public function valuesets()
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- return view('v2/valuesets', [
- 'title' => 'Value Sets',
- 'user' => $this->user,
- 'activePage' => 'valuesets'
- ]);
- }
-
- /**
- * Patient List
- */
- public function patients()
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- return view('v2/patients', [
- 'title' => 'Patients',
- 'user' => $this->user,
- 'activePage' => 'patients'
- ]);
- }
-
- /**
- * Patient Create Form
- */
- public function patientCreate()
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- return view('v2/patient-form', [
- 'title' => 'New Patient',
- 'user' => $this->user,
- 'activePage' => 'patients'
- ]);
- }
-
- /**
- * Patient Edit Form
- */
- public function patientEdit($id)
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- // Load patient data
- $patientModel = new \App\Models\Patient\PatientModel();
- $patient = $patientModel->getPatient($id);
-
- if (!$patient) {
- return redirect()->to(site_url('v2/patients'));
- }
-
- return view('v2/patient-form', [
- 'title' => 'Edit Patient',
- 'user' => $this->user,
- 'activePage' => 'patients',
- 'patient' => $patient
- ]);
- }
-
- /**
- * Patient View/Detail
- */
- public function patientView($id)
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- return view('v2/patient-view', [
- 'title' => 'Patient Details',
- 'user' => $this->user,
- 'activePage' => 'patients',
- 'patientId' => $id
- ]);
- }
-
- /**
- * JWT Decoder
- */
- public function jwtDecoder()
- {
- if ($redirect = $this->requireAuth()) return $redirect;
-
- $token = $this->request->getCookie('token');
- $decoded = null;
- $parts = null;
-
- if ($token) {
- $parts = explode('.', $token);
- if (count($parts) === 3) {
- $decoded = [
- 'header' => json_decode(base64_decode($parts[0]), true),
- 'payload' => json_decode(base64_decode($parts[1]), true),
- 'signature' => $parts[2]
- ];
- }
- }
-
- return view('v2/jwt-decoder', [
- 'title' => 'JWT Decoder',
- 'user' => $this->user,
- 'activePage' => 'jwt-decoder',
- 'token' => $token,
- 'decoded' => $decoded
- ]);
- }
-
- /**
- * API: Get database tables
- */
- public function getTables()
- {
- if (!$this->checkAuth()) {
- return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
- }
-
- $db = Database::connect();
- $tables = $db->listTables();
-
- return $this->response->setJSON(['tables' => $tables]);
- }
-
- /**
- * API: Get table data
- */
- public function getTableData($table)
- {
- if (!$this->checkAuth()) {
- return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
- }
-
- $db = Database::connect();
-
- // Validate table exists
- if (!$db->tableExists($table)) {
- return $this->response->setJSON(['error' => 'Table not found'])->setStatusCode(404);
- }
-
- // Get table structure
- $fields = $db->getFieldData($table);
-
- // Get data (limit 100)
- $builder = $db->table($table);
- $data = $builder->limit(100)->get()->getResultArray();
-
- return $this->response->setJSON([
- 'table' => $table,
- 'fields' => $fields,
- 'data' => $data,
- 'count' => count($data)
- ]);
- }
-
- /**
- * API: Get logs
- */
- public function getLogs()
- {
- if (!$this->checkAuth()) {
- return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
- }
-
- $logPath = WRITEPATH . 'logs/';
- $logs = [];
-
- if (is_dir($logPath)) {
- $files = glob($logPath . 'log-*.log');
- rsort($files); // Most recent first
-
- foreach (array_slice($files, 0, 5) as $file) {
- $logs[] = [
- 'name' => basename($file),
- 'size' => filesize($file),
- 'content' => file_get_contents($file)
- ];
- }
- }
-
- return $this->response->setJSON(['logs' => $logs]);
- }
-}
diff --git a/app/Controllers/PagesController.php b/app/Controllers/PagesController.php
new file mode 100644
index 0000000..ee1dafb
--- /dev/null
+++ b/app/Controllers/PagesController.php
@@ -0,0 +1,67 @@
+ 'Dashboard',
+ 'activePage' => 'dashboard'
+ ]);
+ }
+
+ /**
+ * Patients page
+ */
+ public function patients()
+ {
+ return view('patients/patients_index', [
+ 'pageTitle' => 'Patients',
+ 'activePage' => 'patients'
+ ]);
+ }
+
+ /**
+ * Lab Requests page
+ */
+ public function requests()
+ {
+ return view('requests/requests_index', [
+ 'pageTitle' => 'Lab Requests',
+ 'activePage' => 'requests'
+ ]);
+ }
+
+ /**
+ * Settings page
+ */
+ public function settings()
+ {
+ return view('settings/settings_index', [
+ 'pageTitle' => 'Settings',
+ 'activePage' => 'settings'
+ ]);
+ }
+
+ /**
+ * Login page
+ */
+ public function login()
+ {
+ return view('auth/login', [
+ 'pageTitle' => 'Login',
+ 'activePage' => ''
+ ]);
+ }
+}
diff --git a/app/Database/Migrations/2025-12-29-150000_EdgeRes.php b/app/Database/Migrations/2025-12-29-150000_EdgeRes.php
new file mode 100644
index 0000000..2e5a886
--- /dev/null
+++ b/app/Database/Migrations/2025-12-29-150000_EdgeRes.php
@@ -0,0 +1,58 @@
+forge->addField([
+ 'EdgeResID' => ['type' => 'INT', 'auto_increment' => true],
+ 'SiteID' => ['type' => 'INT', 'null' => true],
+ 'InstrumentID' => ['type' => 'varchar', 'constraint' => 100, 'null' => true],
+ 'SampleID' => ['type' => 'varchar', 'constraint' => 30, 'null' => true],
+ 'PatientID' => ['type' => 'varchar', 'constraint' => 50, 'null' => true],
+ 'Payload' => ['type' => 'TEXT', 'null' => true],
+ 'Status' => ['type' => 'varchar', 'constraint' => 20, 'default' => 'pending'],
+ 'AutoProcess' => ['type' => 'TINYINT', 'default' => 0, 'null' => true],
+ 'ProcessedAt' => ['type' => 'DATETIME', 'null' => true],
+ 'ErrorMessage' => ['type' => 'TEXT', 'null' => true],
+ 'CreateDate' => ['type' => 'DATETIME', 'null' => true],
+ 'EndDate' => ['type' => 'DATETIME', 'null' => true],
+ 'ArchiveDate' => ['type' => 'DATETIME', 'null' => true],
+ 'DelDate' => ['type' => 'DATETIME', 'null' => true],
+ ]);
+ $this->forge->addPrimaryKey('EdgeResID');
+ $this->forge->createTable('edgeres');
+
+ // Edge status log - for instrument status tracking
+ $this->forge->addField([
+ 'EdgeStatusID' => ['type' => 'INT', 'auto_increment' => true],
+ 'InstrumentID' => ['type' => 'varchar', 'constraint' => 100, 'null' => true],
+ 'Status' => ['type' => 'varchar', 'constraint' => 50, 'null' => true],
+ 'LastActivity' => ['type' => 'DATETIME', 'null' => true],
+ 'Timestamp' => ['type' => 'DATETIME', 'null' => true],
+ 'CreateDate' => ['type' => 'DATETIME', 'null' => true],
+ ]);
+ $this->forge->addPrimaryKey('EdgeStatusID');
+ $this->forge->createTable('edgestatus');
+
+ // Edge order acknowledgment log
+ $this->forge->addField([
+ 'EdgeAckID' => ['type' => 'INT', 'auto_increment' => true],
+ 'OrderID' => ['type' => 'INT', 'null' => true],
+ 'InstrumentID' => ['type' => 'varchar', 'constraint' => 100, 'null' => true],
+ 'AckDate' => ['type' => 'DATETIME', 'null' => true],
+ 'CreateDate' => ['type' => 'DATETIME', 'null' => true],
+ ]);
+ $this->forge->addPrimaryKey('EdgeAckID');
+ $this->forge->createTable('edgeack');
+ }
+
+ public function down() {
+ $this->forge->dropTable('edgeack', true);
+ $this->forge->dropTable('edgestatus', true);
+ $this->forge->dropTable('edgeres', true);
+ }
+}
diff --git a/app/Filters/AuthFilter.php b/app/Filters/AuthFilter.php
index 59ff3cb..56ffc3e 100644
--- a/app/Filters/AuthFilter.php
+++ b/app/Filters/AuthFilter.php
@@ -16,14 +16,22 @@ class AuthFilter implements FilterInterface
$key = getenv('JWT_SECRET');
$token = $request->getCookie('token'); // ambil dari cookie
+ // Check if this is an API request or a page request
+ $isApiRequest = strpos($request->getUri()->getPath(), '/api/') !== false
+ || $request->isAJAX();
+
// Kalau tidak ada token
if (!$token) {
- return Services::response()
- ->setStatusCode(401)
- ->setJSON([
- 'status' => 'failed',
- 'message' => 'Unauthorized: Token not found'
- ]);
+ if ($isApiRequest) {
+ return Services::response()
+ ->setStatusCode(401)
+ ->setJSON([
+ 'status' => 'failed',
+ 'message' => 'Unauthorized: Token not found'
+ ]);
+ }
+ // Redirect to login for page requests
+ return redirect()->to('/v2/login');
}
try {
@@ -36,12 +44,16 @@ class AuthFilter implements FilterInterface
// $request->userData = $decoded;
} catch (\Exception $e) {
- return Services::response()
- ->setStatusCode(401)
- ->setJSON([
- 'status' => 'failed',
- 'message' => 'Unauthorized: ' . $e->getMessage()
- ]);
+ if ($isApiRequest) {
+ return Services::response()
+ ->setStatusCode(401)
+ ->setJSON([
+ 'status' => 'failed',
+ 'message' => 'Unauthorized: ' . $e->getMessage()
+ ]);
+ }
+ // Redirect to login for page requests
+ return redirect()->to('/v2/login');
}
}
diff --git a/app/Models/EdgeResModel.php b/app/Models/EdgeResModel.php
new file mode 100644
index 0000000..8129787
--- /dev/null
+++ b/app/Models/EdgeResModel.php
@@ -0,0 +1,63 @@
+where('Status', 'pending')
+ ->whereNull('DelDate')
+ ->orderBy('CreateDate', 'ASC')
+ ->findAll($limit);
+ }
+
+ /**
+ * Mark as processed
+ */
+ public function markProcessed($id) {
+ return $this->update($id, [
+ 'Status' => 'processed',
+ 'ProcessedAt' => date('Y-m-d H:i:s')
+ ]);
+ }
+
+ /**
+ * Mark as error
+ */
+ public function markError($id, $errorMessage) {
+ return $this->update($id, [
+ 'Status' => 'error',
+ 'ErrorMessage' => $errorMessage,
+ 'ProcessedAt' => date('Y-m-d H:i:s')
+ ]);
+ }
+}
diff --git a/app/Views/layout/main_layout.php b/app/Views/layout/main_layout.php
new file mode 100644
index 0000000..1b342bb
--- /dev/null
+++ b/app/Views/layout/main_layout.php
@@ -0,0 +1,188 @@
+
+
+
+
+
+ = esc($pageTitle ?? 'CLQMS') ?> - CLQMS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = $this->renderSection('content') ?>
+
+
+
+
+
+
+
+
+
+ = $this->renderSection('script') ?>
+
+
diff --git a/app/Views/layouts/v2-login.php b/app/Views/layouts/v2-login.php
deleted file mode 100644
index d40e556..0000000
--- a/app/Views/layouts/v2-login.php
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
- Login - CLQMS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- = $this->renderSection('content') ?>
-
-
-
- = $this->renderSection('script') ?>
-
-
diff --git a/app/Views/layouts/v2.php b/app/Views/layouts/v2.php
deleted file mode 100644
index c802758..0000000
--- a/app/Views/layouts/v2.php
+++ /dev/null
@@ -1,387 +0,0 @@
-
-
-
-
-
- = $title ?? 'V2' ?> - CLQMS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- = $this->renderSection('styles') ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 ?>)
-
= $title ?? 'CLQMS' ?>
-
-
-
-
-
- = substr(esc($user->username ?? 'U'), 0, 1) ?>
-
-
-
-
-
-
-
-
-
-
-
= $title ?? 'Dashboard' ?>
-
-
- Clinical Laboratory Quality Management System
-
-
-
-
-
-
- System Time
- = date('H:i') ?>
-
-
-
-
- 3
-
-
-
-
-
-
-
-
-
-
-
- = $this->renderSection('content') ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- = $this->renderSection('script') ?>
-
-
diff --git a/app/Views/layouts/v2_auth.php b/app/Views/layouts/v2_auth.php
deleted file mode 100644
index a14d023..0000000
--- a/app/Views/layouts/v2_auth.php
+++ /dev/null
@@ -1,218 +0,0 @@
-
-
-
-
-
- = $title ?? 'Login' ?> - CLQMS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- = $this->renderSection('styles') ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- = $this->renderSection('content') ?>
-
-
-
-
-
-
-
-
-
- = $this->renderSection('script') ?>
- = $this->renderSection('scripts') ?>
-
-
diff --git a/app/Views/pages/dashboard.php b/app/Views/pages/dashboard.php
deleted file mode 100644
index 8b969f2..0000000
--- a/app/Views/pages/dashboard.php
+++ /dev/null
@@ -1,328 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- = substr(esc($user->username ?? 'U'), 0, 1) ?>
-
-
-
-
Welcome back, = esc($user->username ?? 'User') ?>!
-
-
- = date('l, F j, Y') ?>
-
-
-
-
-
- Your laboratory is running smoothly. You have
- 3 pending tests
- and 2 alerts requiring attention.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Patients Today
-
-
-
- +14% from yesterday
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Pending Tests
-
-
-
- 5 urgent priority
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Completed
-
-
-
- All validated
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Efficiency
-
-
Week over week
-
-
- 86%
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Quick Actions
-
-
Most used
-
-
-
-
-
-
-
-
-
-
-
-
-
- System Status
-
-
-
-
-
-
-
-
-
- LIS Connection
-
- Online
-
-
-
-
-
-
-
-
- Database
-
- Optimal
-
-
-
-
-
-
-
-
- Analyzer Interface
-
- Syncing
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- | Time |
- Action |
- Details |
- Status |
-
-
-
-
- | 09:45 AM |
-
-
-
-
- Test Validated
- |
- CBC Panel - Patient #1234 |
- Complete |
-
-
- | 09:30 AM |
-
-
-
-
- New Order Created
- |
- Lipid Profile - Patient #5678 |
- Processing |
-
-
- | 09:15 AM |
-
-
-
-
- QC Alert
- |
- Glucose analyzer - Calibration needed |
- Pending |
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
diff --git a/app/Views/pages/login.php b/app/Views/pages/login.php
deleted file mode 100644
index 1f74331..0000000
--- a/app/Views/pages/login.php
+++ /dev/null
@@ -1,233 +0,0 @@
-= $this->extend('layouts/v2_auth') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 ?>)
-
-
- Secure
-
-
-
-
-
-
-
-
- Clinical Laboratory
- Quality Management System
-
-
-
-
-
-
- ISO 15189
-
-
-
- HIPAA
-
-
-
-
-
v2.0.0
-
-
-
-
-
-
-
-
-
-
-
-
Welcome Back!
-
Sign in to access your laboratory dashboard
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
SECURE CONNECTION
-
-
-
-
-
-
- 256-bit SSL
-
-
-
- Protected
-
-
-
- © = date('Y') ?> Clinical Laboratory QMS
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
diff --git a/app/Views/patients/dialog_form.php b/app/Views/patients/dialog_form.php
new file mode 100644
index 0000000..b94cce8
--- /dev/null
+++ b/app/Views/patients/dialog_form.php
@@ -0,0 +1,188 @@
+
+
diff --git a/app/Views/patients/patients_index.php b/app/Views/patients/patients_index.php
new file mode 100644
index 0000000..c661ed0
--- /dev/null
+++ b/app/Views/patients/patients_index.php
@@ -0,0 +1,414 @@
+= $this->extend("layout/main_layout"); ?>
+
+= $this->section("content") ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Loading patients...
+
+
+
+
+
+
+
+ | Patient ID |
+ Name |
+ Gender |
+ Birth Date |
+ Phone |
+ Actions |
+
+
+
+
+
+
+
+
+
+ No patients found
+
+
+ |
+
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+ |
+ |
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = $this->include('patients/dialog_form') ?>
+
+
+
+
+= $this->endSection() ?>
+
+= $this->section("script") ?>
+
+= $this->endSection() ?>
diff --git a/app/Views/v2/README.md b/app/Views/v2/README.md
deleted file mode 100644
index 469d36d..0000000
--- a/app/Views/v2/README.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# V2 Frontend - Internal Dev UI
-
-> 🔒 **Private**: This is a hidden frontend for backend development. Not for team use.
-
-## Access
-- **URL**: `/v2`
-- **Auth**: JWT (same login as main app)
-
-## Features
-
-### Dashboard
-- Quick overview and system stats
-
-### API Tester
-- Interactive REST client
-- Test all CLQMS endpoints
-- Supports GET, POST, PATCH, DELETE
-
-### Database Browser
-- View database tables
-- Quick data inspection
-
-### Logs Viewer
-- Read CI4 application logs
-- Filter by date and level
-
-### JWT Decoder
-- Inspect current token
-- View claims and expiry
-
----
-
-## Changelog
-
-### 2024-12-22
-- Initial V2 frontend created
-- Added dashboard, API tester, DB browser, logs, JWT decoder
diff --git a/app/Views/v2/api-tester.php b/app/Views/v2/api-tester.php
deleted file mode 100644
index fe05ac7..0000000
--- a/app/Views/v2/api-tester.php
+++ /dev/null
@@ -1,68 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Quick:
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/dashboard.php b/app/Views/v2/dashboard.php
deleted file mode 100644
index 9d3125d..0000000
--- a/app/Views/v2/dashboard.php
+++ /dev/null
@@ -1,169 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
-
-
-
-
Welcome back, = esc($user->username ?? 'User') ?>!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Welcome
-
= esc($user->username ?? 'User') ?>
-
Administrator
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- | Patient | Gender | Birthdate | Status | |
-
- |
-
-
- |
- |
- |
- Active |
- View |
-
-
- | No patients found |
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
-
-= $this->section('script') ?>
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/db-browser.php b/app/Views/v2/db-browser.php
deleted file mode 100644
index 205b08f..0000000
--- a/app/Views/v2/db-browser.php
+++ /dev/null
@@ -1,80 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
Select a table to view data
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/jwt-decoder.php b/app/Views/v2/jwt-decoder.php
deleted file mode 100644
index 3cc6c3d..0000000
--- a/app/Views/v2/jwt-decoder.php
+++ /dev/null
@@ -1,94 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
Current JWT Token
-
-
-
-
-
-
-
- = esc(substr($token, 0, 60)) ?>...
-
-
-
-
-
-
-
-
-
-
= json_encode($decoded['header'], JSON_PRETTY_PRINT) ?>
-
-
-
-
-
-
= json_encode($decoded['payload'], JSON_PRETTY_PRINT) ?>
-
-
-
-
-
-
-
-
-
-
- | Expires |
-
- = date('Y-m-d H:i:s', $decoded['payload']['exp']) ?>
- 0):
- ?>
- = round($remaining / 60) ?> min remaining
-
- Expired
-
- |
-
-
-
-
-
- | Issued At |
- = date('Y-m-d H:i:s', $decoded['payload']['iat']) ?> |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/login.php b/app/Views/v2/login.php
deleted file mode 100644
index 92f934b..0000000
--- a/app/Views/v2/login.php
+++ /dev/null
@@ -1,70 +0,0 @@
-= $this->extend('layouts/v2-login') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
 ?>)
-
-
Welcome to CLQMS
-
Clinical Laboratory Quality Management
-
-
-
-
-
-
-
-
-
-
-
-
SECURE CONNECTION
-
© = date('Y') ?> CLQMS - Laboratory Management
-
-
-= $this->endSection() ?>
-
-= $this->section('script') ?>
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/logs.php b/app/Views/v2/logs.php
deleted file mode 100644
index 42aa7cc..0000000
--- a/app/Views/v2/logs.php
+++ /dev/null
@@ -1,51 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
Application Logs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/organization.php b/app/Views/v2/organization.php
deleted file mode 100644
index 9cac8d0..0000000
--- a/app/Views/v2/organization.php
+++ /dev/null
@@ -1,297 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
Organization
-
Manage
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- | ID |
- Name |
-
- Parent Account |
- Account ID |
- Site ID |
- Department ID |
- Actions |
-
-
-
-
-
- |
- |
-
-
-
- |
-
-
-
- |
-
-
-
- |
-
-
-
- |
-
-
-
-
-
-
-
- |
-
-
-
-
- | No records found |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
-
-= $this->section('script') ?>
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/patient-form.php b/app/Views/v2/patient-form.php
deleted file mode 100644
index fa4d817..0000000
--- a/app/Views/v2/patient-form.php
+++ /dev/null
@@ -1,456 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
-
-
-
= isset($patient) ? 'Edit Patient' : 'New Patient' ?>
-
= isset($patient) ? 'Update patient information' : 'Register a new patient' ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
-
-= $this->section('script') ?>
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/patient-view.php b/app/Views/v2/patient-view.php
deleted file mode 100644
index 2b8a063..0000000
--- a/app/Views/v2/patient-view.php
+++ /dev/null
@@ -1,305 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Personal Information
-
-
-
-
-
-
-
-
-
-
-
- Contact Information
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Identifier
-
-
-
-
-
-
-
- No identifier on file
-
-
-
-
-
-
-
-
-
- System Info
-
-
-
-
-
-
-
-
Linked Patients
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
-
-= $this->section('script') ?>
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/patients.php b/app/Views/v2/patients.php
deleted file mode 100644
index a0ecb36..0000000
--- a/app/Views/v2/patients.php
+++ /dev/null
@@ -1,694 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
Patients
-
Manage patient records
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
No patients found
-
-
-
-
-
-
-
-
-
-
- | Patient ID |
- Name |
- Gender |
- Birthdate |
- Mobile |
- Actions |
-
-
-
-
-
- |
-
- |
-
-
-
- |
-
-
- |
- |
- |
-
-
-
-
-
- |
-
-
-
-
-
-
-
- Showing patients
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
-
-= $this->section('script') ?>
-
-= $this->endSection() ?>
diff --git a/app/Views/v2/valuesets.php b/app/Views/v2/valuesets.php
deleted file mode 100644
index 2432369..0000000
--- a/app/Views/v2/valuesets.php
+++ /dev/null
@@ -1,390 +0,0 @@
-= $this->extend('layouts/v2') ?>
-
-= $this->section('content') ?>
-
-
-
-
-
-
-
-
-
-
-
- Value Sets
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Select a Value Set
-
Choose a definition from the left to manage its values
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- | VID |
- Value |
- Description |
- Order |
- Actions |
-
-
-
-
-
- |
-
-
-
- |
-
- |
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
-
No values found for this set.
-
-
-
-
-
-
- values
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-= $this->endSection() ?>
-
-= $this->section('script') ?>
-
-= $this->endSection() ?>
diff --git a/public/assets/images/logo.png b/public/assets/images/logo.png
deleted file mode 100644
index 18d9d067d8be7a8b9b7ee3763536b7c83f5bfc72..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 549617
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 |