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:
2025-06-21 02:01:21 +02:00
parent 3d5deef0fb
commit aef8791151
101 changed files with 169 additions and 166 deletions
@@ -0,0 +1,142 @@
import { Card, Title, Box, useMantineTheme } from '@mantine/core';
import { Canvas, extend, useFrame, useThree } from '@react-three/fiber';
import { useRef, useMemo } from 'react';
import * as THREE from 'three';
// 🎨 Utilidad para convertir hex a RGB [01]
function hexToRGBArray(hex: string): [number, number, number] {
const bigint = parseInt(hex.replace('#', ''), 16);
return [
((bigint >> 16) & 255) / 255,
((bigint >> 8) & 255) / 255,
(bigint & 255) / 255,
];
}
// ✨ Shader personalizado estilo holográfico, con color dinámico
class HoloShaderMaterial extends THREE.ShaderMaterial {
constructor(color: [number, number, number]) {
super({
uniforms: {
u_time: { value: 0 },
u_resolution: { value: new THREE.Vector2() },
u_color: { value: new THREE.Vector3(...color) },
},
vertexShader: `
void main() {
gl_Position = vec4(position, 1.0);
}
`,
fragmentShader: `
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;
uniform vec3 u_color;
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution;
vec2 pos = uv * 10.0;
pos.x += u_time * 0.3;
pos.y += sin(u_time * 0.2) * 2.0;
float color = sin(pos.x + sin(pos.y + sin(pos.x))) * 0.5 + 0.5;
vec3 c = vec3(
u_color.r + 0.2 * sin(u_time + pos.x),
u_color.g + 0.2 * cos(u_time + pos.y),
u_color.b + 0.2 * sin(pos.x + pos.y + u_time)
);
gl_FragColor = vec4(c * color, 1.0);
}
`,
});
}
}
extend({ HoloShaderMaterial });
// 🎥 Plano con el shader
function HoloPlane({ color }: { color: [number, number, number] }) {
const mat = useRef<any>(null);
const { size } = useThree();
useFrame(({ clock }) => {
if (mat.current) {
mat.current.uniforms.u_time.value = clock.getElapsedTime();
mat.current.uniforms.u_resolution.value.set(size.width, size.height);
}
});
const material = useMemo(() => new HoloShaderMaterial(color), [color]);
return (
<mesh>
<planeGeometry args={[2, 2]} />
<primitive object={material} ref={mat} attach="material" />
</mesh>
);
}
// 🎨 Fondo que ocupa todo el contenedor
function HolographicBackground({ color }: { color: [number, number, number] }) {
return (
<Box
style={{
position: 'absolute',
inset: 0,
zIndex: 0,
pointerEvents: 'none',
}}
>
<Canvas orthographic camera={{ zoom: 1, position: [0, 0, 1] }}>
<HoloPlane color={color} />
</Canvas>
</Box>
);
}
// 🧩 Componente final con fondo shader y texto 404
export function MantineCardWithShader() {
const theme = useMantineTheme();
const hex = theme.colors[theme.primaryColor][6];
const rgb = hexToRGBArray(hex);
return (
<Card
withBorder
radius="lg"
shadow="xl"
style={{
position: 'relative',
overflow: 'hidden',
minHeight: 300,
minWidth: 400,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<HolographicBackground color={rgb} />
<Box style={{ position: 'relative', zIndex: 1, textAlign: 'center' }}>
<Title
order={1}
style={{
fontSize: '15rem',
fontWeight: 900,
backgroundImage: 'linear-gradient(to bottom, rgba(255,255,255,1), rgba(255,255,255,0))',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
textAlign: 'center',
lineHeight: 1,
userSelect: 'none', // <-- evita selección
textDecoration: 'none', // <-- evita subrayado
}}
>
404
</Title>
</Box>
</Card>
);
}