feat: scaffold frontend (Vite + React + Vitest)

- Añade scaffold de frontend con Vite y React
- Configura Vitest y tests básicos (App, Navbar)
- Añade QueryClient y hooks/plantillas iniciales
This commit is contained in:
2026-02-09 20:22:24 +01:00
parent 79c42fad55
commit 08aca0fd5b
27 changed files with 3171 additions and 215 deletions

13
frontend/src/App.tsx Normal file
View File

@@ -0,0 +1,13 @@
import React from 'react';
import Navbar from './components/layout/Navbar';
export default function App(): JSX.Element {
return (
<div>
<Navbar />
<main>
<h1>Quasar</h1>
</main>
</div>
);
}

View File

@@ -0,0 +1,12 @@
import React from 'react';
export default function Navbar(): JSX.Element {
return (
<nav style={{ padding: 12 }}>
<a href="/roms" style={{ marginRight: 12 }}>
ROMs
</a>
<a href="/games">Games</a>
</nav>
);
}

View File

@@ -0,0 +1,9 @@
import React from 'react';
export default function Sidebar(): JSX.Element {
return (
<aside style={{ padding: 12 }}>
<div>Sidebar (placeholder)</div>
</aside>
);
}

View File

@@ -0,0 +1,4 @@
export function useGames() {
// placeholder stub for tests and future implementation
return { data: [], isLoading: false };
}

3
frontend/src/lib/api.ts Normal file
View File

@@ -0,0 +1,3 @@
export const api = {
// placeholder for future HTTP client
};

View File

@@ -0,0 +1,3 @@
import { QueryClient } from '@tanstack/react-query';
export const queryClient = new QueryClient();

32
frontend/src/main.tsx Normal file
View File

@@ -0,0 +1,32 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClient } from './lib/queryClient';
import App from './App';
import './styles.css';
const rootEl = document.getElementById('root');
if (rootEl) {
createRoot(rootEl).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);
}
import React from 'react';
import ReactDOM from 'react-dom/client';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClient } from './lib/queryClient';
import App from './App';
import './index.css';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);

View File

@@ -0,0 +1,9 @@
import React from 'react';
export default function Games(): JSX.Element {
return (
<div>
<h2>Games</h2>
</div>
);
}

View File

@@ -0,0 +1,9 @@
import React from 'react';
export default function Home(): JSX.Element {
return (
<div>
<h2>Home</h2>
</div>
);
}

View File

@@ -0,0 +1,9 @@
import React from 'react';
export default function Roms(): JSX.Element {
return (
<div>
<h2>ROMs</h2>
</div>
);
}

View File

@@ -0,0 +1,2 @@
import '@testing-library/jest-dom';
import '@testing-library/jest-dom';

8
frontend/src/styles.css Normal file
View File

@@ -0,0 +1,8 @@
/* Minimal global styles */
html, body, #root {
height: 100%;
}
body {
margin: 0;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
}