1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-25 21:06:42 +07:00

Добавили заметки в сайдбар (#126)

* added notes sidebar

* added note dropping and editing

* added sidebar navigation

* handling sidebarchanges over time

* using router back for closing sidebar

* fixed tripping inside single sidebar

* added superpowers toggle to sidebar

* user button opens sidebar now

* added profile cover for profile sidebar

* removed profile sidebar completely

* ran prettier over project

* added note not found error literal
This commit is contained in:
muerwre 2022-08-12 14:07:19 +07:00 committed by GitHub
parent fe3db608d6
commit 5d34090238
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1241 additions and 664 deletions

View file

@ -1,55 +0,0 @@
import { useCallback, useMemo } from 'react';
import useSWRInfinite, { SWRInfiniteKeyLoader } from 'swr/infinite';
import { apiGetNotes } from '~/api/notes';
import { ApiGetNotesRequest } from '~/api/notes/types';
import { useAuth } from '~/hooks/auth/useAuth';
import { GetLabNodesRequest, ILabNode } from '~/types/lab';
import { flatten, uniqBy } from '~/utils/ramda';
const DEFAULT_COUNT = 20;
const getKey: (isUser: boolean, search: string) => SWRInfiniteKeyLoader = (isUser, search) => (
index,
prev: ILabNode[]
) => {
if (!isUser) return null;
if (index > 0 && (!prev?.length || prev.length < 20)) return null;
const props: GetLabNodesRequest = {
limit: DEFAULT_COUNT,
offset: index * DEFAULT_COUNT,
search: search || '',
};
return JSON.stringify(props);
};
const parseKey = (key: string): ApiGetNotesRequest => {
try {
return JSON.parse(key);
} catch (error) {
return { limit: DEFAULT_COUNT, offset: 0, search: '' };
}
};
export const useGetNotes = (search: string) => {
const { isUser } = useAuth();
const { data, isValidating, size, setSize, mutate } = useSWRInfinite(
getKey(isUser, search),
async (key: string) => {
const result = await apiGetNotes(parseKey(key));
return result.list;
},
{
dedupingInterval: 300,
}
);
const notes = useMemo(() => uniqBy(n => n.id, flatten(data || [])), [data]);
const hasMore = (data?.[size - 1]?.length || 0) >= 1;
const loadMore = useCallback(() => setSize(size + 1), [setSize, size]);
return { notes, hasMore, loadMore, isLoading: !data && isValidating };
};

113
src/hooks/notes/useNotes.ts Normal file
View file

@ -0,0 +1,113 @@
import { useCallback, useMemo } from "react";
import useSWRInfinite, { SWRInfiniteKeyLoader } from "swr/infinite";
import {
apiCreateNote,
apiDeleteNote,
apiListNotes,
apiUpdateNote,
} from "~/api/notes";
import { ApiGetNotesRequest } from "~/api/notes/types";
import { useAuth } from "~/hooks/auth/useAuth";
import { GetLabNodesRequest, ILabNode } from "~/types/lab";
import { Note } from "~/types/notes";
import { flatten, uniqBy } from "~/utils/ramda";
const DEFAULT_COUNT = 20;
const getKey: (isUser: boolean, search: string) => SWRInfiniteKeyLoader = (
isUser,
search,
) => (index, prev: ILabNode[]) => {
if (!isUser) return null;
if (index > 0 && (!prev?.length || prev.length < 20)) return null;
const props: GetLabNodesRequest = {
limit: DEFAULT_COUNT,
offset: index * DEFAULT_COUNT,
search: search || "",
};
return JSON.stringify(props);
};
const parseKey = (key: string): ApiGetNotesRequest => {
try {
return JSON.parse(key);
} catch (error) {
return { limit: DEFAULT_COUNT, offset: 0, search: "" };
}
};
export const useNotes = (search: string) => {
const { isUser } = useAuth();
const { data, isValidating, size, setSize, mutate } = useSWRInfinite(
getKey(isUser, search),
async (key: string) => {
const result = await apiListNotes(parseKey(key));
return result.list;
},
{
dedupingInterval: 300,
},
);
const create = useCallback(
async (text: string, onSuccess?: (note: Note) => void) => {
const result = await apiCreateNote({ text });
if (data) {
await mutate(
data?.map((it, index) => (index === 0 ? [result, ...it] : it)),
{ revalidate: false },
);
}
onSuccess?.(result);
},
[mutate, data],
);
const remove = useCallback(
async (id: number, onSuccess?: () => void) => {
await apiDeleteNote(id);
await mutate(
data?.map(page => page.filter(it => it.id !== id)),
{ revalidate: false },
);
onSuccess?.();
},
[mutate, data],
);
const update = useCallback(
async (id: number, text: string, onSuccess?: () => void) => {
const result = await apiUpdateNote({ id, text });
await mutate(
data?.map(page => page.map(it => (it.id === id ? result : it))),
{ revalidate: false },
);
onSuccess?.();
},
[mutate, data],
);
const notes = useMemo(() => uniqBy(n => n.id, flatten(data || [])), [data]);
const hasMore = (data?.[size - 1]?.length || 0) >= 1;
const loadMore = useCallback(() => setSize(size + 1), [setSize, size]);
return useMemo(
() => ({
notes,
hasMore,
loadMore,
isLoading: !data && isValidating,
create,
remove,
update,
}),
[notes, hasMore, loadMore, data, isValidating, create, remove],
);
};