From 836662e9cfa8c9a17c4a4db5a58abc288211182a Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Tue, 22 Aug 2023 22:18:41 +0900 Subject: [PATCH 01/34] =?UTF-8?q?[ADD]=20=EB=B0=B0=EA=B2=BD=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/images/logo.svg | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/frontend/public/images/logo.svg b/frontend/public/images/logo.svg index c51734b..4d2f370 100644 --- a/frontend/public/images/logo.svg +++ b/frontend/public/images/logo.svg @@ -1,11 +1,21 @@ - - - + + + + + + - - - - - - From dcc79511393d0409a01691452223101ce3853f57 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Tue, 22 Aug 2023 22:43:33 +0900 Subject: [PATCH 02/34] =?UTF-8?q?[FIX]=20#409:=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EC=98=B5=EC=85=98=20Hmg=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=97=86=EC=9D=84=20=EB=95=8C=20=ED=83=9C=EA=B7=B8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionPage/OptionBannerContainer.tsx | 46 +++++++++++-------- frontend/src/pages/OptionPage.tsx | 26 ++--------- 2 files changed, 31 insertions(+), 41 deletions(-) diff --git a/frontend/src/containers/OptionPage/OptionBannerContainer.tsx b/frontend/src/containers/OptionPage/OptionBannerContainer.tsx index 1a892ee..dd22b2b 100644 --- a/frontend/src/containers/OptionPage/OptionBannerContainer.tsx +++ b/frontend/src/containers/OptionPage/OptionBannerContainer.tsx @@ -9,18 +9,13 @@ import CenterWrapper from '../../components/common/layout/CenterWrapper'; import Banner from '../../components/common/banner/Banner'; import HmgTag from '../../components/common/hmgTag/HmgTag'; import OptionTab from '../../components/tabs/OptionTab'; -import { useEffect, useState } from 'react'; -import { IMG_URL } from '../../utils/apis'; +import { useContext, useEffect, useState } from 'react'; +import { IMG_URL, OPTION_API } from '../../utils/apis'; +import { DefaultOptionContext } from '../../context/DefaultOptionProvider'; +import { SubOptionContext } from '../../context/SubOptionProvider'; +import { CAR_TYPE } from '../../utils/constants'; +import { useFetch } from '../../hooks/useFetch'; -export interface IOptionDetail { - categoryName: string; - optionName: string; - optionDescription: string; - optionImage: string; - hmgData: IHmgData | null; - subOptionList: ISubOptionList[] | null; - package: boolean; -} interface IHmgData { optionBoughtCount: number; optionUsedCount: number; @@ -37,15 +32,29 @@ export interface ISubOptionList { subOptionList: null; } +export interface IOptionDetail { + categoryName: string; + optionName: string; + optionDescription: string; + optionImage: string; + hmgData: IHmgData | null; + subOptionList: ISubOptionList[] | null; + package: boolean; +} + interface IOptionBannerContainer { - optionDetail: IOptionDetail; - optionDetailLoading: boolean; + isDefault: boolean; } +export default function OptionBannerContainer({ isDefault }: IOptionBannerContainer) { + const defaultOptionContext = useContext(DefaultOptionContext); + const subOptionContext = useContext(SubOptionContext); + const { currentOptionIdx } = isDefault ? defaultOptionContext : subOptionContext; + const optionType = isDefault ? 'default' : 'sub'; + + const { data: optionDetail, loading: optionDetailLoading } = useFetch( + `${OPTION_API}/${optionType}/detail/?carid=${CAR_TYPE}&optionid=${currentOptionIdx}` + ); -export default function OptionBannerContainer({ - optionDetail, - optionDetailLoading, -}: IOptionBannerContainer) { const [bannerInfo, setBannerInfo] = useState({ categoryName: '', hmgData: null, @@ -76,6 +85,7 @@ export default function OptionBannerContainer({ }, []); useEffect(() => { + if (!optionDetail) return; const target = optionDetail.subOptionList ? optionDetail.subOptionList[0] : optionDetail; setBannerInfo({ categoryName: target.categoryName, @@ -115,7 +125,7 @@ export default function OptionBannerContainer({ )} - {bannerInfo.hmgData && ( + {bannerInfo.hmgData?.optionBoughtCount && ( diff --git a/frontend/src/pages/OptionPage.tsx b/frontend/src/pages/OptionPage.tsx index f2587e2..6fc51d7 100644 --- a/frontend/src/pages/OptionPage.tsx +++ b/frontend/src/pages/OptionPage.tsx @@ -8,18 +8,8 @@ import OptionFooterContainer from '../containers/OptionPage/OptionFooterContaine import { ISubOption, SubOptionContext } from '../context/SubOptionProvider'; import { DefaultOptionContext, IDefaultOption } from '../context/DefaultOptionProvider'; import ErrorModal from '../components/modal/ErrorModal'; -import { CAR_TYPE } from '../utils/constants'; import Loading from '../components/loading/Loading'; -interface IOptionDetail { - categoryName: string; - optionName: string; - optionDescription: string; - optionImage: string; - hmgData: IHmgData | null; - subOptionList: ISubOptionList[] | null; - package: boolean; -} interface IHmgData { optionBoughtCount: number; optionUsedCount: number; @@ -37,13 +27,10 @@ export interface ISubOptionList { } export default function OptionPage() { - const defaultOptionContext = useContext(DefaultOptionContext); - const subOptionContext = useContext(SubOptionContext); const [isDefault, setIsDefault] = useState(false); const handleTabItemClick = (isDefault: boolean) => { setIsDefault(isDefault); }; - const { currentOptionIdx } = isDefault ? defaultOptionContext : subOptionContext; const { data: subOption, @@ -57,7 +44,6 @@ export default function OptionPage() { } = useFetch(`${OPTION_API}/defaultlist?carid=${1}`); const { setSubOption, setSubOptionLoading } = useContext(SubOptionContext); const { setDefaultOption, setDefaultOptionLoading } = useContext(DefaultOptionContext); - const optionType = isDefault ? 'default' : 'sub'; useEffect(() => { setSubOption(subOption); @@ -75,24 +61,18 @@ export default function OptionPage() { setDefaultOptionLoading, ]); - const { data: optionDetail, loading: optionDetailLoading } = useFetch( - `${OPTION_API}/${optionType}/detail/?carid=${CAR_TYPE}&optionid=${currentOptionIdx}` - ); - if (subOptionError) { return ; } else if (defaultOptionError) { return ; } + return ( - {subOption && !subOptionLoading && optionDetail && !optionDetailLoading ? ( + {subOption && !subOptionLoading ? ( <> - + From 21fe75d4509e4931ce09e26508af50c7c88b2828 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Tue, 22 Aug 2023 22:55:15 +0900 Subject: [PATCH 03/34] =?UTF-8?q?[REFACTOR]=20#409:=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EB=AC=B8=20=EB=B0=96=EC=9C=BC=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/containers/OptionPage/OptionBannerContainer.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/containers/OptionPage/OptionBannerContainer.tsx b/frontend/src/containers/OptionPage/OptionBannerContainer.tsx index dd22b2b..adca63e 100644 --- a/frontend/src/containers/OptionPage/OptionBannerContainer.tsx +++ b/frontend/src/containers/OptionPage/OptionBannerContainer.tsx @@ -77,6 +77,9 @@ export default function OptionBannerContainer({ isDefault }: IOptionBannerContai const handleDescVisibility = (visible: boolean) => { setVisibleDesc(visible); }; + const hasHmgData = + bannerInfo.hmgData && + (bannerInfo.hmgData.optionBoughtCount || bannerInfo.hmgData.optionUsedCount); useEffect(() => { window.addEventListener('scroll', handleScroll); return () => { @@ -125,7 +128,7 @@ export default function OptionBannerContainer({ isDefault }: IOptionBannerContai )} - {bannerInfo.hmgData?.optionBoughtCount && ( + {hasHmgData && ( From 9881199b62c896fc034dacbdc9a7c4876312d2bf Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 10:17:26 +0900 Subject: [PATCH 04/34] =?UTF-8?q?[FIX]=20#409:=20=ED=98=B8=EB=B2=84=20desc?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=EC=97=90=20=EA=B0=80=EB=A6=AC=EB=8A=94=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/banner/Banner.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/common/banner/Banner.tsx b/frontend/src/components/common/banner/Banner.tsx index fb2319c..90928a8 100644 --- a/frontend/src/components/common/banner/Banner.tsx +++ b/frontend/src/components/common/banner/Banner.tsx @@ -90,7 +90,6 @@ const Title = styled.p<{ $isOverflow: boolean }>` ${({ $isOverflow }) => { if ($isOverflow) return css` - z-index: 1; animation-play-state: paused; &:hover { cursor: pointer; From 3fbe17ffa0b487b4a2410fb20ce39ddab05705d7 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 10:17:52 +0900 Subject: [PATCH 05/34] =?UTF-8?q?[FIX]=20#409:=20null=20=EC=97=90=EB=9F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../containers/OptionPage/OptionBannerContainer.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/containers/OptionPage/OptionBannerContainer.tsx b/frontend/src/containers/OptionPage/OptionBannerContainer.tsx index adca63e..7285549 100644 --- a/frontend/src/containers/OptionPage/OptionBannerContainer.tsx +++ b/frontend/src/containers/OptionPage/OptionBannerContainer.tsx @@ -132,24 +132,24 @@ export default function OptionBannerContainer({ isDefault }: IOptionBannerContai - {bannerInfo.hmgData.optionBoughtCount !== null && ( + {bannerInfo.hmgData!.optionBoughtCount !== null && ( - {bannerInfo.hmgData.overHalf + {bannerInfo.hmgData!.overHalf ? '구매자의 절반 이상이 선택했어요.' : '구매자가 이 옵션을 이만큼 선택했어요.'} - {Number(bannerInfo.hmgData.optionBoughtCount).toLocaleString()}개 + {Number(bannerInfo.hmgData!.optionBoughtCount).toLocaleString()}개 최근 90일 동안 )} - {bannerInfo.hmgData.optionUsedCount !== null && ( + {bannerInfo.hmgData!.optionUsedCount !== null && ( 주행 중 실제로 이만큼 사용해요. - {bannerInfo.hmgData.optionUsedCount}번 + {bannerInfo.hmgData!.optionUsedCount}번 1.5만km 당 From 6a7eb8310701cb1af2c7735d51815139cc52fb08 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 10:35:38 +0900 Subject: [PATCH 06/34] =?UTF-8?q?[FIX]=20#409:=20hovercaption=20z-index=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/banner/Banner.tsx | 1 + frontend/src/components/tabs/OptionTab.tsx | 2 ++ frontend/src/containers/OptionPage/OptionBannerContainer.tsx | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/common/banner/Banner.tsx b/frontend/src/components/common/banner/Banner.tsx index 90928a8..fb2319c 100644 --- a/frontend/src/components/common/banner/Banner.tsx +++ b/frontend/src/components/common/banner/Banner.tsx @@ -90,6 +90,7 @@ const Title = styled.p<{ $isOverflow: boolean }>` ${({ $isOverflow }) => { if ($isOverflow) return css` + z-index: 1; animation-play-state: paused; &:hover { cursor: pointer; diff --git a/frontend/src/components/tabs/OptionTab.tsx b/frontend/src/components/tabs/OptionTab.tsx index 79e8903..c940d37 100644 --- a/frontend/src/components/tabs/OptionTab.tsx +++ b/frontend/src/components/tabs/OptionTab.tsx @@ -119,6 +119,8 @@ export default function OptionTab({ options, setBannerInfo }: ISubOptionTab) { ); } const HoverCaption = styled.div` + z-index: 2; + display: none; white-space: nowrap; left: 0; diff --git a/frontend/src/containers/OptionPage/OptionBannerContainer.tsx b/frontend/src/containers/OptionPage/OptionBannerContainer.tsx index 7285549..c4bd163 100644 --- a/frontend/src/containers/OptionPage/OptionBannerContainer.tsx +++ b/frontend/src/containers/OptionPage/OptionBannerContainer.tsx @@ -180,6 +180,8 @@ export default function OptionBannerContainer({ isDefault }: IOptionBannerContai ); } const HoverCaption = styled.div<{ $visible: boolean }>` + z-index: 2; + white-space: pre-wrap; padding: 4px 12px; border-radius: 10px; @@ -187,7 +189,6 @@ const HoverCaption = styled.div<{ $visible: boolean }>` color: ${({ theme }) => theme.color.gray50}; opacity: 90%; margin-top: 10px; - z-index: 1; width: 448px; background-color: ${({ theme }) => theme.color.gray900}; ${BodyKrRegular4} From ac987c93ff32d513b9b01248e03de87e3614ae14 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 12:04:13 +0900 Subject: [PATCH 07/34] =?UTF-8?q?[FEAT]=20#409:=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=ED=82=A4=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/icons/Icons.tsx | 16 ++++ .../src/components/searchBar/SearchBar.tsx | 91 ++++++++++++++++--- 2 files changed, 94 insertions(+), 13 deletions(-) diff --git a/frontend/src/components/common/icons/Icons.tsx b/frontend/src/components/common/icons/Icons.tsx index 454d856..6526031 100644 --- a/frontend/src/components/common/icons/Icons.tsx +++ b/frontend/src/components/common/icons/Icons.tsx @@ -229,3 +229,19 @@ export function CopyIcon() { ); } + +export function NorthWest({ active, ...props }: ISvg) { + const color = active ? theme.color.white : theme.color.gray200; + return ( + + + + ); +} diff --git a/frontend/src/components/searchBar/SearchBar.tsx b/frontend/src/components/searchBar/SearchBar.tsx index d8b55fe..6e4c201 100644 --- a/frontend/src/components/searchBar/SearchBar.tsx +++ b/frontend/src/components/searchBar/SearchBar.tsx @@ -1,20 +1,69 @@ import { styled } from 'styled-components'; import { BodyKrRegular4 } from '../../styles/typefaces'; -import { SearchIcon } from '../common/icons/Icons'; +import { NorthWest, SearchIcon } from '../common/icons/Icons'; import React, { Dispatch, useCallback, useEffect, useRef, useState } from 'react'; +import { flexCenterCss } from '../../utils/commonStyle'; interface SearchBarProps extends React.HTMLAttributes { value: string; result: string[]; setQuery: Dispatch>; } + +interface IKeyEvent { + [key: string]: () => void; +} export default function SearchBar({ value, result, setQuery, ...props }: SearchBarProps) { + const [focusIndex, setFocusIndex] = useState(-1); + const listRef = useRef(null); const [visibleAutoBox, setVisibleAutoBox] = useState(true); const searchBarRef = useRef(null); const displayData = result.map((res, index) => ( - {res} + + {res} + + + + )); + const KeyEvent: IKeyEvent = { + Enter: () => { + focusIndex >= 0 ? setQuery(result[focusIndex]) : setQuery(value); + setVisibleAutoBox(false); + }, + ArrowDown: () => { + if (result.length === 0) { + return; + } + if (listRef.current && listRef.current.childElementCount === focusIndex + 1) { + setFocusIndex(() => 0); + return; + } + setFocusIndex((index) => index + 1); + }, + ArrowUp: () => { + if (focusIndex === -1) { + return; + } + if (focusIndex === 0) { + setFocusIndex((index) => index - 1); + return; + } + setFocusIndex((index) => index - 1); + }, + Escape: () => { + setFocusIndex(-1); + }, + }; + + const handleKeyUp = (e: React.KeyboardEvent) => { + setVisibleAutoBox(true); + if (KeyEvent[e.key]) { + KeyEvent[e.key](); + } + }; + const handleClick = useCallback( (event: MouseEvent) => { const target = event.target as HTMLInputElement; @@ -28,6 +77,7 @@ export default function SearchBar({ value, result, setQuery, ...props }: SearchB }, [setQuery] ); + useEffect(() => { window.addEventListener('click', (e) => handleClick(e)); return () => { @@ -35,19 +85,25 @@ export default function SearchBar({ value, result, setQuery, ...props }: SearchB }; }, [handleClick]); + useEffect(() => {}, [focusIndex]); + useEffect(() => { - if (!value) return; - setVisibleAutoBox(true); - }, [value]); + if (!value) { + setVisibleAutoBox(false); + return; + } + + setFocusIndex(-1); + }, [value, visibleAutoBox, result]); return ( - + handleKeyUp(e)} {...props} /> 0 && visibleAutoBox}> - {displayData} + {displayData} ); @@ -73,11 +129,6 @@ const AutoSearchWrapper = styled.ul``; const AutoSearchData = styled.li` padding: 8px 16px; width: 100%; - &:hover { - background-color: ${({ theme }) => theme.color.activeBlue2}; - color: ${({ theme }) => theme.color.white}; - cursor: pointer; - } `; const Wrapper = styled.div` position: relative; @@ -106,9 +157,23 @@ const Input = styled.input.attrs(({ value }) => ({ color: ${({ theme }) => theme.color.gray600}; } `; - +const ListItem = styled.div<{ $focus: boolean }>` + ${flexCenterCss} + background-color: ${({ $focus, theme }) => ($focus ? theme.color.activeBlue2 : 'transparent')}; + color: ${({ $focus, theme }) => ($focus ? theme.color.white : theme.color.gray900)}; + &:hover { + background-color: ${({ theme }) => theme.color.activeBlue2}; + color: ${({ theme }) => theme.color.white}; + opacity: 0.5; + cursor: pointer; + } +`; const Button = styled.button` width: 67px; height: 100%; background-color: ${({ theme }) => theme.color.gray100}; `; + +const IconBtn = styled.button` + padding: 8px 16px; +`; From 2e1fcda769be76f10423f556b107fcf0a1a2a342 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 12:09:57 +0900 Subject: [PATCH 08/34] =?UTF-8?q?[FIX]=20#409:=20result=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/searchBar/SearchBar.tsx | 13 ++++++++++--- .../OptionSelectContainer/OptionSelectContainer.tsx | 1 + .../OptionSelectContainer/SubOptionContainer.tsx | 1 - 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/searchBar/SearchBar.tsx b/frontend/src/components/searchBar/SearchBar.tsx index 6e4c201..cb2ac32 100644 --- a/frontend/src/components/searchBar/SearchBar.tsx +++ b/frontend/src/components/searchBar/SearchBar.tsx @@ -8,12 +8,19 @@ interface SearchBarProps extends React.HTMLAttributes { value: string; result: string[]; setQuery: Dispatch>; + setResult: Dispatch>; } interface IKeyEvent { [key: string]: () => void; } -export default function SearchBar({ value, result, setQuery, ...props }: SearchBarProps) { +export default function SearchBar({ + value, + result, + setQuery, + setResult, + ...props +}: SearchBarProps) { const [focusIndex, setFocusIndex] = useState(-1); const listRef = useRef(null); const [visibleAutoBox, setVisibleAutoBox] = useState(true); @@ -89,12 +96,12 @@ export default function SearchBar({ value, result, setQuery, ...props }: SearchB useEffect(() => { if (!value) { + setResult([]); setVisibleAutoBox(false); return; } - setFocusIndex(-1); - }, [value, visibleAutoBox, result]); + }, [value, visibleAutoBox, result, setResult]); return ( diff --git a/frontend/src/containers/OptionPage/OptionSelectContainer/OptionSelectContainer.tsx b/frontend/src/containers/OptionPage/OptionSelectContainer/OptionSelectContainer.tsx index bbef524..c69404e 100644 --- a/frontend/src/containers/OptionPage/OptionSelectContainer/OptionSelectContainer.tsx +++ b/frontend/src/containers/OptionPage/OptionSelectContainer/OptionSelectContainer.tsx @@ -136,6 +136,7 @@ export default function OptionSelectContainer({ value={query} result={result} setQuery={setQuery} + setResult={setResult} onChange={(e) => { handleInputChange(e.currentTarget.value); }} diff --git a/frontend/src/containers/OptionPage/OptionSelectContainer/SubOptionContainer.tsx b/frontend/src/containers/OptionPage/OptionSelectContainer/SubOptionContainer.tsx index f26e3ce..5562f12 100644 --- a/frontend/src/containers/OptionPage/OptionSelectContainer/SubOptionContainer.tsx +++ b/frontend/src/containers/OptionPage/OptionSelectContainer/SubOptionContainer.tsx @@ -110,7 +110,6 @@ export default function SubOptionContainer({ useEffect(() => { if (!filteredByCategory || !query) { setDisplayData(filteredByCategory); - return; } From 4e4f00dce034eb47e0c5c463cdb41a6d8b9d9143 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 12:13:34 +0900 Subject: [PATCH 09/34] =?UTF-8?q?[REFACTOR]=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/tabs/OptionTab.tsx | 23 ++++------------------ 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/tabs/OptionTab.tsx b/frontend/src/components/tabs/OptionTab.tsx index c940d37..308de17 100644 --- a/frontend/src/components/tabs/OptionTab.tsx +++ b/frontend/src/components/tabs/OptionTab.tsx @@ -1,4 +1,4 @@ -import { Dispatch, HTMLAttributes, SetStateAction, useEffect, useRef, useState } from 'react'; +import { Dispatch, HTMLAttributes, SetStateAction, useEffect, useState } from 'react'; import { BodyKrMedium3, BodyKrRegular3, BodyKrRegular4 } from '../../styles/typefaces'; import styled, { css, useTheme } from 'styled-components'; import { ArrowLeft, ArrowRight } from '../common/icons/Icons'; @@ -17,8 +17,6 @@ export default function OptionTab({ options, setBannerInfo }: ISubOptionTab) { const [page, setPage] = useState(0); const arrowLeftColor = page <= 0 ? theme.color.gray200 : theme.color.gray600; const arrowRightColor = page >= TAB_MAX_PAGE - 1 ? theme.color.gray200 : theme.color.gray600; - const tabDivisionRef = useRef(null); - const [tabDivisionWidth, setTabDivisionWidth] = useState(0); const displayUnderline = (groupIndex: number, index: number) => { return page === groupIndex && index === selectedIdx ? ( @@ -72,13 +70,6 @@ export default function OptionTab({ options, setBannerInfo }: ISubOptionTab) { setPage(0); }, [options]); - useEffect(() => { - if (tabDivisionRef.current) { - const tabDivisionWidth = tabDivisionRef.current.offsetWidth; - setTabDivisionWidth(tabDivisionWidth); - } - }, [tabDivisionRef]); - return ( <> @@ -88,8 +79,8 @@ export default function OptionTab({ options, setBannerInfo }: ISubOptionTab) { > - - + + <> {chunkedOptions.map((optionGroup: ISubOptionList[], groupIndex) => ( {optionGroup.map((option: ISubOptionList, index: number) => ( @@ -106,7 +97,7 @@ export default function OptionTab({ options, setBannerInfo }: ISubOptionTab) { ))} ))} - + ` - /* display: flex; */ - /* transition: transform 0.4s ease; */ - /* transform: translateX(${({ $offset }) => $offset}px); */ -`; const TabWrapperInner = styled.div` - /* overflow: hidden; */ width: 408px; height: 100%; `; From 4db141b1b79a25be811a88650a3ea1ad2ca8aa19 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 12:23:47 +0900 Subject: [PATCH 10/34] =?UTF-8?q?[FIX]=20#418:=20key=20=EB=B6=80=EC=97=AC?= =?UTF-8?q?=20=EB=B0=8F=20=EB=AC=B4=ED=95=9C=20=EB=A0=8C=EB=8D=94=EB=A7=81?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/searchBar/SearchBar.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/searchBar/SearchBar.tsx b/frontend/src/components/searchBar/SearchBar.tsx index cb2ac32..79c2b14 100644 --- a/frontend/src/components/searchBar/SearchBar.tsx +++ b/frontend/src/components/searchBar/SearchBar.tsx @@ -26,8 +26,8 @@ export default function SearchBar({ const [visibleAutoBox, setVisibleAutoBox] = useState(true); const searchBarRef = useRef(null); const displayData = result.map((res, index) => ( - - {res} + + {res} @@ -37,6 +37,7 @@ export default function SearchBar({ const KeyEvent: IKeyEvent = { Enter: () => { focusIndex >= 0 ? setQuery(result[focusIndex]) : setQuery(value); + setResult([]); setVisibleAutoBox(false); }, ArrowDown: () => { @@ -101,7 +102,7 @@ export default function SearchBar({ return; } setFocusIndex(-1); - }, [value, visibleAutoBox, result, setResult]); + }, [value, visibleAutoBox, setResult]); return ( From ab18251b894965f21b3e535386eae03c9feaa398 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:19:34 +0900 Subject: [PATCH 11/34] =?UTF-8?q?[STYLE]=20#420:=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=B0=8F=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../containers/ModelTypePage/ModelTypeBannerContainer.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/src/containers/ModelTypePage/ModelTypeBannerContainer.tsx b/frontend/src/containers/ModelTypePage/ModelTypeBannerContainer.tsx index 7678da4..31784a5 100644 --- a/frontend/src/containers/ModelTypePage/ModelTypeBannerContainer.tsx +++ b/frontend/src/containers/ModelTypePage/ModelTypeBannerContainer.tsx @@ -86,11 +86,12 @@ export default function ModelTypePage() { } const OptionDesc = styled.p` - width: 300px; + width: 400px; color: ${({ theme }) => theme.color.gray800}; ${BodyKrRegular4} padding-top: 150px; word-break: keep-all; + white-space: pre-wrap; `; const HmgDataSection = styled.div` @@ -116,8 +117,8 @@ const ImgSection = styled.img` position: absolute; top: 0; right: 0; - width: 632px; + min-width: 632px; height: 360px; - object-fit: cover; + object-fit: contain; object-position: center; `; From ab910446cb3fa82775e6f8afc6d4c83284520792 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:29:33 +0900 Subject: [PATCH 12/34] =?UTF-8?q?[STYLE]=20#420:=20=EC=98=88=EC=82=B0=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=EB=B0=94=20=EC=98=88=EC=82=B0=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../priceStaticBar/PriceStaticBar.tsx | 2 +- .../priceStaticBar/PriceStaticSlider.tsx | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/priceStaticBar/PriceStaticBar.tsx b/frontend/src/components/priceStaticBar/PriceStaticBar.tsx index 846d46e..e37cf54 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticBar.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticBar.tsx @@ -14,7 +14,7 @@ interface IOffset { offsetY: string; } export default function PriceStaticBar({ ...props }: IPriceStaticBar) { - const highestPrice = 80_000_000; //TODO : api 연동 + const highestPrice = 80_000_000; const { totalPrice, selectedItem } = useContext(ItemContext); const { pathname } = useLocation(); const theme = useTheme(); diff --git a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx index 687763f..4f67c5c 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx @@ -25,7 +25,12 @@ export default function Slider({ return ( - 예산: {budget / TEN_THOUSAND_UNIT}만 + + + 내가 설정한 예산은  + {budget / TEN_THOUSAND_UNIT}만원이에요. + + ( margin-top: -6px; } `; +const BlueText = styled.span<{ $isover: boolean }>` + color: ${({ theme, $isover }) => ($isover ? theme.color.sand : theme.color.activeBlue2)}; +`; const PriceInfo = styled.div<{ $isover: boolean }>` ${flexCenterCss}; From 83c45d3f76af99c4a32a6a88c8468e04a84c17c4 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:38:23 +0900 Subject: [PATCH 13/34] =?UTF-8?q?[STYLE]=20#420:=20=EC=98=88=EC=82=B0=20?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=20=EC=A0=95=EB=B3=B4=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/priceStaticBar/PriceStaticSlider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx index 4f67c5c..de5d502 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx @@ -70,7 +70,7 @@ const PriceBarWrapper = styled.div` const BudgetInfo = styled.div` ${BodyKrRegular3} position: absolute; - top: -25px; + top: -34px; right: 0px; background-color: black; opacity: 0.9; From 5b23067260cbae28dafa65b064ab2dd662217f18 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:11:35 +0900 Subject: [PATCH 14/34] =?UTF-8?q?[FEAT]=20#422:=20=EB=A1=9C=EC=BB=AC=20?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/context/ItemProvider.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/frontend/src/context/ItemProvider.tsx b/frontend/src/context/ItemProvider.tsx index 8b9627b..cfa7310 100644 --- a/frontend/src/context/ItemProvider.tsx +++ b/frontend/src/context/ItemProvider.tsx @@ -133,14 +133,26 @@ export default function ItemProvider({ children }: IItemProvider) { const [totalPrice, setTotalPrice] = useState(0); useEffect(() => { - const { price: trimPrice } = selectedItem.trim; - const { price: outerColorPrice } = selectedItem.outerColor; - const { price: innerColorPrice } = selectedItem.innerColor; + const { id: trimId, price: trimPrice } = selectedItem.trim; + const { id: outerColorId, price: outerColorPrice } = selectedItem.outerColor; + const { id: innerColorId, price: innerColorPrice } = selectedItem.innerColor; const { powerTrain, bodyType, operation } = selectedItem.modelType; const modelTypePrice = powerTrain.price + bodyType.price + operation.price; const optionsPrice = selectedItem.options.reduce((acc, option) => acc + option.price, 0); const total = trimPrice + modelTypePrice + outerColorPrice + innerColorPrice + optionsPrice; setTotalPrice(total); + const savedId = { + trimId: trimId, + modelTypeId: { + powerTrain: powerTrain.id, + bodyType: bodyType.id, + operation: operation.id, + }, + outerColorId: outerColorId, + innerColorId: innerColorId, + optionId: selectedItem.options.map((option) => option.id), + }; + localStorage.setItem('selectedItem', JSON.stringify(savedId)); }, [selectedItem]); return ( From 28244ac1c5cec869450bd1dc3a04e9a0e7776b74 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:41:23 +0900 Subject: [PATCH 15/34] =?UTF-8?q?[FEAT]=20#422:=20=EB=A1=9C=EC=BB=AC?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=20=EA=B0=92=20=EB=B6=88?= =?UTF-8?q?=EB=9F=AC=EC=99=80=EC=84=9C=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/banner/Banner.tsx | 2 +- frontend/src/components/modal/GuideModal.tsx | 7 +- frontend/src/context/ItemProvider.tsx | 126 +++++++++++++++++- frontend/src/context/ProgressProvider.tsx | 10 +- frontend/src/hooks/useSharedInfo.ts | 2 +- 5 files changed, 139 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/common/banner/Banner.tsx b/frontend/src/components/common/banner/Banner.tsx index fb2319c..a7ab3f4 100644 --- a/frontend/src/components/common/banner/Banner.tsx +++ b/frontend/src/components/common/banner/Banner.tsx @@ -62,7 +62,7 @@ const InfoWrapper = styled.div` position: absolute; top: 72px; width: 448px; - overflow-x: hidden; + overflow: hidden; `; const SubTitle = styled.p` diff --git a/frontend/src/components/modal/GuideModal.tsx b/frontend/src/components/modal/GuideModal.tsx index 597c166..ae5ed99 100644 --- a/frontend/src/components/modal/GuideModal.tsx +++ b/frontend/src/components/modal/GuideModal.tsx @@ -14,7 +14,7 @@ export default function GuideModal({ ...props }: IGuideModal) { const hmgDataBgRef = useRef(null); const { visible, setVisible } = useContext(GuideModalContext); const { pathname } = useLocation(); - + const isSelectedTrim = localStorage.getItem('isSelectedTrim'); const stopEvent: MouseEventHandler = (e) => { e.stopPropagation(); }; @@ -23,7 +23,10 @@ export default function GuideModal({ ...props }: IGuideModal) { if (!(pathname === PATH.home || pathname === PATH.trim)) { setVisible(false); } - }, [pathname, setVisible]); + if (isSelectedTrim && isSelectedTrim === 'true') { + setVisible(false); + } + }, [pathname, setVisible, isSelectedTrim]); return ( diff --git a/frontend/src/context/ItemProvider.tsx b/frontend/src/context/ItemProvider.tsx index cfa7310..ba993c6 100644 --- a/frontend/src/context/ItemProvider.tsx +++ b/frontend/src/context/ItemProvider.tsx @@ -1,6 +1,8 @@ -import { ReactNode, createContext, useEffect, useReducer, useState } from 'react'; +import { ReactNode, createContext, useCallback, useEffect, useReducer, useState } from 'react'; import itemReducer, { actionType } from '../reducer/itemReducer'; import { OUTER_COLOR_FIRST_IDX } from '../utils/constants'; +import { SHARE_INFO_API } from '../utils/apis'; +import { ISharedInfo } from '../hooks/useSharedInfo'; export type defaultItemType = { id: number; @@ -118,7 +120,6 @@ const initialSelectedItem = { displacement: '', }, }; - const initialItem: IItemContext = { selectedItem: initialSelectedItem, totalPrice: 0, @@ -129,6 +130,48 @@ const initialItem: IItemContext = { export const ItemContext = createContext(initialItem); export default function ItemProvider({ children }: IItemProvider) { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const isSelectedTrim = localStorage.getItem('isSelectedTrim'); + const savedItem = localStorage.getItem('selectedItem'); + const getParams = useCallback(() => { + if (!isSelectedTrim || !savedItem || isSelectedTrim === 'false') return; + const params = { + carId: JSON.parse(savedItem).trimId, + powerTrainId: JSON.parse(savedItem).modelTypeId.powerTrain, + bodyTypeId: JSON.parse(savedItem).modelTypeId.bodyType, + operationId: JSON.parse(savedItem).modelTypeId.operation, + outerColorId: JSON.parse(savedItem).outerColorId, + innerColorId: JSON.parse(savedItem).innerColorId, + optionIdList: JSON.parse(savedItem).optionId ? JSON.parse(savedItem).optionId : [], + }; + return params; + }, [isSelectedTrim, savedItem]); + + useEffect(() => { + if (!isSelectedTrim || !savedItem || isSelectedTrim === 'false') return; + const params = getParams(); + const fetchData = async () => { + try { + const res = await fetch(SHARE_INFO_API, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(params), + }); + const jsonData = await res.json(); + setData(jsonData); + } catch (e) { + setError(e as Error); + } finally { + setLoading(false); + } + }; + fetchData(); + }, [getParams, isSelectedTrim, savedItem]); + const [selectedItem, setSelectedItem] = useReducer(itemReducer, initialSelectedItem); const [totalPrice, setTotalPrice] = useState(0); @@ -155,6 +198,85 @@ export default function ItemProvider({ children }: IItemProvider) { localStorage.setItem('selectedItem', JSON.stringify(savedId)); }, [selectedItem]); + useEffect(() => { + if (!data || loading || error) return; + setSelectedItem({ + type: 'SET_TRIM', + value: { + id: data.carId, + name: data.trim, + price: data.carDefaultPrice, + }, + }); + setSelectedItem({ + type: 'SET_POWER_TRAIN', + value: { + id: data.powerTrainId, + title: data.powerTrainTitle, + name: data.powerTrainName, + imgSrc: data.powerTrainImage, + price: data.powerTrainPrice, + }, + }); + setSelectedItem({ + type: 'SET_BODY_TYPE', + value: { + id: data.bodyTypeId, + title: data.bodyTypeTitle, + name: data.bodyTypeName, + imgSrc: data.bodyTypeImage, + price: data.bodyTypePrice, + }, + }); + setSelectedItem({ + type: 'SET_OPERATION', + value: { + id: data.operationId, + title: data.operationName, + name: data.operationImage, + imgSrc: data.operationImage, + price: data.operationPrice, + }, + }); + + setSelectedItem({ + type: 'SET_OUTER_COLOR', + value: { + id: data.colorOuterId, + name: data.colorOuterImageName, + title: data.colorOuterTitle, + price: data.colorOuterPrice, + carImgSrc: data.colorCarOuterImage, + imgSrc: data.colorOuterImage, + }, + }); + setSelectedItem({ + type: 'SET_INNER_COLOR', + value: { + id: data.colorInnerId, + name: data.colorInnerImageName, + title: data.colorInnerTitle, + price: data.colorInnerPrice, + carImgSrc: data.colorCarInnerImage, + imgSrc: data.colorInnerImage, + }, + }); + + const options = data.optionList + ? data.optionList.map((option) => ({ + id: option.optionId, + name: option.optionName, + title: option.optionTitle, + price: option.optionPrice, + imgSrc: option.optionImage, + })) + : []; + + setSelectedItem({ + type: 'SET_OPTIONS', + value: options, + }); + }, [data, error, loading]); return ( { + const isSelectedTrim = localStorage.getItem('isSelectedTrim'); + if (isSelectedTrim && isSelectedTrim === 'true') setNextStepAvailable(true); + }, []); + useEffect(() => { + localStorage.setItem('isSelectedTrim', nextStepAvailable.toString()); + }, [nextStepAvailable]); return {children}; } diff --git a/frontend/src/hooks/useSharedInfo.ts b/frontend/src/hooks/useSharedInfo.ts index fe02e34..4cba739 100644 --- a/frontend/src/hooks/useSharedInfo.ts +++ b/frontend/src/hooks/useSharedInfo.ts @@ -2,7 +2,7 @@ import { useSearchParams } from 'react-router-dom'; import { SHARE_INFO_API } from '../utils/apis'; import { useCallback, useEffect, useState } from 'react'; -interface ISharedInfo { +export interface ISharedInfo { carId: number; trim: string; carDefaultPrice: number; From 94aa62cb056a32c7e9caf0cb9a949fcca1dbf8c9 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 17:43:22 +0900 Subject: [PATCH 16/34] =?UTF-8?q?[FIX]=20#422:=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/modal/QuoteSummaryModal.tsx | 6 +-- frontend/src/context/ItemProvider.tsx | 46 ++++++++----------- frontend/src/pages/ModelTypePage.tsx | 10 ++-- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/frontend/src/components/modal/QuoteSummaryModal.tsx b/frontend/src/components/modal/QuoteSummaryModal.tsx index d5be7ed..0fc5e03 100644 --- a/frontend/src/components/modal/QuoteSummaryModal.tsx +++ b/frontend/src/components/modal/QuoteSummaryModal.tsx @@ -125,9 +125,9 @@ export default function QuoteSummaryModal({ ...props }: IQuoteSummaryModal) { function Detail({ title, name, price }: IDetail) { return ( - {title} - {name} - + {price.toLocaleString()} 원 + {title && {title}} + {name && {name}} + {price && + {price.toLocaleString()} 원} ); } diff --git a/frontend/src/context/ItemProvider.tsx b/frontend/src/context/ItemProvider.tsx index ba993c6..d015c0d 100644 --- a/frontend/src/context/ItemProvider.tsx +++ b/frontend/src/context/ItemProvider.tsx @@ -1,4 +1,4 @@ -import { ReactNode, createContext, useCallback, useEffect, useReducer, useState } from 'react'; +import { ReactNode, createContext, useEffect, useReducer, useState } from 'react'; import itemReducer, { actionType } from '../reducer/itemReducer'; import { OUTER_COLOR_FIRST_IDX } from '../utils/constants'; import { SHARE_INFO_API } from '../utils/apis'; @@ -133,25 +133,11 @@ export default function ItemProvider({ children }: IItemProvider) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); - const isSelectedTrim = localStorage.getItem('isSelectedTrim'); - const savedItem = localStorage.getItem('selectedItem'); - const getParams = useCallback(() => { - if (!isSelectedTrim || !savedItem || isSelectedTrim === 'false') return; - const params = { - carId: JSON.parse(savedItem).trimId, - powerTrainId: JSON.parse(savedItem).modelTypeId.powerTrain, - bodyTypeId: JSON.parse(savedItem).modelTypeId.bodyType, - operationId: JSON.parse(savedItem).modelTypeId.operation, - outerColorId: JSON.parse(savedItem).outerColorId, - innerColorId: JSON.parse(savedItem).innerColorId, - optionIdList: JSON.parse(savedItem).optionId ? JSON.parse(savedItem).optionId : [], - }; - return params; - }, [isSelectedTrim, savedItem]); useEffect(() => { - if (!isSelectedTrim || !savedItem || isSelectedTrim === 'false') return; - const params = getParams(); + const isSelectedTrim = localStorage.getItem('isSelectedTrim'); + const params = localStorage.getItem('params'); + if (!isSelectedTrim || !params || isSelectedTrim === 'false') return; const fetchData = async () => { try { const res = await fetch(SHARE_INFO_API, { @@ -159,9 +145,10 @@ export default function ItemProvider({ children }: IItemProvider) { headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify(params), + body: params, }); const jsonData = await res.json(); + setData(jsonData); } catch (e) { setError(e as Error); @@ -170,7 +157,7 @@ export default function ItemProvider({ children }: IItemProvider) { } }; fetchData(); - }, [getParams, isSelectedTrim, savedItem]); + }, []); const [selectedItem, setSelectedItem] = useReducer(itemReducer, initialSelectedItem); const [totalPrice, setTotalPrice] = useState(0); @@ -184,18 +171,20 @@ export default function ItemProvider({ children }: IItemProvider) { const optionsPrice = selectedItem.options.reduce((acc, option) => acc + option.price, 0); const total = trimPrice + modelTypePrice + outerColorPrice + innerColorPrice + optionsPrice; setTotalPrice(total); + const powerTrainId = powerTrain.id; + const bodyTypeId = bodyType.id; + const operationId = operation.id; + const optionIds = selectedItem.options.map((option) => option.id); const savedId = { - trimId: trimId, - modelTypeId: { - powerTrain: powerTrain.id, - bodyType: bodyType.id, - operation: operation.id, - }, + carId: trimId, + powerTrainId, + bodyTypeId, + operationId, outerColorId: outerColorId, innerColorId: innerColorId, - optionId: selectedItem.options.map((option) => option.id), + optionIdList: optionIds ? optionIds : [], }; - localStorage.setItem('selectedItem', JSON.stringify(savedId)); + localStorage.setItem('params', JSON.stringify(savedId)); }, [selectedItem]); useEffect(() => { @@ -277,6 +266,7 @@ export default function ItemProvider({ children }: IItemProvider) { value: options, }); }, [data, error, loading]); + return ( - - - + {modelTypeData && !modelTypeLoading && ( + <> + + + + + )} ); } From fc865d96ddfb5f229370bbc4c7902bb27210c38f Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 17:49:21 +0900 Subject: [PATCH 17/34] =?UTF-8?q?[REFACTOR]=20#421:=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EC=9E=98=EB=AA=BB=EB=90=9C=20=EA=B1=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModelTypeSelectContainer.tsx | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/frontend/src/containers/ModelTypePage/ModelTypeSelectContainer.tsx b/frontend/src/containers/ModelTypePage/ModelTypeSelectContainer.tsx index b17a78e..ce30631 100644 --- a/frontend/src/containers/ModelTypePage/ModelTypeSelectContainer.tsx +++ b/frontend/src/containers/ModelTypePage/ModelTypeSelectContainer.tsx @@ -93,14 +93,14 @@ export default function ModelTypelSelectContainer() { {modelType[2].modelTypeName} - {[modelType[2], modelType[3]].map((bodyType) => ( + {[modelType[2], modelType[3]].map((operation) => ( handleSelectedOperation(bodyType.modelId)} - active={isActive(bodyType.modelTypeName, bodyType.modelId)} - percentage={bodyType.percentage} - title={bodyType.modelName} - price={bodyType.modelPrice} + key={operation.modelId} + onClick={() => handleSelectedOperation(operation.modelId)} + active={isActive(operation.modelTypeName, operation.modelId)} + percentage={operation.percentage} + title={operation.modelName} + price={operation.modelPrice} /> ))} @@ -111,14 +111,14 @@ export default function ModelTypelSelectContainer() { {modelType[4].modelTypeName} - {[modelType[4], modelType[5]].map((operation) => ( + {[modelType[4], modelType[5]].map((bodyType) => ( handleSelectedBodyType(operation.modelId)} - active={isActive(operation.modelTypeName, operation.modelId)} - percentage={operation.percentage} - title={operation.modelName} - price={operation.modelPrice} + key={bodyType.modelId} + onClick={() => handleSelectedBodyType(bodyType.modelId)} + active={isActive(bodyType.modelTypeName, bodyType.modelId)} + percentage={bodyType.percentage} + title={bodyType.modelName} + price={bodyType.modelPrice} /> ))} From 43a04906a19cb2c5563ecf69ac10f3acac14c43c Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 20:59:15 +0900 Subject: [PATCH 18/34] =?UTF-8?q?[FEAT]=20#425:=20=EC=9C=A0=EC=82=AC=20?= =?UTF-8?q?=EA=B2=AC=EC=A0=81=20=EC=98=88=EC=82=B0=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=EB=B0=94=20UI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/modal/SimilarQuoteModal.tsx | 2 +- .../priceStaticBar/PriceStaticBar.tsx | 38 +------ .../priceStaticBar/PriceStaticSlider.tsx | 32 ++---- .../priceStaticBar/SimilarPriceBar.tsx | 101 ++++++++++++------ .../priceStaticBar/SimilarPriceSlider.tsx | 76 +++++++------ frontend/src/utils/constants.ts | 2 + 6 files changed, 130 insertions(+), 121 deletions(-) diff --git a/frontend/src/components/modal/SimilarQuoteModal.tsx b/frontend/src/components/modal/SimilarQuoteModal.tsx index f802e2a..dc22db5 100644 --- a/frontend/src/components/modal/SimilarQuoteModal.tsx +++ b/frontend/src/components/modal/SimilarQuoteModal.tsx @@ -43,7 +43,7 @@ export default function SimilarQuoteModal({ ...props }: ISimilarQuoteModal) {
내 견적과 해시태그 유사도가 높은 다른 사람들의 실제 출고 견적이에요. - + diff --git a/frontend/src/components/priceStaticBar/PriceStaticBar.tsx b/frontend/src/components/priceStaticBar/PriceStaticBar.tsx index e37cf54..42c88d3 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticBar.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticBar.tsx @@ -1,20 +1,18 @@ import { ChangeEvent, useCallback, useContext, useEffect, useRef, useState } from 'react'; -import { css, styled, useTheme } from 'styled-components'; +import { styled, useTheme } from 'styled-components'; import { BodyKrRegular4, HeadingKrMedium6 } from '../../styles/typefaces'; import { ArrowUp, ArrowDown } from '../common/icons/Icons'; import React from 'react'; import { useLocation } from 'react-router-dom'; -import { PATH } from '../../utils/constants'; +import { HIGHEST_PRICE, PATH } from '../../utils/constants'; import PriceStaticSlider from './PriceStaticSlider'; import { ItemContext } from '../../context/ItemProvider'; - interface IPriceStaticBar extends React.HTMLAttributes {} interface IOffset { offsetX: string; offsetY: string; } export default function PriceStaticBar({ ...props }: IPriceStaticBar) { - const highestPrice = 80_000_000; const { totalPrice, selectedItem } = useContext(ItemContext); const { pathname } = useLocation(); const theme = useTheme(); @@ -26,17 +24,14 @@ export default function PriceStaticBar({ ...props }: IPriceStaticBar) { const [isOverBudget, setIsOverBudget] = useState(false); const [isOpen, setIsOpen] = useState(false); const balance = ((isOverBudget ? -1 : 1) * (budget - totalPrice)).toLocaleString(); - const getBudgetStatus = useCallback(() => { const status = budget - totalPrice; status >= 0 ? setIsOverBudget(false) : setIsOverBudget(true); }, [budget, totalPrice]); - const handleChange = (event: ChangeEvent) => { const newValue = Number(event.target.value); setBudget(newValue); }; - const stopEvent = (event: React.MouseEvent) => { event.stopPropagation(); }; @@ -45,7 +40,6 @@ export default function PriceStaticBar({ ...props }: IPriceStaticBar) { const element = barRef.current!.getBoundingClientRect(); setStartOffset({ startX: clientX - element.left, startY: clientY - element.top }); }; - const handleMouseMove = (event: MouseEvent, startX: number, startY: number) => { if (!dragRef.current) { return; @@ -59,24 +53,20 @@ export default function PriceStaticBar({ ...props }: IPriceStaticBar) { event.preventDefault(); setOffset({ offsetX: `${newLeft}px`, offsetY: `${newTop}px` }); }; - const handleMouseUp = () => { dragRef.current = false; }; - useEffect(() => { - setBudget((selectedItem.trim.price + highestPrice) / 2); + setBudget((selectedItem.trim.price + HIGHEST_PRICE) / 2); }, [selectedItem.trim.price]); useEffect(() => { getBudgetStatus(); }, [budget, getBudgetStatus]); - useEffect(() => { window.addEventListener('mousemove', (event) => handleMouseMove(event, startOffset.startX, startOffset.startY) ); window.addEventListener('mouseup', handleMouseUp); - return () => { window.removeEventListener('mousemove', (event) => handleMouseMove(event, startOffset.startX, startOffset.startY) @@ -84,11 +74,9 @@ export default function PriceStaticBar({ ...props }: IPriceStaticBar) { window.removeEventListener('mouseup', handleMouseUp); }; }, [startOffset]); - if (pathname === PATH.home || pathname === PATH.trim) { return <>; } - return ( {balance}원 {isOverBudget ? ' 더 들었어요.' : ' 남았어요.'} - setIsOpen(!isOpen)}> {isOpen ? : } - theme.color.primaryColor700}; -`; - -const overBudgetCss = css` - background: rgba(0, 11, 25, 0.9); -`; - const StatusBox = styled.div.attrs<{ $isover: boolean; $isopen: boolean; @@ -143,12 +120,11 @@ const StatusBox = styled.div.attrs<{ transform: $offset.offsetX === '50%' ? 'translateX(-50%)' : 'none', }, }))` - ${({ $isover }) => !$isover && withinBudgetCss} - ${({ $isover }) => $isover && overBudgetCss} + background: ${({ theme, $isover }) => + $isover ? 'rgba(0, 11, 25, 0.9)' : theme.color.primaryColor700}; position: fixed; min-width: 343px; z-index: 1000; - padding: 0px 16px; border-radius: 10px; backdrop-filter: blur(3px); @@ -161,7 +137,6 @@ const StatusBox = styled.div.attrs<{ justify-content: space-between; cursor: pointer; `; - const StatusText = styled.div` width: 100%; min-height: 40px; @@ -169,12 +144,10 @@ const StatusText = styled.div` align-items: center; justify-content: space-between; `; - const StatusTitle = styled.p` margin-right: 8px; ${HeadingKrMedium6} `; - const StatusDesc = styled.p<{ $isover: boolean }>` ${BodyKrRegular4} flex:1; @@ -188,5 +161,4 @@ const AnimatedSection = styled.div<{ $isopen: boolean }>` opacity: ${({ $isopen }) => ($isopen ? '1' : '0')}; transition: opacity 0.5s ease; `; - const IconBtn = styled.button``; diff --git a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx index de5d502..58763ae 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx @@ -3,18 +3,15 @@ import { flexCenterCss } from '../../utils/commonStyle'; import { BodyKrRegular3, BodyKrRegular5 } from '../../styles/typefaces'; import { ChangeEvent, useContext } from 'react'; import { ItemContext } from '../../context/ItemProvider'; -import { TEN_THOUSAND_UNIT } from '../../utils/constants'; +import { HIGHEST_PRICE, TEN_THOUSAND_UNIT } from '../../utils/constants'; import { theme } from '../../styles/theme'; - interface ISlider extends React.HTMLAttributes { - highestPrice: number; isOverBudget: boolean; budget: number; handleChange: (event: ChangeEvent) => void; stopEvent: (event: React.MouseEvent) => void; } export default function Slider({ - highestPrice, isOverBudget, budget, handleChange, @@ -26,28 +23,25 @@ export default function Slider({ - - 내가 설정한 예산은  - {budget / TEN_THOUSAND_UNIT}만원이에요. - + 내가 설정한 예산은  + {budget / TEN_THOUSAND_UNIT}만원이에요. @@ -56,12 +50,11 @@ export default function Slider({ {selectedItem.trim.price / TEN_THOUSAND_UNIT}만원 - {highestPrice / TEN_THOUSAND_UNIT}만원 + {HIGHEST_PRICE / TEN_THOUSAND_UNIT}만원 ); } - const PriceBarWrapper = styled.div` padding-top: 28px; padding-bottom: 4px; @@ -75,15 +68,10 @@ const BudgetInfo = styled.div` background-color: black; opacity: 0.9; `; -const Budget = styled.span` - ${BodyKrRegular3} -`; - const MarkerSvgWrapper = styled.div` height: 100%; position: relative; `; - const MarkerSvg = styled.svg<{ $isover: boolean; $percent: number }>` pointer-events: none; position: absolute; @@ -94,9 +82,8 @@ const MarkerSvg = styled.svg<{ $isover: boolean; $percent: number }>` left: ${({ $percent }) => $percent}%; transform: translate(-50%, -50%); `; - const PriceBar = styled.input.attrs<{ $percent: number; $isover: boolean }>( - ({ type, min, max, value, onChange, step, $percent, $isover }) => ({ + ({ type, min, value, onChange, step, $percent, $isover }) => ({ style: { background: `linear-gradient( to right, @@ -108,7 +95,7 @@ const PriceBar = styled.input.attrs<{ $percent: number; $isover: boolean }>( }, type: type, min: min, - max: max, + max: HIGHEST_PRICE, value: value, onChange: onChange, step: step, @@ -122,14 +109,12 @@ const PriceBar = styled.input.attrs<{ $percent: number; $isover: boolean }>( width: 100%; height: 6px; border-radius: 4px; - &::-webkit-slider-runnable-track { cursor: pointer; width: 100%; height: 6px; border-radius: 4px; } - &::-webkit-slider-thumb { cursor: pointer; width: 20px; @@ -145,7 +130,6 @@ const PriceBar = styled.input.attrs<{ $percent: number; $isover: boolean }>( const BlueText = styled.span<{ $isover: boolean }>` color: ${({ theme, $isover }) => ($isover ? theme.color.sand : theme.color.activeBlue2)}; `; - const PriceInfo = styled.div<{ $isover: boolean }>` ${flexCenterCss}; justify-content: space-between; diff --git a/frontend/src/components/priceStaticBar/SimilarPriceBar.tsx b/frontend/src/components/priceStaticBar/SimilarPriceBar.tsx index 36fcccb..8d27434 100644 --- a/frontend/src/components/priceStaticBar/SimilarPriceBar.tsx +++ b/frontend/src/components/priceStaticBar/SimilarPriceBar.tsx @@ -1,76 +1,80 @@ -import { ChangeEvent, useCallback, useEffect, useState } from 'react'; -import { css, styled } from 'styled-components'; +import { ChangeEvent, useCallback, useContext, useEffect, useState } from 'react'; +import { styled } from 'styled-components'; import { flexCenterCss } from '../../utils/commonStyle'; -import { BodyKrRegular4, HeadingKrMedium6 } from '../../styles/typefaces'; +import { BodyKrMedium5, BodyKrRegular4, HeadingKrMedium6 } from '../../styles/typefaces'; import React from 'react'; import SimilarPriceSlider from './SimilarPriceSlider'; +import { ItemContext } from '../../context/ItemProvider'; +import { HIGHEST_PRICE } from '../../utils/constants'; -interface ISimilarPrice extends React.HTMLAttributes {} +interface ISimilarPriceBar extends React.HTMLAttributes { + similarPrice: number; +} + +export default function SimilarPriceBar({ similarPrice, ...props }: ISimilarPriceBar) { + const { totalPrice, selectedItem } = useContext(ItemContext); -export default function SimilarPrice({ ...props }: ISimilarPrice) { - const lowestPrice = 3850; //단위: 만원 - const highestPrice = 4300; - const total = 4100; - const [budget, setBudget] = useState((lowestPrice + highestPrice) / 2); + const [budget, setBudget] = useState((selectedItem.trim.price + HIGHEST_PRICE) / 2); const [isOverBudget, setIsOverBudget] = useState(false); - const balance = ((isOverBudget ? -10000 : 10000) * (budget - total)).toLocaleString(); + const balance = ((isOverBudget ? -1 : 1) * (budget - totalPrice)).toLocaleString(); const getBudgetStatus = useCallback(() => { - const status = budget - total; + const status = budget - totalPrice; status >= 0 ? setIsOverBudget(false) : setIsOverBudget(true); - }, [budget]); + }, [budget, totalPrice]); const handleChange = (event: ChangeEvent) => { const newValue = Number(event.target.value); setBudget(newValue); }; - useEffect(() => { getBudgetStatus(); }, [budget, getBudgetStatus]); - return ( 유사견적 가격 내 견적 보다   - {balance}원 + {balance}원 {isOverBudget ? ' 비싸요.' : ' 싸요.'} + + + + 내 견적 + + + + 유사 견적 + + + ); } -const withinBudgetCss = css` - background: ${({ theme }) => theme.color.primaryColor700}; - #price-info { - color: ${({ theme }) => theme.color.activeBlue2}; - } -`; -const overBudgetCss = css` - background: rgba(0, 11, 25, 0.9); - #price-info { - color: ${({ theme }) => theme.color.sand}; - } -`; +const PriceInfo = styled.span``; const StatusBox = styled.div<{ $isover: boolean }>` - ${({ $isover }) => !$isover && withinBudgetCss} - ${({ $isover }) => $isover && overBudgetCss} + background: ${({ theme, $isover }) => + $isover ? 'rgba(0, 11, 25, 0.9)' : theme.color.primaryColor700}; min-width: 343px; padding: 8px 16px; border-radius: 10px; backdrop-filter: blur(3px); color: ${({ theme }) => theme.color.gray50}; + ${PriceInfo} { + color: ${({ theme, $isover }) => ($isover ? theme.color.sand : theme.color.activeBlue2)}; + } `; const StatusText = styled.div` @@ -89,3 +93,34 @@ const StatusDesc = styled.span` flex:1; text-align: end; `; + +const InfoWrapper = styled.div` + ${flexCenterCss} +`; + +const InfoCaption = styled.div<{ $isover?: boolean }>` + display: flex; + align-items: center; + gap: 16px; + color: ${({ theme, $isover }) => ($isover ? theme.color.sand : theme.color.activeBlue2)}; + ${BodyKrMedium5} +`; + +const Ellipse = styled.div<{ $isover: boolean }>` + width: 8px; + height: 8px; + border-radius: 50%; + background-color: ${({ theme, $isover }) => + $isover ? theme.color.sand : theme.color.activeBlue2}; +`; + +const Info = styled.span` + ${flexCenterCss} + gap: 4px; + &:last-child { + color: white; + ${Ellipse} { + background-color: white; + } + } +`; diff --git a/frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx b/frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx index 5a1d075..ed559da 100644 --- a/frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx +++ b/frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx @@ -1,70 +1,87 @@ import { styled } from 'styled-components'; import { flexCenterCss } from '../../utils/commonStyle'; -import { BodyKrRegular5 } from '../../styles/typefaces'; -import { ChangeEvent } from 'react'; - -interface INonameS extends React.HTMLAttributes { - lowestPrice: number; - highestPrice: number; +import { BodyKrRegular3, BodyKrRegular5 } from '../../styles/typefaces'; +import { ChangeEvent, useContext } from 'react'; +import { HIGHEST_PRICE, TEN_THOUSAND_UNIT } from '../../utils/constants'; +import { ItemContext } from '../../context/ItemProvider'; +interface ISimilarPriceSlider extends React.HTMLAttributes { isOverBudget: boolean; budget: number; - total: number; + similarPrice: number; percent: number; handleChange: (event: ChangeEvent) => void; } -export default function NonameS({ - lowestPrice, - highestPrice, +export default function SimilarPriceSlider({ isOverBudget, budget, - total, + similarPrice, percent, handleChange, ...props -}: INonameS) { +}: ISimilarPriceSlider) { + const { totalPrice, selectedItem } = useContext(ItemContext); return ( + + 내 차의 견적은 총  + {totalPrice / TEN_THOUSAND_UNIT}만원이에요. + - + - + - {lowestPrice}만원 - {highestPrice}만원 + {selectedItem.trim.price / TEN_THOUSAND_UNIT}만원 + {HIGHEST_PRICE / TEN_THOUSAND_UNIT}만원 ); } - const PriceBarWrapper = styled.div` margin: 0px 4px; padding-top: 34px; padding-bottom: 8px; `; - +const BlueText = styled.span<{ $isover: boolean }>` + color: ${({ theme, $isover }) => ($isover ? theme.color.sand : theme.color.activeBlue2)}; +`; +const BudgetInfo = styled.div` + ${BodyKrRegular3} + position: absolute; + top: -34px; + right: 0px; + background-color: black; + opacity: 0.9; +`; const MarkerSvgWrapper = styled.div` height: 100%; position: relative; `; - -const MarkerSvg = styled.svg<{ $isover: boolean; $percent: number }>` +const MarkerSvg = styled.svg<{ $isover?: boolean; $percent: number }>` pointer-events: none; position: absolute; width: 9px; @@ -74,12 +91,14 @@ const MarkerSvg = styled.svg<{ $isover: boolean; $percent: number }>` left: ${({ $percent }) => $percent}%; transform: translate(-50%, -50%); `; - +const SimilarMarkerSvg = styled(MarkerSvg)` + fill: white; +`; const PriceBar = styled.input.attrs<{ $percent: number; $isover: boolean }>( - ({ type, min, max, value, onChange, step }) => ({ + ({ type, min, value, onChange, step }) => ({ type: type, min: min, - max: max, + max: HIGHEST_PRICE, value: value, onChange: onChange, step: step, @@ -93,15 +112,12 @@ const PriceBar = styled.input.attrs<{ $percent: number; $isover: boolean }>( width: 100%; height: 6px; border-radius: 4px; - &::-webkit-slider-runnable-track { - cursor: pointer; width: 100%; height: 6px; border-radius: 4px; } `; - const PriceInfo = styled.div` ${flexCenterCss}; justify-content: space-between; diff --git a/frontend/src/utils/constants.ts b/frontend/src/utils/constants.ts index 4dafcc5..b84783b 100644 --- a/frontend/src/utils/constants.ts +++ b/frontend/src/utils/constants.ts @@ -4,6 +4,7 @@ export const DEBOUNCE_TIME = 200; export const TEN_THOUSAND_UNIT = 10000; export const PERCENTAGE_LIMIT_VALUE = 5; export const MAX_TEXT_CNT = 16; +export const HIGHEST_PRICE = 80_000_000; export const PATH = { home: '/', trim: '/trim', @@ -45,4 +46,5 @@ Object.freeze({ OUTER_COLOR_FIRST_IDX, PERCENTAGE_LIMIT_VALUE, MAX_TEXT_CNT, + HIGHEST_PRICE, }); From c0dcbbfbdd4eca61d2943ec84af314d8ce56cea6 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 21:28:00 +0900 Subject: [PATCH 19/34] =?UTF-8?q?[FIX]=20#427:=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/navbar/NavBar.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/common/navbar/NavBar.tsx b/frontend/src/components/common/navbar/NavBar.tsx index 3937b13..baebb79 100644 --- a/frontend/src/components/common/navbar/NavBar.tsx +++ b/frontend/src/components/common/navbar/NavBar.tsx @@ -2,7 +2,7 @@ import React, { useContext, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { css, styled, useTheme } from 'styled-components'; import { BodyKrMedium3, BodyKrRegular3, HeadingKrMedium6 } from '../../../styles/typefaces'; -import { ArrowDown, CancelIcon } from '../icons/Icons'; +import { ArrowDown, ArrowUp, CancelIcon } from '../icons/Icons'; import hyundaiLogo from '/images/logo.svg'; import { MESSAGE, PATH } from '../../../utils/constants'; import { CloseModalContext } from '../../../context/CloseModalProvider'; @@ -44,7 +44,11 @@ export default function NavBar() { 펠리세이드 - + {menuVisible ? ( + + ) : ( + + )} Date: Wed, 23 Aug 2023 21:38:19 +0900 Subject: [PATCH 20/34] =?UTF-8?q?[FEAT]=20#427:=20=EC=95=A0=EB=8B=88?= =?UTF-8?q?=EB=A9=94=EC=9D=B4=EC=85=98=20=EB=84=A3=EC=96=B4=EB=B4=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/navbar/CarSelectContainer.tsx | 11 ++++++++--- frontend/src/components/common/navbar/NavBar.tsx | 3 +++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/common/navbar/CarSelectContainer.tsx b/frontend/src/components/common/navbar/CarSelectContainer.tsx index 5b4c9f7..da18bd0 100644 --- a/frontend/src/components/common/navbar/CarSelectContainer.tsx +++ b/frontend/src/components/common/navbar/CarSelectContainer.tsx @@ -55,15 +55,20 @@ export default function CarSelectContainer({ visible }: ICarSelectContainer) { ); } - const Wrapper = styled.div<{ $visible: boolean }>` - display: ${({ $visible }) => ($visible ? 'block' : 'none')}; position: fixed; top: 60px; z-index: 99999999; - height: 220px; + height: ${({ $visible }) => ($visible ? '220px' : '0')}; width: 100%; background-color: ${({ theme }) => theme.color.white}; + display: block; + opacity: ${({ $visible }) => ($visible ? '1' : '0')}; + overflow: hidden; + visibility: ${({ $visible }) => ($visible ? 'visible' : 'hidden')}; + transition: + height 0.5s ease, + opacity 0.5s ease; `; const CetnerWrapper = styled(CenterWrapper)``; diff --git a/frontend/src/components/common/navbar/NavBar.tsx b/frontend/src/components/common/navbar/NavBar.tsx index baebb79..82ffab6 100644 --- a/frontend/src/components/common/navbar/NavBar.tsx +++ b/frontend/src/components/common/navbar/NavBar.tsx @@ -42,6 +42,7 @@ export default function NavBar() { + 펠리세이드 {menuVisible ? ( @@ -50,6 +51,7 @@ export default function NavBar() { )} + handleNavItemClick(PATH.trim)} @@ -88,6 +90,7 @@ export default function NavBar() { +
); From 7d3fbc49e9b4b7188bfc207337d385909917457e Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 21:45:46 +0900 Subject: [PATCH 21/34] =?UTF-8?q?[FIX]=20#427:=20=EB=94=A4=EB=93=9C=20?= =?UTF-8?q?=EB=B0=B0=EA=B2=BD=20=EB=88=84=EB=A5=B4=EB=A9=B4=20=EC=97=86?= =?UTF-8?q?=EC=96=B4=EC=A7=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/navbar/CarSelectContainer.tsx | 15 ++++++++------- frontend/src/components/common/navbar/NavBar.tsx | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/common/navbar/CarSelectContainer.tsx b/frontend/src/components/common/navbar/CarSelectContainer.tsx index da18bd0..d5d7c28 100644 --- a/frontend/src/components/common/navbar/CarSelectContainer.tsx +++ b/frontend/src/components/common/navbar/CarSelectContainer.tsx @@ -2,7 +2,7 @@ import { styled } from 'styled-components'; import CenterWrapper from '../layout/CenterWrapper'; import { useFetch } from '../../../hooks/useFetch'; import { CAR_LIST_API, IMG_URL } from '../../../utils/apis'; -import { useState } from 'react'; +import { Dispatch, useState } from 'react'; import { flexCenterCss } from '../../../utils/commonStyle'; import { BodyKrMedium3, BodyKrMedium4 } from '../../../styles/typefaces'; import DefaultCardStyle from '../card/DefaultCardStyle'; @@ -16,9 +16,10 @@ interface ICar { interface ICarSelectContainer { visible: boolean; + setMenuVisible: Dispatch>; } -export default function CarSelectContainer({ visible }: ICarSelectContainer) { +export default function CarSelectContainer({ visible, setMenuVisible }: ICarSelectContainer) { const { data } = useFetch(CAR_LIST_API); const [active, setActive] = useState(3); // 3: SUV const categoryList = ['수소/전기차', 'N', '승용', 'SUV', 'MVP', '소형트럭/택시', '트럭', '버스']; @@ -26,6 +27,9 @@ export default function CarSelectContainer({ visible }: ICarSelectContainer) { const handleCategoryClick = (idx: number) => { setActive(idx); }; + const handleDimmedClick = () => { + setMenuVisible((cur) => !cur); + }; const isActive = (idx: number) => idx === active; const categoryItemComponents = categoryList?.map((category, idx) => { @@ -51,7 +55,7 @@ export default function CarSelectContainer({ visible }: ICarSelectContainer) { {carItemComponents}
- + ); } @@ -65,10 +69,7 @@ const Wrapper = styled.div<{ $visible: boolean }>` display: block; opacity: ${({ $visible }) => ($visible ? '1' : '0')}; overflow: hidden; - visibility: ${({ $visible }) => ($visible ? 'visible' : 'hidden')}; - transition: - height 0.5s ease, - opacity 0.5s ease; + transition: height 0.5s ease; `; const CetnerWrapper = styled(CenterWrapper)``; diff --git a/frontend/src/components/common/navbar/NavBar.tsx b/frontend/src/components/common/navbar/NavBar.tsx index 82ffab6..4b8e673 100644 --- a/frontend/src/components/common/navbar/NavBar.tsx +++ b/frontend/src/components/common/navbar/NavBar.tsx @@ -91,7 +91,7 @@ export default function NavBar() { - + ); } From f9ec6b87be0f1b35e7886c40e1b45f907a6e7585 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 21:52:10 +0900 Subject: [PATCH 22/34] =?UTF-8?q?[FIX]=20#427:=20=EC=B0=A8=EC=A2=85=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=EC=9D=BC=20=EB=95=8C=20Nav=EB=B0=94=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/navbar/NavBar.tsx | 86 +++++++++++-------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/frontend/src/components/common/navbar/NavBar.tsx b/frontend/src/components/common/navbar/NavBar.tsx index 4b8e673..59e4962 100644 --- a/frontend/src/components/common/navbar/NavBar.tsx +++ b/frontend/src/components/common/navbar/NavBar.tsx @@ -52,42 +52,56 @@ export default function NavBar() { )} - - handleNavItemClick(PATH.trim)} - active={isActive(PATH.trim) || isActive(PATH.home)} - > - 트림 - - handleNavItemClick(PATH.modelType)} - active={isActive(PATH.modelType)} - > - 타입 - - handleNavItemClick(PATH.outerColor)} - active={isActive(PATH.outerColor)} - > - 외장 - - handleNavItemClick(PATH.innerColor)} - active={isActive(PATH.innerColor)} - > - 내장 - - handleNavItemClick(PATH.option)} active={isActive(PATH.option)}> - 옵션 - - handleNavItemClick(PATH.result)} active={isActive(PATH.result)}> - 완료 - - - - 종료 - - + {!menuVisible && ( + + handleNavItemClick(PATH.trim)} + active={isActive(PATH.trim) || isActive(PATH.home)} + > + 트림 + + handleNavItemClick(PATH.modelType)} + active={isActive(PATH.modelType)} + > + 타입 + + handleNavItemClick(PATH.outerColor)} + active={isActive(PATH.outerColor)} + > + 외장 + + handleNavItemClick(PATH.innerColor)} + active={isActive(PATH.innerColor)} + > + 내장 + + handleNavItemClick(PATH.option)} + active={isActive(PATH.option)} + > + 옵션 + + handleNavItemClick(PATH.result)} + active={isActive(PATH.result)} + > + 완료 + + + )} + {!menuVisible ? ( + + 종료 + + + ) : ( + + + + )} From de8df50c231cf674800dc5adfa54ddc4b8b62f93 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:12:38 +0900 Subject: [PATCH 23/34] =?UTF-8?q?[FEAT]=20#428:=20=ED=98=84=EB=8C=80=20?= =?UTF-8?q?=EB=A1=9C=EA=B3=A0=20=EB=88=84=EB=A5=B4=EB=A9=B4=20=ED=8A=B8?= =?UTF-8?q?=EB=A6=BC=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/navbar/NavBar.tsx | 4 ++-- frontend/src/context/ItemProvider.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/common/navbar/NavBar.tsx b/frontend/src/components/common/navbar/NavBar.tsx index 59e4962..d95979b 100644 --- a/frontend/src/components/common/navbar/NavBar.tsx +++ b/frontend/src/components/common/navbar/NavBar.tsx @@ -41,7 +41,7 @@ export default function NavBar() { - + handleNavItemClick(PATH.trim)} /> 펠리세이드 @@ -207,7 +207,7 @@ const HyundaiLogo = styled.img` bottom: 0; width: 39px; height: 22px; - + cursor: pointer; display: flex; justify-content: center; align-items: center; diff --git a/frontend/src/context/ItemProvider.tsx b/frontend/src/context/ItemProvider.tsx index d015c0d..1d29ff1 100644 --- a/frontend/src/context/ItemProvider.tsx +++ b/frontend/src/context/ItemProvider.tsx @@ -221,8 +221,8 @@ export default function ItemProvider({ children }: IItemProvider) { type: 'SET_OPERATION', value: { id: data.operationId, - title: data.operationName, - name: data.operationImage, + title: data.operationTitle, + name: data.operationName, imgSrc: data.operationImage, price: data.operationPrice, }, From c52a381071c271f462eacd16aa3f85cc60accbce Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:21:14 +0900 Subject: [PATCH 24/34] =?UTF-8?q?[FIX]=20#429:=20=ED=8A=B8=EB=A6=BC=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=ED=95=98=EB=A9=B4=20=EB=8B=A4=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/containers/TrimPage/TrimSelectContainer.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/containers/TrimPage/TrimSelectContainer.tsx b/frontend/src/containers/TrimPage/TrimSelectContainer.tsx index 61dfe27..a8b7e24 100644 --- a/frontend/src/containers/TrimPage/TrimSelectContainer.tsx +++ b/frontend/src/containers/TrimPage/TrimSelectContainer.tsx @@ -79,6 +79,10 @@ export default function TrimSelectContainer() { imgSrc: defaultInfo.innerColor.imgSrc, }, }); + setSelectedItem({ + type: 'SET_OPTIONS', + value: [], + }); }, [defaultInfo, setSelectedItem]); const handleSelectedIdx = (idx: number) => { From 09a6d5e3c470de176c7ee0505220a17167d5bff5 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:37:29 +0900 Subject: [PATCH 25/34] =?UTF-8?q?[FIX]=20#428:=20path=20=ED=99=88=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/navbar/NavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/common/navbar/NavBar.tsx b/frontend/src/components/common/navbar/NavBar.tsx index d95979b..d002f6c 100644 --- a/frontend/src/components/common/navbar/NavBar.tsx +++ b/frontend/src/components/common/navbar/NavBar.tsx @@ -41,7 +41,7 @@ export default function NavBar() { - handleNavItemClick(PATH.trim)} /> + handleNavItemClick(PATH.home)} /> 펠리세이드 From f9455fff29f516214fb304ebc6d62745cedca13a Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:40:46 +0900 Subject: [PATCH 26/34] =?UTF-8?q?[FIX]=20#426:=20=EC=B5=9C=EA=B3=A0=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=EB=B3=B4=EB=8B=A4=20=EB=86=92=EC=9D=80=20?= =?UTF-8?q?=EC=98=88=EC=82=B0=20=EC=84=A4=EC=A0=95=20=EB=AA=BB=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/priceStaticBar/PriceStaticSlider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx index 58763ae..6dd5cce 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx @@ -95,7 +95,7 @@ const PriceBar = styled.input.attrs<{ $percent: number; $isover: boolean }>( }, type: type, min: min, - max: HIGHEST_PRICE, + max: HIGHEST_PRICE + 100_000, value: value, onChange: onChange, step: step, From fff2d4694dc725b290c25922772690ea15d08f3b Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:42:14 +0900 Subject: [PATCH 27/34] =?UTF-8?q?[REFACTOR]=2010=EB=A7=8C=EC=9B=90=20const?= =?UTF-8?q?ants=EB=A1=9C=20=EB=BA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/priceStaticBar/PriceStaticSlider.tsx | 4 ++-- frontend/src/utils/constants.ts | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx index 6dd5cce..d508d7e 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx @@ -32,7 +32,7 @@ export default function Slider({ value={budget} onChange={handleChange} onMouseDown={stopEvent} - step={100_000} + step={HUNDRED_THOUSAND_UNIT} $percent={ ((budget - selectedItem.trim.price) / (HIGHEST_PRICE - selectedItem.trim.price)) * 100 } @@ -95,7 +95,7 @@ const PriceBar = styled.input.attrs<{ $percent: number; $isover: boolean }>( }, type: type, min: min, - max: HIGHEST_PRICE + 100_000, + max: HIGHEST_PRICE + HUNDRED_THOUSAND_UNIT, value: value, onChange: onChange, step: step, diff --git a/frontend/src/utils/constants.ts b/frontend/src/utils/constants.ts index b84783b..e590eeb 100644 --- a/frontend/src/utils/constants.ts +++ b/frontend/src/utils/constants.ts @@ -1,7 +1,8 @@ export const MAX_PAGE = 3; export const NUM_IN_A_PAGE = 4; export const DEBOUNCE_TIME = 200; -export const TEN_THOUSAND_UNIT = 10000; +export const TEN_THOUSAND_UNIT = 10_000; +export const HUNDRED_THOUSAND_UNIT = 100_000; export const PERCENTAGE_LIMIT_VALUE = 5; export const MAX_TEXT_CNT = 16; export const HIGHEST_PRICE = 80_000_000; @@ -43,6 +44,7 @@ Object.freeze({ PAGE_ANIMATION_DURATION, DEBOUNCE_TIME, TEN_THOUSAND_UNIT, + HUNDRED_THOUSAND_UNIT, OUTER_COLOR_FIRST_IDX, PERCENTAGE_LIMIT_VALUE, MAX_TEXT_CNT, From 2815c832273b54a311a16023f737a469524aeae8 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:55:38 +0900 Subject: [PATCH 28/34] Update SimilarPriceSlider.tsx --- frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx b/frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx index ed559da..8aaee82 100644 --- a/frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx +++ b/frontend/src/components/priceStaticBar/SimilarPriceSlider.tsx @@ -2,7 +2,7 @@ import { styled } from 'styled-components'; import { flexCenterCss } from '../../utils/commonStyle'; import { BodyKrRegular3, BodyKrRegular5 } from '../../styles/typefaces'; import { ChangeEvent, useContext } from 'react'; -import { HIGHEST_PRICE, TEN_THOUSAND_UNIT } from '../../utils/constants'; +import { HIGHEST_PRICE, HUNDRED_THOUSAND_UNIT, TEN_THOUSAND_UNIT } from '../../utils/constants'; import { ItemContext } from '../../context/ItemProvider'; interface ISimilarPriceSlider extends React.HTMLAttributes { isOverBudget: boolean; @@ -32,7 +32,7 @@ export default function SimilarPriceSlider({ min={selectedItem.trim.price} value={budget} onChange={handleChange} - step={100_000} + step={HUNDRED_THOUSAND_UNIT} $percent={percent} $isover={isOverBudget} /> From c5573ede87bbb271c1742439b725602bab9e4953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EC=98=88?= <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 23:41:57 +0900 Subject: [PATCH 29/34] Update README.md --- README.md | 102 +++++++++--------------------------------------------- 1 file changed, 17 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index ad1e826..3fc93c7 100644 --- a/README.md +++ b/README.md @@ -2,101 +2,33 @@ 안녕하세요🙌🏻 현대 오토에버 2팀 **CarTag** 🚙 (~~칼퇴~~)입니다. -## 프로젝트 소개 - -> 내가 탈 차, 이제 감이 아닌 **데이터**로. - -현대만의 데이터로 차량견적을 산출할 수 있는 서비스를 개발하였습니다. - -[기획/디자인 링크](https://www.figma.com/file/UPMMnkNQegdhJXFuZqQqph/Car-ta-log_Hand-off?type=design&node-id=1-6&mode=design&t=sBmZzwne4kOQ0Cub-0) - -## 팀원 소개 +### 팀원 소개 | | | | | | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | | [FE-김다예](https://github.com/kimdaye77) | [FE-박지성](https://github.com/jijiseong) | [BE-김종원](https://github.com/tank3a) | [BE-이용재](https://github.com/dydwo0740) | +## 프로젝트 소개 -## 👇🏻 그라운드 룰 - -### Check In/Out - -- 10:00 까지 모든 준비(노트북 세팅등 작업을 시작할 준비, 스크럼 시작전 코멘트 준비 등)가 완료된 상태로 프로젝트 룸에서 대기합니다. -- 12:30 부터 14:00 까지 점심 식사 및 휴식을 취합니다. -- 18:00 이전까지 회고를 할 준비를 끝내도록 합니다. 단, 그룹 내 피어세션은 동일 시간 금요일에 진행되므로 제외합니다. -- 19:00 까지 스크럼에서 정한 일들을 모두 끝냈을 때 귀가합니다. 단, 그렇지 못한 경우에는 그룹 구성원 모두 남아서 과제를 수행합니다. -- **귀가 관련 사항은 2주차부터 적용됩니다. 1주차에는 자율적으로 목표를 맞추어 일정에 차질이 생기지 않도록 합니다.** - -### 팀 내에서 태도 - -- 소통을 통해 모르는 내용을 바로 물어보는 태도를 취합니다. (단, 팀원들에게 부담을 줄이기 위해서 질문 이전에 찾아보려는 노력을 하도록 합니다.) -- 러버덕 디버깅을 적용하여 팀원들과 소통하면서 문제 해결능력을 높이는 방안을 채택합니다. -- 프로젝트 기간동안 좋은 분위기를 위해서 팀원을 배려하는 태도를 가집니다. -- 계획 수정시에는 팀원과 협의를 통해 수정합니다. - -### 팀 내 규칙 - -- 1일 1커밋하기 (최소 기준이기 때문에 더 많은 과제를 수행하도록 노력합니다.) -- 이슈를 만들고 팀원들과 함께 각 이슈의 소요시간 예측하도록 합니다. -- 프론트/백엔드 간 데이터 전달 시 API 명세 반드시 하도록 합니다. -- 수정사항은 수정 시작 전에 미리 팀원들에게 알리도록 합니다. -- 도메인 네임 규칙 지켜서 개발하도록 합니다. - -## 📝 Convention - -### Commit Convention - -- 커밋 메시지 첫 줄 컨벤션은 다음과 같습니다. - `[태그] #{issue number}: 커밋 메시지`의 형태이며 `:`뒤에만 space가 있음에 유의합니다. - -#### 예시 - -`[FEAT] #1: 작업 내용` - -#### Commit Tag - -- 태그는 영어로 쓰되 대문자로 합니다. -- 태그 종류는 다음과 같습니다. - - `FEAT`: 기능 구현 - - `FIX`: 버그 수정 - - `DOCS`: 문서 작업 - - `REFACTOR`: 리팩토링 - - `TEST`: 테스트 코드 - - `CHORE`: 빌드 업무 수정, 패키지 매니저 수정 - - `ADD`: assets, data 파일 추가하는 경우 - - `STYLE`: 코드 포맷팅, 세미콜론 누락, UI 디자인 변경 → 코드 변경이 없는 경우 - -## 🤝 협업 전략 - -### branch 전략 - -- Git Flow 전략을 응용합니다. - -### Pull Request - -- Pull Request 같은 파트 다른 팀원이 리뷰 후 approve/revert 합니다. - -### 매주 계획하기 - -- 매주 월요일 스프린트 계획 회의에 정한 내용을 Github Issue로 정리합니다. +> 내가 탈 차, 이제 감이 아닌 **데이터**로. -## 📖 브랜치 룰 +현대만의 데이터로 차량 견적을 산출할 수 있는 서비스를 개발하였습니다.
-### Branch Type + ![ant](https://github.com/softeerbootcamp-2nd/A2-CarTag/assets/63107805/3e59ccd2-a9a4-4f32-9ecd-bd3355f8994e)
+🐜 저희 팀 `칼퇴`가 개발한 서비스로 **합리적인 내 차**를 만들어 보세요! + ### 👉🏻 [내 차 만들기 - A2 Cartag](http://www.a2cartag.com/) 👈🏻 -- `main` : 배포 가능한 상태의 브랜치 -- `dev` : 개발 과정 중 하나의 feature/bug를 완료하고 merge하는 브랜치 -- `feat` : 하나의 기능을 구현하는 브랜치 -- `hotfix` : main에서 긴급한 수정사항이 생겼을 때 수정하는 브랜치 -- `bugfix` : 개발 과정 중 발생한 버그를 수정하는 브랜치 -### Naming method +### 주요 기능 -- branch 양식 - `{옵션}/{브랜치 명}` (소문자, kebab-case) - ex) `feat/option-selection` +### Preview +### 기술 스택 -## 📁설계 문서 +### 프로젝트 구조 -### ERD -ERD가 생성되었습니다.(2023.08.02) : [Wiki 링크](https://github.com/softeerbootcamp-2nd/A2-CarTag.wiki.git) +### 👇🏻 링크 +- [그라운드 룰 🗣️](https://github.com/softeerbootcamp-2nd/A2-CarTag/wiki/%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C-%EB%A3%B0) +- [기획/디자인 링크 👩‍🎨](https://www.figma.com/file/UPMMnkNQegdhJXFuZqQqph/Car-ta-log_Hand-off?type=design&node-id=1-6&mode=design&t=sBmZzwne4kOQ0Cub-0) +- [컨벤션 ✅](https://github.com/softeerbootcamp-2nd/A2-CarTag/wiki/Convention) +- [ERD 버전 관리 📜](https://github.com/softeerbootcamp-2nd/A2-CarTag/wiki/ERD) +- [용어 사전 📋](https://github.com/softeerbootcamp-2nd/A2-CarTag/wiki/%EC%9A%A9%EC%96%B4%EC%82%AC%EC%A0%84) From a63e5a266358a538bc94c192141dd8ed160fab32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EC=98=88?= <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 23:42:47 +0900 Subject: [PATCH 30/34] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3fc93c7..2091765 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ > 내가 탈 차, 이제 감이 아닌 **데이터**로. 현대만의 데이터로 차량 견적을 산출할 수 있는 서비스를 개발하였습니다.
- + ### 👉🏻 [내 차 만들기 - A2 Cartag](http://www.a2cartag.com/) 👈🏻 ![ant](https://github.com/softeerbootcamp-2nd/A2-CarTag/assets/63107805/3e59ccd2-a9a4-4f32-9ecd-bd3355f8994e)
🐜 저희 팀 `칼퇴`가 개발한 서비스로 **합리적인 내 차**를 만들어 보세요! - ### 👉🏻 [내 차 만들기 - A2 Cartag](http://www.a2cartag.com/) 👈🏻 + ### 주요 기능 From defaa7ef771240e2b7d5d71cbb47b8bb9d3a0982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EC=98=88?= <63107805+kimdaye77@users.noreply.github.com> Date: Wed, 23 Aug 2023 23:57:31 +0900 Subject: [PATCH 31/34] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2091765..3ea74af 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,10 @@ 현대만의 데이터로 차량 견적을 산출할 수 있는 서비스를 개발하였습니다.
### 👉🏻 [내 차 만들기 - A2 Cartag](http://www.a2cartag.com/) 👈🏻 - ![ant](https://github.com/softeerbootcamp-2nd/A2-CarTag/assets/63107805/3e59ccd2-a9a4-4f32-9ecd-bd3355f8994e)
+
🐜 저희 팀 `칼퇴`가 개발한 서비스로 **합리적인 내 차**를 만들어 보세요! - ### 주요 기능 ### Preview From 140eb33782917cf45944019dc24047a880b2f7ca Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Thu, 24 Aug 2023 00:01:31 +0900 Subject: [PATCH 32/34] Update PriceStaticSlider.tsx --- frontend/src/components/priceStaticBar/PriceStaticSlider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx index d508d7e..aa294bd 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticSlider.tsx @@ -3,7 +3,7 @@ import { flexCenterCss } from '../../utils/commonStyle'; import { BodyKrRegular3, BodyKrRegular5 } from '../../styles/typefaces'; import { ChangeEvent, useContext } from 'react'; import { ItemContext } from '../../context/ItemProvider'; -import { HIGHEST_PRICE, TEN_THOUSAND_UNIT } from '../../utils/constants'; +import { HIGHEST_PRICE, HUNDRED_THOUSAND_UNIT, TEN_THOUSAND_UNIT } from '../../utils/constants'; import { theme } from '../../styles/theme'; interface ISlider extends React.HTMLAttributes { isOverBudget: boolean; From 3775bc192b45407ae31e5b2242f95ace94622e57 Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Thu, 24 Aug 2023 00:31:45 +0900 Subject: [PATCH 33/34] =?UTF-8?q?[FIX]=20#431:=20=EC=99=B8=EC=9E=A5=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EC=9D=B4=EB=A6=84=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=ED=95=9C=20=EA=B0=92=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../containers/OuterColorPage/OuterColorBannerContainer.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/containers/OuterColorPage/OuterColorBannerContainer.tsx b/frontend/src/containers/OuterColorPage/OuterColorBannerContainer.tsx index 1f0da25..cb7dc44 100644 --- a/frontend/src/containers/OuterColorPage/OuterColorBannerContainer.tsx +++ b/frontend/src/containers/OuterColorPage/OuterColorBannerContainer.tsx @@ -114,7 +114,11 @@ export default function OuterColorBannerContainer() { return ( <> - + From 3fdb16126e7bc3323c0d959c155ef59cfd2f922c Mon Sep 17 00:00:00 2001 From: kimdaye77 <63107805+kimdaye77@users.noreply.github.com> Date: Thu, 24 Aug 2023 00:37:05 +0900 Subject: [PATCH 34/34] =?UTF-8?q?[REFACTOR]=20#431:=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InnerColorPage/InnerColorBannerContainer.tsx | 16 ++++------------ frontend/src/pages/InnerColorPage.tsx | 14 +++++++++----- frontend/src/pages/OuterColorPage.tsx | 14 +++++++++----- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/frontend/src/containers/InnerColorPage/InnerColorBannerContainer.tsx b/frontend/src/containers/InnerColorPage/InnerColorBannerContainer.tsx index 85be3f6..19fb7bb 100644 --- a/frontend/src/containers/InnerColorPage/InnerColorBannerContainer.tsx +++ b/frontend/src/containers/InnerColorPage/InnerColorBannerContainer.tsx @@ -1,27 +1,19 @@ import { styled } from 'styled-components'; import Banner from '../../components/common/banner/Banner'; import { useContext } from 'react'; -import { InnerColorContext } from '../../context/InnerColorProvider'; import { IMG_URL } from '../../utils/apis'; -import Loading from '../../components/loading/Loading'; import { flexCenterCss } from '../../utils/commonStyle'; import { ItemContext } from '../../context/ItemProvider'; export default function InnerColorBannerContainer() { - const { data: innerColorData } = useContext(InnerColorContext); const { selectedItem } = useContext(ItemContext); - const idx = selectedItem.innerColor.id - 1; - const imgSrc = innerColorData && innerColorData[idx].colorCarImage; + const imgSrc = selectedItem.innerColor.carImgSrc; return ( - {innerColorData ? ( - - - - ) : ( - - )} + + + ); } diff --git a/frontend/src/pages/InnerColorPage.tsx b/frontend/src/pages/InnerColorPage.tsx index 691880a..0a166a4 100644 --- a/frontend/src/pages/InnerColorPage.tsx +++ b/frontend/src/pages/InnerColorPage.tsx @@ -22,11 +22,15 @@ export default function InnerColorPage() { return ( <> - - - - - + {innerColorData && ( + <> + + + + + s + + )} ); } diff --git a/frontend/src/pages/OuterColorPage.tsx b/frontend/src/pages/OuterColorPage.tsx index 389d52f..1b7e405 100644 --- a/frontend/src/pages/OuterColorPage.tsx +++ b/frontend/src/pages/OuterColorPage.tsx @@ -41,11 +41,15 @@ export default function OuterColorPage() { } return ( <> - - - - - + {outerColorData && ( + <> + + + + + + + )} ); }