1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-28 14:16:41 +07:00

added sidebar navigation

This commit is contained in:
Fedor Katurov 2022-08-05 18:45:11 +07:00
parent 1bb08f72e6
commit a03f80259d
6 changed files with 150 additions and 70 deletions

View file

@ -1,78 +1,100 @@
import { Context, createContext, createElement, FunctionComponent, PropsWithChildren, useCallback, useContext, useMemo } from 'react';
import {
Context,
createContext,
createElement,
FunctionComponent,
PropsWithChildren,
useCallback,
useContext,
useMemo,
} from "react";
import { useRouter } from 'next/router';
import { has } from 'ramda';
import { useRouter } from "next/router";
import { has, omit } from "ramda";
import { ModalWrapper } from '~/components/dialogs/ModalWrapper';
import { sidebarComponents, SidebarName } from '~/constants/sidebar';
import { DialogComponentProps } from '~/types/modal';
import { ModalWrapper } from "~/components/dialogs/ModalWrapper";
import { sidebarComponents, SidebarName } from "~/constants/sidebar";
import { DialogComponentProps } from "~/types/modal";
import { SidebarComponentProps } from "~/types/sidebar";
type ContextValue = typeof SidebarContext extends Context<infer U> ? U : never;
type Name = keyof typeof sidebarComponents;
// TODO: use it to store props for sidebar
type Props<T extends Name> = typeof sidebarComponents[T] extends FunctionComponent<infer U>
? U extends DialogComponentProps ? Omit<U, 'onRequestClose'> : U
type Props<
T extends Name
> = typeof sidebarComponents[T] extends FunctionComponent<infer U>
? U extends object
? U extends SidebarComponentProps
? Omit<U, "onRequestClose">
: U
: U
: {};
const SidebarContext = createContext({
current: undefined as SidebarName | undefined,
open: <T extends Name>(name: T) => {},
close: () => {},
open: <T extends Name>(name: T, props: Props<T>) => {},
close: () => {},
});
export const SidebarProvider = <T extends Name>({ children }: PropsWithChildren<{}>) => {
export const SidebarProvider = <T extends Name>({
children,
}: PropsWithChildren<{}>) => {
const router = useRouter();
const current = useMemo(() => {
const val = router.query.sidebar as SidebarName | undefined
const val = router.query.sidebar as SidebarName | undefined;
return val && has(val, sidebarComponents) ? val : undefined;
}, [router]);
const open = useCallback(
<T extends Name>(name: T) => {
const [path] = router.asPath.split('?');
void router.push(path + '?sidebar=' + name, path + '?sidebar=' + name, {
<T extends Name>(name: T, props: Props<T>) => {
const [path] = router.asPath.split("?");
const query = Object.entries(props as {})
.filter(([, val]) => val)
.map(([name, val]) => `${name}=${val}`)
.join("&");
const url = path + "?sidebar=" + name + (query && `&${query}`);
void router.push(url, url, {
shallow: true,
scroll: false,
});
},
[router]
[router],
);
const close = useCallback(
() => {
const [path] = router.asPath.split('?');
const close = useCallback(() => {
const [path] = router.asPath.split("?");
console.log('trying to close');
void router.replace(path, path, {
shallow: true,
scroll: false,
});
}, [router]);
void router.replace(path, path, {
shallow: true,
scroll: false,
});
},
[router]
const value = useMemo<ContextValue>(
() => ({
current,
open,
close,
}),
[current, open, close],
);
const value = useMemo<ContextValue>(() => ({
current,
open,
close,
}), [current, open, close]);
return (
<SidebarContext.Provider value={value}>
{children}
{current &&
{current && (
<ModalWrapper onOverlayClick={close}>
{createElement(
sidebarComponents[current],
{ onRequestClose: close } as any
)}
{createElement(sidebarComponents[current], {
onRequestClose: close,
...omit(["sidebar"], router.query),
} as any)}
</ModalWrapper>
}
)}
</SidebarContext.Provider>
);
}
};
export const useSidebar = () => useContext(SidebarContext);