1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

made lab use provider and context

This commit is contained in:
Fedor Katurov 2021-11-22 16:24:46 +07:00
parent cb314e9f8d
commit 96f1529f2b
9 changed files with 129 additions and 56 deletions

View file

@ -6,7 +6,7 @@ import styles from './styles.module.scss';
import { INode } from '~/redux/types';
import { getPrettyDate } from '~/utils/dom';
import { URLS } from '~/constants/urls';
import { Link, useHistory } from 'react-router-dom';
import { useHistory } from 'react-router-dom';
interface IProps {
node?: Partial<INode>;

View file

@ -4,14 +4,10 @@ import styles from './styles.module.scss';
import { LabNode } from '~/components/lab/LabNode';
import { EMPTY_NODE, NODE_TYPES } from '~/redux/node/constants';
import { values } from 'ramda';
import { ILabNode } from '~/redux/lab/types';
import { useLabPagination } from '~/utils/hooks/lab/useLabPagination';
import { useLabContext } from '~/utils/context/LabContextProvider';
interface IProps {
isLoading: boolean;
nodes: ILabNode[];
onLoadMore: () => void;
}
interface IProps {}
const breakpointCols = {
default: 2,
@ -30,7 +26,9 @@ const LoadingNode = () => (
/>
);
const LabGrid: FC<IProps> = ({ isLoading, nodes, onLoadMore }) => {
const LabGrid: FC<IProps> = () => {
const { isLoading, nodes, onLoadMore } = useLabContext();
const columns = useMemo(() => Array.from(document.querySelectorAll(`.${styles.column}`)), []);
useLabPagination(isLoading, columns, onLoadMore);

View file

@ -2,25 +2,16 @@ import React, { FC } from 'react';
import styles from './styles.module.scss';
import { LabBanner } from '~/components/lab/LabBanner';
import { Group } from '~/components/containers/Group';
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import {
selectLabStatsHeroes,
selectLabStatsLoading,
selectLabStatsTags,
selectLabUpdatesNodes
} from '~/redux/lab/selectors';
import { LabTags } from '~/components/lab/LabTags';
import { LabHeroes } from '~/components/lab/LabHeroes';
import { FlowRecentItem } from '~/components/flow/FlowRecentItem';
import { SubTitle } from '~/components/common/SubTitle';
import { useLabContext } from '~/utils/context/LabContextProvider';
interface IProps {}
const LabStats: FC<IProps> = () => {
const tags = useShallowSelect(selectLabStatsTags);
const heroes = useShallowSelect(selectLabStatsHeroes);
const isLoading = useShallowSelect(selectLabStatsLoading);
const updates = useShallowSelect(selectLabUpdatesNodes);
const { isLoadingStats, tags, heroes, updates } = useLabContext();
return (
<Group>
@ -28,14 +19,14 @@ const LabStats: FC<IProps> = () => {
<div className={styles.card}>
<Group>
{(!!tags.length || isLoading) && (
<SubTitle isLoading={isLoading} className={styles.title}>
{(!!tags.length || isLoadingStats) && (
<SubTitle isLoading={isLoadingStats} className={styles.title}>
Тэги
</SubTitle>
)}
<div className={styles.tags}>
<LabTags tags={tags} isLoading={isLoading} />
<LabTags tags={tags} isLoading={isLoadingStats} />
</div>
<div />
@ -53,14 +44,14 @@ const LabStats: FC<IProps> = () => {
</>
)}
{(!!heroes.length || isLoading) && (
<SubTitle isLoading={isLoading} className={styles.title}>
{(!!heroes.length || isLoadingStats) && (
<SubTitle isLoading={isLoadingStats} className={styles.title}>
Важные
</SubTitle>
)}
<div className={styles.heroes}>
<LabHeroes nodes={heroes} isLoading={isLoading} />
<LabHeroes nodes={heroes} isLoading={isLoadingStats} />
</div>
</Group>
</div>

View file

@ -2,13 +2,13 @@ import React, { FC } from 'react';
import { URLS } from '~/constants/urls';
import { ErrorNotFound } from '~/containers/pages/ErrorNotFound';
import { Redirect, Route, Switch, useLocation } from 'react-router';
import { LabLayout } from '~/layouts/LabLayout';
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import { selectAuthUser } from '~/redux/auth/selectors';
import { ProfileLayout } from '~/layouts/ProfileLayout';
import FlowPage from '~/pages';
import BorisPage from '~/pages/boris';
import NodePage from '~/pages/node/[id]';
import LabPage from '~/pages/lab';
interface IProps {}
@ -23,7 +23,7 @@ const MainRouter: FC<IProps> = () => {
<Route path={URLS.ERRORS.NOT_FOUND} component={ErrorNotFound} />
<Route path={URLS.PROFILE_PAGE(':username')} component={ProfileLayout} />
{is_user && <Route path={URLS.LAB} component={LabLayout} />}
{is_user && <Route path={URLS.LAB} component={LabPage} />}
<Route path={URLS.BASE} component={FlowPage} />
<Redirect to="/" />

View file

@ -1,42 +1,18 @@
import React, { FC, useCallback, useEffect, useMemo, useRef } from 'react';
import React, { FC } from 'react';
import styles from './styles.module.scss';
import { Sticky } from '~/components/containers/Sticky';
import { Container } from '~/containers/main/Container';
import { LabGrid } from '~/containers/lab/LabGrid';
import { useDispatch } from 'react-redux';
import { labGetList, labGetMore, labGetStats } from '~/redux/lab/actions';
import { Group } from '~/components/containers/Group';
import { LabHead } from '~/components/lab/LabHead';
import { LabStats } from '~/containers/lab/LabStats';
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import { selectLabList } from '~/redux/lab/selectors';
import { SidebarRouter } from '~/containers/main/SidebarRouter';
import { Superpower } from '~/components/boris/Superpower';
import { Toggle } from '~/components/input/Toggle';
import { usePersistedState } from '~/utils/hooks/usePersistedState';
import classNames from 'classnames';
import { useLabPagination } from '~/utils/hooks/lab/useLabPagination';
import { useLabContext } from '~/utils/context/LabContextProvider';
interface IProps {}
const LabLayout: FC<IProps> = () => {
const { is_loading, nodes, count } = useShallowSelect(selectLabList);
const dispatch = useDispatch();
useEffect(() => {
dispatch(labGetList());
dispatch(labGetStats());
}, [dispatch]);
const onLoadMore = useCallback(() => {
if (nodes.length >= count) {
return;
}
dispatch(labGetMore());
}, [nodes, count, dispatch]);
const isInitialLoading = is_loading && !nodes.length;
const { isLoading } = useLabContext();
return (
<Container>
@ -44,10 +20,10 @@ const LabLayout: FC<IProps> = () => {
<div className={styles.wrap}>
<Group className={styles.content}>
<div className={styles.head}>
<LabHead isLoading={isInitialLoading} />
<LabHead isLoading={isLoading} />
</div>
<LabGrid nodes={nodes} isLoading={isInitialLoading} onLoadMore={onLoadMore} />
<LabGrid />
</Group>
<div className={styles.panel}>

13
src/pages/lab.tsx Normal file
View file

@ -0,0 +1,13 @@
import React, { VFC } from 'react';
import { LabLayout } from '~/layouts/LabLayout';
import { LabProvider } from '~/utils/providers/LabProvider';
interface LabPageProps {}
const LabPage: VFC<LabPageProps> = () => (
<LabProvider>
<LabLayout />
</LabProvider>
);
export default LabPage;

View file

@ -0,0 +1,34 @@
import { ILabNode } from '~/redux/lab/types';
import React, { createContext, FC, useContext } from 'react';
import { INode, ITag } from '~/redux/types';
export interface LabContextProps {
isLoading: boolean;
nodes: ILabNode[];
count: number;
onLoadMore: () => void;
tags: ITag[];
heroes: Partial<INode>[];
isLoadingStats: boolean;
updates: Partial<INode>[];
}
const defaultValues: LabContextProps = {
isLoading: false,
nodes: [],
count: 0,
onLoadMore: () => {},
tags: [],
heroes: [],
isLoadingStats: false,
updates: [],
};
const LabContext = createContext<LabContextProps>(defaultValues);
export const LabContextProvider: FC<LabContextProps> = ({ children, ...rest }) => (
<LabContext.Provider value={rest}>{children}</LabContext.Provider>
);
export const useLabContext = () => useContext(LabContext);

View file

@ -0,0 +1,35 @@
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import {
selectLabList,
selectLabStatsHeroes,
selectLabStatsLoading,
selectLabStatsTags,
selectLabUpdatesNodes,
} from '~/redux/lab/selectors';
import { useDispatch } from 'react-redux';
import { useCallback, useEffect } from 'react';
import { labGetList, labGetMore, labGetStats } from '~/redux/lab/actions';
export const useLab = () => {
const { is_loading: isLoading, nodes, count } = useShallowSelect(selectLabList);
const dispatch = useDispatch();
const tags = useShallowSelect(selectLabStatsTags);
const heroes = useShallowSelect(selectLabStatsHeroes);
const isLoadingStats = useShallowSelect(selectLabStatsLoading);
const updates = useShallowSelect(selectLabUpdatesNodes);
useEffect(() => {
dispatch(labGetList());
dispatch(labGetStats());
}, [dispatch]);
const onLoadMore = useCallback(() => {
if (nodes.length >= count) {
return;
}
dispatch(labGetMore());
}, [nodes, count, dispatch]);
return { isLoading, nodes, count, onLoadMore, tags, heroes, isLoadingStats, updates };
};

View file

@ -0,0 +1,26 @@
import React, { FC } from 'react';
import { LabContextProvider } from '~/utils/context/LabContextProvider';
import { useLab } from '~/utils/hooks/lab/useLab';
interface LabProviderProps {}
const LabProvider: FC<LabProviderProps> = ({ children }) => {
const { isLoading, nodes, count, onLoadMore, tags, heroes, isLoadingStats, updates } = useLab();
return (
<LabContextProvider
isLoading={isLoading && !nodes.length}
nodes={nodes}
count={count}
onLoadMore={onLoadMore}
tags={tags}
heroes={heroes}
isLoadingStats={isLoadingStats}
updates={updates}
>
{children}
</LabContextProvider>
);
};
export { LabProvider };