update docker

This commit is contained in:
AnggerRevo5
2026-01-30 13:10:48 +07:00
parent 9df710d81e
commit 39bb79f848
31 changed files with 142 additions and 100887 deletions
+191
View File
@@ -0,0 +1,191 @@
# Backend API Documentation
## Server Configuration
- **IP Address**: `10.10.11.34`
- **Port**: `8081`
- **Base URL**: `http://10.10.11.34:8081`
## Required Endpoints
### 1. Health Check
```
GET /tarifRS
```
**Response:**
```json
{
"status": "ok",
"timestamp": "2025-11-29T10:30:00Z"
}
```
### 2. Get Tarif Rumah Sakit
```
GET /tarifRS
```
**Query Parameters:**
- `kategori` (optional): Filter by category
- Values: `"Operatif"`, `"Non Operatif"`, `"Transplantasi Ginjal"`, `"Komplementer"`, `"Med Check Up"`
- `search` (optional): Search by kode or tindakan
- `page` (optional): Page number for pagination
- `limit` (optional): Items per page
**Example Request:**
```
GET /tarifRS?kategori=Operatif&search=ABDOMEN
```
**Response:**
```json
[
{
"id": 1,
"kode": "R.TO.0001",
"tindakan": "ABDOMEN, LAPAROTOMY, TRAUMA REOPERATION",
"tarif": "17.958.000",
"kategori": "Operatif",
"created_at": "2025-11-29T10:00:00Z",
"updated_at": "2025-11-29T10:00:00Z"
}
]
```
### 3. Create Tarif Rumah Sakit
```
POST /tarifRS
```
**Request Body:**
```json
{
"kode": "R.TO.0013",
"tindakan": "NEW PROCEDURE NAME",
"tarif": "5.000.000",
"kategori": "Operatif"
}
```
**Response:**
```json
{
"id": 13,
"kode": "R.TO.0013",
"tindakan": "NEW PROCEDURE NAME",
"tarif": "5.000.000",
"kategori": "Operatif",
"created_at": "2025-11-29T10:30:00Z",
"updated_at": "2025-11-29T10:30:00Z"
}
```
### 4. Update Tarif Rumah Sakit
```
PUT /tarifRS/{id}
```
**Request Body:** (partial update allowed)
```json
{
"tarif": "6.000.000"
}
```
### 5. Delete Tarif Rumah Sakit
```
DELETE /tarifRS/{id}
```
## Error Responses
### 400 Bad Request
```json
{
"error": "Bad Request",
"message": "Validation error details"
}
```
### 404 Not Found
```json
{
"error": "Not Found",
"message": "Resource not found"
}
```
### 500 Internal Server Error
```json
{
"error": "Internal Server Error",
"message": "Error description"
}
```
## CORS Configuration
Please ensure your backend allows CORS for:
- **Origin**: `http://localhost:3000` (development)
- **Methods**: `GET, POST, PUT, DELETE, OPTIONS`
- **Headers**: `Content-Type, Accept, Authorization`
## Database Schema (Suggested)
### Table: `tarif_rumah_sakit`
```sql
CREATE TABLE tarif_rumah_sakit (
id SERIAL PRIMARY KEY,
kode VARCHAR(50) UNIQUE NOT NULL,
tindakan TEXT NOT NULL,
tarif VARCHAR(50) NOT NULL,
kategori VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
```
### Sample Data
```sql
INSERT INTO tarif_rumah_sakit (kode, tindakan, tarif, kategori) VALUES
('R.TO.0001', 'ABDOMEN, LAPAROTOMY, TRAUMA REOPERATION', '17.958.000', 'Operatif'),
('R.TO.0002', 'APPENDECTOMY, LAPAROSCOPIC', '12.500.000', 'Operatif'),
('R.NO.0001', 'KONSULTASI SPESIALIS BEDAH', '350.000', 'Non Operatif'),
('R.TG.0001', 'TRANSPLANTASI GINJAL DONOR HIDUP', '125.000.000', 'Transplantasi Ginjal'),
('R.KM.0001', 'AKUPUNKTUR MEDIK', '200.000', 'Komplementer'),
('R.MC.0001', 'MEDICAL CHECK UP BASIC', '750.000', 'Med Check Up');
```
## Testing
You can test the API endpoints using:
- **Postman**: Import the endpoints above
- **curl**: `curl -X GET http://10.10.11.34:8081/tarifRS`
- **Browser**: Navigate to `http://10.10.11.34:8081/tarifRS`
## Notes
- All timestamps should be in ISO 8601 format
- Tarif values are stored as strings to preserve formatting
- Category values must match exactly (case-sensitive)
- Search should be case-insensitive for kode and tindakan fields
+87
View File
@@ -0,0 +1,87 @@
# Konfigurasi API untuk Electron App
## Cara Kerja API di Electron
Di Electron app, API calls **langsung ke backend Go** (tidak melalui Next.js API routes), karena:
- Electron menggunakan static files (tidak ada Next.js server)
- API routes Next.js tidak bisa berjalan di static export
- Solusi: langsung call backend Go
## Konfigurasi API URL
Ada 3 cara untuk set API URL:
### 1. Menggunakan `electron.config.js` (Recommended)
Edit file `electron.config.js`:
```javascript
module.exports = {
apiUrl: 'http://31.97.109.192:8081', // Ganti dengan URL backend Anda
};
```
### 2. Menggunakan Environment Variable
Set sebelum build atau run:
```powershell
# PowerShell
$env:NEXT_PUBLIC_API_URL = "http://31.97.109.192:8081"
npm run electron:dev
# Atau saat build
$env:NEXT_PUBLIC_API_URL = "http://31.97.109.192:8081"
.\build-electron.ps1
```
### 3. Default (localhost)
Jika tidak di-set, akan menggunakan: `http://localhost:8081`
## Testing API Connection
1. Pastikan backend Go berjalan
2. Test dengan Electron dev mode:
```bash
npm run dev # Terminal 1: Next.js dev server
npm run electron:dev # Terminal 2: Electron app
```
3. Buka DevTools di Electron (F12) dan cek console untuk melihat API URL yang digunakan
## Build untuk Production
Saat build installer, API URL akan di-inject ke aplikasi:
```powershell
# Set API URL untuk production
$env:NEXT_PUBLIC_API_URL = "http://31.97.109.192:8081"
.\build-electron.ps1
```
Atau edit `electron.config.js` sebelum build.
## CORS Configuration
Pastikan backend Go mengizinkan request dari Electron app. Di backend Go, pastikan CORS config mengizinkan:
- Origin: `file://` (untuk Electron)
- Atau semua origin untuk development
## Troubleshooting
### API tidak connect
1. Cek console di Electron (F12) untuk melihat error
2. Pastikan backend Go berjalan dan bisa diakses
3. Cek API URL yang digunakan (akan di-log di console)
4. Pastikan CORS di backend sudah benar
### API URL tidak ter-update
1. Restart Electron app setelah mengubah config
2. Rebuild aplikasi jika sudah di-build
## Catatan Penting
- API URL di-inject saat runtime, bukan saat build
- Setiap user bisa mengubah `electron.config.js` untuk mengubah API URL
- Untuk production, pertimbangkan hardcode API URL atau gunakan config file yang bisa diubah user
+82
View File
@@ -0,0 +1,82 @@
# PANDUAN ELECTRON - CareIt Desktop App
## Persiapan Backend API
1. **Konfigurasi URL Backend**
Buat file `.env.local` di root folder project (jika belum ada):
```bash
NEXT_PUBLIC_API_URL=http://localhost:8081
```
Ganti `http://localhost:8081` dengan URL backend Golang yang sudah di-deploy.
Contoh:
- Development: `http://localhost:8081`
- Production: `https://api-careit.example.com`
## Cara Menjalankan
### 1. Install Dependencies
```bash
npm install
```
### 2. Development Mode (untuk testing)
```bash
# Terminal 1: Jalankan Next.js dev server
npm run dev
# Terminal 2: Jalankan Electron
npm run electron:dev
```
### 3. Build dan Package untuk Windows EXE
#### Build Aplikasi
```bash
npm run electron:build
```
File `.exe` akan ada di folder `dist/` setelah build selesai.
#### Untuk 32-bit dan 64-bit
```bash
npm run electron:build:all
```
## Struktur File Electron
- `electron.js` - Main process Electron
- `preload.js` - Bridge script untuk security
- `out/` - Next.js static export output
- `dist/` - Folder hasil build Electron (berisi installer .exe)
## Troubleshooting
### Error: "Cannot find module electron"
```bash
npm install
```
### Error: Backend tidak terhubung
- Pastikan file `.env.local` sudah dibuat
- Cek URL backend di `.env.local` sudah benar
- Pastikan backend Golang sudah running
### Icon tidak muncul
- Pastikan ada file `icon.png` di folder `public/`
- Ukuran minimal 256x256 pixels
- Format: PNG dengan transparency
## Distribusi
Setelah build, file installer ada di:
- `dist/CareIt Setup 0.1.0.exe` - Installer untuk Windows
File ini bisa langsung dibagikan ke user lain tanpa perlu install Node.js/npm.
## Catatan Penting
- Aplikasi Electron akan langsung connect ke backend Golang (tidak pakai Next.js API routes)
- Pastikan backend sudah running dan URL di `.env.local` benar
- CORS harus dikonfigurasi di backend agar menerima request dari Electron
+138
View File
@@ -0,0 +1,138 @@
# Panduan Integrasi Frontend dengan Backend
Dokumen ini menjelaskan bagaimana frontend Next.js terintegrasi dengan backend Go.
## Konfigurasi
### Backend URL
Backend berjalan di `http://localhost:8081` secara default. Untuk mengubah URL backend:
1. Buat file `.env.local` di folder `Frontend_CareIt/` (jika belum ada)
2. Tambahkan:
```
NEXT_PUBLIC_API_URL=http://localhost:8081
```
Atau ganti dengan IP address backend Anda jika berbeda.
### CORS
Backend sudah dikonfigurasi dengan CORS default yang mengizinkan semua origin. Untuk production, sebaiknya dikonfigurasi lebih spesifik.
## API Functions
Semua fungsi API tersedia di `src/lib/api.ts`. Fungsi-fungsi utama:
### Authentication
- `loginDokter(credentials)` - Login dokter dengan email dan password
### Data Master
- `getDokter()` - Ambil daftar dokter
- `getRuangan()` - Ambil daftar ruangan
- `getICD9()` - Ambil daftar ICD9
- `getICD10()` - Ambil daftar ICD10
- `getTarifRumahSakit(params)` - Ambil tarif rumah sakit
- `getTarifBPJSRawatInap()` - Ambil tarif BPJS rawat inap
- `getTarifBPJSRawatJalan()` - Ambil tarif BPJS rawat jalan
### Pasien
- `getPasienById(id)` - Ambil data pasien by ID
- `searchPasien(nama)` - Cari pasien by nama
### Billing
- `createBilling(data)` - Buat billing baru
- `getBillingAktifByNama(namaPasien)` - Ambil billing aktif by nama pasien
- `getAllBilling()` - Ambil semua billing (untuk admin)
### Admin
- `postINACBGAdmin(data)` - Post INACBG dari admin
## Komponen yang Sudah Terintegrasi
### 1. Login (`login.tsx`)
- Menggunakan API `loginDokter` untuk autentikasi
- Menyimpan token dan data dokter di localStorage
- Menampilkan error jika login gagal
### 2. Billing Pasien (`billing-pasien.tsx`)
- Fetch data dropdown (dokter, ruangan, ICD9, ICD10, tarif RS) dari backend
- Search pasien menggunakan API
- Create billing dengan API `createBilling`
- Auto-calculate total tarif RS berdasarkan tindakan yang dipilih
### 3. Riwayat Billing Pasien (`riwayat-billing-pasien.tsx`)
- Fetch semua billing dari API `getAllBilling`
- Search/filter billing berdasarkan nama atau ID
- Menampilkan status billing dengan color coding
## Cara Menggunakan
### 1. Menjalankan Backend
```bash
cd Backend_CareIt
go run main.go
```
Backend akan berjalan di `http://localhost:8081`
### 2. Menjalankan Frontend
```bash
cd Frontend_CareIt
npm run dev
```
Frontend akan berjalan di `http://localhost:3000`
### 3. Testing
1. Buka browser ke `http://localhost:3000`
2. Login menggunakan email dan password dokter yang ada di database
3. Test fitur billing pasien
4. Test dashboard admin untuk melihat riwayat billing
## Troubleshooting
### Error: "Tidak dapat terhubung ke server"
- Pastikan backend server berjalan di port 8081
- Cek apakah URL di `.env.local` sudah benar
- Cek firewall atau network settings
### Error: "CORS error"
- Backend sudah dikonfigurasi dengan CORS default
- Jika masih error, pastikan backend menggunakan `cors.Default()` atau konfigurasi CORS yang sesuai
### Error: "Data tidak ditemukan"
- Pastikan database sudah terisi dengan data
- Cek endpoint API di backend apakah sudah benar
## Catatan Penting
1. **Token Management**: Token login disimpan di localStorage. Untuk production, pertimbangkan menggunakan httpOnly cookies atau session management yang lebih aman.
2. **Error Handling**: Semua API calls sudah memiliki error handling. Error akan ditampilkan di UI.
3. **Loading States**: Komponen yang fetch data akan menampilkan loading state saat mengambil data.
4. **Data Validation**: Form validation dilakukan di frontend sebelum submit ke backend.
## Endpoint Backend yang Tersedia
- `GET /` - Health check
- `GET /dokter` - List dokter
- `GET /ruangan` - List ruangan
- `GET /icd9` - List ICD9
- `GET /icd10` - List ICD10
- `GET /tarifRS` - List tarif rumah sakit
- `GET /tarifBPJSRawatInap` - List tarif BPJS rawat inap
- `GET /tarifBPJSRawatJalan` - List tarif BPJS rawat jalan
- `GET /pasien/:id` - Get pasien by ID
- `GET /pasien/search?nama=...` - Search pasien
- `POST /login` - Login dokter
- `POST /billing` - Create billing
- `GET /billing/aktif?nama_pasien=...` - Get billing aktif
- `GET /admin/billing` - Get all billing (admin)
- `POST /admin/inacbg` - Post INACBG (admin)
## Next Steps
1. Update komponen tarif-bpjs untuk menggunakan API real
2. Implementasi authentication middleware untuk protected routes
3. Add refresh token mechanism
4. Improve error handling dan user feedback
5. Add loading skeletons untuk better UX
+71
View File
@@ -0,0 +1,71 @@
{
"nama_dokter": "dr. Fadilah Muttaqin, Spp.A,MBiomed",
"nama_pasien": "Budi Hartono",
"jenis_kelamin": "Laki-laki",
"usia": 40,
"ruangan": "ICU",
"kelas": "1",
"tindakan_rs": [
"ASUHAN KEFARMASIAN SELAMA PERAWATAN - RAWAT INAP",
"BERCAK DARAH KERING"
],
"icd9": [
"Therapeutic ultrasound",
"Therapeutic ultrasound of vessels of head and neck"
],
"icd10": [
"Cholera",
"Cholera due to vibrio cholerae 01, biovar eltor"
],
"cara_bayar": "UMUM",
"total_tarif_rs": 250000
}
FE harus kirim gini
data untuk admin dari be:
{
"data": [
{
"nama_pasien": "mahdi Jamaludin",
"id_pasien": 1,
"Kelas": "2",
"ruangan": "R. Nusa Dua",
"total_tarif_rs": 150000,
"tindakan_rs": [
"DAR.001",
"DAR.002"
],
"icd9": [
"00.0",
"00"
],
"icd10": [
"A00",
"A00.0"
]
}
],
"status": "success"
}
if strings.TrimSpace(dokter.Password) == "" || dokter.Password != req.Password {
c.JSON(http.StatusUnauthorized, gin.H{
"status": "error",
"message": "Email atau password salah",
})
return
}
{
"dokter": {
"email": "hajengwulandari.fk@ub.ac.id",
"id": 2,
"ksm": "Anak",
"nama": "dr. Hajeng Wulandari, Sp.A, Mbiomed"
},
"status": "success",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImhhamVuZ3d1bGFuZGFyaS5ma0B1Yi5hYy5pZCIsImV4cCI6MTc2NDc1NzIxMCwiaWF0IjoxNzY0NjcwODEwLCJpZCI6Miwia3NtIjoiQW5hayIsIm5hbWEiOiJkci4gSGFqZW5nIFd1bGFuZGFyaSwgU3AuQSwgTWJpb21lZCJ9.X1PyxjbC1Ht3DFbvi4svqXY4hsNIS_nmYMROkRaK-Ko"
}
jadi data yang dihitung cuma yang rawat inap nanti yang isi tanggal keluar berarti admin billing dan nanti total tarif dan total klaim nanti di tampilin juga ketika datanya di tampilin sama kaya tindakan dan tarif rs nanti di admin billing juga bisa liat data tindakan lama dan icd lama dan tindakan baru dan icd bari dan inacbg lama dan inacbg baru plus total tarif yang lama di tambah yang barui dan total klaim lama nanti setelah dimasukan ditambah lagi sama total klaim baru baru dihitung billing sign baru paham gak
+104
View File
@@ -0,0 +1,104 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app) and configured for mobile deployment with [Capacitor](https://capacitorjs.com/).
## Getting Started
### Web Development
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
### Mobile Development (Capacitor)
This project supports both web and mobile platforms:
- **Web**: Uses Next.js API routes as proxy to backend (no CORS issues)
- **Mobile**: Uses direct backend calls (static export, no API routes)
**Prerequisites:**
- Backend server must be running (default: `http://localhost:8081`)
- For production mobile app, set `NEXT_PUBLIC_API_URL` environment variable to your backend server URL
**Build for Mobile (with static export):**
**Windows:**
```powershell
# PowerShell
.\build-mobile.ps1
# Or CMD
build-mobile.bat
# Or manually set environment variable
$env:NEXT_EXPORT="true"; npm run build; npx cap sync
```
**Linux/Mac:**
```bash
# Set environment variable and build
NEXT_EXPORT=true npm run build && npx cap sync
# Or use the npm script (requires cross-env)
npm run build:mobile:export
```
**Note:** Regular `npm run build` is for web development (with API routes). Use the mobile build scripts above for Capacitor.
**Open Native Projects:**
```bash
# Android
npm run cap:open:android
# iOS (macOS only)
npm run cap:open:ios
```
**Run on Device/Emulator:**
```bash
# Android
npm run cap:run:android
# iOS
npm run cap:run:ios
```
**Other Capacitor Commands:**
```bash
# Copy web assets only (without updating dependencies)
npm run cap:copy
# Sync web assets and update native dependencies
npm run cap:sync
```
**How It Works:**
- **Web Development**: API calls go through `/api` routes (Next.js proxy) → Backend Go server
- **Mobile App**: API calls go directly to backend Go server (detected automatically via Capacitor)
- The app automatically detects the platform and uses the appropriate API endpoint
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
@@ -0,0 +1,205 @@
# Tanggal Keluar Auto-Fill Flow Documentation
## Overview
Ketika admin/dokter memasukkan kode INACBG, `tanggal_keluar` **TIDAK** otomatis terisi dari field form, tetapi **OTOMATIS DIKIRIM** ke backend menggunakan nilai fallback.
---
## Alur Lengkap
### 1. **INACBG_Admin_Ruangan.tsx** - Ketika Submit (handleSave)
**Location:** [Line 705-715](../frontendcareitv2/src/app/component/INACBG_Admin_Ruangan.tsx#L705-L715)
```typescript
const payload: PostINACBGRequest = {
id_billing: billingId,
tipe_inacbg: tipeInacbg,
kode_inacbg: selectedInacbgCodes,
total_klaim: deltaKlaim,
billing_sign: billingSignColor,
tanggal_keluar: tanggalKeluar || new Date().toISOString().split("T")[0],
};
```
**Logika:**
- `tanggalKeluar` sudah di-load dari API saat page load (dari `billingId`)
- Jika `tanggalKeluar` kosong/undefined, gunakan **hari ini** (`new Date().toISOString().split("T")[0]`)
- Kirim ke `/admin/inacbg` endpoint dengan nilai tanggal (entah dari user edit atau default hari ini)
**Flow yang terjadi:**
1. User memilih kode INACBG → `setSelectedInacbgCodes([...codes])`
2. User klik tombol "Simpan" → `handleSave()` dipanggil
3. Di dalam `handleSave()`:
- Cek `selectedInacbgCodes.length > 0` (minimal 1 kode harus dipilih)
- Buat payload dengan `tanggal_keluar: tanggalKeluar || new Date().toISOString().split("T")[0]`
- POST ke `/admin/inacbg`
---
### 2. **billing-pasien.tsx** - Ketika Create Billing (handleSubmit)
**Location:** [Line 650-655](../frontendcareitv2/src/app/component/billing-pasien.tsx#L650-L655)
```typescript
const billingData: BillingRequest = {
nama_pasien: namaPasien,
// ... other fields ...
tanggal_masuk: convertDateFormat(tanggalMasuk),
tanggal_keluar: convertDateFormat(tanggalKeluar) || '',
// ... other fields ...
};
```
**Logika:**
- User opsional mengisi `tanggal_keluar` di billing form
- Jika kosong, kirim string kosong `''`
- Backend akan handle nullable field
**Flow yang terjadi:**
1. User fill form + select tindakan/ICD10
2. User klik "Buat Billing" → `handleSubmit()`
3. Format tanggal dengan `convertDateFormat()` (handle both YYYY-MM-DD dan DD/MM/YYYY)
4. POST ke `/billing` endpoint
---
### 3. **Data Loading - Tanggal Keluar di-Fetch dari API**
**INACBG_Admin_Ruangan.tsx** - [Line 106-245](../frontendcareitv2/src/app/component/INACBG_Admin_Ruangan.tsx#L106-L245)
Ada 3 priority untuk load tanggal_keluar:
```typescript
// PRIORITY 1: From props (jika parent pass data)
if (pasienData) {
// Fetch dari API /admin/billing/{billingId}
const response = await apiFetch<any>(`/admin/billing/${billingId}`);
const tanggalKeluarData = response.data.tanggal_keluar || response.data.Tanggal_keluar || "";
setTanggalKeluar(tanggalKeluarData);
}
// PRIORITY 2: From localStorage (jika data sudah disimpan sebelumnya)
const storedData = localStorage.getItem('currentBillingData');
if (storedData) {
// Fetch dari API /admin/billing/{billingId}
const response = await apiFetch<any>(`/admin/billing/${billingId}`);
const tanggalKeluarData = response.data.tanggal_keluar || response.data.Tanggal_keluar || "";
setTanggalKeluar(tanggalKeluarData);
}
// PRIORITY 3: From API direct fetch (jika billingId tersedia)
if (billingId) {
const response = await apiFetch<any>(`/admin/billing/${billingId}`);
const tanggalKeluarData = data.tanggal_keluar || data.Tanggal_keluar || "";
setTanggalKeluar(tanggalKeluarData);
}
```
---
## Form Input untuk Tanggal Keluar
### INACBG_Admin_Ruangan.tsx
**Location:** [Line 1004-1012](../frontendcareitv2/src/app/component/INACBG_Admin_Ruangan.tsx#L1004-L1012)
```typescript
<div className="ml-0 sm:ml-4 mt-2">
<label className="block text-sm sm:text-md text-[#2591D0] mb-1 sm:mb-2 font-bold">
Tanggal Keluar (Opsional)
</label>
<input
type="date"
value={tanggalKeluar}
onChange={(e) => setTanggalKeluar(e.target.value)}
className="w-full border text-sm border-blue-200 rounded-full py-2 sm:py-3 pl-3 sm:pl-4 pr-8 sm:pr-10 text-[#2591D0] bg-white focus:ring-2 focus:ring-blue-400 focus:border-blue-400 focus:outline-0"
/>
</div>
```
**Status:**
- ✅ Input field ada
- ✅ Auto-filled dari API saat page load
- ✅ User bisa edit nilai
- ✅ Kirim ke backend saat submit
---
## Riwayat Billing Aktif - Kolom Tanggal Ditampilkan
### billing-pasien.tsx
**Location:** [Line 1215-1238](../frontendcareitv2/src/app/component/billing-pasien.tsx#L1215-L1238) (Desktop Table)
```typescript
<table className="w-full text-sm md:text-base border-collapse">
<thead>
<tr className="bg-blue-100 border-b border-blue-200">
<th>Tanggal Masuk</th>
<th>Tanggal Keluar</th>
<th>Tindakan RS</th>
<th>ICD 9</th>
<th>ICD 10</th>
<th>INACBG</th>
</tr>
</thead>
<tbody>
{/* Loop untuk show dates dan data */}
<td>
{billingHistory.tanggal_masuk
? new Date(billingHistory.tanggal_masuk).toLocaleDateString('id-ID', {...})
: '-'}
</td>
<td>
{billingHistory.tanggal_keluar
? new Date(billingHistory.tanggal_keluar).toLocaleDateString('id-ID', {...})
: '-'}
</td>
</tbody>
</table>
```
### INACBG_Admin_Ruangan.tsx
**Location:** [Line 1047-1070](../frontendcareitv2/src/app/component/INACBG_Admin_Ruangan.tsx#L1047-L1070) (Desktop Table)
```typescript
<table className="w-full text-sm md:text-base border-collapse">
<thead>
<tr className="bg-blue-100 border-b border-blue-200">
<th>Tanggal Masuk</th>
<th>Tanggal Keluar</th>
<th>ICD 9</th>
<th>ICD 10</th>
<th>INACBG</th>
</tr>
</thead>
</table>
```
---
## Debugging Logs
Cek browser console (F12) untuk melihat flow:
**INACBG_Admin_Ruangan.tsx:**
```
📥 Tanggal keluar from API: [nilai tanggal atau empty]
📅 Extracted dates from billing history: { tanggalMasuk: ..., tanggalKeluar: ... }
📤 Sending INACBG payload: { tanggal_keluar: ..., ... }
```
**billing-pasien.tsx:**
```
💾 Extracted dates: { tanggalMasuk, tanggalKeluar, billingObj }
💾 Patient data saved to localStorage: { tanggal_masuk, tanggal_keluar }
```
---
## Summary
| Aspek | INACBG Form | Billing Pasien Form |
|-------|-------------|-------------------|
| **Input Field** | ✅ Ada (type=date) | ✅ Ada (type=date) |
| **Auto-fill saat load** | ✅ Dari API | ✅ Dari API |
| **User bisa edit** | ✅ Ya | ✅ Ya |
| **Submit behavior** | Gunakan nilai yang ada atau hari ini | Kirim nilai atau kosong |
| **Riwayat ditampilkan** | ✅ Ya, di table | ✅ Ya, di table |
| **Format tanggal** | ISO format dari backend | YYYY-MM-DD atau DD/MM/YYYY |
+27
View File
@@ -0,0 +1,27 @@
Feature: Fix INACBG Total Claim Calculation
Problem:
When a user adds a new INACBG code, the total claim amount does not increase as expected. Instead, it seems to reset or absorb the new code's value into the base offset. This happens because the Base Offset calculation logic uses the *current* list of selected codes (which includes the new code) to calculate the offset from the *original* total.
Formula used: Offset = OriginalTotal - Sum(CurrentCodes)
If user adds code: Offset = Original - (Old + New)
Final Total = Offset + (Old + New) = Original.
Solution:
We must distinguish between "Original Codes" (loaded from DB) and "Current Codes" (live state).
The Base Offset should strictly be:
BaseOffset = OriginalTotal - Sum(OriginalCodes)
Steps:
1. Add `initialLoadedCodes` state to `INACBG_Admin_Ruangan.tsx`.
2. Populate checking `initialLoadedCodes` in `loadBillingAktifHistory` when data is loaded from DB.
3. Update `useEffect` calculation logic to validly calculate Base Offset using `initialLoadedCodes` instead of `selectedInacbgCodes` during initialization.
4. Ensure `baseKlaimOffset` is calculated only once.
Refined Logic:
- If `!hasInitializedBaseRef.current`:
- Calculate `Sum(InitialCodes)`.
- `Offset = OriginalTotal - Sum(InitialCodes)`.
- Set `BaseOffset`.
- Mark initialized.
- Always:
- `FinalTotal = BaseOffset + Sum(CurrentCodes)`.