244 lines
7.4 KiB
JavaScript
244 lines
7.4 KiB
JavaScript
import { useCallback, useEffect, useState } from 'react';
|
|
import Modal from '../components/Modal';
|
|
import { cabanasApi, lotesApi, rematesApi } from '../api/client';
|
|
|
|
const emptyForm = () => ({
|
|
nombre: '',
|
|
precio: '',
|
|
raza: '',
|
|
prelance: '',
|
|
puja: '',
|
|
estado: '',
|
|
video: '',
|
|
numLote: 0,
|
|
visible: true,
|
|
remateId: '',
|
|
cabanaId: '',
|
|
});
|
|
|
|
function toPayload(form) {
|
|
const body = {
|
|
nombre: form.nombre,
|
|
raza: form.raza || null,
|
|
estado: form.estado || null,
|
|
video: form.video || null,
|
|
numLote: Number(form.numLote) || 0,
|
|
visible: form.visible,
|
|
};
|
|
if (form.precio !== '') body.precio = Number(form.precio);
|
|
if (form.prelance !== '') body.prelance = Number(form.prelance);
|
|
if (form.puja !== '') body.puja = Number(form.puja);
|
|
if (form.remateId) body.remate = { id: Number(form.remateId) };
|
|
if (form.cabanaId) body.cabana = { id: Number(form.cabanaId) };
|
|
return body;
|
|
}
|
|
|
|
export default function Lotes() {
|
|
const [items, setItems] = useState([]);
|
|
const [remates, setRemates] = useState([]);
|
|
const [cabanas, setCabanas] = useState([]);
|
|
const [error, setError] = useState('');
|
|
const [modal, setModal] = useState(null);
|
|
const [form, setForm] = useState(emptyForm());
|
|
const [saving, setSaving] = useState(false);
|
|
|
|
const load = useCallback(() => {
|
|
Promise.all([lotesApi.list(), rematesApi.list(), cabanasApi.list()])
|
|
.then(([l, r, c]) => {
|
|
setItems(l);
|
|
setRemates(r);
|
|
setCabanas(c);
|
|
})
|
|
.catch((e) => setError(e.message));
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
load();
|
|
}, [load]);
|
|
|
|
const openCreate = () => {
|
|
setForm(emptyForm());
|
|
setModal('create');
|
|
};
|
|
|
|
const openEdit = (l) => {
|
|
setForm({
|
|
nombre: l.nombre || '',
|
|
precio: l.precio ?? '',
|
|
raza: l.raza || '',
|
|
prelance: l.prelance ?? '',
|
|
puja: l.puja ?? '',
|
|
estado: l.estado || '',
|
|
video: l.video || '',
|
|
numLote: l.numLote ?? 0,
|
|
visible: l.visible !== false,
|
|
remateId: l.remate?.id ?? '',
|
|
cabanaId: l.cabana?.id ?? '',
|
|
});
|
|
setModal({ type: 'edit', id: l.id });
|
|
};
|
|
|
|
const guardar = async () => {
|
|
setSaving(true);
|
|
setError('');
|
|
try {
|
|
const payload = toPayload(form);
|
|
if (modal === 'create') await lotesApi.create(payload);
|
|
else await lotesApi.update(modal.id, payload);
|
|
setModal(null);
|
|
load();
|
|
} catch (e) {
|
|
setError(e.message);
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
const eliminar = async (id) => {
|
|
if (!confirm('¿Eliminar lote?')) return;
|
|
try {
|
|
await lotesApi.remove(id);
|
|
load();
|
|
} catch (e) {
|
|
setError(e.message);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="page-header">
|
|
<h1>Lotes</h1>
|
|
<button type="button" className="btn btn-primary" onClick={openCreate}>
|
|
+ Nuevo lote
|
|
</button>
|
|
</div>
|
|
{error && <div className="alert alert-error">{error}</div>}
|
|
<div className="card">
|
|
<div className="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Nº</th>
|
|
<th>Nombre</th>
|
|
<th>Precio</th>
|
|
<th>Remate</th>
|
|
<th>Estado</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{items.map((l) => (
|
|
<tr key={l.id}>
|
|
<td>{l.id}</td>
|
|
<td>{l.numLote}</td>
|
|
<td>{l.nombre}</td>
|
|
<td>{l.precio}</td>
|
|
<td>{l.remate?.nombre ?? l.remate?.id ?? '—'}</td>
|
|
<td>{l.estado}</td>
|
|
<td>
|
|
<div className="btn-group">
|
|
<button type="button" className="btn btn-ghost btn-sm" onClick={() => openEdit(l)}>
|
|
Editar
|
|
</button>
|
|
<button type="button" className="btn btn-danger btn-sm" onClick={() => eliminar(l.id)}>
|
|
Eliminar
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{modal && (
|
|
<Modal
|
|
title={modal === 'create' ? 'Nuevo lote' : 'Editar lote'}
|
|
onClose={() => setModal(null)}
|
|
onSave={guardar}
|
|
saving={saving}
|
|
>
|
|
<div className="form-row">
|
|
<div className="form-group">
|
|
<label>Nombre</label>
|
|
<input value={form.nombre} onChange={(e) => setForm({ ...form, nombre: e.target.value })} />
|
|
</div>
|
|
<div className="form-group">
|
|
<label>Nº lote</label>
|
|
<input
|
|
type="number"
|
|
value={form.numLote}
|
|
onChange={(e) => setForm({ ...form, numLote: e.target.value })}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="form-row">
|
|
<div className="form-group">
|
|
<label>Precio</label>
|
|
<input value={form.precio} onChange={(e) => setForm({ ...form, precio: e.target.value })} />
|
|
</div>
|
|
<div className="form-group">
|
|
<label>Puja actual</label>
|
|
<input value={form.puja} onChange={(e) => setForm({ ...form, puja: e.target.value })} />
|
|
</div>
|
|
</div>
|
|
<div className="form-row">
|
|
<div className="form-group">
|
|
<label>Raza</label>
|
|
<input value={form.raza} onChange={(e) => setForm({ ...form, raza: e.target.value })} />
|
|
</div>
|
|
<div className="form-group">
|
|
<label>Prelance</label>
|
|
<input value={form.prelance} onChange={(e) => setForm({ ...form, prelance: e.target.value })} />
|
|
</div>
|
|
</div>
|
|
<div className="form-group">
|
|
<label>Estado</label>
|
|
<input value={form.estado} onChange={(e) => setForm({ ...form, estado: e.target.value })} />
|
|
</div>
|
|
<div className="form-group">
|
|
<label>Video (URL)</label>
|
|
<input value={form.video} onChange={(e) => setForm({ ...form, video: e.target.value })} />
|
|
</div>
|
|
<div className="form-row">
|
|
<div className="form-group">
|
|
<label>Remate</label>
|
|
<select value={form.remateId} onChange={(e) => setForm({ ...form, remateId: e.target.value })}>
|
|
<option value="">—</option>
|
|
{remates.map((r) => (
|
|
<option key={r.id} value={r.id}>
|
|
{r.nombre} (#{r.id})
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
<div className="form-group">
|
|
<label>Cabaña</label>
|
|
<select value={form.cabanaId} onChange={(e) => setForm({ ...form, cabanaId: e.target.value })}>
|
|
<option value="">—</option>
|
|
{cabanas.map((c) => (
|
|
<option key={c.id} value={c.id}>
|
|
{c.nombre}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div className="form-group">
|
|
<label>
|
|
<input
|
|
type="checkbox"
|
|
checked={form.visible}
|
|
onChange={(e) => setForm({ ...form, visible: e.target.checked })}
|
|
/>{' '}
|
|
Visible
|
|
</label>
|
|
</div>
|
|
</Modal>
|
|
)}
|
|
</>
|
|
);
|
|
}
|