update docker
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 |
|
||||
@@ -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)`.
|
||||
Reference in New Issue
Block a user