refactor: data fetching for the public paste page
This includes changing routing to use createBrowserRouter and createRoutesFromElements which includes the use of the loader function.
This commit is contained in:
parent
ec87692ff3
commit
5851a41fce
@ -3,3 +3,4 @@ node_modules
|
||||
example_request_do.log
|
||||
bin/
|
||||
.git
|
||||
hemmelig.backup.db
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -122,3 +122,4 @@ prisma_test.js
|
||||
database/
|
||||
data/
|
||||
.vscode
|
||||
hemmelig.backup.db
|
@ -6,3 +6,4 @@ config/
|
||||
public/
|
||||
.github/
|
||||
tests/
|
||||
hemmelig.backup.db
|
62
package-lock.json
generated
62
package-lock.json
generated
@ -40,6 +40,7 @@
|
||||
"node-fetch": "^2.6.7",
|
||||
"pretty-bytes": "^4.0.2",
|
||||
"react-qr-code": "^2.0.8",
|
||||
"react-router-dom": "^6.21.3",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"tweetnacl": "^0.14.5",
|
||||
"tweetnacl-util": "^0.15.1",
|
||||
@ -75,7 +76,6 @@
|
||||
"react-i18next": "^11.18.5",
|
||||
"react-quill": "^2.0.0",
|
||||
"react-redux": "^7.2.5",
|
||||
"react-router-dom": "^6.10.0",
|
||||
"redux": "^4.1.1",
|
||||
"vite": "^4.2.1"
|
||||
}
|
||||
@ -2431,12 +2431,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz",
|
||||
"integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==",
|
||||
"dev": true,
|
||||
"version": "1.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz",
|
||||
"integrity": "sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/abort-controller": {
|
||||
@ -7084,31 +7083,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
|
||||
"integrity": "sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==",
|
||||
"dev": true,
|
||||
"version": "6.21.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.3.tgz",
|
||||
"integrity": "sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.5.0"
|
||||
"@remix-run/router": "1.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.10.0.tgz",
|
||||
"integrity": "sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==",
|
||||
"dev": true,
|
||||
"version": "6.21.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.3.tgz",
|
||||
"integrity": "sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.5.0",
|
||||
"react-router": "6.10.0"
|
||||
"@remix-run/router": "1.14.2",
|
||||
"react-router": "6.21.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
@ -10469,10 +10466,9 @@
|
||||
}
|
||||
},
|
||||
"@remix-run/router": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz",
|
||||
"integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==",
|
||||
"dev": true
|
||||
"version": "1.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz",
|
||||
"integrity": "sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg=="
|
||||
},
|
||||
"@smithy/abort-controller": {
|
||||
"version": "2.0.13",
|
||||
@ -13871,22 +13867,20 @@
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
|
||||
"integrity": "sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==",
|
||||
"dev": true,
|
||||
"version": "6.21.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.3.tgz",
|
||||
"integrity": "sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==",
|
||||
"requires": {
|
||||
"@remix-run/router": "1.5.0"
|
||||
"@remix-run/router": "1.14.2"
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.10.0.tgz",
|
||||
"integrity": "sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==",
|
||||
"dev": true,
|
||||
"version": "6.21.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.3.tgz",
|
||||
"integrity": "sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==",
|
||||
"requires": {
|
||||
"@remix-run/router": "1.5.0",
|
||||
"react-router": "6.10.0"
|
||||
"@remix-run/router": "1.14.2",
|
||||
"react-router": "6.21.3"
|
||||
}
|
||||
},
|
||||
"react-style-singleton": {
|
||||
|
@ -65,6 +65,7 @@
|
||||
"node-fetch": "^2.6.7",
|
||||
"pretty-bytes": "^4.0.2",
|
||||
"react-qr-code": "^2.0.8",
|
||||
"react-router-dom": "^6.21.3",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"tweetnacl": "^0.14.5",
|
||||
"tweetnacl-util": "^0.15.1",
|
||||
@ -97,7 +98,6 @@
|
||||
"react-i18next": "^11.18.5",
|
||||
"react-quill": "^2.0.0",
|
||||
"react-redux": "^7.2.5",
|
||||
"react-router-dom": "^6.10.0",
|
||||
"redux": "^4.1.1",
|
||||
"vite": "^4.2.1"
|
||||
},
|
||||
|
@ -1,54 +1,52 @@
|
||||
import { MantineProvider } from '@mantine/core';
|
||||
import { ModalsProvider } from '@mantine/modals';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import AppRoutes from './routes.jsx';
|
||||
import { RouterProvider } from 'react-router-dom';
|
||||
import appRouter from './routes.jsx';
|
||||
|
||||
const HemmeligApplication = () => {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<MantineProvider
|
||||
withGlobalStyles
|
||||
withNormalizeCSS
|
||||
theme={{
|
||||
colorScheme: 'dark',
|
||||
colors: {
|
||||
hemmelig: [
|
||||
'#ffffff',
|
||||
'#eaf5f4',
|
||||
'#d4ebe9',
|
||||
'#bfe2dd',
|
||||
'#aad8d2',
|
||||
'#95cec7',
|
||||
'#7fc4bc',
|
||||
'#6abab1',
|
||||
'#55b1a5',
|
||||
'#3fa79a',
|
||||
'#2a9d8f',
|
||||
],
|
||||
'hemmelig-orange': [
|
||||
'#ffffff',
|
||||
'#fff5f0',
|
||||
'#ffeae1',
|
||||
'#ffe0d2',
|
||||
'#ffd5c3',
|
||||
'#ffcbb4',
|
||||
'#ffc1a5',
|
||||
'#ffb696',
|
||||
'#ffac87',
|
||||
'#ffa178',
|
||||
'#ff9769',
|
||||
],
|
||||
},
|
||||
fontFamily: 'Inter, sans-serif',
|
||||
fontFamilyMonospace: 'Inter, sans-serif',
|
||||
headings: { fontFamily: 'Inter, sans-serif' },
|
||||
}}
|
||||
>
|
||||
<ModalsProvider>
|
||||
<AppRoutes />
|
||||
</ModalsProvider>
|
||||
</MantineProvider>
|
||||
</BrowserRouter>
|
||||
<MantineProvider
|
||||
withGlobalStyles
|
||||
withNormalizeCSS
|
||||
theme={{
|
||||
colorScheme: 'dark',
|
||||
colors: {
|
||||
hemmelig: [
|
||||
'#ffffff',
|
||||
'#eaf5f4',
|
||||
'#d4ebe9',
|
||||
'#bfe2dd',
|
||||
'#aad8d2',
|
||||
'#95cec7',
|
||||
'#7fc4bc',
|
||||
'#6abab1',
|
||||
'#55b1a5',
|
||||
'#3fa79a',
|
||||
'#2a9d8f',
|
||||
],
|
||||
'hemmelig-orange': [
|
||||
'#ffffff',
|
||||
'#fff5f0',
|
||||
'#ffeae1',
|
||||
'#ffe0d2',
|
||||
'#ffd5c3',
|
||||
'#ffcbb4',
|
||||
'#ffc1a5',
|
||||
'#ffb696',
|
||||
'#ffac87',
|
||||
'#ffa178',
|
||||
'#ff9769',
|
||||
],
|
||||
},
|
||||
fontFamily: 'Inter, sans-serif',
|
||||
fontFamilyMonospace: 'Inter, sans-serif',
|
||||
headings: { fontFamily: 'Inter, sans-serif' },
|
||||
}}
|
||||
>
|
||||
<ModalsProvider>
|
||||
<RouterProvider router={appRouter}></RouterProvider>
|
||||
</ModalsProvider>
|
||||
</MantineProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { lazy } from 'react';
|
||||
import { Route, Routes } from 'react-router-dom';
|
||||
import { Route, createBrowserRouter, createRoutesFromElements } from 'react-router-dom';
|
||||
import AdminShell from './admin-shell.jsx';
|
||||
import ApplicationShell from './app-shell.jsx';
|
||||
|
||||
@ -18,21 +18,29 @@ const Settings = lazy(() => import('./routes/account/settings'));
|
||||
const Users = lazy(() => import('./routes/account/users'));
|
||||
const UserAccount = lazy(() => import('./routes/account/account'));
|
||||
|
||||
const AppRoutes = () => {
|
||||
return (
|
||||
<Routes>
|
||||
// loader: https://reactrouter.com/en/main/route/loader
|
||||
const appRouter = createBrowserRouter(
|
||||
createRoutesFromElements(
|
||||
<>
|
||||
<Route path="/" element={<ApplicationShell />}>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="secret/:encryptionKey/:secretId" element={<Secret />} />
|
||||
<Route path="secret/:secretId" element={<Secret />} />
|
||||
<Route path="public" element={<PublicSecrets />} />
|
||||
<Route
|
||||
element={<PublicSecrets />}
|
||||
path="public"
|
||||
loader={async () => {
|
||||
const { getPublicSecrets } = await import('./api/secret');
|
||||
|
||||
return await getPublicSecrets();
|
||||
}}
|
||||
/>
|
||||
<Route path="signin" element={<SignIn />} />
|
||||
<Route path="signup" element={<SignUp />} />
|
||||
<Route path="signout" element={<SignOut />} />
|
||||
<Route path="privacy" element={<Privacy />} />
|
||||
<Route path="terms" element={<Terms />} />
|
||||
</Route>
|
||||
|
||||
<Route path="/account" element={<AdminShell />}>
|
||||
<Route index element={<Account />} />
|
||||
<Route path="account" element={<Account />} />
|
||||
@ -43,8 +51,8 @@ const AppRoutes = () => {
|
||||
<Route path="privacy" element={<Privacy />} />
|
||||
<Route path="terms" element={<Terms />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
</>
|
||||
)
|
||||
);
|
||||
|
||||
export default AppRoutes;
|
||||
export default appRouter;
|
||||
|
@ -1,29 +1,15 @@
|
||||
import { Anchor, Container, Group, Loader, Stack, Table, Title } from '@mantine/core';
|
||||
import { Anchor, Container, Group, Stack, Table, Title } from '@mantine/core';
|
||||
import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { getPublicSecrets } from '../../api/secret';
|
||||
import { Link, useLoaderData } from 'react-router-dom';
|
||||
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
const PublicSecrets = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [secrets, setPublicSecrets] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const secrets = await getPublicSecrets();
|
||||
|
||||
setPublicSecrets(secrets);
|
||||
|
||||
setIsLoading(false);
|
||||
})();
|
||||
}, []);
|
||||
const secrets = useLoaderData();
|
||||
|
||||
const getTime = (expiresAt) => {
|
||||
return dayjs().to(dayjs(expiresAt));
|
||||
@ -46,14 +32,6 @@ const PublicSecrets = () => {
|
||||
</tr>
|
||||
));
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Container>
|
||||
<Loader color="teal" variant="bars" />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Stack>
|
||||
|
@ -236,7 +236,7 @@ async function secret(fastify) {
|
||||
});
|
||||
|
||||
if (!data?.length) {
|
||||
return reply.code(404).send({ error: 'Public pastes not found' });
|
||||
return reply.code(204).send([]);
|
||||
}
|
||||
|
||||
return data.map((secret) => ({
|
||||
|
Loading…
x
Reference in New Issue
Block a user