diff --git a/locales/en.json b/locales/en.json index 208bc92..edd4171 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1781,7 +1781,73 @@ "mayar_webhook": "Mayar Webhook (Mode 1 — Gateway)", "save": "Save Settings", "pay_mode": "Mode", - "qris_note": "Note" + "qris_note": "Note", + "no_data": "No data yet.", + "ew_not_tx": "Not a transaction", + "ew_paid": "Paid", + "ew_unmatched": "Not matched" + }, + "mt": { + "updating": "Updating...", + "online_list": "Online PPPoE Users", + "offline_list": "Offline PPPoE Users", + "limit_uptime": "Uptime Limit (e.g. 1h)" + }, + "disc": { + "title": "Invoice Discount", + "settings_title": "Discount Settings", + "opt_selected": "Selected customers (batch)", + "opt_single": "Single customer (1 by 1)", + "opt_all": "All active customers", + "pick_customer": "Select Customer", + "ph_pick_customer": "-- select customer --", + "disc_type": "Discount Type", + "opt_percent": "Percent (%)", + "opt_amount": "Amount (Rp)", + "disc_value": "Discount Value", + "ph_value": "e.g. 10 (percent) / 20000 (Rp)", + "disc_hint": "The percentage is calculated from the base price (before VAT/USO).", + "period_month": "Billing Period — Month", + "year": "Year", + "note_opt": "Note (optional)", + "ph_note": "e.g. independence month promo", + "apply_hint": "The discount applies to unpaid invoices in the selected period. Paid/void invoices are unchanged. The QRIS unique code is regenerated from the new amount.", + "apply": "Apply Discount", + "selected": "selected", + "history": "Discount History (last 100)", + "th_note": "Note" + }, + "cpay": { + "title": "Collector Payment Approval", + "list": "Request List", + "opt_all": "All Processes", + "opt_pending": "Needs Approval", + "opt_auto": "Collector Auto", + "opt_admin": "Approved by Admin", + "opt_cashier": "Approved by Cashier", + "opt_rejected": "Manually Rejected", + "opt_manual": "Processed Manually", + "th_invoice": "Invoice", + "th_process": "Process", + "approve": "Approve", + "reject": "Reject" + }, + "att": { + "late_checkin": "Late Check-in", + "not_checkout": "Not Checked-out", + "all_attendance": "All Attendance", + "total_staff": "Total Staff", + "today": "Today", + "working": "Currently Working", + "checked_out": "Checked Out", + "late": "Late", + "after_0830": "After 08:30", + "technician": "Technician", + "cashier": "Cashier", + "checkin_time": "Check-in Time", + "duration": "Duration", + "location": "Location", + "photo": "Photo" } }, "tech": { diff --git a/locales/id.json b/locales/id.json index 69d9efe..2573a86 100644 --- a/locales/id.json +++ b/locales/id.json @@ -1782,7 +1782,73 @@ "mayar_webhook": "Webhook Mayar (Mode 1 — Gateway)", "save": "Simpan Pengaturan", "pay_mode": "Mode", - "qris_note": "Catatan" + "qris_note": "Catatan", + "no_data": "Belum ada data.", + "ew_not_tx": "Bukan transaksi", + "ew_paid": "Lunas", + "ew_unmatched": "Belum cocok" + }, + "mt": { + "updating": "Memperbarui...", + "online_list": "Daftar User PPPoE Online", + "offline_list": "Daftar User PPPoE Offline", + "limit_uptime": "Limit Uptime (e.g. 1h)" + }, + "disc": { + "title": "Diskon Tagihan", + "settings_title": "Pengaturan Diskon", + "opt_selected": "Pelanggan terpilih (batch)", + "opt_single": "Satu pelanggan (1 per 1)", + "opt_all": "Semua pelanggan aktif", + "pick_customer": "Pilih Pelanggan", + "ph_pick_customer": "-- pilih pelanggan --", + "disc_type": "Tipe Diskon", + "opt_percent": "Persen (%)", + "opt_amount": "Nominal (Rp)", + "disc_value": "Nilai Diskon", + "ph_value": "mis. 10 (persen) / 20000 (Rp)", + "disc_hint": "Persen dihitung dari harga dasar (sebelum PPN/USO).", + "period_month": "Periode Tagihan — Bulan", + "year": "Tahun", + "note_opt": "Catatan (opsional)", + "ph_note": "mis. promo bulan kemerdekaan", + "apply_hint": "Diskon berlaku ke tagihan belum bayar pada periode terpilih. Tagihan lunas/hangus tidak diubah. Kode unik QRIS akan digenerate ulang dari nominal baru.", + "apply": "Terapkan Diskon", + "selected": "dipilih", + "history": "Riwayat Diskon (100 terakhir)", + "th_note": "Catatan" + }, + "cpay": { + "title": "Approval Pembayaran Kolektor", + "list": "Daftar Request", + "opt_all": "Semua Proses", + "opt_pending": "Butuh Approval", + "opt_auto": "Auto Kolektor", + "opt_admin": "Disetujui Admin", + "opt_cashier": "Disetujui Kasir", + "opt_rejected": "Ditolak Manual", + "opt_manual": "Diproses Manual", + "th_invoice": "Tagihan", + "th_process": "Proses", + "approve": "Setujui", + "reject": "Tolak" + }, + "att": { + "late_checkin": "Terlambat Check-in", + "not_checkout": "Belum Check-out", + "all_attendance": "Semua Absensi", + "total_staff": "Total Karyawan", + "today": "Hari ini", + "working": "Sedang Bekerja", + "checked_out": "Sudah Pulang", + "late": "Terlambat", + "after_0830": "Setelah 08:30", + "technician": "Teknisi", + "cashier": "Kasir", + "checkin_time": "Waktu Check-in", + "duration": "Durasi", + "location": "Lokasi", + "photo": "Foto" } }, "tech": { diff --git a/views/admin/attendance.ejs b/views/admin/attendance.ejs index fc9deeb..a7ecf5f 100644 --- a/views/admin/attendance.ejs +++ b/views/admin/attendance.ejs @@ -131,34 +131,34 @@
-
Total Karyawan
+
<%= t('admin.att.total_staff','Total Karyawan') %>
<%= totalAll %>
-
Hari ini
+
<%= t('admin.att.today','Hari ini') %>
-
Sedang Bekerja
+
<%= t('admin.att.working','Sedang Bekerja') %>
<%= checkedInAll %>
Check-in
-
Sudah Pulang
+
<%= t('admin.att.checked_out','Sudah Pulang') %>
<%= checkedOutAll %>
Check-out
-
Terlambat
+
<%= t('admin.att.late','Terlambat') %>
<%= lateCheckIns.length %>
-
Setelah 08:30
+
<%= t('admin.att.after_0830','Setelah 08:30') %>
-
Teknisi
+
<%= t('admin.att.technician','Teknisi') %>
<%= techStats.total || 0 %>
<%= techStats.checked_in || 0 %> aktif • @@ -174,7 +174,7 @@
-
Kasir
+
<%= t('admin.att.cashier','Kasir') %>
<%= cashierStats.total || 0 %>
<%= cashierStats.checked_in || 0 %> aktif • @@ -195,7 +195,7 @@ <% if (lateCheckIns.length > 0) { %>
-
Terlambat Check-in (<%= lateCheckIns.length %>)
+
<%= t('admin.att.late_checkin','Terlambat Check-in') %> (<%= lateCheckIns.length %>)
@@ -203,8 +203,8 @@ - - + + @@ -231,7 +231,7 @@ <% if (notCheckedOut.length > 0) { %>
-
Belum Check-out (<%= notCheckedOut.length %>)
+
<%= t('admin.att.not_checkout','Belum Check-out') %> (<%= notCheckedOut.length %>)
<%= t('pwa.field.name','Nama') %> <%= t('common.type','Tipe') %>Waktu Check-inTerlambat<%= t('admin.att.checkin_time','Waktu Check-in') %><%= t('admin.att.late','Terlambat') %>
@@ -240,7 +240,7 @@ - + @@ -267,7 +267,7 @@
-
Semua Absensi - <%= parseDateInTimezone(selectedDate).toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) %>
+
<%= t('admin.att.all_attendance','Semua Absensi') %> - <%= parseDateInTimezone(selectedDate).toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) %>
<% if (attendances.length > 0) { %> @@ -279,10 +279,10 @@
- + - - + + @@ -336,13 +336,13 @@
<% if (att.check_in_photo) { %> - Foto check-in + <%= t('admin.att.photo','Foto') %> check-in In <% } %> <% if (att.check_out_photo) { %> - Foto check-out + <%= t('admin.att.photo','Foto') %> check-out Out <% } %> @@ -402,7 +402,7 @@ } function editAttendance(id) { - const checkIn = prompt('Waktu Check-in (YYYY-MM-DD HH:MM:SS):'); + const checkIn = prompt('<%= t('admin.att.checkin_time','Waktu Check-in') %> (YYYY-MM-DD HH:MM:SS):'); if (!checkIn) return; const checkOut = prompt('Waktu Check-out (YYYY-MM-DD HH:MM:SS) - kosongkan jika belum:'); diff --git a/views/admin/collector_payments.ejs b/views/admin/collector_payments.ejs index 0aba021..d0863d2 100644 --- a/views/admin/collector_payments.ejs +++ b/views/admin/collector_payments.ejs @@ -2,7 +2,7 @@ - Approval Pembayaran Kolektor | <%= company %> + <%= t('admin.cpay.title','Approval Pembayaran Kolektor') %> | <%= company %> @@ -14,7 +14,7 @@
- Approval Pembayaran Kolektor + <%= t('admin.cpay.title','Approval Pembayaran Kolektor') %>
<%= (typeof session !== 'undefined' && session.isCashier) ? t('admin.role.cashier', 'Kasir') : t('admin.role.admin', 'Admin') %> @@ -31,20 +31,20 @@
-
Daftar Request (<%= (rows || []).length %>)
+
<%= t('admin.cpay.list','Daftar Request') %> (<%= (rows || []).length %>)
Label proses membantu membedakan request yang memang menunggu approval, request yang otomatis langsung lunas oleh kolektor, dan request yang sudah diproses admin atau kasir.
@@ -54,9 +54,9 @@
- + - + @@ -119,12 +119,12 @@
- +
- +
diff --git a/views/admin/discounts.ejs b/views/admin/discounts.ejs index ae24762..a98c6c1 100644 --- a/views/admin/discounts.ejs +++ b/views/admin/discounts.ejs @@ -2,7 +2,7 @@ - Diskon Tagihan | <%= company %> + <%= t('admin.disc.title','Diskon Tagihan') %> | <%= company %>
<%= t('pwa.field.name','Nama') %> <%= t('common.type','Tipe') %> Check-inDurasi<%= t('admin.att.duration','Durasi') %>
<%= t('common.type','Tipe') %> Check-in Check-outDurasi<%= t('admin.att.duration','Durasi') %> <%= t('common.status','Status') %>LokasiFoto<%= t('admin.att.location','Lokasi') %><%= t('admin.att.photo','Foto') %> <%= t('common.actions','Aksi') %>
<%= t('collector.col_time','Waktu') %> <%= t('collector.role','Kolektor') %> <%= t('common.customer','Pelanggan') %>Tagihan<%= t('admin.cpay.th_invoice','Tagihan') %> <%= t('collector.col_amount','Nominal') %>Proses<%= t('admin.cpay.th_process','Proses') %> <%= t('common.status','Status') %> <%= t('common.actions','Aksi') %>