diff --git a/backend/src/main/java/autoever2/cartag/controller/OptionController.java b/backend/src/main/java/autoever2/cartag/controller/OptionController.java index 21dd369..8f5f7ac 100644 --- a/backend/src/main/java/autoever2/cartag/controller/OptionController.java +++ b/backend/src/main/java/autoever2/cartag/controller/OptionController.java @@ -36,13 +36,22 @@ public List getSubOptionList(@Parameter(description = "차량 트 return optionService.getSubOptionList(carId); } - @Operation(summary = "옵션 상세정보 조회", description = "옵션 데이터 상세정보 및 이미지, HMG가 존재한다면(비어있다면 비어있는 부분을 Null) 보냄") + @Operation(summary = "추가옵션 상세정보 조회", description = "추가옵션 데이터 상세정보 및 이미지, HMG가 존재한다면(비어있다면 비어있는 부분을 Null) 보냄") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = OptionDetailDto.class))) }) - @GetMapping("/optiondetail") - public OptionDetailDto getOptionDetail(@Parameter(description = "차량 트림 ID") @RequestParam("carid") int carId, @Parameter(description = "옵션 ID") @RequestParam("optionid") int optionId) { - return optionService.getOptionDetailData(carId, optionId); + @GetMapping("/sub/detail") + public OptionDetailDto getSubOptionDetail(@Parameter(description = "차량 트림 ID") @RequestParam("carid") int carId, @Parameter(description = "옵션 ID") @RequestParam("optionid") int optionId) { + return optionService.getOptionDetailData(carId, optionId, false); + } + + @Operation(summary = "기본옵션 상세정보 조회", description = "기본옵션 데이터 상세정보 및 이미지, HMG가 존재한다면(비어있다면 비어있는 부분을 Null) 보냄") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = OptionDetailDto.class))) + }) + @GetMapping("/default/detail") + public OptionDetailDto getDefaultOptionDetail(@Parameter(description = "차량 트림 ID") @RequestParam("carid") int carId, @Parameter(description = "옵션 ID") @RequestParam("optionid") int optionId) { + return optionService.getOptionDetailData(carId, optionId, true); } @Operation(summary = "기본 옵션 리스트 조회", description = "기본 옵션 데이터와 및 HMG 데이터 존재 여부 List 제공") diff --git a/backend/src/main/java/autoever2/cartag/service/OptionService.java b/backend/src/main/java/autoever2/cartag/service/OptionService.java index 60585ad..28c885d 100644 --- a/backend/src/main/java/autoever2/cartag/service/OptionService.java +++ b/backend/src/main/java/autoever2/cartag/service/OptionService.java @@ -54,8 +54,8 @@ public List getDefaultOptionList(int carId) { } //TODO: RuntimeException 처리 - public OptionDetailDto getOptionDetailData(int carId, int optionId) { - OptionDetailMappedDto detail = optionRepository.findOptionDetail(carId, optionId, false).orElseThrow(() -> new RuntimeException("데이터가 존재하지 않습니다.")); + public OptionDetailDto getOptionDetailData(int carId, int optionId, boolean isDefault) { + OptionDetailMappedDto detail = optionRepository.findOptionDetail(carId, optionId, isDefault).orElseThrow(() -> new RuntimeException("데이터가 존재하지 않습니다.")); List packageSubOptions = optionRepository.findPackageSubOptions(optionId); diff --git a/backend/src/test/java/autoever2/cartag/controller/OptionControllerTest.java b/backend/src/test/java/autoever2/cartag/controller/OptionControllerTest.java index ff3af9b..bff5ed7 100644 --- a/backend/src/test/java/autoever2/cartag/controller/OptionControllerTest.java +++ b/backend/src/test/java/autoever2/cartag/controller/OptionControllerTest.java @@ -154,8 +154,8 @@ void getOptionDetail() throws Exception { .subOptionList(subOptions) .build(); - given(optionService.getOptionDetailData(carId, optionWithHmg)).willReturn(expected1); - given(optionService.getOptionDetailData(carId, optionPackage)).willReturn(expected2); + given(optionService.getOptionDetailData(carId, optionWithHmg, false)).willReturn(expected1); + given(optionService.getOptionDetailData(carId, optionPackage, false)).willReturn(expected2); ResultActions singleOption = mockMvc.perform(MockMvcRequestBuilders.get("/api/options/optiondetail").param("carid", String.valueOf(carId)).param("optionid", String.valueOf(optionWithHmg))); ResultActions packageOption = mockMvc.perform(MockMvcRequestBuilders.get("/api/options/optiondetail").param("carid", String.valueOf(carId)).param("optionid", String.valueOf(optionPackage))); diff --git a/backend/src/test/java/autoever2/cartag/service/OptionServiceTest.java b/backend/src/test/java/autoever2/cartag/service/OptionServiceTest.java index a0a26e9..00a63be 100644 --- a/backend/src/test/java/autoever2/cartag/service/OptionServiceTest.java +++ b/backend/src/test/java/autoever2/cartag/service/OptionServiceTest.java @@ -198,8 +198,8 @@ void getOptionDetail() { when(optionRepository.findPackageSubOptions(packageOption)).thenReturn(subPackages); when(carRepository.findCarBoughtCountByCarId(carId)).thenReturn(Optional.of(150000L)); - OptionDetailDto singleResult = optionService.getOptionDetailData(carId, singleOption); - OptionDetailDto packageResult = optionService.getOptionDetailData(carId, packageOption); + OptionDetailDto singleResult = optionService.getOptionDetailData(carId, singleOption, false); + OptionDetailDto packageResult = optionService.getOptionDetailData(carId, packageOption, false); softAssertions.assertThat(singleResult).usingRecursiveComparison().isEqualTo(expected1); softAssertions.assertThat(packageResult).usingRecursiveComparison().isEqualTo(expected2); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f4083ee..631e53c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,17 +1,23 @@ import { BrowserRouter } from 'react-router-dom'; import NavBar from './components/layout/NavBar'; +import Providers from './components/contextProviders/Providers'; import PriceStaticBar from './components/priceStaticBar/PriceStaticBar'; import CustomRouter from './components/router/CustomRouter'; import ModalContainer from './containers/Modal/ModalContainer'; -import CloseModalProvider from './context/CloseModalContext'; -import SimilarQuoteModalProvider from './context/SimilarQuoteModalContext'; -import GuideModalProvider from './context/GuideMoadlContext'; -import Providers from './components/contextProviders/Providers'; +import CloseModalProvider from './context/CloseModalProvider'; +import SimilarQuoteModalProvider from './context/SimilarQuoteModalProvider'; +import GuideModalProvider from './context/GuideModalProvider'; +import ItemProvider from './context/ItemProvider'; function App() { - const modalProviders = [CloseModalProvider, SimilarQuoteModalProvider, GuideModalProvider]; + const globalProviders = [ + CloseModalProvider, + SimilarQuoteModalProvider, + GuideModalProvider, + ItemProvider, + ]; return ( - + @@ -23,4 +29,3 @@ function App() { } export default App; - diff --git a/frontend/src/components/histogram/BarHistogram.tsx b/frontend/src/components/histogram/BarHistogram.tsx index eab0e2c..6828c1d 100644 --- a/frontend/src/components/histogram/BarHistogram.tsx +++ b/frontend/src/components/histogram/BarHistogram.tsx @@ -3,7 +3,7 @@ import HmgTag from '../common/hmgTag/HmgTag'; import { BodyKrMedium2, BodyKrRegular3, HeadingKrMedium6 } from '../../styles/typefaces'; import { flexCenterCss } from '../../utils/commonStyle'; import { useContext } from 'react'; -import { SimilarQuoteModalContext } from '../../context/SimilarQuoteModalContext'; +import { SimilarQuoteModalContext } from '../../context/SimilarQuoteModalProvider'; export default function BarHistogram() { const { setVisible: setSimilarQuoteModalVisible } = useContext(SimilarQuoteModalContext); diff --git a/frontend/src/components/layout/NavBar.tsx b/frontend/src/components/layout/NavBar.tsx index 827fb0d..fdda1d3 100644 --- a/frontend/src/components/layout/NavBar.tsx +++ b/frontend/src/components/layout/NavBar.tsx @@ -5,7 +5,7 @@ import { BodyKrMedium3, BodyKrRegular3, HeadingKrMedium6 } from '../../styles/ty import { ArrowDown, CancelIcon } from '../common/icons/Icons'; import hyundaiLogo from '/images/logo.svg'; import { PATH } from '../../utils/constants'; -import { CloseModalContext } from '../../context/CloseModalContext'; +import { CloseModalContext } from '../../context/CloseModalProvider'; interface INavItem extends React.HTMLAttributes { active: boolean; diff --git a/frontend/src/components/modal/CloseModal.tsx b/frontend/src/components/modal/CloseModal.tsx index f98666b..0ba0a16 100644 --- a/frontend/src/components/modal/CloseModal.tsx +++ b/frontend/src/components/modal/CloseModal.tsx @@ -5,7 +5,7 @@ import { flexCenterCss } from '../../utils/commonStyle'; import RectButton from '../common/buttons/RectButton'; import { HYUNDAI_URL } from '../../utils/constants'; import { DimmedBackground } from './DimmedBackground'; -import { CloseModalContext } from '../../context/CloseModalContext'; +import { CloseModalContext } from '../../context/CloseModalProvider'; interface ICloseModal extends HTMLAttributes {} diff --git a/frontend/src/components/modal/GuideModal.tsx b/frontend/src/components/modal/GuideModal.tsx index d57bb95..43a2efd 100644 --- a/frontend/src/components/modal/GuideModal.tsx +++ b/frontend/src/components/modal/GuideModal.tsx @@ -4,7 +4,7 @@ import { Bubble, CloseIcon } from '../common/icons/Icons'; import { BodyKrRegular3, HeadingKrMedium7 } from '../../styles/typefaces'; import CenterWrapper from '../layout/CenterWrapper'; import { DimmedBackground } from './DimmedBackground'; -import { GuideModalContext } from '../../context/GuideMoadlContext'; +import { GuideModalContext } from '../../context/GuideModalProvider'; import { useLocation } from 'react-router-dom'; import { PATH } from '../../utils/constants'; diff --git a/frontend/src/components/modal/SimilarQuoteModal.tsx b/frontend/src/components/modal/SimilarQuoteModal.tsx index 8c025c4..c0173db 100644 --- a/frontend/src/components/modal/SimilarQuoteModal.tsx +++ b/frontend/src/components/modal/SimilarQuoteModal.tsx @@ -14,7 +14,7 @@ import ExtraOptionCard from '../cards/ExtraOptionCard'; import HmgTag from '../common/hmgTag/HmgTag'; import RectButton from '../common/buttons/RectButton'; import { DimmedBackground } from './DimmedBackground'; -import { SimilarQuoteModalContext } from '../../context/SimilarQuoteModalContext'; +import { SimilarQuoteModalContext } from '../../context/SimilarQuoteModalProvider'; import SimilarPriceBar from '../priceStaticBar/SimilarPriceBar'; interface ISimilarQuoteModal extends HTMLAttributes {} diff --git a/frontend/src/components/priceStaticBar/PriceStaticBar.tsx b/frontend/src/components/priceStaticBar/PriceStaticBar.tsx index 61369b9..c5d6c98 100644 --- a/frontend/src/components/priceStaticBar/PriceStaticBar.tsx +++ b/frontend/src/components/priceStaticBar/PriceStaticBar.tsx @@ -58,7 +58,7 @@ export default function PriceStaticBar({ ...props }: IPriceStaticBar) { const maxY = window.innerHeight - (barRef.current?.offsetHeight || 0); const newLeft = Math.min(Math.max(minX, event.clientX - startX), maxX); const newTop = Math.min(Math.max(minY, event.clientY - startY), maxY); - + event.preventDefault(); setOffset({ offsetX: `${newLeft}px`, offsetY: `${newTop}px` }); }; @@ -71,14 +71,14 @@ export default function PriceStaticBar({ ...props }: IPriceStaticBar) { }, [budget, getBudgetStatus]); useEffect(() => { - window.addEventListener('mousemove', (e) => - handleMouseMove(e, startOffset.startX, startOffset.startY) + window.addEventListener('mousemove', (event) => + handleMouseMove(event, startOffset.startX, startOffset.startY) ); window.addEventListener('mouseup', handleMouseUp); return () => { - window.removeEventListener('mousemove', (e) => - handleMouseMove(e, startOffset.startX, startOffset.startY) + window.removeEventListener('mousemove', (event) => + handleMouseMove(event, startOffset.startX, startOffset.startY) ); window.removeEventListener('mouseup', handleMouseUp); }; diff --git a/frontend/src/components/router/CustomRouter.tsx b/frontend/src/components/router/CustomRouter.tsx index ff16dc0..d583afa 100644 --- a/frontend/src/components/router/CustomRouter.tsx +++ b/frontend/src/components/router/CustomRouter.tsx @@ -8,7 +8,7 @@ import ResultPage from '../../pages/ResultPage'; import TrimPage from '../../pages/TrimPage'; import ModelTypePage from '../../pages/ModelTypePage'; import { PATH } from '../../utils/constants'; -import TrimProvider from '../../context/TrimContext'; +import TrimProvider from '../../context/TrimProvider'; import ModelTypeProvider from '../../context/ModelTypeProvider'; export default function CustomRouter() { diff --git a/frontend/src/components/summary/PriceSummary.tsx b/frontend/src/components/summary/PriceSummary.tsx index 17fe4b7..ac8bcf6 100644 --- a/frontend/src/components/summary/PriceSummary.tsx +++ b/frontend/src/components/summary/PriceSummary.tsx @@ -3,13 +3,15 @@ import RectButton from '../common/buttons/RectButton'; import RoundButton from '../common/buttons/RoundButton'; import { BodyKrRegular4, HeadingKrMedium2 } from '../../styles/typefaces'; import { useNavigate } from 'react-router-dom'; +import { useContext } from 'react'; +import { ItemContext } from '../../context/ItemProvider'; interface IPriceSummary extends React.HTMLAttributes { nextPagePath: string; } export default function PriceSummary({ nextPagePath, ...props }: IPriceSummary) { - const total = 43_560_000; + const { totalPrice } = useContext(ItemContext); const navigate = useNavigate(); const handleButtonClick = (price: number) => { price; // Todo. price 누적 값 저장 @@ -20,10 +22,10 @@ export default function PriceSummary({ nextPagePath, ...props }: IPriceSummary) 견적 요약 - 현재 총 가격{total.toLocaleString()} 원 + 현재 총 가격{totalPrice.toLocaleString()} 원 - handleButtonClick(total)}> + handleButtonClick(totalPrice)}> 다음 diff --git a/frontend/src/containers/Modal/ModalContainer.tsx b/frontend/src/containers/Modal/ModalContainer.tsx index 54f3db8..5261311 100644 --- a/frontend/src/containers/Modal/ModalContainer.tsx +++ b/frontend/src/containers/Modal/ModalContainer.tsx @@ -2,9 +2,9 @@ import { useContext } from 'react'; import CloseModal from '../../components/modal/CloseModal'; import GuideModal from '../../components/modal/GuideModal'; import SimilarQuoteModal from '../../components/modal/SimilarQuoteModal'; -import { GuideModalContext } from '../../context/GuideMoadlContext'; -import { SimilarQuoteModalContext } from '../../context/SimilarQuoteModalContext'; -import { CloseModalContext } from '../../context/CloseModalContext'; +import { GuideModalContext } from '../../context/GuideModalProvider'; +import { SimilarQuoteModalContext } from '../../context/SimilarQuoteModalProvider'; +import { CloseModalContext } from '../../context/CloseModalProvider'; export default function ModalContainer() { const { setVisible: setCloseModalVisible } = useContext(CloseModalContext); diff --git a/frontend/src/containers/ModelTypePage/ModelTypeSelectContainer.tsx b/frontend/src/containers/ModelTypePage/ModelTypeSelectContainer.tsx index 2a1da2a..5f00b2a 100644 --- a/frontend/src/containers/ModelTypePage/ModelTypeSelectContainer.tsx +++ b/frontend/src/containers/ModelTypePage/ModelTypeSelectContainer.tsx @@ -31,7 +31,7 @@ export default function ModelTypelSelectContainer() { { setCurrentModelTypeIdx(el.modelId); - handleSelectedIdx(el.modelTypeName, el.modelId); + handleSelectedIdx(modelTypeToEn[el.modelTypeName], el.modelId); }} active={selectedModelTypeIdx[modelTypeToEn[el.modelTypeName]] === el.modelId} desc={el.percentage + '%의 선택'} diff --git a/frontend/src/containers/TrimPage/TrimBannerContainer.tsx b/frontend/src/containers/TrimPage/TrimBannerContainer.tsx index 61c0644..b596f3f 100644 --- a/frontend/src/containers/TrimPage/TrimBannerContainer.tsx +++ b/frontend/src/containers/TrimPage/TrimBannerContainer.tsx @@ -6,7 +6,7 @@ import { IMG_URL } from '../../utils/apis'; import CenterWrapper from '../../components/layout/CenterWrapper'; import Banner from '../../components/common/banner/Banner'; import HmgTag from '../../components/common/hmgTag/HmgTag'; -import { ICartype, TrimContext } from '../../context/TrimContext'; +import { ICartype, TrimContext } from '../../context/TrimProvider'; import Loading from '../../components/loading/Loading'; export default function TrimBannerContainer() { diff --git a/frontend/src/containers/TrimPage/TrimSelectContainer.tsx b/frontend/src/containers/TrimPage/TrimSelectContainer.tsx index 84e5e4e..ba2f6b0 100644 --- a/frontend/src/containers/TrimPage/TrimSelectContainer.tsx +++ b/frontend/src/containers/TrimPage/TrimSelectContainer.tsx @@ -7,39 +7,62 @@ import { HeadingKrMedium6, HeadingKrMedium7, } from '../../styles/typefaces'; -import { PATH } from '../../utils/constants'; +import { MESSAGE, PATH } from '../../utils/constants'; import CenterWrapper from '../../components/layout/CenterWrapper'; import DefaultCardStyle from '../../components/common/card/DefaultCardStyle'; import RectButton from '../../components/common/buttons/RectButton'; -import { TrimContext } from '../../context/TrimContext'; +import { TrimContext } from '../../context/TrimProvider'; +import { ItemContext } from '../../context/ItemProvider'; export default function TrimSelectContainer() { + const { + selectedTrimIdx, + data: trimData, + loading, + setSelectedTrimIdx, + setSelectedImgIdx, + } = useContext(TrimContext); + const { setSelectedItem, setTotalPrice } = useContext(ItemContext); + const selectedTrim = trimData && trimData[selectedTrimIdx]; const navigate = useNavigate(); - const { selectedTrimIdx, setSelectedTrimIdx, data, loading, setSelectedImgIdx } = - useContext(TrimContext); - const selectedData = data && data[selectedTrimIdx]; const handleSelectedIdx = (idx: number) => { setSelectedTrimIdx(idx); setSelectedImgIdx(0); }; - const handleButtonClick = (price: number) => { - price; // Todo. price 누적 값 저장 + const isAcitve = (idx: number) => selectedTrimIdx === idx; + const handleNextButtonClick = (idx: number) => { + if (!isAcitve(idx)) { + return; + } + if (!selectedTrim) { + alert(MESSAGE.trimSelectRequired); + return; + } + setSelectedItem({ + type: 'SET_TRIM', + value: { + id: selectedTrimIdx, + name: selectedTrim.trim, + price: selectedTrim.carDefaultPrice, + }, + }); + setTotalPrice(selectedTrim.carDefaultPrice); navigate(PATH.modelType); }; const displayTrimCards = () => { - if (!(selectedData && !loading)) { + if (!(selectedTrim && !loading)) { return <>; } - const cardIndices = Array.from({ length: data.length }, (_, index) => index); + const cardIndices = Array.from({ length: trimData.length }, (_, index) => index); return cardIndices.map((idx) => ( - handleSelectedIdx(idx)} active={selectedTrimIdx === idx}> - {data[idx].carDescription} - {data[idx].trim} - {data[idx].carDefaultPrice.toLocaleString()} 원 - handleButtonClick(data[idx].carDefaultPrice)}> + handleSelectedIdx(idx)} active={isAcitve(idx)}> + {trimData[idx].carDescription} + {trimData[idx].trim} + {trimData[idx].carDefaultPrice.toLocaleString()} 원 + handleNextButtonClick(idx)}> 선택하기 @@ -48,7 +71,7 @@ export default function TrimSelectContainer() { return ( <> - {data ? ( + {trimData ? ( 트림을 선택해주세요. {displayTrimCards()} diff --git a/frontend/src/context/CloseModalContext.tsx b/frontend/src/context/CloseModalProvider.tsx similarity index 100% rename from frontend/src/context/CloseModalContext.tsx rename to frontend/src/context/CloseModalProvider.tsx diff --git a/frontend/src/context/GuideMoadlContext.tsx b/frontend/src/context/GuideModalProvider.tsx similarity index 100% rename from frontend/src/context/GuideMoadlContext.tsx rename to frontend/src/context/GuideModalProvider.tsx diff --git a/frontend/src/context/ItemProvider.tsx b/frontend/src/context/ItemProvider.tsx new file mode 100644 index 0000000..f1a8602 --- /dev/null +++ b/frontend/src/context/ItemProvider.tsx @@ -0,0 +1,136 @@ +import { ReactNode, createContext, useReducer, useState } from 'react'; + +type defaultItemType = { + id: number; + name: string; + price: number; +}; +interface detailItemType extends defaultItemType { + title: string; + imgSrc: string; +} +interface ISelectedItem { + trim: defaultItemType; + modelType: { + powerTrain: detailItemType; + bodyType: detailItemType; + operation: detailItemType; + }; + innerColor: detailItemType; + outerColor: detailItemType; + options: detailItemType[]; +} + +interface IItemContext { + selectedItem: ISelectedItem; + totalPrice: number; + setSelectedItem: React.Dispatch; + setTotalPrice: React.Dispatch>; +} + +interface IItemProvider { + children: ReactNode; +} + +const initialSelectedItem = { + trim: { + id: 0, + name: '', + price: 0, + }, + modelType: { + powerTrain: { + id: 0, + name: '', + title: '', + imgSrc: '', + price: 0, + }, + bodyType: { + id: 0, + name: '', + title: '', + imgSrc: '', + price: 0, + }, + operation: { + id: 0, + name: '', + title: '', + imgSrc: '', + price: 0, + }, + }, + innerColor: { + id: 0, + name: '', + title: '', + imgSrc: '', + price: 0, + }, + outerColor: { + id: 0, + name: '', + title: '', + imgSrc: '', + price: 0, + }, + options: [{ id: 0, name: '', title: '', imgSrc: '', price: 0 }], +}; + +const initialItem: IItemContext = { + selectedItem: initialSelectedItem, + totalPrice: 0, + setSelectedItem: () => {}, + setTotalPrice: () => {}, +}; + +type actionType = + | { type: 'SET_TRIM'; value: defaultItemType } + | { type: 'SET_POWER_TRAIN'; value: detailItemType } + | { type: 'SET_OPERATION'; value: detailItemType } + | { type: 'SET_BODY_TYPE'; value: detailItemType } + | { type: 'SET_INNER_COLOR'; value: detailItemType } + | { type: 'SET_OUTER_COLOR'; value: detailItemType } + | { type: 'SET_OPTIONS'; value: detailItemType[] }; + +const reducer = (state: ISelectedItem, action: actionType): ISelectedItem => { + switch (action.type) { + case 'SET_TRIM': + return { ...state, trim: action.value }; + case 'SET_POWER_TRAIN': + return { ...state, modelType: { ...state.modelType, powerTrain: action.value } }; + case 'SET_OPERATION': + return { ...state, modelType: { ...state.modelType, operation: action.value } }; + case 'SET_BODY_TYPE': + return { ...state, modelType: { ...state.modelType, bodyType: action.value } }; + case 'SET_INNER_COLOR': + return { ...state, innerColor: action.value }; + case 'SET_OPTIONS': + return { ...state, options: action.value }; + case 'SET_OUTER_COLOR': + return { ...state, outerColor: action.value }; + default: + return state; + } +}; + +export const ItemContext = createContext(initialItem); + +export default function ItemProvider({ children }: IItemProvider) { + const [selectedItem, setSelectedItem] = useReducer(reducer, initialSelectedItem); + const [totalPrice, setTotalPrice] = useState(0); + + return ( + + {children} + + ); +} diff --git a/frontend/src/context/SimilarQuoteModalContext.tsx b/frontend/src/context/SimilarQuoteModalProvider.tsx similarity index 100% rename from frontend/src/context/SimilarQuoteModalContext.tsx rename to frontend/src/context/SimilarQuoteModalProvider.tsx diff --git a/frontend/src/context/TrimContext.tsx b/frontend/src/context/TrimProvider.tsx similarity index 100% rename from frontend/src/context/TrimContext.tsx rename to frontend/src/context/TrimProvider.tsx diff --git a/frontend/src/pages/TrimPage.tsx b/frontend/src/pages/TrimPage.tsx index 3f209cb..b098c7b 100644 --- a/frontend/src/pages/TrimPage.tsx +++ b/frontend/src/pages/TrimPage.tsx @@ -3,7 +3,7 @@ import TrimBannerContainer from '../containers/TrimPage/TrimBannerContainer'; import TrimSelectContainer from '../containers/TrimPage/TrimSelectContainer'; import { useFetch } from '../hooks/useFetch'; import { TRIM_API } from '../utils/apis'; -import { ICartype, TrimContext } from '../context/TrimContext'; +import { ICartype, TrimContext } from '../context/TrimProvider'; export default function TrimPage() { const { data, loading } = useFetch(`${TRIM_API}?carType=${1}`); diff --git a/frontend/src/utils/constants.ts b/frontend/src/utils/constants.ts index fe9b4e8..afa3d90 100644 --- a/frontend/src/utils/constants.ts +++ b/frontend/src/utils/constants.ts @@ -12,6 +12,10 @@ export const PATH = { result: '/result', }; +export const MESSAGE = { + trimSelectRequired: '트림을 선택해 주세요.', +}; + export const modelTypeToEn: { [key: string]: string } = { 파워트레인: 'powertrain', 바디타입: 'bodytype', @@ -19,7 +23,6 @@ export const modelTypeToEn: { [key: string]: string } = { }; export const HYUNDAI_URL = 'https://www.hyundai.com/kr/ko/e'; -export const FONT_URL = 'fonts/'; export const PAGE_ANIMATION_DURATION = 500; Object.freeze({ @@ -28,5 +31,6 @@ Object.freeze({ MAX_TEXT_CNT, HYUNDAI_URL, PATH, + MESSAGE, PAGE_ANIMATION_DURATION, });