From bcc816ea555882885d10bf2f92b772ea34619349 Mon Sep 17 00:00:00 2001 From: diced Date: Mon, 20 Mar 2023 22:36:10 -0700 Subject: [PATCH] fix: save list-view setting to localStorage --- src/components/pages/Invites.tsx | 9 +++- src/components/pages/Urls/index.tsx | 5 ++- src/components/pages/Users/index.tsx | 5 ++- src/lib/recoil/settings.ts | 66 ++++++++++++++++++++++++++-- 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/components/pages/Invites.tsx b/src/components/pages/Invites.tsx index 55b2227..02c4d69 100644 --- a/src/components/pages/Invites.tsx +++ b/src/components/pages/Invites.tsx @@ -29,10 +29,12 @@ import { } from '@tabler/icons-react'; import MutedText from 'components/MutedText'; import useFetch from 'hooks/useFetch'; +import { listViewInvitesSelector } from 'lib/recoil/settings'; import { expireText, relativeTime } from 'lib/utils/client'; import { DataTable, DataTableSortStatus } from 'mantine-datatable'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; +import { useRecoilState } from 'recoil'; const expires = ['30m', '1h', '6h', '12h', '1d', '3d', '5d', '7d', 'never']; @@ -137,8 +139,9 @@ export default function Invites() { const [invites, setInvites] = useState([]); const [open, setOpen] = useState(false); + const [ok, setOk] = useState(false); - const [listView, setListView] = useState(true); + const [listView, setListView] = useRecoilState(listViewInvitesSelector); const [sortStatus, setSortStatus] = useState({ columnAccessor: 'createdAt', @@ -212,6 +215,7 @@ export default function Invites() { const us = await useFetch('/api/auth/invite'); if (!us.error) { setInvites(us); + setOk(true); } else { router.push('/dashboard'); } @@ -283,7 +287,8 @@ export default function Invites() { sortStatus={sortStatus} onSortStatusChange={setSortStatus} records={records ?? []} - fetching={records.length === 0} + fetching={!ok} + minHeight={160} loaderBackgroundBlur={5} loaderVariant='dots' rowContextMenu={{ diff --git a/src/components/pages/Urls/index.tsx b/src/components/pages/Urls/index.tsx index 9fba0e1..06fb469 100644 --- a/src/components/pages/Urls/index.tsx +++ b/src/components/pages/Urls/index.tsx @@ -29,10 +29,11 @@ import { import Link from 'components/Link'; import MutedText from 'components/MutedText'; import { useURLDelete, useURLs } from 'lib/queries/url'; +import { listViewUrlsSelector } from 'lib/recoil/settings'; import { userSelector } from 'lib/recoil/user'; import { DataTable, DataTableSortStatus } from 'mantine-datatable'; import { useEffect, useState } from 'react'; -import { useRecoilValue } from 'recoil'; +import { useRecoilState, useRecoilValue } from 'recoil'; import URLCard from './URLCard'; export default function Urls() { @@ -46,7 +47,7 @@ export default function Urls() { const updateURLs = async () => urls.refetch(); - const [listView, setListView] = useState(true); + const [listView, setListView] = useRecoilState(listViewUrlsSelector); const [sortStatus, setSortStatus] = useState({ columnAccessor: 'id', diff --git a/src/components/pages/Users/index.tsx b/src/components/pages/Users/index.tsx index dcb7d48..f802fdd 100644 --- a/src/components/pages/Users/index.tsx +++ b/src/components/pages/Users/index.tsx @@ -14,11 +14,12 @@ import { } from '@tabler/icons-react'; import MutedText from 'components/MutedText'; import useFetch from 'hooks/useFetch'; +import { listViewUsersSelector } from 'lib/recoil/settings'; import { userSelector } from 'lib/recoil/user'; import { DataTable, DataTableSortStatus } from 'mantine-datatable'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; -import { useRecoilValue } from 'recoil'; +import { useRecoilState, useRecoilValue } from 'recoil'; import { CreateUserModal } from './CreateUserModal'; import { EditUserModal } from './EditUserModal'; @@ -33,7 +34,7 @@ export default function Users() { const [editOpen, setEditOpen] = useState(false); const [selectedUser, setSelectedUser] = useState(null); - const [listView, setListView] = useState(true); + const [listView, setListView] = useRecoilState(listViewUsersSelector); const [sortStatus, setSortStatus] = useState({ columnAccessor: 'id', diff --git a/src/lib/recoil/settings.ts b/src/lib/recoil/settings.ts index e8abe33..e4132a4 100644 --- a/src/lib/recoil/settings.ts +++ b/src/lib/recoil/settings.ts @@ -15,18 +15,76 @@ const localStorageEffect = export type Settings = { showNonMedia: boolean; + listView: { + urls: boolean; + users: boolean; + invites: boolean; + folders: boolean; + }; +}; + +export const DEFAULT_SETTINGS: Settings = { + showNonMedia: false, + listView: { + urls: true, + users: true, + invites: true, + folders: true, + }, }; export const settingsState = atom({ key: 'settingsState', - default: { - showNonMedia: false, - }, + default: DEFAULT_SETTINGS, effects: [localStorageEffect('zipline_settings')], }); export const showNonMediaSelector = selector({ key: 'settingsShowNonMediaSelector', get: ({ get }) => get(settingsState).showNonMedia, - set: ({ set }, newValue) => set(settingsState, { showNonMedia: newValue }), + set: ({ set, get }, newValue) => + set(settingsState, { + showNonMedia: newValue, + listView: get(settingsState).listView ?? DEFAULT_SETTINGS.listView, + }), +}); + +export const listViewUrlsSelector = selector({ + key: 'listViewUrlsSelector', + get: ({ get }) => get(settingsState).listView?.urls ?? DEFAULT_SETTINGS.listView.urls, + set: ({ set, get }, newValue) => + set(settingsState, { + showNonMedia: get(settingsState).showNonMedia, + listView: { ...(get(settingsState).listView ?? DEFAULT_SETTINGS.listView), urls: newValue }, + }), +}); + +export const listViewUsersSelector = selector({ + key: 'listViewUsersSelector', + get: ({ get }) => get(settingsState).listView?.users ?? DEFAULT_SETTINGS.listView.users, + set: ({ set, get }, newValue) => + set(settingsState, { + showNonMedia: get(settingsState).showNonMedia, + listView: { ...(get(settingsState).listView ?? DEFAULT_SETTINGS.listView), users: newValue }, + }), +}); + +export const listViewInvitesSelector = selector({ + key: 'listViewInvitesSelector', + get: ({ get }) => get(settingsState).listView?.invites ?? DEFAULT_SETTINGS.listView.invites, + set: ({ set, get }, newValue) => + set(settingsState, { + showNonMedia: get(settingsState).showNonMedia, + listView: { ...(get(settingsState).listView ?? DEFAULT_SETTINGS.listView), invites: newValue }, + }), +}); + +export const listViewFoldersSelector = selector({ + key: 'listViewFoldersSelector', + get: ({ get }) => get(settingsState).listView?.folders ?? DEFAULT_SETTINGS.listView.folders, + set: ({ set, get }, newValue) => + set(settingsState, { + showNonMedia: get(settingsState).showNonMedia, + listView: { ...(get(settingsState).listView ?? DEFAULT_SETTINGS.listView), folders: newValue }, + }), });