#10. Добавление localStorage сервиса, добавлены верхнее и нижнее меню приложения (#11)

This commit is contained in:
Nikolay
2020-12-26 22:33:23 +03:00
committed by GitHub
parent 31ad97954b
commit ef4a6ecbc8
37 changed files with 373 additions and 174 deletions

View File

@ -1,3 +1,5 @@
import {PageType} from '../enums/common';
export const ROUTES = {
MAIN: '/',
CHAOS_BOX: '/chaos-box',
@ -8,3 +10,14 @@ export const ROUTES = {
SETTINGS: '/settings',
SIGN_IN: '/sign-in',
};
export const PAGE_TITLE = {
[PageType.Main]: 'Free your brain',
[PageType.ChaosBox]: 'Chaos box',
[PageType.Calendar]: 'Calendar',
[PageType.Information]: 'Information',
[PageType.Tags]: 'Tags',
[PageType.Projects]: 'Projects',
[PageType.Settings]: 'Settings',
[PageType.SigIn]: 'SigIn',
};

21
src/core/enums/common.ts Normal file
View File

@ -0,0 +1,21 @@
export const enum TaskStatus {
Progress = 'progress',
Removed = 'removed',
Done = 'done',
}
export const enum FolderType {
Project = 'project',
Information = 'information',
}
export enum PageType {
Main = '',
ChaosBox = 'chaos-box',
Projects = 'projects',
Information = 'information',
Tags = 'tags',
Calendar = 'calendar',
Settings = 'settings',
SigIn = 'sign-in',
}

View File

@ -0,0 +1,25 @@
import {useMemo} from 'react';
import {useLocation, useParams as useReactParams} from 'react-router-dom';
import {PageType} from '../enums/common';
import {getPageType} from '../utils/common';
type ParamsParser<T> = (value?: string) => T;
export type ParamsParsers<T> = Partial<{[K in keyof T]: ParamsParser<T[K]>}>;
export function useParams<T extends {[name: string]: unknown}>(paramParsers: ParamsParsers<T> = {}) {
const params = useReactParams<Record<keyof T, string>>();
const {pathname} = useLocation();
return useMemo(() => {
return Object.keys(paramParsers).reduce<T & {pageType: PageType}>((memo, key) => {
const parser = paramParsers[key];
return {
...memo,
[key]: parser?.(params[key]),
};
}, {
pageType: getPageType(pathname),
} as T & {pageType: PageType});
}, [params, paramParsers, pathname]);
}

View File

@ -49,16 +49,14 @@ export function booleanParser(defaultValue?: boolean) {
// Array parser (должен уметь с enum)
export function useQuery(): ParsedUrlQuery;
export function useQuery<T extends {[name: string]: unknown}>(queryParsers: QueryParsers<T>): Partial<T>;
export function useQuery<T extends {[name: string]: unknown}>(
queryParsers?: QueryParsers<T>
queryParsers: QueryParsers<T>
): ParsedUrlQuery | Partial<T> {
const {search} = useLocation();
return useMemo(() => {
const query = parse(search.slice(1));
return queryParsers ? Object.keys(query).reduce<Partial<T>>((memo, key) => {
return queryParsers ? Object.keys(queryParsers).reduce<T>((memo, key) => {
if (key in queryParsers) {
const parser = queryParsers[key];
return {
@ -67,6 +65,6 @@ export function useQuery<T extends {[name: string]: unknown}>(
};
}
return memo;
}, {}) : query;
}, {} as T) : query;
}, [search, queryParsers]);
}

View File

@ -0,0 +1,5 @@
import {PageType} from '../enums/common';
export const isPageType = (value?: string): value is PageType => (
Object.values(PageType).some(pageType => pageType === value)
);

View File

@ -1,20 +0,0 @@
import {createAdapter} from '@most/adapter';
import {state} from 'fp-ts/lib/State';
export namespace AuthService {
type State = {
isAuth: boolean;
};
export const initState: State = {
isAuth: false,
};
const [changeState, stream$] = createAdapter<State>();
export const handleChangeAuth = (isAuth: boolean): void => changeState({
...state,
isAuth,
});
export const state$ = stream$;
}

View File

@ -0,0 +1,21 @@
export const makeLocalStorageService = <T>(init: T, stateName: string) => {
if (!localStorage.getItem(stateName)) {
localStorage.setItem(stateName, JSON.stringify(init));
}
return {
set: (updatedState: T) => {
localStorage.setItem(stateName, JSON.stringify(updatedState));
return updatedState;
},
get: (): T => {
const stringValue = localStorage.getItem(stateName) || '';
try {
return JSON.parse(stringValue);
} catch (e) {
return init;
}
},
};
};

View File

@ -0,0 +1,36 @@
import {v4} from 'uuid';
import {TaskStatus} from '../enums/common';
import {Task} from '../types/common';
import {createService} from '../utils/createService';
import {makeLocalStorageService} from './LocalStorageService';
const TASK_STORAGE_NAME = 'FYB_TASK_STORAGE';
const INIT_TASKS: Task[] = [
{
id: v4(),
status: TaskStatus.Progress,
created_at: '2021-03-01T13:00+03:00',
title: 'Первая таска',
body: 'Описание таски',
},
{
id: v4(),
status: TaskStatus.Progress,
created_at: '2021-03-01T13:00+03:00',
title: 'Вторая таска',
body: 'Описание таски',
},
{
id: v4(),
status: TaskStatus.Progress,
created_at: '2021-03-01T13:00+03:00',
title: 'Третья таска',
body: 'Описание таски',
},
];
const taskListService = makeLocalStorageService(INIT_TASKS, TASK_STORAGE_NAME);
export const tasksService = createService(taskListService.get(), {
});

View File

@ -1,13 +0,0 @@
import {createAdapter} from '@most/adapter';
const arr: Array<number> = [];
let inc = 0;
const [handler, stream$] = createAdapter<Array<number>>();
export const list$ = stream$;
setInterval(() => {
arr.push(inc += 1);
handler(arr);
}, 500);

View File

@ -1,4 +1,49 @@
export type ListItem = {
title: string;
url: string;
import {FolderType, TaskStatus} from '../enums/common';
export type Task = {
/**
* Идентификатор
*/
id: string;
title?: string;
body?: string;
created_at: string;
start_at?: string;
end_at?: string;
/**
* Контекст выполнения, теги
*/
tags?: string[];
/**
* Папка, проект, список
*/
folder?: string;
status: TaskStatus;
};
export type Folder = {
/**
* Идентификатор
*/
id: string;
name: string;
type: FolderType;
/**
* Папка, проект
*/
folder?: string;
removed?: boolean;
};
export type Tag = {
/**
* Идентификатор
*/
id: string;
name: string;
/**
* Цвет тега в формате #FFFFFF
*/
color?: string;
removed?: boolean;
};

View File

@ -1 +1,9 @@
import {PageType} from '../enums/common';
import {isPageType} from '../referers/common';
export const numberToString = (num: number): string => num.toString();
export const getPageType = (pathname?: string): PageType => {
const path = pathname?.startsWith('/') ? pathname.slice(1) : pathname ?? '';
return isPageType(path) ? path : PageType.Main;
};