diff --git a/.env.development b/.env.development index f03ba3d..d09b8e4 100644 --- a/.env.development +++ b/.env.development @@ -1,3 +1,4 @@ VITE_KAKAO_JAVASCRIPT_KEY=02e0caae3e4116da61d734a06528cd86 VITE_KAKAO_RESTAPI_KEY=09bebf5106adf50d6a204a7ac2c22779 VITE_KAKAO_OPEN_URL=https://kauth.kakao.com/oauth/authorize?client_id={clientId}&redirect_uri={redirectUri}&response_type=code&prompt=login +VITE_SERVER_URL=http://49.50.175.112:8080 \ No newline at end of file diff --git a/package.json b/package.json index 10600ad..0068c4b 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ }, "dependencies": { "@types/styled-components": "^5.1.25", + "axios": "^0.27.2", + "qs": "^6.11.0", "react": "^18.0.0", "react-dom": "^18.0.0", "react-router-dom": "^6.3.0", @@ -19,6 +21,7 @@ }, "devDependencies": { "@honkhonk/vite-plugin-svgr": "^1.1.0", + "@types/qs": "^6.9.7", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@typescript-eslint/eslint-plugin": "^5.23.0", diff --git a/src/assets/img/TripleLineMenu.png b/src/assets/img/TripleLineMenu.png new file mode 100644 index 0000000..bb37eed Binary files /dev/null and b/src/assets/img/TripleLineMenu.png differ diff --git a/src/assets/img/index.ts b/src/assets/img/index.ts index 6cd7627..9a597c2 100644 --- a/src/assets/img/index.ts +++ b/src/assets/img/index.ts @@ -10,3 +10,4 @@ export { default as MatchingSuccess } from './MatchingSuccess.png'; export { default as Waiting } from './Waiting.png'; export { default as Complete } from './Complete.png'; export { default as CopyIcon } from './CopyIcon.png'; +export { default as TripleLineMenu } from './TripleLineMenu.png'; diff --git a/src/atoms/datingState.ts b/src/atoms/datingState.ts index 00d8dfb..35dd1db 100644 --- a/src/atoms/datingState.ts +++ b/src/atoms/datingState.ts @@ -35,7 +35,7 @@ const INITIAL_DATING_STATE: Dating = { }; const datingState = atom({ - key: 'dating/datingState', + key: 'datingState', default: INITIAL_DATING_STATE, effects_UNSTABLE: [persistAtom], }); diff --git a/src/atoms/meetingState.ts b/src/atoms/meetingState.ts index ba8891c..c16857b 100644 --- a/src/atoms/meetingState.ts +++ b/src/atoms/meetingState.ts @@ -29,7 +29,7 @@ const INITIAL_MEETING_STATE: Meeting = { kakaoId: '', }; -const meetingState = atom({ +export const meetingState = atom({ key: 'meetingState', default: INITIAL_MEETING_STATE, effects_UNSTABLE: [persistAtom], diff --git a/src/components/base/CheckBox.tsx b/src/components/base/CheckBox.tsx index ab46e37..b517f00 100644 --- a/src/components/base/CheckBox.tsx +++ b/src/components/base/CheckBox.tsx @@ -4,19 +4,24 @@ import styled from 'styled-components'; interface CheckBoxProps extends React.InputHTMLAttributes { text: string; - + isMulti?: boolean; /** * important: 전체동의에서 쓸것, true일시 글씨크기,fontweight커짐 */ impotrant?: boolean; } -function CheckBox({ text, impotrant = false, ...rest }: CheckBoxProps) { - return ( +function CheckBox({ isMulti = true, text, impotrant = false, ...rest }: CheckBoxProps) { + return isMulti ? ( {text} + ) : ( + + + {text} + ); } diff --git a/src/components/base/Input.tsx b/src/components/base/Input.tsx index d7dc3ea..2791ec8 100644 --- a/src/components/base/Input.tsx +++ b/src/components/base/Input.tsx @@ -31,7 +31,6 @@ const Input = ({ width = '100%', height = '38px', focusColor = palette.primary, useEffect(() => { if (inputRef.current && isFocus) { - console.log(isFocus, 'isFocus'); inputRef.current.focus(); } }, [isFocus]); diff --git a/src/components/domain/landing/LandingContainer.tsx b/src/components/domain/landing/LandingContainer.tsx index 0c35438..5550bf9 100644 --- a/src/components/domain/landing/LandingContainer.tsx +++ b/src/components/domain/landing/LandingContainer.tsx @@ -20,6 +20,8 @@ function LandingContainer() { const loginUrl = import.meta.env.VITE_KAKAO_OPEN_URL.replace('{clientId}', clientId).replace('{redirectUri}', redirectUri); window.location.href = loginUrl; + // const code = new URL(window.location.href).searchParams.get('code'); + // console.log(code); }; return ( @@ -50,9 +52,9 @@ function LandingContainer() { > 시작하기 - {/* setIsLogin((prev) => !prev)}>*/} - {/* 응답 수정하기*/} - {/**/} + setIsLogin((prev) => !prev)}> + 응답 수정하기 + )} {isModal && ( diff --git a/src/components/domain/matching/EndBox.tsx b/src/components/domain/matching/EndBox.tsx index 96dd3e8..1215b95 100644 --- a/src/components/domain/matching/EndBox.tsx +++ b/src/components/domain/matching/EndBox.tsx @@ -4,10 +4,12 @@ import { schools } from '@/mock/schools'; import { Meeting } from '@/types/meeting'; import styled from 'styled-components'; import KakaoCopyBox from './KakaoCopyBox'; -import AddCommaFunction from '@/hooks/common/AddCommaFunction'; +import { conversionDepartment, conversionDomesticArea, conversionMindset, conversionPlay } from '@/utils/converson'; +import { addComma } from '@/utils/addComma'; +import { addCommaTail } from '@/utils/addCommaTail'; const TempData: Meeting = { - averageHeight: [170, 175], + averageHeight: 175, averageAge: 22, ourUniversities: [1, 2, 11], ourDepartments: ['ATHLETIC', 'SCIENCE'], @@ -29,7 +31,6 @@ const TempData: Meeting = { }; function EndBox() { const { kakaoId, averageAge, averageHeight, mindset, ourDepartments, ourUniversities, play } = TempData; - const { addComma, addTailComma } = AddCommaFunction(); return (
@@ -39,9 +40,7 @@ function EndBox() { 평균키 - - {averageHeight[0]} ~ {averageHeight[1]} - + {averageHeight} 학교 @@ -49,7 +48,7 @@ function EndBox() { {ourUniversities.map((univ, index) => (

{schools[univ].name} - {addTailComma(ourUniversities.length, index)} + {addCommaTail(ourUniversities.length, index)}

))} @@ -60,7 +59,7 @@ function EndBox() { {ourDepartments.map((department, index) => (

{addComma(index)} - {{ LIBERAL: '문과', SCIENCE: '이과', ATHLETIC: '체육', ART: '예술' }[department]} + {conversionDepartment(department)}

))} @@ -79,17 +78,17 @@ function EndBox() { {TempData.domesticAreas?.map((area, index) => ( {addComma(index)} - {{ ICN: '인천', SNW: '서북', SNE: '동북', SSW: '서남', SSE: '동서', GN: '경기 북부', GS: '경기 남부' }[area]}, + {conversionDomesticArea(area)}, ))}
마인드셋 - {{ ALL: '친구랑 노는, 설레는 둘 다', FRIEND: '친구랑 노는 느낌', LOVE: '설레는 느낌' }[mindset]} + {conversionMindset(mindset)} 술게임 - {{ ALL: '술게임, 얘기하면서 둘 다', GAME: '술게임 할래요!', TALK: '얘기하면서 놀래요.' }[play]} + {conversionPlay(play)}
diff --git a/src/components/domain/matching/MatchingTemplete.tsx b/src/components/domain/matching/MatchingTemplete.tsx index 7a59aae..e75c5a1 100644 --- a/src/components/domain/matching/MatchingTemplete.tsx +++ b/src/components/domain/matching/MatchingTemplete.tsx @@ -1,48 +1,62 @@ -import React, { MouseEventHandler, ReactNode, useEffect, useState } from 'react'; +import React, { ReactNode, useEffect, useState } from 'react'; import styled from 'styled-components'; import { Button } from '@/components/base'; -import UserHeader from './UserHeader'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { Title } from '@/lib/styles/styledComponents'; +import CompleteButton from './buttons/CompleteButton'; +import EndButton from './buttons/EndButton'; +import NoneButton from './buttons/NoneButton'; +import WaitingButton from './buttons/WaitingButton'; +import SuccessButton from './buttons/SuccessButton'; +import Path from '@/router/Path'; interface MatchingTemplateProps { children: ReactNode; - handleClick?: MouseEventHandler; - IsDisable: boolean; title: ReactNode; btnName: string; } -const MatchingTemplete = ({ children, handleClick, IsDisable, btnName, title }: MatchingTemplateProps) => { +const MatchingTemplete = ({ children, btnName, title }: MatchingTemplateProps) => { const location = useLocation(); const [type, setType] = useState('meeting'); + const navigate = useNavigate(); + useEffect(() => { location.pathname.includes('meeting') ? setType('meeting') : setType('dating'); }, [location.pathname]); return ( - {title} - + navigate(Path.MatchingMeeting)} + size="medium" + variant={type === 'meeting' ? 'default' : 'gray'} + fontWeight={type === 'dating' ? 700 : 400} + > 미팅 - + navigate(Path.MatchingDating)} + size="medium" + variant={type === 'dating' ? 'default' : 'gray'} + fontWeight={type === 'dating' ? 700 : 400} + > 소개팅
{children}
- + { + { + none: , + waiting: , + success: , + pay: , + end: , + }[btnName] + }
@@ -51,7 +65,7 @@ const MatchingTemplete = ({ children, handleClick, IsDisable, btnName, title }: const TemplateBlock = styled.section` position: relative; - height: 100%; + height: calc(100% - 56px); margin: 0 8px; `; diff --git a/src/components/domain/matching/UserHeader.tsx b/src/components/domain/matching/UserHeader.tsx deleted file mode 100644 index 79397e5..0000000 --- a/src/components/domain/matching/UserHeader.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; -import { HeaderWrapper, Logo } from '../survey/SurveyTemplate'; - -const UserHeader = () => { - return ( - - 외딴썸 - {/* 유저 정보 불러오고 햄버거 매뉴 만들어야함! */} - - ); -}; - -const HeaderLayout = styled(HeaderWrapper)` - margin-bottom: 10px; -`; - -export default UserHeader; diff --git a/src/components/domain/matching/buttons/CompleteButton.tsx b/src/components/domain/matching/buttons/CompleteButton.tsx new file mode 100644 index 0000000..b7a0194 --- /dev/null +++ b/src/components/domain/matching/buttons/CompleteButton.tsx @@ -0,0 +1,20 @@ +import { Button } from '@/components/base'; +import { palette } from '@/lib/styles/palette'; +import React from 'react'; +import styled from 'styled-components'; + +function CompleteButton() { + return ( + + 이미 결제를 완료하였습니다. + + ); +} + +const ButtonStyled = styled(Button)` + color: white; + font-weight: 700; + background-color: ${palette.disableColor}; +`; + +export default CompleteButton; diff --git a/src/components/domain/matching/buttons/EndButton.tsx b/src/components/domain/matching/buttons/EndButton.tsx new file mode 100644 index 0000000..45aa2fb --- /dev/null +++ b/src/components/domain/matching/buttons/EndButton.tsx @@ -0,0 +1,15 @@ +import { Button } from '@/components/base'; +import React from 'react'; + +function EndButton() { + const handleClick = () => { + console.log('asd'); + }; + return ( + + ); +} + +export default EndButton; diff --git a/src/components/domain/matching/buttons/NoneButton.tsx b/src/components/domain/matching/buttons/NoneButton.tsx new file mode 100644 index 0000000..e45d7f6 --- /dev/null +++ b/src/components/domain/matching/buttons/NoneButton.tsx @@ -0,0 +1,15 @@ +import { Button } from '@/components/base'; +import React from 'react'; + +function NoneButton() { + const handleClick = () => { + console.log('asd'); + }; + return ( + + ); +} + +export default NoneButton; diff --git a/src/components/domain/matching/buttons/SuccessButton.tsx b/src/components/domain/matching/buttons/SuccessButton.tsx new file mode 100644 index 0000000..6e5081e --- /dev/null +++ b/src/components/domain/matching/buttons/SuccessButton.tsx @@ -0,0 +1,15 @@ +import { Button } from '@/components/base'; +import React from 'react'; + +function SuccessButton() { + const handleClick = () => { + console.log('asd'); + }; + return ( + + ); +} + +export default SuccessButton; diff --git a/src/components/domain/matching/buttons/WaitingButton.tsx b/src/components/domain/matching/buttons/WaitingButton.tsx new file mode 100644 index 0000000..fa8eefe --- /dev/null +++ b/src/components/domain/matching/buttons/WaitingButton.tsx @@ -0,0 +1,15 @@ +import { Button } from '@/components/base'; +import React from 'react'; + +function WaitingButton() { + const handleClick = () => { + console.log('asd'); + }; + return ( + + ); +} + +export default WaitingButton; diff --git a/src/components/domain/survey/AgeBox.tsx b/src/components/domain/survey/AgeBox.tsx index b195f42..80ce2b4 100644 --- a/src/components/domain/survey/AgeBox.tsx +++ b/src/components/domain/survey/AgeBox.tsx @@ -7,7 +7,7 @@ import { OnChangeProps } from '@/components/base/SimpleRangeSlider'; interface AgeBoxProps { ageOption?: number; setAgeOption?: React.Dispatch>; - multiAgeOption: number[]; + multiAgeOption?: number[]; setMultiAgeOption?: React.Dispatch>; children: React.ReactNode; isMulti?: boolean; diff --git a/src/components/domain/survey/ChooseTwoBox.tsx b/src/components/domain/survey/ChooseTwoBox.tsx index 10b18a8..e735eaa 100644 --- a/src/components/domain/survey/ChooseTwoBox.tsx +++ b/src/components/domain/survey/ChooseTwoBox.tsx @@ -39,7 +39,6 @@ const ChooseTwoBox = ({ selectedOption, onChangeOption, children, items, size = const Container = styled.section` width: 100%; - margin-top: 67px; `; const ButtonWrapper = styled.div` diff --git a/src/components/domain/survey/SearchSelector.tsx b/src/components/domain/survey/SearchSelector.tsx index 65f2e18..fc967ae 100644 --- a/src/components/domain/survey/SearchSelector.tsx +++ b/src/components/domain/survey/SearchSelector.tsx @@ -1,4 +1,4 @@ -import React, { ChangeEvent, useCallback, useRef, useState } from 'react'; +import React, { ChangeEvent, useCallback, useEffect, useRef, useState } from 'react'; import styled from 'styled-components'; import { DeleteIcon, SearchIcon } from '@/assets/img'; @@ -23,17 +23,22 @@ const SearchSelector = ({ placeholder, searchData, selectedResults, setSelectedR const findId = useCallback((value: string) => Number(searchData.find((data) => data.name === value)?.id), [searchData]); + useEffect(() => { + const result = selectedResults.flatMap((id) => searchData.filter((item) => item.id === id)).map(({ name }) => name); + setSelectedSchools(result); + }, []); + const handleInputChange = (e: ChangeEvent) => { const { value } = e.target; const id = findId(value); const noMatchData = !searchData.map(({ id }) => id).includes(id); + const existSelected = selectedResults.includes(id); const overMaxLimit = selectedResults.length >= MAX; - if (noMatchData || overMaxLimit) return; + if (noMatchData || existSelected || overMaxLimit) return; setSelectedResults((prev) => [...prev, id]); setSelectedSchools((prev) => [...prev, value]); - console.log(selectedResults); }; const handleDeleteClick = (value: string) => { @@ -41,10 +46,16 @@ const SearchSelector = ({ placeholder, searchData, selectedResults, setSelectedR setSelectedResults((prev) => prev.filter((id) => id !== findId(value))); }; + const resetClick = () => { + if (inputRef.current) { + inputRef.current.value = ''; + } + }; + return ( <> - + {searchData.map(({ name, id }) => (