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:
bjarneo 2024-01-28 10:03:47 +01:00
parent ec87692ff3
commit 5851a41fce
No known key found for this signature in database
GPG Key ID: AA3697C46F530672
9 changed files with 100 additions and 119 deletions

View File

@ -3,3 +3,4 @@ node_modules
example_request_do.log
bin/
.git
hemmelig.backup.db

1
.gitignore vendored
View File

@ -122,3 +122,4 @@ prisma_test.js
database/
data/
.vscode
hemmelig.backup.db

View File

@ -6,3 +6,4 @@ config/
public/
.github/
tests/
hemmelig.backup.db

62
package-lock.json generated
View File

@ -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": {

View File

@ -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"
},

View File

@ -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>
);
};

View File

@ -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;

View File

@ -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>

View File

@ -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) => ({