This commit is contained in:
@ -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
21
src/core/enums/common.ts
Normal 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',
|
||||
}
|
||||
25
src/core/hooks/useParams.ts
Normal file
25
src/core/hooks/useParams.ts
Normal 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]);
|
||||
}
|
||||
@ -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]);
|
||||
}
|
||||
|
||||
5
src/core/referers/common.ts
Normal file
5
src/core/referers/common.ts
Normal 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)
|
||||
);
|
||||
@ -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$;
|
||||
}
|
||||
21
src/core/services/LocalStorageService.ts
Normal file
21
src/core/services/LocalStorageService.ts
Normal 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;
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
36
src/core/services/TasksService.ts
Normal file
36
src/core/services/TasksService.ts
Normal 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(), {
|
||||
});
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user