From 0ab54da2e7807956f5582e6ccad85ab38844bc82 Mon Sep 17 00:00:00 2001 From: OlegBrony Date: Sun, 6 Jun 2021 18:41:16 +0300 Subject: [PATCH 01/27] feat(pages/search): adds search page, adds ability to search adds search ability with trigger on field change, with debounce ISSUES CLOSED: #61 --- .gitignore | 1 + package.json | 4 +- src/entities/card/index.ts | 1 + src/entities/card/organisms/card-preview.tsx | 14 +- src/entities/user/index.ts | 1 + src/entities/user/organisms/index.ts | 1 + .../user/organisms/user-preview-list.tsx | 25 +++ src/entities/user/organisms/user-preview.tsx | 52 ++++++ src/entities/user/types.ts | 5 + src/features/search-bar/index.ts | 5 + src/features/search-bar/lib.ts | 5 + src/features/search-bar/models/index.ts | 34 ++++ src/features/search-bar/models/login.ts | 5 - src/features/search-bar/molecules/search.tsx | 23 ++- src/features/search-bar/organisms/profile.tsx | 13 -- .../search-bar/organisms/search-bar.tsx | 19 ++- src/lib/get-s-end.ts | 3 + src/lib/use-query.ts | 5 + src/pages/home/index.tsx | 6 - src/pages/paths.ts | 4 + src/pages/routes.ts | 31 +--- src/pages/search/index.ts | 1 + src/pages/search/model.ts | 161 ++++++++++++++++++ src/pages/search/page.tsx | 81 +++++++++ src/ui/atoms/avatar.tsx | 2 +- src/ui/atoms/button.tsx | 2 +- src/ui/templates/card-container.ts | 10 ++ src/ui/templates/content-centered.tsx | 6 +- src/ui/templates/index.ts | 1 + yarn.lock | 16 +- 30 files changed, 450 insertions(+), 87 deletions(-) create mode 100644 src/entities/user/index.ts create mode 100644 src/entities/user/organisms/index.ts create mode 100644 src/entities/user/organisms/user-preview-list.tsx create mode 100644 src/entities/user/organisms/user-preview.tsx create mode 100644 src/entities/user/types.ts create mode 100644 src/features/search-bar/lib.ts create mode 100644 src/features/search-bar/models/index.ts delete mode 100644 src/features/search-bar/models/login.ts delete mode 100644 src/features/search-bar/organisms/profile.tsx create mode 100644 src/lib/get-s-end.ts create mode 100644 src/lib/use-query.ts create mode 100644 src/pages/search/index.ts create mode 100644 src/pages/search/model.ts create mode 100644 src/pages/search/page.tsx create mode 100644 src/ui/templates/card-container.ts diff --git a/.gitignore b/.gitignore index 6625ae2c..86b951de 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ npm-debug.log* coverage node_modules +.idea build public/static .env.local diff --git a/package.json b/package.json index 26a9f0b3..a1afcc42 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "lint": "eslint --fix ./src" }, "dependencies": { - "@effector/reflect": "^0.5.0", + "@effector/reflect": "^0.6.0", "cookie-parser": "^1.4.5", "cross-fetch": "^3.0.4", "dotenv": "^8.2.0", @@ -25,7 +25,7 @@ "express": "^4.17.1", "http-proxy-middleware": "^1.0.5", "node-fetch": "^2.6.1", - "patronum": "^0.106.0", + "patronum": "^1.1.0", "query-string": "^6.13.1", "react": "^16.8.6", "react-dom": "^16.8.6", diff --git a/src/entities/card/index.ts b/src/entities/card/index.ts index d1b79408..381db255 100644 --- a/src/entities/card/index.ts +++ b/src/entities/card/index.ts @@ -1 +1,2 @@ export * from './organisms'; +export type { Card } from './types'; diff --git a/src/entities/card/organisms/card-preview.tsx b/src/entities/card/organisms/card-preview.tsx index 6b99666b..bad32754 100644 --- a/src/entities/card/organisms/card-preview.tsx +++ b/src/entities/card/organisms/card-preview.tsx @@ -1,5 +1,6 @@ import React from 'react'; import styled from 'styled-components'; +import { CardContainer } from '@cardbox/ui'; import { Card } from '../types'; @@ -8,7 +9,7 @@ interface Props { } export const CardPreview: React.FC = ({ card }) => ( - +
{card.title} @@ -16,18 +17,9 @@ export const CardPreview: React.FC = ({ card }) => (
{card.content} -
+ ); -const Container = styled.article` - background-color: #fff; - border: 1px solid #e7e5ee; - border-radius: 6px; - box-shadow: 0px 6px 9px #f6f5f8; - color: #1a1e23; - padding: 1.125rem 1.5rem 0.625rem 1.5rem; -`; - const Header = styled.header` display: flex; `; diff --git a/src/entities/user/index.ts b/src/entities/user/index.ts new file mode 100644 index 00000000..7e5b87db --- /dev/null +++ b/src/entities/user/index.ts @@ -0,0 +1 @@ +export { UserPreviewList } from './organisms'; diff --git a/src/entities/user/organisms/index.ts b/src/entities/user/organisms/index.ts new file mode 100644 index 00000000..ece4dbb1 --- /dev/null +++ b/src/entities/user/organisms/index.ts @@ -0,0 +1 @@ +export { UserPreviewList } from './user-preview-list'; diff --git a/src/entities/user/organisms/user-preview-list.tsx b/src/entities/user/organisms/user-preview-list.tsx new file mode 100644 index 00000000..7ad08fe5 --- /dev/null +++ b/src/entities/user/organisms/user-preview-list.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import styled from 'styled-components'; + +import type { IUserPreview } from '../types'; +import { UserPreview } from './user-preview'; + +interface UserListProps { + users: IUserPreview[]; +} +export const UserPreviewList = ({ users }: UserListProps) => ( + + {users.map((user) => ( + + ))} + +); + +const Container = styled.div` + display: flex; + flex-direction: column; + + & > *:not(:last-child) { + margin-bottom: 1.125rem; + } +`; diff --git a/src/entities/user/organisms/user-preview.tsx b/src/entities/user/organisms/user-preview.tsx new file mode 100644 index 00000000..2bfa4543 --- /dev/null +++ b/src/entities/user/organisms/user-preview.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import styled from 'styled-components'; + +import { Avatar, CardContainer } from '../../../ui'; +import { IUserPreview } from '../types'; +import { getSEnd } from '../../../lib/get-s-end'; + +interface UserPreviewProps { + user: IUserPreview; +} +export const UserPreview: React.FC = ({ user }) => { + return ( + + + + {user.name} + + {user.cardsCount} card{getSEnd(user.cardsCount)} + + + + + + ); +}; + +const Container = styled.div` + display: grid; + grid-template-columns: 1fr min-content; + grid-gap: 0.5rem; + align-items: center; + margin-bottom: 0.5rem; +`; +const Texts = styled.div` + overflow: hidden; +`; +const Title = styled.h3` + font-size: 1.12rem; + font-weight: 500; + line-height: 1rem; + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +`; +const Counter = styled.p` + color: #a39bb2; + flex-shrink: 0; + font-size: 0.75rem; + margin: 0 0 0 auto; + padding-top: 0.5rem; +`; diff --git a/src/entities/user/types.ts b/src/entities/user/types.ts new file mode 100644 index 00000000..c3f9f487 --- /dev/null +++ b/src/entities/user/types.ts @@ -0,0 +1,5 @@ +export interface IUserPreview { + name: string; + id: string; + cardsCount: number; +} diff --git a/src/features/search-bar/index.ts b/src/features/search-bar/index.ts index d8b04490..44ee9964 100644 --- a/src/features/search-bar/index.ts +++ b/src/features/search-bar/index.ts @@ -1 +1,6 @@ +import * as model from './models'; + export { Searchbar } from './organisms'; +export { useSearchQuery } from './lib'; + +export { model }; diff --git a/src/features/search-bar/lib.ts b/src/features/search-bar/lib.ts new file mode 100644 index 00000000..6a67e2c4 --- /dev/null +++ b/src/features/search-bar/lib.ts @@ -0,0 +1,5 @@ +import { useQuery } from '../../lib/use-query'; + +export function useSearchQuery() { + return useQuery().get('query') || ''; +} diff --git a/src/features/search-bar/models/index.ts b/src/features/search-bar/models/index.ts new file mode 100644 index 00000000..627f850b --- /dev/null +++ b/src/features/search-bar/models/index.ts @@ -0,0 +1,34 @@ +import { ChangeEvent } from 'react'; +import { createEvent, forward, guard, restore } from 'effector-root'; +import { debounce } from 'patronum/debounce'; +import { history } from '@cardbox/entities/navigation'; + +import { paths } from '../../../pages/paths'; + +type ChangeEv = ChangeEvent; +export const searchFieldChanged = createEvent(); + +export const searchValueChanged = createEvent(); +export const $searchValue = restore(searchValueChanged, ''); + +forward({ + from: searchFieldChanged.map((event) => event.target.value), + to: searchValueChanged, +}); + +const searchDebounced = debounce({ + source: searchValueChanged, + timeout: 350, +}); + +const searchSubmitted = guard({ + clock: searchDebounced, + source: $searchValue, + filter: (query) => Boolean(query.trim()), +}); + +const trimedSearchSubmitted = searchSubmitted.map((query) => query.trim()); + +trimedSearchSubmitted.watch((searchValue) => { + if (history) history.push(paths.search(searchValue)); +}); diff --git a/src/features/search-bar/models/login.ts b/src/features/search-bar/models/login.ts deleted file mode 100644 index 98df0ec8..00000000 --- a/src/features/search-bar/models/login.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createEvent } from 'effector-root'; - -type ButtonClick = React.MouseEvent; - -export const loginClicked = createEvent(); diff --git a/src/features/search-bar/molecules/search.tsx b/src/features/search-bar/molecules/search.tsx index 39fc4fad..cc4bd74b 100644 --- a/src/features/search-bar/molecules/search.tsx +++ b/src/features/search-bar/molecules/search.tsx @@ -1,15 +1,20 @@ import React from 'react'; import styled from 'styled-components'; -import { button } from '@cardbox/ui'; +import { useEvent, useStore } from 'effector-react/ssr'; -export const Search = () => { - return ( - - - Advanced - - ); -}; +import * as model from '../models'; + +export const Search = () => ( + + + {/* todo: implement in v1 */} + {/*Advanced*/} + +); const Container = styled.div` border: 1px solid #e7e5ee; diff --git a/src/features/search-bar/organisms/profile.tsx b/src/features/search-bar/organisms/profile.tsx deleted file mode 100644 index ad9e2672..00000000 --- a/src/features/search-bar/organisms/profile.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import * as React from 'react'; -import styled from 'styled-components'; -import { useEvent, useStore } from 'effector-react/ssr'; - -import * as LoginModel from '../models/login'; - -export const Profile = () => { - const loginClicked = useEvent(LoginModel.loginClicked); - - return Login; -}; - -const Login = styled.button``; diff --git a/src/features/search-bar/organisms/search-bar.tsx b/src/features/search-bar/organisms/search-bar.tsx index d459ee5a..04f8d347 100644 --- a/src/features/search-bar/organisms/search-bar.tsx +++ b/src/features/search-bar/organisms/search-bar.tsx @@ -2,15 +2,21 @@ import React from 'react'; import styled from 'styled-components'; import { Avatar, ContentCenteredTemplate, IconLogo, button } from '@cardbox/ui'; import { Link } from 'react-router-dom'; +import { useEvent } from 'effector-react/ssr'; +import * as model from '../models'; import { Search } from '../molecules'; +import { paths } from '../../../pages/paths'; +import { useSearchQuery } from '../lib'; export const Searchbar = () => { + useSearchQueryChanged(); + return (