feat: Implement main application shell with navigation and color scheme toggle
- Added Appshell component with responsive navbar and main content area - Integrated ColorSchemeToggle for light/dark mode switching - Created Welcome component with styled title and introductory text - Developed ChatPage for LLM interaction with WebSocket support - Implemented Biblioteca for managing notes with rich text editor - Added LoginPage for user authentication with error handling - Introduced MessageList and MessageBubble components for chat messages - Styled components with CSS modules for consistent design
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
import { Card, Text, Switch, Group, useMantineTheme, useComputedColorScheme } from '@mantine/core';
|
||||
import { Rnd } from 'react-rnd';
|
||||
import { useState } from 'react';
|
||||
|
||||
const GRID_SIZE = 30;
|
||||
|
||||
function hexToRgba(hex: string, alpha: number): string {
|
||||
const sanitized = hex.replace('#', '');
|
||||
const bigint = parseInt(sanitized, 16);
|
||||
|
||||
const r = (bigint >> 16) & 255;
|
||||
const g = (bigint >> 8) & 255;
|
||||
const b = bigint & 255;
|
||||
|
||||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||||
}
|
||||
|
||||
interface CardData {
|
||||
id: string;
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
const initialCards: CardData[] = [
|
||||
{ id: '1', x: 0, y: 0, width: GRID_SIZE * 2, height: GRID_SIZE * 2 },
|
||||
{ id: '2', x: GRID_SIZE * 2, y: 0, width: GRID_SIZE * 3, height: GRID_SIZE * 2 },
|
||||
{ id: '3', x: GRID_SIZE * 3, y: 0, width: GRID_SIZE * 3, height: GRID_SIZE * 2 },
|
||||
];
|
||||
|
||||
export const GridDashboard = () => {
|
||||
const theme = useMantineTheme();
|
||||
const colorScheme = useComputedColorScheme(); // ✅ directamente 'light' o 'dark'
|
||||
const isDark = colorScheme === 'dark';
|
||||
|
||||
// Color de la rejilla adaptado al modo del tema
|
||||
const gridBaseColor = isDark ? theme.colors.dark[4] : theme.colors.gray[3];
|
||||
const gridColor = hexToRgba(gridBaseColor, 0.25); // Ajusta la opacidad aquí
|
||||
|
||||
const [cards, setCards] = useState<CardData[]>(initialCards);
|
||||
const [showGrid, setShowGrid] = useState(true);
|
||||
|
||||
const updateCard = (id: string, updates: Partial<CardData>) => {
|
||||
setCards((prev) =>
|
||||
prev.map((card) => (card.id === id ? { ...card, ...updates } : card))
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Group mb="xs">
|
||||
<Switch
|
||||
checked={showGrid}
|
||||
onChange={(event) => setShowGrid(event.currentTarget.checked)}
|
||||
label="Mostrar cuadrícula"
|
||||
/>
|
||||
</Group>
|
||||
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '700px',
|
||||
backgroundSize: `${GRID_SIZE}px ${GRID_SIZE}px`,
|
||||
backgroundImage: showGrid
|
||||
? `linear-gradient(to right, ${gridColor} 1px, transparent 1px),
|
||||
linear-gradient(to bottom, ${gridColor} 1px, transparent 1px)`
|
||||
: 'none',
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
{cards.map((card) => (
|
||||
<Rnd
|
||||
key={card.id}
|
||||
size={{
|
||||
width: Math.round(card.width / GRID_SIZE) * GRID_SIZE,
|
||||
height: Math.round(card.height / GRID_SIZE) * GRID_SIZE,
|
||||
}}
|
||||
position={{ x: card.x, y: card.y }}
|
||||
minWidth={GRID_SIZE * 8}
|
||||
minHeight={GRID_SIZE * 8}
|
||||
bounds="parent"
|
||||
grid={[GRID_SIZE, GRID_SIZE]}
|
||||
onDragStop={(_, d) =>
|
||||
updateCard(card.id, {
|
||||
x: Math.round(d.x / GRID_SIZE) * GRID_SIZE,
|
||||
y: Math.round(d.y / GRID_SIZE) * GRID_SIZE,
|
||||
})
|
||||
}
|
||||
onResizeStop={(_, __, ref, ___, pos) =>
|
||||
updateCard(card.id, {
|
||||
width: Math.round(ref.offsetWidth / GRID_SIZE) * GRID_SIZE,
|
||||
height: Math.round(ref.offsetHeight / GRID_SIZE) * GRID_SIZE,
|
||||
x: Math.round(pos.x / GRID_SIZE) * GRID_SIZE,
|
||||
y: Math.round(pos.y / GRID_SIZE) * GRID_SIZE,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Card
|
||||
shadow="sm"
|
||||
padding="md"
|
||||
radius="md"
|
||||
withBorder
|
||||
style={{ height: '100%', userSelect: 'none' }}
|
||||
>
|
||||
<Text fw={500}>Card {card.id}</Text>
|
||||
<Text size="sm">Mueve o redimensiona</Text>
|
||||
</Card>
|
||||
</Rnd>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user