Enhancements

This commit is contained in:
2026-06-25 11:19:08 +02:00
parent 8804d21c32
commit 9343657d20
62 changed files with 10210 additions and 976 deletions
@@ -0,0 +1,94 @@
import React, { useState } from 'react'
import { Member, Payment } from '../types'
interface PaymentsTableProps {
members: Member[]
payments: Payment[]
loading: boolean
}
export const PaymentsTable: React.FC<PaymentsTableProps> = ({ members, payments, loading }) => {
const [filter, setFilter] = useState('')
const getMemberName = (memberId: number) => {
const member = members.find((m) => m.id === memberId)
return member ? `${member.member_firstname} ${member.member_surname}` : 'Unknown'
}
const filteredPayments = payments.filter((p) => {
const memberName = getMemberName(p.member_id).toLowerCase()
return memberName.includes(filter.toLowerCase())
})
if (loading) {
return (
<div className="text-center py-5">
<div className="spinner-border" role="status">
<span className="visually-hidden">Loading...</span>
</div>
</div>
)
}
return (
<div>
<div className="mb-4">
<input
type="text"
className="form-control"
placeholder="🔍 Search by member name..."
value={filter}
onChange={(e) => setFilter(e.target.value)}
style={{ fontSize: '0.95rem' }}
/>
</div>
{filteredPayments.length > 0 ? (
<>
<div className="table-responsive">
<table className="table table-hover">
<thead>
<tr>
<th>Payment ID</th>
<th>Member Name</th>
<th>Member ID</th>
<th>Payment Date</th>
<th>Year</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
{filteredPayments.map((payment) => (
<tr key={payment.id}>
<td style={{ fontWeight: 600, color: '#27ae60' }}>{payment.id}</td>
<td>{getMemberName(payment.member_id)}</td>
<td>{payment.member_id}</td>
<td style={{ fontSize: '0.9rem' }}>
{new Date(payment.payment_date).toLocaleDateString()}
</td>
<td>{payment.payment_year}</td>
<td style={{ fontWeight: 600, color: '#3498db' }}>
{payment.payment_amount ? payment.payment_amount.toFixed(2) : '0.00'}
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="mt-3 text-muted">
Showing <strong>{filteredPayments.length}</strong> of <strong>{payments.length}</strong> payments
{filteredPayments.length > 0 && (
<span className="ms-3">
Total: <strong>{filteredPayments.reduce((sum, p) => sum + (p.payment_amount || 0), 0).toFixed(2)}</strong>
</span>
)}
</div>
</>
) : (
<div className="text-center py-5 text-muted">
<p>No payments found matching your search</p>
</div>
)}
</div>
)
}