basic frontend adjustments - routing, minimal layout, template

This commit is contained in:
Ricardo Zylbergeld 2025-04-26 11:42:30 +03:00
parent c75dc399d5
commit e2e6ec541a
11 changed files with 303 additions and 215 deletions

View file

@ -88,7 +88,7 @@ app.post('/login', async (req: Request, res: Response) => {
app.post('/refresh', (req: Request, res: Response) => { app.post('/refresh', (req: Request, res: Response) => {
const token = req.cookies?.refreshToken; const token = req.cookies?.refreshToken;
// TODO: voltar a verificaço abaixo, quando refresh tokens estiver em DB // TODO: voltar à verificação abaixo, quando refresh tokens estiver em DB
// estudar melhor (exemplo, verificar expiração de refresh token etc) // estudar melhor (exemplo, verificar expiração de refresh token etc)
if (!token /*|| !refreshTokens.has(token)*/) return res.sendStatus(403); if (!token /*|| !refreshTokens.has(token)*/) return res.sendStatus(403);

View file

@ -1,7 +1,12 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Route, Routes, Navigate } from 'react-router';
import { useAuthStore } from './auth/authStore'; import { useAuthStore } from './auth/authStore';
import { refreshToken, logout } from './auth/auth-utils'; import { refreshToken } from './auth/auth-utils';
import api from './auth/axiosInstance';
/* Components */
import LoginPage from './components/pages/LoginPage';
import TemplatePage from './components/pages/TemplatePage';
import HomePage from './components/pages/HomePage';
export default function App() { export default function App() {
const accessToken = useAuthStore((s) => s.accessToken); const accessToken = useAuthStore((s) => s.accessToken);
@ -20,84 +25,22 @@ export default function App() {
if (loading) return <div>Loading...</div>; if (loading) return <div>Loading...</div>;
return ( return (
<div> <Routes>
<h1>Hybrid Auth Flow</h1>
{!accessToken ? ( {!accessToken ? (
<> <>
<LoginArea /> {/* Unauthenticated routes */}
<Protected /> <Route path="login" element={<LoginPage />} />
{/* Redirect other routes to login */}
<Route path="*" element={<Navigate to="/login" replace />} />
</> </>
) : ( ) : (
<> <Route element={<TemplatePage />}>
<LogoutButton /> {/* Authenticated routes */}
<Protected /> <Route path="/" element={<HomePage />} />
</> {/* Redirect other routes to the home */}
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
)} )}
</div> </Routes>
); );
} }
function LoginArea() {
const setAccessToken = useAuthStore((s) => s.setAccessToken);
const [email, _email] = useState('');
const [password, _password] = useState('');
const login = async () => {
const res = await fetch(`${import.meta.env.VITE_SERVER}/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
email,
password,
}),
});
const data = await res.json();
setAccessToken(data.accessToken);
};
return (
<>
<div>
<input
type="text"
name="email"
value={email}
onChange={(e) => _email(e.target.value)}
/>
</div>
<div>
<input
type="password"
name="password"
value={password}
onChange={(e) => _password(e.target.value)}
/>
</div>
<div>
<button onClick={login}>Login</button>
</div>
</>
);
}
function LogoutButton() {
return <button onClick={logout}>Logout</button>;
}
function Protected() {
const callAPI = async () => {
try {
const res = await api.get('/protected');
alert(res.data.message);
} catch {
alert('Unauthorized');
}
};
return <button onClick={callAPI}>Call Protected Route</button>;
}

View file

@ -11,6 +11,7 @@ export function setAccessToken(token: string | null) {
} }
export async function refreshToken(): Promise<string> { export async function refreshToken(): Promise<string> {
// TODO: verificar se há cookie para tentar o refresh?
const res = await fetch(`${import.meta.env.VITE_SERVER}/refresh`, { const res = await fetch(`${import.meta.env.VITE_SERVER}/refresh`, {
method: 'POST', method: 'POST',
credentials: 'include', credentials: 'include',

View file

@ -0,0 +1,12 @@
import React from "react";
interface ButtonProps {
label?: string;
onClick?: () => void;
}
const TextField: React.FC<ButtonProps> = ({ label = 'button', onClick }) => {
return (<button className="border my-5 bg-gray-50 hover:bg-gray-500 hover:text-white rounded-lg p-2 font-bold" onClick={onClick}>{label}</button>);
}
export default TextField;

View file

@ -0,0 +1,28 @@
import React from "react";
interface InputTextProps {
label?: string;
inputType?: 'text' | 'password';
value?: string;
id?: string;
name?: string;
disabled?: boolean;
onChange?: (value: string) => void;
}
const TextField: React.FC<InputTextProps> = ({ inputType = 'text', label = '', name, value, onChange }) => {
return (<div className="flex flex-col">
{label && (<div className={`font-semibold text-black`}>
{label}
</div>)}
<input
type={inputType}
name={name}
value={value}
onChange={(e) => onChange?.(e.target.value)}
className="text-black-1 border disabled:!bg-gray-2 disabled:!border-gray-2 rounded-lg h-10 p-2"
/>
</div>);
}
export default TextField;

View file

@ -0,0 +1,25 @@
import api from '../../auth/axiosInstance';
export default function HomePage() {
return (
<div className='flex flex-col gap-4'>
<p>Welcome to Fediswald!</p>
<p>
<Protected />
</p>
</div>
);
}
function Protected() {
const callAPI = async () => {
try {
const res = await api.get('/protected');
alert(res.data.message);
} catch {
alert('Unauthorized');
}
};
return <button onClick={callAPI}>Call Protected Route</button>;
}

View file

@ -0,0 +1,52 @@
import { useState } from 'react';
import { useAuthStore } from '../../auth/authStore';
/* Components */
import TextField from '../inputs/TextField';
import Button from '../inputs/Button';
export default function LoginPage() {
const setAccessToken = useAuthStore((s) => s.setAccessToken);
const [email, _email] = useState('');
const [password, _password] = useState('');
const login = async () => {
const res = await fetch(`${import.meta.env.VITE_SERVER}/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
email,
password,
}),
});
const data = await res.json();
setAccessToken(data.accessToken);
};
return (<div className="flex flex-col grow max-h-screen overflow-hidden p-10">
<main className="flex flex-col grow h-full w-1/3">
<TextField
label='E-mail'
name="email"
value={email}
onChange={_email}
/>
<TextField
label='Password'
inputType="password"
name="password"
value={password}
onChange={_password}
/>
<div>
<Button onClick={login} label="Login" />
</div>
</main>
</div>
);
}

View file

@ -0,0 +1,25 @@
import { Outlet } from "react-router";
import { NavLink } from "react-router";
import { logout } from '../../auth/auth-utils';
export default function TemplatePage() {
return (<div className="flex flex-col grow max-h-screen overflow-hidden">
<div className="flex justify-between p-md bg-white border-b border-gray-2 py-2 px-5">
{/* <img src={logo} alt="Fediswald" className="h-lg w-lg" /> */}
<div className="flex gap-lg">
<NavLink to="/" end>
Home
</NavLink>
</div>
<div className="flex gap-sm border-gray-2 pl-sm">
{/* <div>{user.name}</div> */}
<button onClick={logout}>Logout</button>
</div>
</div>
<main className="flex grow h-full p-5">
<Outlet />
</main>
</div>)
}

View file

@ -1,5 +1,5 @@
import { StrictMode } from 'react'; import { StrictMode } from 'react';
import { BrowserRouter } from 'react-router-dom'; import { BrowserRouter } from 'react-router';
import * as ReactDOM from 'react-dom/client'; import * as ReactDOM from 'react-dom/client';
import App from './App'; import App from './App';

269
package-lock.json generated
View file

@ -21,7 +21,7 @@
"pg": "^8.14.1", "pg": "^8.14.1",
"react": "19.0.0", "react": "19.0.0",
"react-dom": "19.0.0", "react-dom": "19.0.0",
"react-router-dom": "6.29.0", "react-router": "^7.5.2",
"zod": "^3.24.2", "zod": "^3.24.2",
"zustand": "^5.0.3" "zustand": "^5.0.3"
}, },
@ -3119,9 +3119,9 @@
} }
}, },
"node_modules/@eslint-community/eslint-utils": { "node_modules/@eslint-community/eslint-utils": {
"version": "4.5.1", "version": "4.6.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz",
"integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
@ -3164,9 +3164,9 @@
} }
}, },
"node_modules/@eslint/config-array": { "node_modules/@eslint/config-array": {
"version": "0.19.2", "version": "0.20.0",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz",
"integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true, "peer": true,
@ -3206,9 +3206,9 @@
} }
}, },
"node_modules/@eslint/config-helpers": { "node_modules/@eslint/config-helpers": {
"version": "0.2.0", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz",
"integrity": "sha512-yJLLmLexii32mGrhW29qvU3QBVTu0GUmEf/J4XsBtVhp4JkIUFN/BjWqTF63yRvGApIDpZm5fa97LtYtINmfeQ==", "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true, "peer": true,
@ -3217,9 +3217,9 @@
} }
}, },
"node_modules/@eslint/core": { "node_modules/@eslint/core": {
"version": "0.12.0", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz",
"integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true, "peer": true,
@ -3296,9 +3296,9 @@
} }
}, },
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "9.23.0", "version": "9.25.1",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.1.tgz",
"integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", "integrity": "sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
@ -3318,14 +3318,14 @@
} }
}, },
"node_modules/@eslint/plugin-kit": { "node_modules/@eslint/plugin-kit": {
"version": "0.2.7", "version": "0.2.8",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz",
"integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@eslint/core": "^0.12.0", "@eslint/core": "^0.13.0",
"levn": "^0.4.1" "levn": "^0.4.1"
}, },
"engines": { "engines": {
@ -5798,15 +5798,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@remix-run/router": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.22.0.tgz",
"integrity": "sha512-MBOl8MeOzpK0HQQQshKB7pABXbmyHizdTpqnrIseTbsv0nAepwC2ENZa1aaBExNQcpLoXmWthhak8SABLzvGPw==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.38.0", "version": "4.38.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.38.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.38.0.tgz",
@ -6088,28 +6079,28 @@
] ]
}, },
"node_modules/@rspack/binding": { "node_modules/@rspack/binding": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.3.7.tgz",
"integrity": "sha512-MqXxbU5ei/xem+Ier48x0/IfJSpfBVbmB/FlziM59wF+mP8DYsMskr7sapN5YfeBhcfelKOtr9hERXRv/p1k2Q==", "integrity": "sha512-jSXLktIGmNNZssxT+fjZ31IyUO7lRoFrFO+XuqKlMpbnHE8yCrpaHE6rLyDPVO4Vnl6xx/df8usUXtZwIc4jrw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"optionalDependencies": { "optionalDependencies": {
"@rspack/binding-darwin-arm64": "1.3.0", "@rspack/binding-darwin-arm64": "1.3.7",
"@rspack/binding-darwin-x64": "1.3.0", "@rspack/binding-darwin-x64": "1.3.7",
"@rspack/binding-linux-arm64-gnu": "1.3.0", "@rspack/binding-linux-arm64-gnu": "1.3.7",
"@rspack/binding-linux-arm64-musl": "1.3.0", "@rspack/binding-linux-arm64-musl": "1.3.7",
"@rspack/binding-linux-x64-gnu": "1.3.0", "@rspack/binding-linux-x64-gnu": "1.3.7",
"@rspack/binding-linux-x64-musl": "1.3.0", "@rspack/binding-linux-x64-musl": "1.3.7",
"@rspack/binding-win32-arm64-msvc": "1.3.0", "@rspack/binding-win32-arm64-msvc": "1.3.7",
"@rspack/binding-win32-ia32-msvc": "1.3.0", "@rspack/binding-win32-ia32-msvc": "1.3.7",
"@rspack/binding-win32-x64-msvc": "1.3.0" "@rspack/binding-win32-x64-msvc": "1.3.7"
} }
}, },
"node_modules/@rspack/binding-darwin-arm64": { "node_modules/@rspack/binding-darwin-arm64": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.3.7.tgz",
"integrity": "sha512-AexGJ+PBTIURvXzMG/aQILTCB+D5HocmwWLw5jNq1DFVpgb7GX+3ZW3s2MBa8K+3JNeNgRiGcHyYcSV0l1dIfQ==", "integrity": "sha512-/5k4H0M7vvu7uorhc0OQKdQ7ybcjcJA//ptfYB646Ca/XY8FI1T/H88prPNrLNu97FGqUT4QWo5AHj01XymfDw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -6122,9 +6113,9 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/binding-darwin-x64": { "node_modules/@rspack/binding-darwin-x64": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.3.7.tgz",
"integrity": "sha512-LPzsI2VVwhn9Y88BOE4a0lICH4Jp3zLpNzJjDwMeDANJJ6MLmGbEBAxxRxo0adPG2sWhW7/RKU+ISVhu09aZtw==", "integrity": "sha512-/eNcZFDHxo5RVmIxgVM5zxCXmufeWpvviWJMDjhycS175nJb6103YWpu6H0lHgbj0GnHM/Q2VjVRFNhaGbXqdA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -6137,9 +6128,9 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/binding-linux-arm64-gnu": { "node_modules/@rspack/binding-linux-arm64-gnu": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.3.7.tgz",
"integrity": "sha512-acj5ikpIvkjy1sEV818RL+tK+EYvj1/g0jBqfttuCdczMMDzb1ciGEOHIuqONCMNdoCpieYnGt65rRwSS7NVHQ==", "integrity": "sha512-bSxA4MgGOdSvf/nTqNMuLeeyWS4Okh1iPskGuyAv/Sdf7cGbflUyZe6+w7A9BZEFR0CVTfj3f8kt73N+lu72Kg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -6152,9 +6143,9 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/binding-linux-arm64-musl": { "node_modules/@rspack/binding-linux-arm64-musl": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.3.7.tgz",
"integrity": "sha512-8BVoZTmxreQXSoSfUObydaVjVxYUReTZMpdmLTaewBs2KaoZEC8RvddLbEupiLie23Wwz02WDAiSUG1+zuCi5Q==", "integrity": "sha512-i6QK6YodCA5R8/ShRylkyunwvNcRx/Q7af14jSCa7TPOi6pPoDUL2pmwGcJBk1uPc2wjQwAMZzfJjTWNjEyW2Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -6167,9 +6158,9 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/binding-linux-x64-gnu": { "node_modules/@rspack/binding-linux-x64-gnu": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.3.7.tgz",
"integrity": "sha512-8QC553EczUmeVtr5Dqc+TocStYoKHbT6CFRb52sqaLOhka6r/zgchvKYmji+51gohfD5f0gtqjkb2pLWGPHE7w==", "integrity": "sha512-6AmOHLOv4XAK7Y5cFDBtnetIZ44MqG8Q6wZ20zjql/khTxsRZa/edis/eUppGb8fy5gzi+qqSAznEZ+Qj3LMrQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -6182,9 +6173,9 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/binding-linux-x64-musl": { "node_modules/@rspack/binding-linux-x64-musl": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.3.7.tgz",
"integrity": "sha512-Zi4vUONm94iN5oO6k8yc7a7AP4H24qesG8J4wNnByZIcSuhFeXhQbkEF+45BY/Kw4HB5K2gU/Oqd+kVlRwqIuQ==", "integrity": "sha512-rPt0c9UHp5AxWHhjziEtd2uwiWyzM4UZLFJV6hawBWOoIQf2uLSl3fp0HTqxpslfTh3uo5ymhHN/bV48m5THzg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -6197,9 +6188,9 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/binding-win32-arm64-msvc": { "node_modules/@rspack/binding-win32-arm64-msvc": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.3.7.tgz",
"integrity": "sha512-H6Q3WgLxkHFxxdasQ1MtlbWesyLGT+lr6gMW7Hc3nIl5QOJEcLvwF8OBOR8Di092uvDOyIRSwkUtnkI/tQV8UA==", "integrity": "sha512-+Db7NGBzad1dCcSm94uARkIIhbVv1+BXAl1duLBnYQMfqsu/pirsInE9wbp7WVUbSl2hmdRi9MYgWACjoReo4g==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -6212,9 +6203,9 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/binding-win32-ia32-msvc": { "node_modules/@rspack/binding-win32-ia32-msvc": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.3.7.tgz",
"integrity": "sha512-oQEtxVylcKLNFPlzegPkyuBwXg8bKMD4FGrUOwE7Tp/NtI42uhD9kIY+W/U4tLFhIz1bGApdYRdJH71Kl+jBpw==", "integrity": "sha512-VPqqC0U6FolGoonmZYBBiFyWjQ4+X+e/l/t4QZP2DRonlpE418+MdCxq2ldVGgvtxwERNlz61zxEX9yh/8KOfw==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -6227,9 +6218,9 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/binding-win32-x64-msvc": { "node_modules/@rspack/binding-win32-x64-msvc": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.3.7.tgz",
"integrity": "sha512-vND1d0sAbEfYjkW2H9eOfgO49dYFPTbkN4M7va+SSOI+Gqa4zMqHNg1kcoC5jWEvek6RFSheD1100RiJliLPBg==", "integrity": "sha512-zi9tKxlq85lSYTb1sbEluLjZlkbjuoJoy2TaNzVlfNkmiJ6EiqBbyCWoPPBJRP6HQ9pG25W0y4NWKp7iVhiBvg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -6242,97 +6233,93 @@
"peer": true "peer": true
}, },
"node_modules/@rspack/core": { "node_modules/@rspack/core": {
"version": "1.3.0", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.3.7.tgz",
"integrity": "sha512-7WZdw8EaEy/TlySn46Xgg9qMPoZBA4uTQR+nxgomAA0u9s/31VYFDpPsLIc/uT8OGemGU2kydgAgu9A6Gyp0GQ==", "integrity": "sha512-InXnEmImLKkxzkY7XaAozycjMvS5myf/o3zu1rw5tNq3ONxWvW0QOHVTcrF0FbeKQ/jCOFSfdaoFjbXjdUs38w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@module-federation/runtime-tools": "0.11.1", "@module-federation/runtime-tools": "0.13.0",
"@rspack/binding": "1.3.0", "@rspack/binding": "1.3.7",
"@rspack/lite-tapable": "1.0.1", "@rspack/lite-tapable": "1.0.1",
"caniuse-lite": "^1.0.30001706" "caniuse-lite": "^1.0.30001715"
}, },
"engines": { "engines": {
"node": ">=16.0.0" "node": ">=16.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"@rspack/tracing": "^1.x",
"@swc/helpers": ">=0.5.1" "@swc/helpers": ">=0.5.1"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@rspack/tracing": {
"optional": true
},
"@swc/helpers": { "@swc/helpers": {
"optional": true "optional": true
} }
} }
}, },
"node_modules/@rspack/core/node_modules/@module-federation/error-codes": { "node_modules/@rspack/core/node_modules/@module-federation/error-codes": {
"version": "0.11.1", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.11.1.tgz", "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.13.0.tgz",
"integrity": "sha512-N1cs1qwrO8cU/OzfnBbr+3FaVbrJk6QEAsQ8H+YxGRrh/kHsR2BKpZCX79jTG27oDbz45FLjQ98YucMMXC24EA==", "integrity": "sha512-4soAMLr7qcVWuvCsyRmBbiBfuhxmnDeyl+qzjMx8VurQgL+XQDQJapM9RXngNGT4g8FoCq9o7rM5YWNgFFNUiw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true "peer": true
}, },
"node_modules/@rspack/core/node_modules/@module-federation/runtime": { "node_modules/@rspack/core/node_modules/@module-federation/runtime": {
"version": "0.11.1", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.11.1.tgz", "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.13.0.tgz",
"integrity": "sha512-yxxa/TRXaNggb34N+oL82J7r9+GZ3gYTCDyGibYqtsC5j7+9oB4tmc0UyhjrGMhg+fF8TAWFZjNKo7ZnyN9LcQ==", "integrity": "sha512-Ne/3AEVWz6LL6G/i41O5MC6YYlg0SatNNqG/0XbuMAfyGM+llRmB6VKt0o2+JR4isxWuPNp97TbUkkfORit6Eg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@module-federation/error-codes": "0.11.1", "@module-federation/error-codes": "0.13.0",
"@module-federation/runtime-core": "0.11.1", "@module-federation/runtime-core": "0.13.0",
"@module-federation/sdk": "0.11.1" "@module-federation/sdk": "0.13.0"
} }
}, },
"node_modules/@rspack/core/node_modules/@module-federation/runtime-core": { "node_modules/@rspack/core/node_modules/@module-federation/runtime-core": {
"version": "0.11.1", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.11.1.tgz", "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.13.0.tgz",
"integrity": "sha512-6KxLfkCl05Ey69Xg/dsjf7fPit9qGXZ0lpwaG2agiCqC3JCDxYjT7tgGvnWhTXCcztb/ThpT+bHrRD4Kw8SMhA==", "integrity": "sha512-Oj/1p0mfxZ+8EbU7ND4gMvRmikFpIvPCbblOgat9N8ZIVAKYpTimCgMhzg4yRqAwzlGCVwnnW7XZ8UlA+Zqrvg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@module-federation/error-codes": "0.11.1", "@module-federation/error-codes": "0.13.0",
"@module-federation/sdk": "0.11.1" "@module-federation/sdk": "0.13.0"
} }
}, },
"node_modules/@rspack/core/node_modules/@module-federation/runtime-tools": { "node_modules/@rspack/core/node_modules/@module-federation/runtime-tools": {
"version": "0.11.1", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.11.1.tgz", "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.13.0.tgz",
"integrity": "sha512-8UqMbHJSdkEvKlnlXpR/OjMA77bUbhtmv0I4UO+PA1zBga4y3/St6NOjD66NTINKeWEgsCt1aepXHspduXp33w==", "integrity": "sha512-6ECWX18yGrQKcmkrQoNPd5VEpxZP1SMaB/Bp55xlpEhsrpn4zHnriQluxDw6xldjSOLl1qbokfxwCwjS2OaEbg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@module-federation/runtime": "0.11.1", "@module-federation/runtime": "0.13.0",
"@module-federation/webpack-bundler-runtime": "0.11.1" "@module-federation/webpack-bundler-runtime": "0.13.0"
} }
}, },
"node_modules/@rspack/core/node_modules/@module-federation/sdk": { "node_modules/@rspack/core/node_modules/@module-federation/sdk": {
"version": "0.11.1", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.1.tgz", "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.13.0.tgz",
"integrity": "sha512-QS6zevdQYLCGF6NFf0LysMGARh+dZxMeoRKKDUW5PYi3XOk+tjJ7QsDKybfcBZBNgBJfIuwxh4Oei6WOFJEfRg==", "integrity": "sha512-JdMZaPD+EQvMJYS+/8/8QjaAHQ3qljogvioXBsAuedcStu/msn5e1Fswc0G34kXY9ixs2hUPZU2cAllfSKWIBQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true "peer": true
}, },
"node_modules/@rspack/core/node_modules/@module-federation/webpack-bundler-runtime": { "node_modules/@rspack/core/node_modules/@module-federation/webpack-bundler-runtime": {
"version": "0.11.1", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.11.1.tgz", "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.13.0.tgz",
"integrity": "sha512-XlVegGyCBBLId8Jr6USjPOFYViQ0CCtoYjHpC8y1FOGtuXLGrvnEdFcl4XHlFlp3MY3Rxhr8QigrdZhYe5bRWg==", "integrity": "sha512-ycgAsFeCTo+3GR8JxkhCyg2UZm6Au98ISdLTdVXYphO4UDcO/KjqyJen1LXEslkpCEohDj68Prei2fUHRruK6g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@module-federation/runtime": "0.11.1", "@module-federation/runtime": "0.13.0",
"@module-federation/sdk": "0.11.1" "@module-federation/sdk": "0.13.0"
} }
}, },
"node_modules/@rspack/lite-tapable": { "node_modules/@rspack/lite-tapable": {
@ -8803,9 +8790,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001707", "version": "1.0.30001715",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz",
"integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", "integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -10266,21 +10253,21 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "9.23.0", "version": "9.25.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.1.tgz",
"integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", "integrity": "sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1", "@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.19.2", "@eslint/config-array": "^0.20.0",
"@eslint/config-helpers": "^0.2.0", "@eslint/config-helpers": "^0.2.1",
"@eslint/core": "^0.12.0", "@eslint/core": "^0.13.0",
"@eslint/eslintrc": "^3.3.1", "@eslint/eslintrc": "^3.3.1",
"@eslint/js": "9.23.0", "@eslint/js": "9.25.1",
"@eslint/plugin-kit": "^0.2.7", "@eslint/plugin-kit": "^0.2.8",
"@humanfs/node": "^0.16.6", "@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2", "@humanwhocodes/retry": "^0.4.2",
@ -15191,35 +15178,35 @@
} }
}, },
"node_modules/react-router": { "node_modules/react-router": {
"version": "6.29.0", "version": "7.5.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.29.0.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.2.tgz",
"integrity": "sha512-DXZJoE0q+KyeVw75Ck6GkPxFak63C4fGqZGNijnWgzB/HzSP1ZfTlBj5COaGWwhrMQ/R8bXiq5Ooy4KG+ReyjQ==", "integrity": "sha512-9Rw8r199klMnlGZ8VAsV/I8WrIF6IyJ90JQUdboupx1cdkgYqwnrYjH+I/nY/7cA1X5zia4mDJqH36npP7sxGQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@remix-run/router": "1.22.0" "cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0",
"turbo-stream": "2.4.0"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=20.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"react": ">=16.8" "react": ">=18",
"react-dom": ">=18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
} }
}, },
"node_modules/react-router-dom": { "node_modules/react-router/node_modules/cookie": {
"version": "6.29.0", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.29.0.tgz", "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
"integrity": "sha512-pkEbJPATRJ2iotK+wUwHfy0xs2T59YPEN8BQxVCPeBZvK7kfPESRc/nyxzdcxR17hXgUPYx2whMwl+eo9cUdnQ==", "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
"license": "MIT", "license": "MIT",
"dependencies": {
"@remix-run/router": "1.22.0",
"react-router": "6.29.0"
},
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=18"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
} }
}, },
"node_modules/read-cache": { "node_modules/read-cache": {
@ -15796,6 +15783,12 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/set-cookie-parser": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
"license": "MIT"
},
"node_modules/setimmediate": { "node_modules/setimmediate": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@ -16915,6 +16908,12 @@
"node": ">=0.6.x" "node": ">=0.6.x"
} }
}, },
"node_modules/turbo-stream": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
"integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
"license": "ISC"
},
"node_modules/type-check": { "node_modules/type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",

View file

@ -2,7 +2,10 @@
"name": "@fediswald/source", "name": "@fediswald/source",
"version": "0.0.0", "version": "0.0.0",
"license": "MIT", "license": "MIT",
"scripts": {}, "scripts": {
"backend": "npx nx serve backend",
"frontend": "npx nx serve frontend"
},
"private": true, "private": true,
"dependencies": { "dependencies": {
"@fedify/fedify": "^1.5.0", "@fedify/fedify": "^1.5.0",
@ -14,7 +17,7 @@
"pg": "^8.14.1", "pg": "^8.14.1",
"react": "19.0.0", "react": "19.0.0",
"react-dom": "19.0.0", "react-dom": "19.0.0",
"react-router-dom": "6.29.0", "react-router": "^7.5.2",
"zod": "^3.24.2", "zod": "^3.24.2",
"zustand": "^5.0.3" "zustand": "^5.0.3"
}, },