Files
UAS-SIG-d1041231006/sistem-km-next/src/components/dashboard/modals/DonationModal.js
T
2026-06-10 19:36:52 +07:00

141 lines
6.8 KiB
JavaScript

import React from 'react';
export default function DonationModal({
showDonationModal,
setShowDonationModal,
donationFormData,
setDonationFormData,
hubs,
isSubmittingDonation,
handleSaveDonation,
donationsList,
profile
}) {
if (!showDonationModal) return null;
if (!profile) return null; // Secure fail-safe for unauthenticated users
// Check roles: PIC, Hub Head, and Super Admin can record transactions
const canEdit = profile.role === 'super_admin' || profile.role === 'pic' || profile.role === 'hub_head';
// Calculate Running / Total Balance
const totalBalance = donationsList.reduce((acc, curr) => {
if (curr.type === 'IN') {
return acc + Number(curr.amount);
} else {
return acc - Number(curr.amount);
}
}, 0);
// Filter hubs list based on role
const allowedHubs = profile.role === 'super_admin'
? hubs
: hubs.filter(h => h.pic_id === profile.id || h.head_id === profile.id);
return (
<div className="modal-overlay active">
<div className="modal-content" style={{ maxWidth: '800px', width: '90%' }}>
<div className="modal-header">
<h2><i className="fas fa-hand-holding-heart text-primary"></i> Manajemen Donasi / Kas</h2>
<button className="close-btn" onClick={() => setShowDonationModal(false)}>&times;</button>
</div>
<div className="modal-body" style={{
display: 'grid',
gridTemplateColumns: canEdit ? '1fr 1fr' : '1fr',
gap: '20px',
maxHeight: '60vh',
overflowY: 'auto'
}}>
{/* Form Transaksi (Only for PIC & Super Admin) */}
{canEdit && (
<div>
<h3 style={{ margin: '0 0 15px 0', fontSize: '1.1rem' }}>Tambah Transaksi</h3>
<form onSubmit={handleSaveDonation} style={{ display: 'flex', flexDirection: 'column', gap: '15px' }}>
<div className="form-group">
<label>Rumah Ibadah</label>
<select
className="form-control"
value={donationFormData.hub_id}
onChange={(e) => setDonationFormData({...donationFormData, hub_id: e.target.value})}
required
disabled={profile.role !== 'super_admin'}
>
<option value="">Pilih Rumah Ibadah</option>
{allowedHubs.map(h => <option key={h.id} value={h.id}>{h.name}</option>)}
</select>
</div>
<div className="form-group">
<label>Jenis Transaksi</label>
<select className="form-control" value={donationFormData.type} onChange={(e) => setDonationFormData({...donationFormData, type: e.target.value})} required>
<option value="IN">Pemasukan (Donasi/Sedekah)</option>
<option value="OUT">Pengeluaran (Bantuan/Operasional)</option>
</select>
</div>
<div className="form-group">
<label>Nominal (Rp)</label>
<input type="number" className="form-control" value={donationFormData.amount} onChange={(e) => setDonationFormData({...donationFormData, amount: e.target.value})} min="1" required />
</div>
<div className="form-group">
<label>Keterangan</label>
<textarea className="form-control" value={donationFormData.description} onChange={(e) => setDonationFormData({...donationFormData, description: e.target.value})} required rows="3" placeholder="Contoh: Sedekah hamba Allah / Bantuan Sembako"></textarea>
</div>
<div className="form-group">
<label>Tanggal Transaksi</label>
<input type="date" className="form-control" value={donationFormData.transaction_date} onChange={(e) => setDonationFormData({...donationFormData, transaction_date: e.target.value})} required />
</div>
<button type="submit" className="btn btn-primary" disabled={isSubmittingDonation} style={{ width: '100%', padding: '10px' }}>
<i className="fas fa-save"></i> {isSubmittingDonation ? 'Menyimpan...' : 'Simpan Transaksi'}
</button>
</form>
</div>
)}
{/* Transaction Logs */}
<div style={{ background: '#f8fafc', padding: '15px', borderRadius: '8px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '15px', flexWrap: 'wrap', gap: '10px' }}>
<h3 style={{ margin: 0, fontSize: '1.1rem' }}>Riwayat Transaksi</h3>
<div style={{
padding: '6px 12px',
background: totalBalance >= 0 ? '#dcfce7' : '#fee2e2',
color: totalBalance >= 0 ? '#15803d' : '#b91c1c',
borderRadius: '20px',
fontWeight: 'bold',
fontSize: '0.85rem'
}}>
Saldo Kas: Rp{totalBalance.toLocaleString('id-ID')}
</div>
</div>
{donationsList.length === 0 ? (
<p style={{ textAlign: 'center', color: '#94a3b8', fontSize: '0.9rem', padding: '20px 0' }}>Belum ada data transaksi.</p>
) : (
<table style={{ width: '100%', borderCollapse: 'collapse', fontSize: '0.85rem' }}>
<thead>
<tr style={{ background: '#e2e8f0', textAlign: 'left' }}>
<th style={{ padding: '8px', borderBottom: '2px solid #cbd5e1' }}>Tanggal</th>
<th style={{ padding: '8px', borderBottom: '2px solid #cbd5e1' }}>Keterangan</th>
<th style={{ padding: '8px', borderBottom: '2px solid #cbd5e1', textAlign: 'right' }}>Nominal</th>
</tr>
</thead>
<tbody>
{donationsList.map(d => (
<tr key={d.id} style={{ borderBottom: '1px solid #e2e8f0' }}>
<td style={{ padding: '8px', color: '#475569' }}>{d.transaction_date}</td>
<td style={{ padding: '8px' }}>
<span style={{ fontWeight: '500', color: '#1e293b' }}>{d.description}</span>
{d.profiles && d.profiles.full_name && <div style={{ fontSize: '0.7rem', color: '#94a3b8' }}>Oleh: {d.profiles.full_name}</div>}
</td>
<td style={{ padding: '8px', textAlign: 'right', fontWeight: 'bold', color: d.type === 'IN' ? '#10b981' : '#ef4444' }}>
{d.type === 'IN' ? '+' : '-'} Rp{Number(d.amount).toLocaleString('id-ID')}
</td>
</tr>
))}
</tbody>
</table>
)}
</div>
</div>
</div>
</div>
);
}