diff --git a/client/src/components/books/BookItem.tsx b/client/src/components/books/BookItem.tsx index a9d9134..2bfbb0b 100644 --- a/client/src/components/books/BookItem.tsx +++ b/client/src/components/books/BookItem.tsx @@ -3,14 +3,16 @@ import { styled } from "styled-components"; import { Book } from "../../models/book.model"; import { formatNumber } from "../../utils/format"; import { getImgSrc } from "../../utils/image"; +import { ViewMode } from "./BooksViewSwitcher"; interface Props { book: Book; + view?: ViewMode; } -const BookItem = ({ book }: Props) => { +const BookItem = ({ book, view }: Props) => { return ( - +
{book.title}
@@ -28,7 +30,7 @@ const BookItem = ({ book }: Props) => { ); }; -const BookItemStyled = styled.div` +const BookItemStyled = styled.div>` display: flex; flex-direction: column; box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); @@ -36,6 +38,7 @@ const BookItemStyled = styled.div` .img { border-radius: ${({ theme }) => theme.borderRadius.default}; overflow: hidden; + width: ${({ view }) => (view === "grid" ? "auto" : "160px")}; img { max-width: 100%; } @@ -44,6 +47,7 @@ const BookItemStyled = styled.div` .content { padding: 16px; position: relative; + flex: ${({ view }) => (view === "grid" ? 0 : 1)}; .title { font-size: 1.25rem; diff --git a/client/src/components/books/BooksList.tsx b/client/src/components/books/BooksList.tsx index 6e09c82..030c8d0 100644 --- a/client/src/components/books/BooksList.tsx +++ b/client/src/components/books/BooksList.tsx @@ -1,26 +1,44 @@ +import { useEffect, useState } from "react"; +import { useLocation } from "react-router-dom"; import { styled } from "styled-components"; import { Book } from "../../models/book.model"; +import { QUERYSTRING } from "../constants/querystring"; import BookItem from "./BookItem"; +import { ViewMode } from "./BooksViewSwitcher"; interface Props { books: Book[] } const BooksList = ({ books}: Props) => { + const [view, setView] = useState('grid'); + const location = useLocation(); + + useEffect(() => { + const params = new URLSearchParams(location.search) + if (params.get(QUERYSTRING.VIEW)) { + setView(params.get(QUERYSTRING.VIEW) as ViewMode) + } + }, [location.search]) + return ( - + { books?.map((item) => ( - + )) } ); }; -const BooksListStyle = styled.div` +interface BooksListStyleProps { + view: ViewMode; +} + +const BooksListStyle = styled.div` display: grid; - grid-template-columns: repeat(4, 1fr); + grid-template-columns: ${({ view }) => (view === 'grid' ? "repeat(4, 1fr)" : "repeat(1, 1fr)")}; gap: 24px; `; diff --git a/client/src/components/books/BooksViewSwitcher.tsx b/client/src/components/books/BooksViewSwitcher.tsx index 1775e38..15f36b3 100644 --- a/client/src/components/books/BooksViewSwitcher.tsx +++ b/client/src/components/books/BooksViewSwitcher.tsx @@ -1,13 +1,63 @@ +import { useEffect } from "react"; +import { FaList, FaTh } from "react-icons/fa"; +import { useSearchParams } from "react-router-dom"; import { styled } from "styled-components"; +import Button from "../common/Button"; +import { QUERYSTRING } from "../constants/querystring"; + +const viewOptions = [ + { + value: 'list', + icon: + }, + { + value: 'grid', + icon: + } +] + +export type ViewMode = 'grid' | 'list' const BooksViewSwitcher = () => { + const [searchParams, setSearchParams] = useSearchParams() + + const handleSwitch = (value: ViewMode) => { + const newSearchParams = new URLSearchParams(searchParams); + + newSearchParams.set(QUERYSTRING.VIEW, value) + setSearchParams(newSearchParams); + } + + useEffect(() => { + if (!searchParams.get(QUERYSTRING.VIEW)) { + handleSwitch('grid'); + } + }, []) + return ( -
-

BooksViewSwitcher

-
+ + { + viewOptions.map((option) => ( + + )) + } + ); }; -const BooksViewSwitcherStyled = styled.div``; +const BooksViewSwitcherStyle = styled.div` + display: flex; + gap: 8px; + svg { + fill: #fff; + } +`; export default BooksViewSwitcher; diff --git a/client/src/components/constants/querystring.ts b/client/src/components/constants/querystring.ts index 54018a0..c43062c 100644 --- a/client/src/components/constants/querystring.ts +++ b/client/src/components/constants/querystring.ts @@ -1,5 +1,6 @@ export const QUERYSTRING = { CATEGORY_ID: 'category_id', NEWS: 'news', - PAGE: 'page' + PAGE: 'page', + VIEW: 'view' } diff --git a/server/package.json b/server/package.json index f3c180a..d4d2870 100644 --- a/server/package.json +++ b/server/package.json @@ -12,7 +12,7 @@ "test": "jest --runInBand --detectOpenHandles --forceExit", "test:only-changed": "jest --runInBand --onlyChanged", "test:watch": "jest --watch --runInBand --detectOpenHandles --forceExit", - "start": "tsx --watch src/index.ts" + "start": "tsx watch src/index.ts" }, "keywords": [], "author": "",