diff --git a/src/Components/Nav.js b/src/Components/Nav.js index 8de47a6..11cc4b4 100644 --- a/src/Components/Nav.js +++ b/src/Components/Nav.js @@ -2,7 +2,7 @@ import React from 'react'; import { withRouter } from 'react-router-dom'; import { Layout, Menu } from 'antd'; -import sitemap from '../Utils/sitemap'; +import { sitemap } from '../Constants'; const { Header } = Layout; diff --git a/src/Components/TableModal.js b/src/Components/TableModal.js new file mode 100644 index 0000000..ed5ed6c --- /dev/null +++ b/src/Components/TableModal.js @@ -0,0 +1,93 @@ +/* eslint-disable react/prop-types */ +import React from 'react'; +import styled from 'styled-components/macro'; + +const TableModal = ({ data }) => { + return ( + + beer_image + +

{data.name}

+

{data.description}

+
+ ABV : {data.abv} + PH : {data.ph} + IBU : {data.ibu} + SRM : {data.srm} + EBC : {data.ebc} + TARGET FG : {data.target_fg} + TARGET OG : {data.target_og} + FIRST BREWED : {data.first_brewed} + TAGLINE : {data.tagline} +
+
+ ); +}; + +const S = {}; +S.Container = styled.section` + /* width */ + ::-webkit-scrollbar { + width: 8px; + } + + /* Track */ + ::-webkit-scrollbar-track { + background: none; + margin: 1px 8px; + } + + /* Handle */ + ::-webkit-scrollbar-thumb { + background: lightgray; + border-radius: 10px; + } + + /* Handle on hover */ + ::-webkit-scrollbar-thumb:hover { + background: gray; + } + + margin-top: 40px; + display: flex; + align-items: center; + justify-content: center; + gap: 5rem; + overflow: auto; + + img { + height: 400px; + object-fit: cover; + } +`; + +S.ContentWrapper = styled.section` + height: 400px; + width: 60%; + display: flex; + flex-direction: column; + text-align: left; + + hr { + width: 100%; + border: 2px solid black; + } + + h1 { + margin: -5px 0 20px 0; + text-align: center; + } + + h3 { + font-style: italic; + } + + span:after { + content: ''; + display: block; + border-bottom: 0.5px solid lightgray; + margin: 8px 0; + } +`; + +export default TableModal; diff --git a/src/Constants/index.js b/src/Constants/index.js new file mode 100644 index 0000000..b424d14 --- /dev/null +++ b/src/Constants/index.js @@ -0,0 +1,88 @@ +export const UNIT = { + PERCENT: '%', +}; + +export const sitemap = [ + { + name: 'HOME', + path: '/home', + }, + { + name: 'BEERs', + path: '/beerlist', + }, + { + name: 'CART', + path: '/cart', + }, +]; + +export const abvRange = [ + { + range: [3, 4], + unit: UNIT.PERCENT, + }, + { + range: [4, 5], + unit: UNIT.PERCENT, + }, + { + range: [5, 6], + unit: UNIT.PERCENT, + }, + { + range: [6, 7], + unit: UNIT.PERCENT, + }, + { + range: [7, 8], + unit: UNIT.PERCENT, + }, + { + range: [8, 9], + unit: UNIT.PERCENT, + }, + { + range: [10, 100], + unit: `10${UNIT.PERCENT} 이상`, + }, +]; + +export const beerListColumns = [ + { + title: 'NAME', + field: 'name', + cellStyle: { + // whiteSpace: 'nowrap', + minWidth: '18rem', + }, + }, + { + title: 'TAGLINE', + field: 'tagline', + cellStyle: { + // whiteSpace: 'nowrap', + minWidth: '18rem', + }, + }, + { + title: 'ABV', + field: 'abv', + }, + { + title: 'IBU', + field: 'ibu', + }, + { + title: 'SRM', + field: 'srm', + }, + { + title: 'EBC', + field: 'ebc', + }, + { + title: 'PH', + field: 'ph', + }, +]; diff --git a/src/Hooks/useFetch.js b/src/Hooks/useFetch.js deleted file mode 100644 index 89ff463..0000000 --- a/src/Hooks/useFetch.js +++ /dev/null @@ -1,22 +0,0 @@ -import { useState, useEffect } from 'react'; - -const useFetchData = callback => { - const [isFetched, setIsFetched] = useState(false); - const [data, setData] = useState(null); - const [error, setError] = useState(null); - - useEffect(() => { - callback() - .then(res => { - setData(res.data); - setIsFetched(true); - }) - .catch(err => { - setError(err); - }); - }, [callback]); - - return [isFetched, data, error]; -}; - -export default useFetchData; diff --git a/src/Hooks/useFilter.js b/src/Hooks/useFilter.js deleted file mode 100644 index a6798cd..0000000 --- a/src/Hooks/useFilter.js +++ /dev/null @@ -1,5 +0,0 @@ -import { useState, useEffect } from 'react'; - -const useFilter = (range, data) => { - const [value, setValue] = useState(initialValue); -}; diff --git a/src/Modules/listColumns.js b/src/Modules/listColumns.js index ebcad34..673ac55 100644 --- a/src/Modules/listColumns.js +++ b/src/Modules/listColumns.js @@ -1,10 +1,12 @@ -import defaultColumns from '../Utils/defaultColumns'; +// Duck 패턴 https://github.com/JisuPark/ducks-modular-redux + +import { beerListColumns } from '../Constants'; const initialState = { loading: false, error: null, - defaultColumns, - modifiedColumns: defaultColumns, + beerListColumns, + modifiedColumns: beerListColumns, }; export const SET_COLUMNS_REQUEST = 'listColumns/SET_COLUMNS_REQUEST'; diff --git a/src/Modules/saga/beerListSaga.js b/src/Modules/saga/beerListSaga.js index f2866a5..5ec1393 100644 --- a/src/Modules/saga/beerListSaga.js +++ b/src/Modules/saga/beerListSaga.js @@ -1,5 +1,5 @@ import { call, put, takeLatest } from 'redux-saga/effects'; -import defaultColumns from '../../Utils/defaultColumns'; +import { beerListColumns } from '../../Constants'; import { GET_BEER_LIST_REQUEST, getBeerListSuccess, @@ -11,7 +11,7 @@ function* getBeerList() { try { const { data: rawData } = yield call(APIs.getBeerList); // yield call은 결과 반환시까지 기다려줌 const renderData = rawData.map(beer => { - return defaultColumns.reduce((acc, cur) => { + return beerListColumns.reduce((acc, cur) => { if (cur.field in beer) { acc[cur.field] = beer[cur.field]; } diff --git a/src/Pages/BeerList.js b/src/Pages/BeerList.js index e55ce4e..a139d36 100644 --- a/src/Pages/BeerList.js +++ b/src/Pages/BeerList.js @@ -7,9 +7,10 @@ import tableIcons from '../Assets/tableIcons'; import PatchedPagination from '../Components/PatchedPagination'; import { ContainerStyle, ScrollStyle } from '../Styles/commonStyles'; import { setColumnsRequest } from '../Modules/listColumns'; -import abvRange from '../Utils/abvRange'; import AbvFilterButton from '../Components/AbvFilterButton'; -import filterDataByAbv from '../Utils/filterDataByAbv'; +import TableModal from '../Components/TableModal'; +import { getTableOptions, filterDataByAbv } from '../Utils'; +import { abvRange } from '../Constants'; const BeerList = () => { const dispatch = useDispatch(); @@ -23,32 +24,23 @@ const BeerList = () => { isColumnLoaded: state.listColumnReducer.loading, })); - const [selectedRange, setSelectedRange] = useState(new Set([])); + const [selectedRange, setSelectedRange] = useState(new Set()); const columnDragHandler = (fromIdx, toIdx) => { dispatch(setColumnsRequest(fromIdx, toIdx, columns)); }; - const tableOptions = { - headerStyle: { - backgroundColor: '#1890FF', - color: '#FFF', - fontSize: '1rem', - }, - pageSize: 6, - pageSizeOptions: [6, 10, 15], - }; - const rowClickHandler = (_, selected) => { const { id } = selected.tableData; Modal.info({ - title: '맥주 상세 정보', - width: '50%', - content:

모달

, + title: '맥주 상세정보', + width: '50vw', + content: , onOk() {}, }); }; + const tableOptions = getTableOptions({}); const filteredData = filterDataByAbv( [...selectedRange], renderData, @@ -61,7 +53,7 @@ const BeerList = () => { {abvRange.map(({ range, unit }, idx) => { const props = { selectedRange, setSelectedRange, range, unit, idx }; // eslint-disable-next-line react/jsx-props-no-spreading - return ; + return ; })}

알콜 도수(ABV) 필터

diff --git a/src/Utils/abvRange.js b/src/Utils/abvRange.js deleted file mode 100644 index 004e378..0000000 --- a/src/Utils/abvRange.js +++ /dev/null @@ -1,30 +0,0 @@ -export default [ - { - range: [3, 4], - unit: '%', - }, - { - range: [4, 5], - unit: '%', - }, - { - range: [5, 6], - unit: '%', - }, - { - range: [6, 7], - unit: '%', - }, - { - range: [7, 8], - unit: '%', - }, - { - range: [8, 9], - unit: '%', - }, - { - range: [10, 100], - unit: '10% 이상', - }, -]; diff --git a/src/Utils/defaultColumns.js b/src/Utils/defaultColumns.js deleted file mode 100644 index d6de4a7..0000000 --- a/src/Utils/defaultColumns.js +++ /dev/null @@ -1,38 +0,0 @@ -export default [ - { - title: 'NAME', - field: 'name', - cellStyle: { - // whiteSpace: 'nowrap', - minWidth: '18rem', - }, - }, - { - title: 'TAGLINE', - field: 'tagline', - cellStyle: { - // whiteSpace: 'nowrap', - minWidth: '18rem', - }, - }, - { - title: 'ABV', - field: 'abv', - }, - { - title: 'IBU', - field: 'ibu', - }, - { - title: 'SRM', - field: 'srm', - }, - { - title: 'EBC', - field: 'ebc', - }, - { - title: 'PH', - field: 'ph', - }, -]; diff --git a/src/Utils/filterDataByAbv.js b/src/Utils/filterDataByAbv.js deleted file mode 100644 index 9deea23..0000000 --- a/src/Utils/filterDataByAbv.js +++ /dev/null @@ -1,13 +0,0 @@ -export default (selectedRange, data, abvRange) => { - if (selectedRange.length === 0) { - return data; - } - return selectedRange.reduce((acc, cur) => { - const { - range: [fromRange, toRange], - } = abvRange[cur]; - return acc.concat( - data?.filter(({ abv }) => !!(fromRange <= abv && toRange >= abv)), - ); - }, []); -}; diff --git a/src/Utils/index.js b/src/Utils/index.js new file mode 100644 index 0000000..4e00d86 --- /dev/null +++ b/src/Utils/index.js @@ -0,0 +1,27 @@ +// 맥주 리스트 ABV 데이터 필터 +export const filterDataByAbv = (selectedRange, data, abvRange) => { + if (selectedRange.length === 0) { + return data; + } + return selectedRange.reduce((acc, cur) => { + const { + range: [fromRange, toRange], + } = abvRange[cur]; + return acc.concat( + data?.filter(({ abv }) => !!(fromRange <= abv && toRange >= abv)), + ); + }, []); +}; + +export const getTableOptions = styles => { + const defaultOptions = { + headerStyle: styles?.headerStyle ?? { + backgroundColor: '#1890FF', + color: '#FFF', + fontSize: '1rem', + }, + pageSize: styles?.pageSize ?? 6, + pageSizeOptions: styles?.pageSizeOptions ?? [6, 10, 15], + }; + return defaultOptions; +}; diff --git a/src/Utils/sitemap.js b/src/Utils/sitemap.js deleted file mode 100644 index 3f49ed0..0000000 --- a/src/Utils/sitemap.js +++ /dev/null @@ -1,14 +0,0 @@ -export default [ - { - name: 'HOME', - path: '/home', - }, - { - name: 'BEERs', - path: '/beerlist', - }, - { - name: 'CART', - path: '/cart', - }, -];