Notas y bibliotecas funcionando
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
Modal,
|
||||
Box,
|
||||
Loader,
|
||||
Textarea
|
||||
} from '@mantine/core';
|
||||
import { AppShellWithMenu } from '../components/Appshell/Appshell';
|
||||
import axios from 'axios';
|
||||
@@ -38,6 +39,10 @@ export function Biblioteca() {
|
||||
const [loadingNotas, setLoadingNotas] = useState(false);
|
||||
const [notaEnEdicion, setNotaEnEdicion] = useState<Nota | null>(null);
|
||||
const [modalEditarAbierto, setModalEditarAbierto] = useState(false);
|
||||
const [modalNuevaBiblio, setModalNuevaBiblio] = useState(false);
|
||||
const [nombreBiblio, setNombreBiblio] = useState('');
|
||||
const [descripcionBiblio, setDescripcionBiblio] = useState('');
|
||||
const [loadingNuevaBiblio, setLoadingNuevaBiblio] = useState(false);
|
||||
|
||||
|
||||
const fetchBibliotecas = async () => {
|
||||
@@ -63,6 +68,31 @@ export function Biblioteca() {
|
||||
}
|
||||
};
|
||||
|
||||
const crearBiblioteca = async () => {
|
||||
setLoadingNuevaBiblio(true); // 🔄 Activa el loader en el botón
|
||||
try {
|
||||
// Llamada a backend
|
||||
await axios.post('/api/v1/text_manager/biblioteca', {
|
||||
nombre_biblioteca: nombreBiblio,
|
||||
descripcion: descripcionBiblio,
|
||||
});
|
||||
|
||||
// 🧼 Limpia formularios
|
||||
setNombreBiblio('');
|
||||
setDescripcionBiblio('');
|
||||
|
||||
// 🔒 Cierra el modal
|
||||
setModalNuevaBiblio(false);
|
||||
|
||||
// 🔄 Refresca la lista de bibliotecas
|
||||
await fetchBibliotecas();
|
||||
} catch (error) {
|
||||
console.error('❌ Error al crear biblioteca:', error);
|
||||
} finally {
|
||||
setLoadingNuevaBiblio(false); // ✅ Apaga el loader
|
||||
}
|
||||
};
|
||||
|
||||
const agregarNota = async () => {
|
||||
if (!bibliotecaSeleccionada) return;
|
||||
|
||||
@@ -101,7 +131,14 @@ export function Biblioteca() {
|
||||
if (!bibliotecaSeleccionada) return;
|
||||
try {
|
||||
await axios.delete(`/api/v1/text_manager/nota/${bibliotecaSeleccionada.id}/${notaId}`);
|
||||
await fetchBibliotecas();
|
||||
|
||||
// Solo actualiza la biblioteca actual
|
||||
const nuevasNotas = await axios.get(`/api/v1/text_manager/nota/list/${bibliotecaSeleccionada.id}`);
|
||||
const nuevasBibliotecas = bibliotecas.map((b) =>
|
||||
b.id === bibliotecaSeleccionada.id ? { ...b, notas: nuevasNotas.data as Nota[] } : b
|
||||
);
|
||||
setBibliotecas(nuevasBibliotecas);
|
||||
setBibliotecaSeleccionada(nuevasBibliotecas.find(b => b.id === bibliotecaSeleccionada.id) || null);
|
||||
} catch (error) {
|
||||
console.error("Error al eliminar nota:", error);
|
||||
}
|
||||
@@ -140,9 +177,9 @@ export function Biblioteca() {
|
||||
<Box w={240} p="md">
|
||||
<ScrollArea h="100%">
|
||||
<Stack>
|
||||
<Button color="teal" onClick={fetchBibliotecas}>
|
||||
🔄 Recuperar bibliotecas
|
||||
</Button>
|
||||
<Button color="teal" onClick={fetchBibliotecas}>🔄 Recuperar bibliotecas</Button>
|
||||
<Button color="grape" variant="outline" onClick={() => setModalNuevaBiblio(true)}>➕ Nueva biblioteca</Button>
|
||||
|
||||
|
||||
{bibliotecas.map((biblio) => (
|
||||
<Button
|
||||
@@ -181,32 +218,29 @@ export function Biblioteca() {
|
||||
padding="lg"
|
||||
radius="md"
|
||||
withBorder
|
||||
style={{ width: 300, position: 'relative' }}
|
||||
style={{
|
||||
width: 300,
|
||||
height: 250, // Altura fija para asegurar la separación
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
{/* Botones en esquina superior derecha */}
|
||||
<Box style={{ position: 'absolute', top: 8, right: 8, display: 'flex', gap: 4, zIndex: 1 }}>
|
||||
<div>
|
||||
<Title order={4} style={{ marginBottom: 10 }}>{nota.titulo}</Title>
|
||||
<Text>{nota.texto}</Text>
|
||||
</div>
|
||||
|
||||
<Box mt="md" style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<Button
|
||||
size="xs"
|
||||
color="blue"
|
||||
variant="light"
|
||||
p={4}
|
||||
color="blue"
|
||||
onClick={() => abrirModalEditar(nota)}
|
||||
>
|
||||
✏️
|
||||
</Button>
|
||||
<Button
|
||||
size="xs"
|
||||
color="red"
|
||||
variant="light"
|
||||
p={4}
|
||||
onClick={() => eliminarNota(nota.id)}
|
||||
>
|
||||
🗑️
|
||||
Editar
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Title order={4} style={{ marginBottom: 10 }}>{nota.titulo}</Title>
|
||||
<Text>{nota.texto}</Text>
|
||||
</Card>
|
||||
|
||||
// Fin de notas en cards
|
||||
@@ -218,9 +252,7 @@ export function Biblioteca() {
|
||||
) : (
|
||||
<Stack>
|
||||
<Text>Selecciona una biblioteca</Text>
|
||||
<Button color="teal" onClick={fetchBibliotecas}>
|
||||
🔄 Recuperar bibliotecas
|
||||
</Button>
|
||||
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
@@ -234,8 +266,10 @@ export function Biblioteca() {
|
||||
value={tituloNota}
|
||||
onChange={(event) => setTituloNota(event.currentTarget.value)}
|
||||
/>
|
||||
<TextInput
|
||||
<Textarea
|
||||
label="Contenido"
|
||||
minRows={6}
|
||||
autosize
|
||||
value={contenidoNota}
|
||||
onChange={(event) => setContenidoNota(event.currentTarget.value)}
|
||||
/>
|
||||
@@ -253,16 +287,60 @@ export function Biblioteca() {
|
||||
setNotaEnEdicion((prev) => (prev ? { ...prev, titulo: e.currentTarget.value } : null))
|
||||
}
|
||||
/>
|
||||
<TextInput
|
||||
<Textarea
|
||||
label="Contenido"
|
||||
minRows={6}
|
||||
autosize
|
||||
value={notaEnEdicion?.texto || ""}
|
||||
onChange={(e) =>
|
||||
setNotaEnEdicion((prev) => (prev ? { ...prev, texto: e.currentTarget.value } : null))
|
||||
}
|
||||
/>
|
||||
<Button onClick={guardarEdicionNota}>Guardar cambios</Button>
|
||||
<Group grow>
|
||||
<Button color="blue" onClick={guardarEdicionNota}>
|
||||
💾 Guardar cambios
|
||||
</Button>
|
||||
<Button
|
||||
color="red"
|
||||
onClick={async () => {
|
||||
if (!notaEnEdicion || !bibliotecaSeleccionada) return;
|
||||
await eliminarNota(notaEnEdicion.id);
|
||||
setModalEditarAbierto(false);
|
||||
setNotaEnEdicion(null);
|
||||
}}
|
||||
>
|
||||
🗑️ Eliminar nota
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Modal>
|
||||
|
||||
{/* Modal para crear una biblioteca */}
|
||||
<Modal
|
||||
opened={modalNuevaBiblio}
|
||||
onClose={() => setModalNuevaBiblio(false)}
|
||||
title="Crear nueva biblioteca"
|
||||
>
|
||||
<Stack>
|
||||
<TextInput
|
||||
label="Nombre"
|
||||
value={nombreBiblio}
|
||||
onChange={(e) => setNombreBiblio(e.currentTarget.value)}
|
||||
disabled={loadingNuevaBiblio}
|
||||
/>
|
||||
<TextInput
|
||||
label="Descripción"
|
||||
value={descripcionBiblio}
|
||||
onChange={(e) => setDescripcionBiblio(e.currentTarget.value)}
|
||||
disabled={loadingNuevaBiblio}
|
||||
/>
|
||||
<Button onClick={crearBiblioteca} loading={loadingNuevaBiblio}>
|
||||
Crear
|
||||
</Button>
|
||||
</Stack>
|
||||
</Modal>
|
||||
|
||||
|
||||
</AppShellWithMenu>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user