refactor: redux -> recoil

This commit is contained in:
diced 2022-10-01 11:08:51 -07:00
parent d236589644
commit d4369d2503
No known key found for this signature in database
GPG key ID: 370BD1BA142842D1
27 changed files with 103 additions and 227 deletions

View file

@ -31,7 +31,6 @@
"@prisma/client": "^4.1.0",
"@prisma/internals": "^4.1.0",
"@prisma/migrate": "^4.1.0",
"@reduxjs/toolkit": "^1.8.2",
"@tanstack/react-query": "^4.2.3",
"argon2": "^0.28.5",
"chart.js": "^3.9.1",
@ -53,8 +52,7 @@
"react-chartjs-2": "^4.3.1",
"react-dom": "^18.2.0",
"react-feather": "^2.0.10",
"react-redux": "^8.0.2",
"redux": "^4.2.0",
"recoil": "^0.7.5",
"sharp": "^0.30.7",
"yup": "^0.32.11"
},

View file

@ -4,11 +4,11 @@ import { useModals } from '@mantine/modals';
import { showNotification } from '@mantine/notifications';
import useFetch from 'hooks/useFetch';
import { useVersion } from 'lib/queries/version';
import { updateUser } from 'lib/redux/reducers/user';
import { useStoreDispatch } from 'lib/redux/store';
import { userSelector } from 'lib/recoil/user';
import { useRecoilState } from 'recoil';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { ExternalLinkIcon, ActivityIcon, CheckIcon, CopyIcon, CrossIcon, DeleteIcon, FileIcon, HomeIcon, LinkIcon, LogoutIcon, PencilIcon, SettingsIcon, TagIcon, TypeIcon, UploadIcon, UserIcon } from './icons';
import { friendlyThemeName, themes } from './Theming';
@ -109,20 +109,20 @@ const admin_items = [
},
];
export default function Layout({ children, user, props }) {
export default function Layout({ children, props }) {
const [user, setUser] = useRecoilState(userSelector);
const { title } = props;
const external_links = JSON.parse(props.external_links ?? '[]');
const [token, setToken] = useState(user?.token);
const [systemTheme, setSystemTheme] = useState(user.systemTheme ?? 'system');
// const [version, setVersion] = useState<{ local: string, upstream: string }>(null);
const version = useVersion();
const [opened, setOpened] = useState(false); // navigation open
const [open, setOpen] = useState(false); // manage acc dropdown
const avatar = user?.avatar ?? null;
const router = useRouter();
const dispatch = useStoreDispatch();
const theme = useMantineTheme();
const modals = useModals();
const clipboard = useClipboard();
@ -133,7 +133,7 @@ export default function Layout({ children, user, props }) {
});
setSystemTheme(newUser.systemTheme);
dispatch(updateUser(newUser));
setUser(newUser);
router.replace(router.pathname);
showNotification({

View file

@ -16,7 +16,8 @@ import { MantineProvider, MantineThemeOverride } from '@mantine/core';
import { useColorScheme } from '@mantine/hooks';
import { ModalsProvider } from '@mantine/modals';
import { NotificationsProvider } from '@mantine/notifications';
import { useStoreSelector } from 'lib/redux/store';
import { useRecoilValue } from 'recoil';
import { userSelector } from 'lib/recoil/user';
export const themes = {
system: (colorScheme: 'dark' | 'light') => colorScheme === 'dark' ? dark_blue : light_blue,
@ -47,7 +48,7 @@ export const friendlyThemeName = {
};
export default function ZiplineTheming({ Component, pageProps, ...props }) {
const user = useStoreSelector(state => state.user);
const user = useRecoilValue(userSelector);
const colorScheme = useColorScheme();
let theme: MantineThemeOverride;

View file

@ -8,12 +8,13 @@ import MutedText from 'components/MutedText';
import useFetch from 'lib/hooks/useFetch';
import { useFiles, useRecent } from 'lib/queries/files';
import { useStats } from 'lib/queries/stats';
import { useStoreSelector } from 'lib/redux/store';
import { userSelector } from 'lib/recoil/user';
import { useRecoilValue } from 'recoil';
import RecentFiles from './RecentFiles';
import { StatCards } from './StatCards';
export default function Dashboard() {
const user = useStoreSelector(state => state.user);
const user = useRecoilValue(userSelector);
const theme = useMantineTheme();
const images = useFiles();

View file

@ -9,10 +9,10 @@ import Link from 'components/Link';
import MutedText from 'components/MutedText';
import { SmallTable } from 'components/SmallTable';
import useFetch from 'hooks/useFetch';
import { userSelector } from 'lib/recoil/user';
import { bytesToRead } from 'lib/utils/client';
import { updateUser } from 'lib/redux/reducers/user';
import { useStoreDispatch, useStoreSelector } from 'lib/redux/store';
import { useEffect, useState } from 'react';
import { useRecoilState } from 'recoil';
import Flameshot from './Flameshot';
import ShareX from './ShareX';
@ -21,8 +21,7 @@ function ExportDataTooltip({ children }) {
}
export default function Manage() {
const user = useStoreSelector(state => state.user);
const dispatch = useStoreDispatch();
const [user, setUser] = useRecoilState(userSelector);
const modals = useModals();
const [shareXOpen, setShareXOpen] = useState(false);
@ -77,7 +76,7 @@ export default function Manage() {
icon: <CrossIcon />,
});
} else {
dispatch(updateUser(newUser));
setUser(newUser);
updateNotification({
id: 'update-user',
title: 'Saved User',
@ -150,7 +149,7 @@ export default function Manage() {
icon: <CrossIcon />,
});
} else {
dispatch(updateUser(newUser));
setUser(newUser);
updateNotification({
id: 'update-user',
title: 'Saved User',

View file

@ -6,8 +6,9 @@ import FileDropzone from 'components/dropzone/DropzoneFile';
import { ClockIcon, CrossIcon, UploadIcon } from 'components/icons';
import Link from 'components/Link';
import { invalidateFiles } from 'lib/queries/files';
import { useStoreSelector } from 'lib/redux/store';
import { userSelector } from 'lib/recoil/user';
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
const expires = [
'5min',
@ -42,7 +43,7 @@ const expires = [
export default function Upload() {
const clipboard = useClipboard();
const user = useStoreSelector(state => state.user);
const user = useRecoilValue(userSelector);
const [files, setFiles] = useState([]);
const [progress, setProgress] = useState(0);

View file

@ -4,11 +4,12 @@ import CodeInput from 'components/CodeInput';
import { TypeIcon, UploadIcon } from 'components/icons';
import Link from 'components/Link';
import exts from 'lib/exts';
import { useStoreSelector } from 'lib/redux/store';
import { userSelector } from 'lib/recoil/user';
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
export default function Upload() {
const user = useStoreSelector(state => state.user);
const user = useRecoilValue(userSelector);
const [value, setValue] = useState('');
const [lang, setLang] = useState('txt');

View file

@ -2,14 +2,15 @@ import { ActionIcon, Button, Group, Modal, SimpleGrid, Skeleton, TextInput, Titl
import { useForm } from '@mantine/form';
import { showNotification } from '@mantine/notifications';
import { CrossIcon, LinkIcon, PlusIcon } from 'components/icons';
import { useStoreSelector } from 'lib/redux/store';
import { useEffect, useState } from 'react';
import { useURLs } from 'lib/queries/url';
import URLCard from './URLCard';
import MutedText from 'components/MutedText';
import { useRecoilValue } from 'recoil';
import { userSelector } from 'lib/recoil/user';
export default function Urls() {
const user = useStoreSelector(state => state.user);
const user = useRecoilValue(userSelector);
const urls = useURLs();
const [createOpen, setCreateOpen] = useState(false);

View file

@ -5,9 +5,10 @@ import { showNotification } from '@mantine/notifications';
import { CrossIcon, DeleteIcon, PlusIcon } from 'components/icons';
import MutedText from 'components/MutedText';
import useFetch from 'hooks/useFetch';
import { useStoreSelector } from 'lib/redux/store';
import { userSelector } from 'lib/recoil/user';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
function CreateUserModal({ open, setOpen, updateUsers }) {
@ -73,7 +74,7 @@ function CreateUserModal({ open, setOpen, updateUsers }) {
}
export default function Users() {
const user = useStoreSelector(state => state.user);
const user = useRecoilValue(userSelector);
const router = useRouter();
const modals = useModals();

View file

@ -1,16 +1,13 @@
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { updateUser, User } from 'lib/redux/reducers/user';
import { useStoreDispatch, useStoreSelector } from 'lib/redux/store';
import { User, userState } from 'lib/recoil/user';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import useFetch from './useFetch';
export default function login() {
const router = useRouter();
const dispatch = useStoreDispatch();
const userState = useStoreSelector(s => s.user);
const [user, setUser] = useState<User>(userState);
const [loading, setLoading] = useState(!userState);
const [user, setUser] = useRecoilState(userState);
const [loading, setLoading] = useState(!user);
async function load() {
setLoading(true);
@ -18,7 +15,6 @@ export default function login() {
const res = await useFetch('/api/user');
if (res.error) return router.push('/auth/login?url=' + router.route);
dispatch(updateUser(res));
setUser(res);
setLoading(false);
}
@ -28,5 +24,5 @@ export default function login() {
load();
}, []);
return { loading, user };
return { loading };
}

24
src/lib/recoil/user.ts Normal file
View file

@ -0,0 +1,24 @@
import { atom, selector } from 'recoil';
export interface User {
username: string;
token: string;
embedTitle: string;
embedColor: string;
embedSiteName: string;
systemTheme: string;
domains: string[];
avatar?: string;
administrator: boolean;
}
export const userState = atom({
key: 'userState',
default: null as User,
});
export const userSelector = selector<User>({
key: 'userSelector',
get: ({ get }) => get(userState),
set: ({ set }, newValue) => set(userState, newValue),
});

View file

@ -1,4 +0,0 @@
import { combineReducers } from 'redux';
import user from './reducers/user';
export default combineReducers({ user });

View file

@ -1,29 +0,0 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
export interface User {
username: string;
token: string;
embedTitle: string;
embedColor: string;
embedSiteName: string;
systemTheme: string;
domains: string[];
avatar?: string;
}
const initialState: User = null;
const user = createSlice({
name: 'user',
initialState,
reducers: {
updateUser(state, action: PayloadAction<User>) {
state = action.payload;
return state;
},
},
});
export const { updateUser } = user.actions;
export default user.reducer;

View file

@ -1,13 +0,0 @@
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';
import { useDispatch, TypedUseSelectorHook, useSelector } from 'react-redux';
export const store = configureStore({
reducer: rootReducer,
});
export type AppState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
export const useStoreDispatch = () => useDispatch<AppDispatch>();
export const useStoreSelector: TypedUseSelectorHook<AppState> = useSelector;

View file

@ -1,14 +1,13 @@
import React from 'react';
import { Provider } from 'react-redux';
import Head from 'next/head';
import { store } from 'lib/redux/store';
import ZiplineTheming from 'components/Theming';
import { QueryClientProvider } from '@tanstack/react-query';
import queryClient from 'lib/queries/client';
import { RecoilRoot } from 'recoil';
export default function MyApp({ Component, pageProps }) {
return (
<Provider store={store}>
<RecoilRoot>
<Head>
<meta name='viewport' content='minimum-scale=1, initial-scale=1, width=device-width' />
</Head>
@ -17,6 +16,6 @@ export default function MyApp({ Component, pageProps }) {
>
<ZiplineTheming Component={Component} pageProps={pageProps} />
</QueryClientProvider>
</Provider>
</RecoilRoot>
);
}

View file

@ -1,11 +1,11 @@
import React, { useEffect } from 'react';
import { useRouter } from 'next/router';
import { LoadingOverlay } from '@mantine/core';
import { useStoreDispatch } from 'lib/redux/store';
import { updateUser } from 'lib/redux/reducers/user';
import { useSetRecoilState } from 'recoil';
import { userSelector } from 'lib/recoil/user';
export default function Logout() {
const dispatch = useStoreDispatch();
const setUser = useSetRecoilState(userSelector);
const router = useRouter();
useEffect(() => {
@ -14,7 +14,7 @@ export default function Logout() {
if (userRes.ok) {
const res = await fetch('/api/auth/logout');
if (res.ok) {
dispatch(updateUser(null));
setUser(null);
router.push('/auth/login');
}
} else {

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function FilesPage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -18,7 +18,6 @@ export default function FilesPage(props) {
</Head>
<Layout
user={user}
props={props}
>
<Files />

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function DashboardPage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -17,7 +17,6 @@ export default function DashboardPage(props) {
<title>{props.title}</title>
</Head>
<Layout
user={user}
props={props}
>
<Dashboard />

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function InvitesPage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -17,7 +17,6 @@ export default function InvitesPage(props) {
<title>{props.title} - Invites</title>
</Head>
<Layout
user={user}
props={props}
>
<Invites />

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function ManagePage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -17,7 +17,6 @@ export default function ManagePage(props) {
<title>{props.title} - Manage User</title>
</Head>
<Layout
user={user}
props={props}
>
<Manage />

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function StatsPage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -17,7 +17,6 @@ export default function StatsPage(props) {
<title>{props.title} - Stats</title>
</Head>
<Layout
user={user}
props={props}
>
<Stats />

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function UploadTextPage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -17,7 +17,6 @@ export default function UploadTextPage(props) {
<title>{props.title} - Upload Text</title>
</Head>
<Layout
user={user}
props={props}
>
<UploadText/>

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function UploadPage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -17,7 +17,6 @@ export default function UploadPage(props) {
<title>{props.title} - Upload</title>
</Head>
<Layout
user={user}
props={props}
>
<Upload />

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function UrlsPage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -17,7 +17,6 @@ export default function UrlsPage(props) {
<title>{props.title} - URLs</title>
</Head>
<Layout
user={user}
props={props}
>
<Urls />

View file

@ -7,7 +7,7 @@ import Head from 'next/head';
export { getServerSideProps } from 'middleware/getServerSideProps';
export default function UsersPage(props) {
const { user, loading } = useLogin();
const { loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
@ -17,7 +17,6 @@ export default function UsersPage(props) {
<title>{props.title} - Users</title>
</Head>
<Layout
user={user}
props={props}
>
<Users />

View file

@ -6,11 +6,11 @@ import useFetch from 'hooks/useFetch';
import PasswordStrength from 'components/PasswordStrength';
import { showNotification } from '@mantine/notifications';
import { CrossIcon, UserIcon } from 'components/icons';
import { useStoreDispatch } from 'lib/redux/store';
import { updateUser } from 'lib/redux/reducers/user';
import { useRouter } from 'next/router';
import Head from 'next/head';
import config from 'lib/config';
import { useSetRecoilState } from 'recoil';
import { userSelector } from 'lib/recoil/user';
export default function Invite({ code, title }) {
const [active, setActive] = useState(0);
@ -21,7 +21,7 @@ export default function Invite({ code, title }) {
const [verifyPasswordError, setVerifyPasswordError] = useState('');
const [strength, setStrength] = useState(0);
const dispatch = useStoreDispatch();
const setUser = useSetRecoilState(userSelector);
const router = useRouter();
const nextStep = () => setActive((current) => (current < 3 ? current + 1 : current));
@ -67,7 +67,7 @@ export default function Invite({ code, title }) {
icon: <UserIcon />,
});
dispatch(updateUser(null));
setUser(null);
await useFetch('/api/auth/logout');
await useFetch('/api/auth/login', 'POST', {
username, password,

137
yarn.lock
View file

@ -272,7 +272,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7":
version: 7.18.9
resolution: "@babel/runtime@npm:7.18.9"
dependencies:
@ -1394,26 +1394,6 @@ __metadata:
languageName: node
linkType: hard
"@reduxjs/toolkit@npm:^1.8.2":
version: 1.8.4
resolution: "@reduxjs/toolkit@npm:1.8.4"
dependencies:
immer: ^9.0.7
redux: ^4.1.2
redux-thunk: ^2.4.1
reselect: ^4.1.5
peerDependencies:
react: ^16.9.0 || ^17.0.0 || ^18
react-redux: ^7.2.1 || ^8.0.2
peerDependenciesMeta:
react:
optional: true
react-redux:
optional: true
checksum: 2ed7ee22bc84f0a2370ca2746513ece4593b8310c16c89e1ccf43ce23dcb83d7c4f4773d78049b68b4e92b3c5bee641e8081faf3947371be6b004ebba8142a51
languageName: node
linkType: hard
"@rushstack/eslint-patch@npm:^1.1.3":
version: 1.1.4
resolution: "@rushstack/eslint-patch@npm:1.1.4"
@ -1621,16 +1601,6 @@ __metadata:
languageName: node
linkType: hard
"@types/hoist-non-react-statics@npm:^3.3.1":
version: 3.3.1
resolution: "@types/hoist-non-react-statics@npm:3.3.1"
dependencies:
"@types/react": "*"
hoist-non-react-statics: ^3.3.0
checksum: 2c0778570d9a01d05afabc781b32163f28409bb98f7245c38d5eaf082416fdb73034003f5825eb5e21313044e8d2d9e1f3fe2831e345d3d1b1d20bcd12270719
languageName: node
linkType: hard
"@types/json5@npm:^0.0.29":
version: 0.0.29
resolution: "@types/json5@npm:0.0.29"
@ -1733,17 +1703,6 @@ __metadata:
languageName: node
linkType: hard
"@types/react@npm:*":
version: 18.0.17
resolution: "@types/react@npm:18.0.17"
dependencies:
"@types/prop-types": "*"
"@types/scheduler": "*"
csstype: ^3.0.2
checksum: 18cae64f5bfd6bb58fbd8ee2ba52ec82de844f114254e26de7b513e4b86621f643f9b71d7066958cd571b0d78cb86cbceda449c5289f9349ca573df29ab69252
languageName: node
linkType: hard
"@types/react@npm:^18.0.18":
version: 18.0.18
resolution: "@types/react@npm:18.0.18"
@ -4728,6 +4687,13 @@ __metadata:
languageName: node
linkType: hard
"hamt_plus@npm:1.0.2":
version: 1.0.2
resolution: "hamt_plus@npm:1.0.2"
checksum: af26ea32db03009019cc83dfa9411521a2fa16079443de1a502c9be46d8b3c975acda8ed93fc5750ef08d3186d35901e2d8cfe717dd54bea67b358601fa74e4c
languageName: node
linkType: hard
"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2":
version: 1.0.2
resolution: "has-bigints@npm:1.0.2"
@ -4839,7 +4805,7 @@ __metadata:
languageName: node
linkType: hard
"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2":
"hoist-non-react-statics@npm:^3.3.1":
version: 3.3.2
resolution: "hoist-non-react-statics@npm:3.3.2"
dependencies:
@ -4980,13 +4946,6 @@ __metadata:
languageName: node
linkType: hard
"immer@npm:^9.0.7":
version: 9.0.15
resolution: "immer@npm:9.0.15"
checksum: 92e3d63e810e3c3c2bb61b70c45443e37ef983ad12924e3edaf03725ae5979618f5b473439bb3bb4a8c4769f25132f18dec10ea15c40f0b20da5691ff96ff611
languageName: node
linkType: hard
"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1":
version: 3.3.0
resolution: "import-fresh@npm:3.3.0"
@ -7243,13 +7202,6 @@ __metadata:
languageName: node
linkType: hard
"react-is@npm:^18.0.0":
version: 18.2.0
resolution: "react-is@npm:18.2.0"
checksum: e72d0ba81b5922759e4aff17e0252bd29988f9642ed817f56b25a3e217e13eea8a7f2322af99a06edb779da12d5d636e9fda473d620df9a3da0df2a74141d53e
languageName: node
linkType: hard
"react-property@npm:2.0.0":
version: 2.0.0
resolution: "react-property@npm:2.0.0"
@ -7257,38 +7209,6 @@ __metadata:
languageName: node
linkType: hard
"react-redux@npm:^8.0.2":
version: 8.0.2
resolution: "react-redux@npm:8.0.2"
dependencies:
"@babel/runtime": ^7.12.1
"@types/hoist-non-react-statics": ^3.3.1
"@types/use-sync-external-store": ^0.0.3
hoist-non-react-statics: ^3.3.2
react-is: ^18.0.0
use-sync-external-store: ^1.0.0
peerDependencies:
"@types/react": ^16.8 || ^17.0 || ^18.0
"@types/react-dom": ^16.8 || ^17.0 || ^18.0
react: ^16.8 || ^17.0 || ^18.0
react-dom: ^16.8 || ^17.0 || ^18.0
react-native: ">=0.59"
redux: ^4
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
react-dom:
optional: true
react-native:
optional: true
redux:
optional: true
checksum: 44c1739c45dad04ecc65a290897c73828ff0bf43f2b7618ed5ef6d4ceecedae38e76cecd189a5ecedf579c28ead05427bc000fb45ad30b9fcd5c2be27cd3ac73
languageName: node
linkType: hard
"react-textarea-autosize@npm:8.3.4":
version: 8.3.4
resolution: "react-textarea-autosize@npm:8.3.4"
@ -7407,21 +7327,19 @@ __metadata:
languageName: node
linkType: hard
"redux-thunk@npm:^2.4.1":
version: 2.4.1
resolution: "redux-thunk@npm:2.4.1"
peerDependencies:
redux: ^4
checksum: af5abb425fb9dccda02e5f387d6f3003997f62d906542a3d35fc9420088f550dc1a018bdc246c7d23ee852b4d4ab8b5c64c5be426e45a328d791c4586a3c6b6e
languageName: node
linkType: hard
"redux@npm:^4.1.2, redux@npm:^4.2.0":
version: 4.2.0
resolution: "redux@npm:4.2.0"
"recoil@npm:^0.7.5":
version: 0.7.5
resolution: "recoil@npm:0.7.5"
dependencies:
"@babel/runtime": ^7.9.2
checksum: 75f3955c89b3f18edf5411e5fb482aa2e4f41a416183e8802a6bf6472c4fc3d47675b8b321d147f8af8e0f616436ac507bf5a25f1c4d6180e797b549c7db2c1d
hamt_plus: 1.0.2
peerDependencies:
react: ">=16.13.1"
peerDependenciesMeta:
react-dom:
optional: true
react-native:
optional: true
checksum: 19b410cca6839c8b886b91378112e12de3e0393b547211dafcf7a272c1aa2d7af6c09a9ed39fb3e1997abe5f3d6583e3774dc9f9cdda8c36e4cb0be64a1b17ce
languageName: node
linkType: hard
@ -7464,13 +7382,6 @@ __metadata:
languageName: node
linkType: hard
"reselect@npm:^4.1.5":
version: 4.1.6
resolution: "reselect@npm:4.1.6"
checksum: 3ea1058422904063ec93c8f4693fe33dcb2178bbf417ace8db5b2c797a5875cf357d9308d11ed3942ee22507dd34ecfbf1f3a21340a4f31c206cab1d36ceef31
languageName: node
linkType: hard
"resolve-from@npm:^4.0.0":
version: 4.0.0
resolution: "resolve-from@npm:4.0.0"
@ -8715,7 +8626,7 @@ __metadata:
languageName: node
linkType: hard
"use-sync-external-store@npm:1.2.0, use-sync-external-store@npm:^1.0.0, use-sync-external-store@npm:^1.2.0":
"use-sync-external-store@npm:1.2.0, use-sync-external-store@npm:^1.2.0":
version: 1.2.0
resolution: "use-sync-external-store@npm:1.2.0"
peerDependencies:
@ -9022,7 +8933,6 @@ __metadata:
"@prisma/client": ^4.1.0
"@prisma/internals": ^4.1.0
"@prisma/migrate": ^4.1.0
"@reduxjs/toolkit": ^1.8.2
"@tanstack/react-query": ^4.2.3
"@types/cookie": ^0.5.1
"@types/minio": ^7.0.13
@ -9057,8 +8967,7 @@ __metadata:
react-chartjs-2: ^4.3.1
react-dom: ^18.2.0
react-feather: ^2.0.10
react-redux: ^8.0.2
redux: ^4.2.0
recoil: ^0.7.5
sharp: ^0.30.7
ts-node: ^10.8.1
tsx: ^3.8.0