3907414742
Multi-user FastAPI + React app with JWT auth, SQLite storage, and CoinGecko price integration. Dockerized with docker-compose. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
59 lines
2.3 KiB
JavaScript
59 lines
2.3 KiB
JavaScript
import React from 'react';
|
|
|
|
const API = process.env.REACT_APP_API_URL || 'http://localhost:8000';
|
|
|
|
const styles = {
|
|
card: { background: '#1a1a1a', padding: '1.5rem', borderRadius: '12px', border: '1px solid #333', marginBottom: '1.5rem' },
|
|
title: { fontSize: '1.1rem', fontWeight: 700, marginBottom: '1rem', color: '#f7931a' },
|
|
table: { width: '100%', borderCollapse: 'collapse' },
|
|
th: { textAlign: 'left', padding: '0.5rem 0.75rem', borderBottom: '1px solid #333', color: '#888', fontSize: '0.85rem' },
|
|
td: { padding: '0.6rem 0.75rem', borderBottom: '1px solid #222', fontSize: '0.95rem' },
|
|
deleteBtn: { background: 'none', border: '1px solid #555', color: '#ff6b6b', borderRadius: '6px', padding: '0.25rem 0.6rem', cursor: 'pointer', fontSize: '0.85rem' },
|
|
empty: { color: '#555', textAlign: 'center', padding: '1rem' },
|
|
};
|
|
|
|
export default function PurchaseList({ purchases, onDeleted }) {
|
|
const handleDelete = async (id) => {
|
|
const token = localStorage.getItem('token');
|
|
await fetch(`${API}/purchases/${id}`, {
|
|
method: 'DELETE',
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
});
|
|
onDeleted();
|
|
};
|
|
|
|
return (
|
|
<div style={styles.card}>
|
|
<div style={styles.title}>Purchases</div>
|
|
{purchases.length === 0 ? (
|
|
<div style={styles.empty}>No purchases yet.</div>
|
|
) : (
|
|
<table style={styles.table}>
|
|
<thead>
|
|
<tr>
|
|
<th style={styles.th}>Date</th>
|
|
<th style={styles.th}>Amount (€)</th>
|
|
<th style={styles.th}>Price (€/BTC)</th>
|
|
<th style={styles.th}>BTC</th>
|
|
<th style={styles.th}></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{purchases.map(p => (
|
|
<tr key={p.id}>
|
|
<td style={styles.td}>{new Date(p.created_at).toLocaleDateString()}</td>
|
|
<td style={styles.td}>€{p.amount_eur.toLocaleString()}</td>
|
|
<td style={styles.td}>€{p.price_eur.toLocaleString()}</td>
|
|
<td style={styles.td}>{(p.amount_eur / p.price_eur).toFixed(6)}</td>
|
|
<td style={styles.td}>
|
|
<button style={styles.deleteBtn} onClick={() => handleDelete(p.id)}>Delete</button>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|