115 lines
3.7 KiB
Markdown
115 lines
3.7 KiB
Markdown
# Result Menu — Design Spec
|
|
Date: 2026-04-30
|
|
|
|
## Overview
|
|
Halaman `/result` menampilkan daftar peserta MCU beserta tombol "View PDF" untuk membuka laporan hasil konsolidasi. Data diambil sepenuhnya dari `cpone_dashboard` (zero dependency ke `cpone`).
|
|
|
|
## Data Sources
|
|
Semua tabel ada di `cpone_dashboard`:
|
|
- `mcu_patient` — data peserta (NIP, nama, posisi/dept, order ID)
|
|
- `published_mcu_dashboard_sync` — file URL PDF per peserta
|
|
|
|
Join key: `mcu_patient.Mcu_PatientOrderID = published_mcu_dashboard_sync.Published_McuDasboardT_OrderHeaderID`
|
|
|
|
## Config / Env
|
|
Tambah key baru ke `.env`, `.env.example`, dan `config/config.go`:
|
|
```
|
|
PDF_BASE_URL=http://devcpone.aplikasi.web.id/dashboard-files/
|
|
```
|
|
Field `PDFBaseURL string` ditambah ke struct `Config`. Nilai ini di-passing ke `result` handler saat setup di `main.go`.
|
|
|
|
## Backend — `menu/result/`
|
|
|
|
### query.go
|
|
```go
|
|
type ResultRow struct {
|
|
NIP string
|
|
Name string
|
|
Posisi string
|
|
FileUrl string // kosong jika belum ada PDF
|
|
ReportDate string // Published_McuDasboardLastUpdated
|
|
}
|
|
|
|
type ResultSummary struct {
|
|
Total int
|
|
HasPDF int
|
|
}
|
|
```
|
|
|
|
Query:
|
|
```sql
|
|
SELECT
|
|
COALESCE(NULLIF(TRIM(mp.Mcu_PatientNIP), ''), '-') AS nip,
|
|
COALESCE(NULLIF(TRIM(mp.Mcu_PatientName), ''), '-') AS name,
|
|
COALESCE(
|
|
NULLIF(TRIM(mp.Mcu_PatientDepartment), ''),
|
|
NULLIF(TRIM(mp.Mcu_PatientDivision), ''),
|
|
NULLIF(TRIM(mp.Mcu_PatientPosisi), ''),
|
|
'-'
|
|
) AS posisi,
|
|
COALESCE(p.Published_McuDasboardFileUrl, '') AS file_url,
|
|
CASE
|
|
WHEN p.Published_McuDasboardFileUrl IS NOT NULL AND p.Published_McuDasboardFileUrl != ''
|
|
THEN COALESCE(p.Published_McuDasboardLastUpdated, '')
|
|
ELSE ''
|
|
END AS report_date
|
|
FROM mcu_patient mp
|
|
LEFT JOIN published_mcu_dashboard_sync p
|
|
ON p.Published_McuDasboardT_OrderHeaderID = mp.Mcu_PatientOrderID
|
|
WHERE mp.Mcu_PatientMcuID = ?
|
|
AND mp.Mcu_PatientIsActive = 'Y'
|
|
ORDER BY
|
|
(p.Published_McuDasboardFileUrl IS NOT NULL AND p.Published_McuDasboardFileUrl != '') DESC,
|
|
mp.Mcu_PatientName ASC
|
|
```
|
|
|
|
Helper functions:
|
|
- `BuildResultSummary(rows []ResultRow) ResultSummary`
|
|
- `FilterResultRows(rows []ResultRow, search, filter string) []ResultRow`
|
|
- filter values: `""` (all), `"has_pdf"`, `"no_pdf"`
|
|
|
|
### handler.go
|
|
`pageData` struct:
|
|
```go
|
|
type pageData struct {
|
|
Username string
|
|
CurrentProject projects.ProjectItem
|
|
Search string
|
|
Filter string
|
|
Rows []ResultRow
|
|
FilteredRows []ResultRow
|
|
Summary ResultSummary
|
|
PDFBaseURL string
|
|
}
|
|
```
|
|
|
|
Handler `Index` mengikuti pola progress: redirect ke `/projects` jika belum pilih project, fetch rows, build summary, apply filter, render template.
|
|
|
|
`PDFBaseURL` di-inject saat `SetTemplates` — tambah fungsi `SetPDFBaseURL(url string)` di package result.
|
|
|
|
### route.go
|
|
Tidak berubah — sudah ada `r.Get("/", Index)`.
|
|
|
|
## Template — `templates/result/index.html`
|
|
|
|
**Section 1 — Current project card**
|
|
Sama persis dengan progress/arrival: nama project, nomor, tombol "Ganti project".
|
|
|
|
**Section 2 — Summary cards (2 cards)**
|
|
- Total Patients
|
|
- Has PDF (count `FileUrl != ""`)
|
|
|
|
**Section 3 — Filter form**
|
|
- Search input (nama atau NIP)
|
|
- Dropdown: All / Has PDF / No PDF
|
|
- Tombol Filter
|
|
|
|
**Section 4 — Patient list**
|
|
- Desktop: table dengan kolom NIP, Nama, Posisi/Dept, Report Date, Action
|
|
- Mobile: card stack
|
|
- Action: tombol `View PDF` (buka tab baru) jika `FileUrl != ""`, teks `—` jika kosong
|
|
- PDF full URL: `PDFBaseURL + FileUrl`
|
|
|
|
## Referensi Visual
|
|
`/PLAN/draft-cpone/06-result.html` — warna dan layout mengikuti color scheme brand yang ada (`brand-500`, `slate-*`), bukan warna `diagnos-*` dari draft.
|