170 lines
5.0 KiB
TypeScript
170 lines
5.0 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import {
|
|
AppShell,
|
|
Stack,
|
|
Card,
|
|
Text,
|
|
Title,
|
|
ScrollArea,
|
|
Group,
|
|
Button,
|
|
TextInput,
|
|
Modal,
|
|
Box,
|
|
Loader,
|
|
} from '@mantine/core';
|
|
import { AppShellWithMenu } from '../components/Appshell/Appshell';
|
|
import axios from 'axios';
|
|
|
|
type Nota = {
|
|
id: string;
|
|
titulo: string;
|
|
texto: string;
|
|
};
|
|
|
|
type Biblioteca = {
|
|
id: string;
|
|
nombre: string;
|
|
descripcion: string;
|
|
notas: Nota[];
|
|
};
|
|
|
|
export function Biblioteca() {
|
|
const [bibliotecas, setBibliotecas] = useState<Biblioteca[]>([]);
|
|
const [bibliotecaSeleccionada, setBibliotecaSeleccionada] = useState<Biblioteca | null>(null);
|
|
const [modalAbierto, setModalAbierto] = useState(false);
|
|
const [tituloNota, setTituloNota] = useState('');
|
|
const [contenidoNota, setContenidoNota] = useState('');
|
|
const [loadingNotas, setLoadingNotas] = useState(false);
|
|
|
|
const fetchBibliotecas = async () => {
|
|
try {
|
|
const res = await axios.get('/api/v1/text_manager/list');
|
|
console.log('📦 Respuesta del backend:', res.data);
|
|
|
|
if (!Array.isArray(res.data)) {
|
|
console.error('❌ La respuesta no es un array:', res.data);
|
|
return;
|
|
}
|
|
|
|
const bibliotecasConNotas = await Promise.all(
|
|
res.data.map(async (biblio: Omit<Biblioteca, 'notas'>) => {
|
|
const notas = await axios.get(`/api/v1/text_manager/nota/list/${biblio.id}`);
|
|
return { ...biblio, notas: notas.data as Nota[] };
|
|
})
|
|
);
|
|
setBibliotecas(bibliotecasConNotas);
|
|
setBibliotecaSeleccionada(bibliotecasConNotas[0] || null);
|
|
} catch (error) {
|
|
console.error('Error al cargar bibliotecas:', error);
|
|
}
|
|
};
|
|
|
|
const agregarNota = async () => {
|
|
if (!bibliotecaSeleccionada) return;
|
|
|
|
try {
|
|
await axios.post(`/api/v1/text_manager/nota/${bibliotecaSeleccionada.id}`, {
|
|
titulo: tituloNota,
|
|
texto: contenidoNota,
|
|
tags: [],
|
|
conexiones: [],
|
|
resumen: '',
|
|
});
|
|
|
|
setLoadingNotas(true);
|
|
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);
|
|
setTituloNota('');
|
|
setContenidoNota('');
|
|
setModalAbierto(false);
|
|
} catch (error) {
|
|
console.error('Error al agregar nota:', error);
|
|
} finally {
|
|
setLoadingNotas(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchBibliotecas();
|
|
}, []);
|
|
|
|
return (
|
|
<AppShellWithMenu>
|
|
<Box display="flex" h="100%">
|
|
<Box w={240} p="md">
|
|
<ScrollArea h="100%">
|
|
<Stack>
|
|
{bibliotecas.map((biblio) => (
|
|
<Button
|
|
key={biblio.id}
|
|
size="xs"
|
|
fullWidth
|
|
variant={biblio.id === bibliotecaSeleccionada?.id ? 'filled' : 'light'}
|
|
color="blue"
|
|
onClick={() => setBibliotecaSeleccionada(biblio)}
|
|
>
|
|
{biblio.nombre}
|
|
</Button>
|
|
))}
|
|
</Stack>
|
|
</ScrollArea>
|
|
</Box>
|
|
|
|
<Box p="md" style={{ flex: 1 }}>
|
|
{bibliotecaSeleccionada ? (
|
|
<Stack>
|
|
<Title order={2}>{bibliotecaSeleccionada.nombre}</Title>
|
|
<Group>
|
|
<Button color="teal" onClick={fetchBibliotecas}>
|
|
🔄 Recuperar bibliotecas
|
|
</Button>
|
|
<Button onClick={() => setModalAbierto(true)}>Agregar nota</Button>
|
|
</Group>
|
|
<Group>
|
|
{loadingNotas ? (
|
|
<Loader />
|
|
) : (
|
|
bibliotecaSeleccionada.notas.map((nota) => (
|
|
<Card key={nota.id} shadow="sm" padding="lg" radius="md" withBorder style={{ width: 300 }}>
|
|
<Title order={4}>{nota.titulo}</Title>
|
|
<Text>{nota.texto}</Text>
|
|
</Card>
|
|
))
|
|
)}
|
|
</Group>
|
|
</Stack>
|
|
) : (
|
|
<Stack>
|
|
<Text>Selecciona una biblioteca</Text>
|
|
<Button color="teal" onClick={fetchBibliotecas}>
|
|
🔄 Recuperar bibliotecas
|
|
</Button>
|
|
</Stack>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
|
|
<Modal opened={modalAbierto} onClose={() => setModalAbierto(false)} title="Agregar nueva nota">
|
|
<Stack>
|
|
<TextInput
|
|
label="Título"
|
|
value={tituloNota}
|
|
onChange={(event) => setTituloNota(event.currentTarget.value)}
|
|
/>
|
|
<TextInput
|
|
label="Contenido"
|
|
value={contenidoNota}
|
|
onChange={(event) => setContenidoNota(event.currentTarget.value)}
|
|
/>
|
|
<Button onClick={agregarNota}>Guardar</Button>
|
|
</Stack>
|
|
</Modal>
|
|
</AppShellWithMenu>
|
|
);
|
|
}
|