From 40d2778e185477a158ffce625e4c85b5dc9ffdbf Mon Sep 17 00:00:00 2001 From: joanShim Date: Wed, 10 Jan 2024 16:28:46 +0900 Subject: [PATCH 01/46] =?UTF-8?q?Feat:=20createTrip=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 + pnpm-lock.yaml | 73 +++++++++++- src/components/DatePicker/DatePicker.tsx | 106 ++++++++++++++++++ .../DatePicker/DatePickerInfinite.tsx | 29 +++++ src/components/common/header/BackHeader.tsx | 16 +++ src/components/createTrip/SelectDate.tsx | 12 ++ src/components/search/ResultCategory.tsx | 2 +- src/components/search/SearchRegion.tsx | 3 + src/pages/create/createTrip.page.tsx | 43 +++++++ src/router/mainRouter.tsx | 4 + src/router/routerLayout.tsx | 1 + 11 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 src/components/DatePicker/DatePicker.tsx create mode 100644 src/components/DatePicker/DatePickerInfinite.tsx create mode 100644 src/components/common/header/BackHeader.tsx create mode 100644 src/components/createTrip/SelectDate.tsx create mode 100644 src/components/search/SearchRegion.tsx create mode 100644 src/pages/create/createTrip.page.tsx diff --git a/package.json b/package.json index 2af0d0d1..f06c44ef 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,12 @@ "@tanstack/react-query": "^5.14.6", "@tanstack/react-query-devtools": "^5.14.6", "axios": "^1.6.2", + "date-fns": "^3.1.0", "msw": "0.36.3", "path": "^0.12.7", "react": "^18.2.0", + "react-date-range": "2.0.0-alpha.4", + "react-day-picker": "^8.10.0", "react-dom": "^18.2.0", "react-infinite-scroller": "^1.2.6", "react-kakao-maps-sdk": "^1.1.24", @@ -37,6 +40,7 @@ }, "devDependencies": { "@types/react": "^18.2.43", + "@types/react-date-range": "^1.4.9", "@types/react-dom": "^18.2.17", "@types/react-infinite-scroller": "^1.2.5", "@types/react-modal": "^3.16.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 12b2de0d..a6a746aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ dependencies: axios: specifier: ^1.6.2 version: 1.6.3 + date-fns: + specifier: ^3.1.0 + version: 3.1.0 msw: specifier: 0.36.3 version: 0.36.3 @@ -44,6 +47,12 @@ dependencies: react: specifier: ^18.2.0 version: 18.2.0 + react-date-range: + specifier: 2.0.0-alpha.4 + version: 2.0.0-alpha.4(date-fns@3.1.0)(react@18.2.0) + react-day-picker: + specifier: ^8.10.0 + version: 8.10.0(date-fns@3.1.0)(react@18.2.0) react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) @@ -82,6 +91,9 @@ devDependencies: '@types/react': specifier: ^18.2.43 version: 18.2.45 + '@types/react-date-range': + specifier: ^1.4.9 + version: 1.4.9 '@types/react-dom': specifier: ^18.2.17 version: 18.2.18 @@ -1405,7 +1417,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 - dev: false /@babel/template@7.22.15: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} @@ -2688,6 +2699,13 @@ packages: /@types/prop-types@15.7.11: resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} + /@types/react-date-range@1.4.9: + resolution: {integrity: sha512-5oVEDW0ElYmY1+YVSzdMUR8stxSI5QrRJCgCFUvuEAV5197t412vimD9aVTW6g4JTaxCnMmB1BdEOT/odpaBxQ==} + dependencies: + '@types/react': 18.2.45 + date-fns: 2.30.0 + dev: true + /@types/react-dom@18.2.18: resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==} dependencies: @@ -3180,6 +3198,10 @@ packages: optionalDependencies: fsevents: 2.3.3 + /classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + dev: false + /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -3356,6 +3378,17 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + /date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + dependencies: + '@babel/runtime': 7.23.6 + dev: true + + /date-fns@3.1.0: + resolution: {integrity: sha512-ZO7yefXV/wCWzd3I9haCHmfzlfA3i1a2HHO7ZXjtJrRjXt8FULKJ2Vl8wji3XYF4dQ0ZJ/tokXDZeYlFvgms9Q==} + dev: false + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -4602,6 +4635,30 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /react-date-range@2.0.0-alpha.4(date-fns@3.1.0)(react@18.2.0): + resolution: {integrity: sha512-8IP6DVW6nGQu1PUUw7iCAOnRfLP8cKrjDNKZFb9z7SAWUZ/RiUYNbUfdZxGySlcx5V52BpgFpEuAKD16pEN+MA==} + peerDependencies: + date-fns: 3.0.6 || >=3.0.0 + react: ^0.14 || ^15.0.0-rc || >=15.0 + dependencies: + classnames: 2.5.1 + date-fns: 3.1.0 + prop-types: 15.8.1 + react: 18.2.0 + react-list: 0.8.17(react@18.2.0) + shallow-equal: 1.2.1 + dev: false + + /react-day-picker@8.10.0(date-fns@3.1.0)(react@18.2.0): + resolution: {integrity: sha512-mz+qeyrOM7++1NCb1ARXmkjMkzWVh2GL9YiPbRjKe0zHccvekk4HE+0MPOZOrosn8r8zTHIIeOUXTmXRqmkRmg==} + peerDependencies: + date-fns: ^2.28.0 || ^3.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + date-fns: 3.1.0 + react: 18.2.0 + dev: false + /react-dom@18.2.0(react@18.2.0): resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -4641,6 +4698,15 @@ packages: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} dev: false + /react-list@0.8.17(react@18.2.0): + resolution: {integrity: sha512-pgmzGi0G5uGrdHzMhgO7KR1wx5ZXVvI3SsJUmkblSAKtewIhMwbQiMuQiTE83ozo04BQJbe0r3WIWzSO0dR1xg==} + peerDependencies: + react: 0.14 || 15 - 18 + dependencies: + prop-types: 15.8.1 + react: 18.2.0 + dev: false + /react-modal@3.16.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==} engines: {node: '>=8'} @@ -4806,7 +4872,6 @@ packages: /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: false /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} @@ -4938,6 +5003,10 @@ packages: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} dev: false + /shallow-equal@1.2.1: + resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==} + dev: false + /shallowequal@1.1.0: resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} dev: false diff --git a/src/components/DatePicker/DatePicker.tsx b/src/components/DatePicker/DatePicker.tsx new file mode 100644 index 00000000..4f33dcae --- /dev/null +++ b/src/components/DatePicker/DatePicker.tsx @@ -0,0 +1,106 @@ +import { format, addDays } from 'date-fns'; +import { ko } from 'date-fns/locale'; +import { useState } from 'react'; +import { DateFormatter, DayPicker, DateRange } from 'react-day-picker'; +import 'react-day-picker/dist/style.css'; +import styled from 'styled-components'; + +const formatCaption: DateFormatter = (date, options) => { + const y = date.getFullYear(); + const m = format(date, 'LLLL', { locale: options?.locale }); + return `${y} ${m} `; +}; + +export const DatePicker = () => { + const today = new Date(); + const defaultSelected: DateRange = { + from: today, + to: addDays(today, 4), + }; + const [range, setRange] = useState(defaultSelected); + + return ( + +
+ {range?.from ? ( + !range.to ? ( +

{format(range.from, 'PPP', { locale: ko })}

+ ) : ( +

+ {format(range.from, 'PP', { locale: ko })} –{' '} + {format(range.to, 'PP', { locale: ko })} +

+ ) + ) : ( +

날짜를 선택하세요.

+ )} +
+ +
+ ); +}; + +const DatePickerSection = styled.section` + .rdp { + --rdp-cell-size: 40px; + --rdp-caption-font-size: 14px; + --rdp-accent-color: #0000ff; + --rdp-background-color: #fff; + --rdp-accent-color-dark: #3003e1; + --rdp-background-color-dark: #180270; + --rdp-outline: none; + --rdp-outline-selected: none; + --rdp-selected-color: #fff; + margin: 0; + } + .rdp-months { + flex-direction: column; + width: 100%; + } + .rdp-month { + margin: 0; + width: 100%; + } + + .rdp-caption, + select.rdp-dropdown { + text-align: left; + } + + .rdp-caption_label { + font-size: 15px; + } + + .rdp-caption_start { + margin-bottom: 30px; + } + + .rdp-table { + max-width: 100%; + width: 100%; + } + + .rdp-row { + /* display: flex; */ + width: 100%; + } + + .rdp-day_selected { + background-color: #ddd; + } + + .rdp-button:hover:not([disabled]):not(.rdp-day_selected) { + background-color: #eee; + } +`; diff --git a/src/components/DatePicker/DatePickerInfinite.tsx b/src/components/DatePicker/DatePickerInfinite.tsx new file mode 100644 index 00000000..46aeaf22 --- /dev/null +++ b/src/components/DatePicker/DatePickerInfinite.tsx @@ -0,0 +1,29 @@ +import 'react-date-range/dist/styles.css'; // main css file +import 'react-date-range/dist/theme/default.css'; // theme css file +import { DateRange } from 'react-date-range'; +import { useState } from 'react'; +import { addDays } from 'date-fns'; + +export const DatePickerInfinite = () => { + const [state, setState] = useState([ + { + startDate: new Date(), + endDate: null, + key: 'selection', + }, + ]); + return ( +
+ setState([item.selection])} + moveRangeOnFirstSelection={false} + direction="vertical" + scroll={{ enabled: true }} + ranges={state} + minDate={new Date()} + maxDate={addDays(new Date(), 900)} + /> +
+ ); +}; diff --git a/src/components/common/header/BackHeader.tsx b/src/components/common/header/BackHeader.tsx new file mode 100644 index 00000000..d5c36214 --- /dev/null +++ b/src/components/common/header/BackHeader.tsx @@ -0,0 +1,16 @@ +import { useNavigate } from 'react-router-dom'; +import { BackIcon } from '../icons/Icons'; + +export default function BackHeader() { + const navigate = useNavigate(); + + const goBack = () => { + navigate(-1); + }; + + return ( +
+ +
+ ); +} diff --git a/src/components/createTrip/SelectDate.tsx b/src/components/createTrip/SelectDate.tsx new file mode 100644 index 00000000..4ba07441 --- /dev/null +++ b/src/components/createTrip/SelectDate.tsx @@ -0,0 +1,12 @@ +import { DatePicker } from '@components/DatePicker/DatePicker'; +import { DatePickerInfinite } from '@components/DatePicker/DatePickerInfinite'; + +export const SelectDate = ({ onClose }) => { + return ( +
+ {/* */} + + +
+ ); +}; diff --git a/src/components/search/ResultCategory.tsx b/src/components/search/ResultCategory.tsx index 6707f6c0..e6447af1 100644 --- a/src/components/search/ResultCategory.tsx +++ b/src/components/search/ResultCategory.tsx @@ -1,7 +1,7 @@ import { ButtonWhite } from '@components/common/button/Button'; -import { ResultItem } from './ResultItem'; import { TourType } from '@/@types/tours.types'; import { InfiniteQueryObserverResult } from '@tanstack/react-query'; +import { ResultItem } from './ResultItem'; interface ResultCategoryProps { data: TourType[]; diff --git a/src/components/search/SearchRegion.tsx b/src/components/search/SearchRegion.tsx new file mode 100644 index 00000000..cb2ab6ea --- /dev/null +++ b/src/components/search/SearchRegion.tsx @@ -0,0 +1,3 @@ +export const SearchRegion = () => { + return
SearchRegion
; +}; diff --git a/src/pages/create/createTrip.page.tsx b/src/pages/create/createTrip.page.tsx new file mode 100644 index 00000000..978af6cc --- /dev/null +++ b/src/pages/create/createTrip.page.tsx @@ -0,0 +1,43 @@ +import BackHeader from '@components/common/header/BackHeader'; +import { useState } from 'react'; +import { SelectDate } from '../../components/createTrip/SelectDate'; + +export const CreateTrip = () => { + const [inputValue, setInputValue] = useState('나의 여정'); + const [showSelectDate, setShowSelectDate] = useState(false); + + const handleChange = (e) => { + setInputValue(e.target.value); + }; + + const handleDateButtonClick = () => { + setShowSelectDate(true); + }; + + const handleCloseSelectDate = () => { + setShowSelectDate(false); + }; + + if (showSelectDate) { + return ; + } + return ( +
+ +
여행 생성하기
+ + +
+ ); +}; diff --git a/src/router/mainRouter.tsx b/src/router/mainRouter.tsx index 549ca215..85c184b2 100644 --- a/src/router/mainRouter.tsx +++ b/src/router/mainRouter.tsx @@ -5,6 +5,8 @@ import Detail from '@pages/detail/detail.page'; import ReviewComment from '@pages/reviewComment/reviewComment.page'; import ReviewPosting from '@pages/reviewPosting/reviewPosting.page'; import MainLayout from './routerLayout'; +import { SelectDate } from '@components/createTrip/SelectDate'; +import { CreateTrip } from '@pages/create/createTrip.page'; const MainRouter = () => { return ( @@ -16,6 +18,8 @@ const MainRouter = () => { } /> } /> } /> + } /> + } /> diff --git a/src/router/routerLayout.tsx b/src/router/routerLayout.tsx index 6a37f7d9..435e01cd 100644 --- a/src/router/routerLayout.tsx +++ b/src/router/routerLayout.tsx @@ -13,6 +13,7 @@ const MainLayout = () => { '/detail', '/reviewPosting', '/reviewComment', + '/create', ]; const showNav = !hideNavPaths.some((path) => location.pathname.includes(path), From 55739c9aacaa2daccc5315639d6c367947ae966e Mon Sep 17 00:00:00 2001 From: joanShim Date: Thu, 11 Jan 2024 15:27:01 +0900 Subject: [PATCH 02/46] =?UTF-8?q?Feat:=20=EC=BA=98=EB=A6=B0=EB=8D=94=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 171 +++++++++++++++++++++++++++ src/pages/create/createTrip.page.tsx | 14 ++- src/router/mainRouter.tsx | 2 - 4 files changed, 182 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f06c44ef..fa16e9cf 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-toggle-group": "^1.0.4", "@svgr/rollup": "^8.1.0", "@tanstack/react-query": "^5.14.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a6a746aa..f54144a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ dependencies: '@radix-ui/react-radio-group': specifier: ^1.1.3 version: 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-select': + specifier: ^2.0.0 + version: 2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-toggle-group': specifier: ^1.0.4 version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) @@ -1709,6 +1712,34 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@floating-ui/core@1.5.3: + resolution: {integrity: sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==} + dependencies: + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/dom@1.5.4: + resolution: {integrity: sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==} + dependencies: + '@floating-ui/core': 1.5.3 + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/react-dom@2.0.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-UsBK30Bg+s6+nsgblXtZmwHhgS2vmbuQK22qgt2pTQM6M3X6H1+cQcLXqgRY3ihVLcZJE6IvqDQozhsnIVqK/Q==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.5.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@floating-ui/utils@0.2.1: + resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} + dev: false + /@humanwhocodes/config-array@0.11.13: resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} engines: {node: '>=10.10.0'} @@ -1829,12 +1860,39 @@ packages: resolution: {integrity: sha512-SseX4HmwtyCYp51GFwFNqwTTcsoRwG/2iUUicVtlEtJrIee4al63o4UzpvD3b0/XUxBbJdxAUXVDYPlC6HQytw==} dev: false + /@radix-ui/number@1.0.1: + resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} + dependencies: + '@babel/runtime': 7.23.6 + dev: false + /@radix-ui/primitive@1.0.1: resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} dependencies: '@babel/runtime': 7.23.6 dev: false + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.6 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.45 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==} peerDependencies: @@ -2048,6 +2106,36 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.6 + '@floating-ui/react-dom': 2.0.5(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.45 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} peerDependencies: @@ -2171,6 +2259,47 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.6 + '@radix-ui/number': 1.0.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.45 + '@types/react-dom': 18.2.18 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.45)(react@18.2.0) + dev: false + /@radix-ui/react-slot@1.0.2(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: @@ -2308,6 +2437,21 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.45)(react@18.2.0): + resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.6 + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.45 + react: 18.2.0 + dev: false + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} peerDependencies: @@ -2323,6 +2467,33 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.6 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.45 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/rect@1.0.1: + resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==} + dependencies: + '@babel/runtime': 7.23.6 + dev: false + /@remix-run/router@1.14.1: resolution: {integrity: sha512-Qg4DMQsfPNAs88rb2xkdk03N3bjK4jgX5fR24eHCTR9q6PrhZQZ4UJBPzCHJkIpTRN1UKxx2DzjZmnC+7Lj0Ow==} engines: {node: '>=14.0.0'} diff --git a/src/pages/create/createTrip.page.tsx b/src/pages/create/createTrip.page.tsx index 978af6cc..190c1b26 100644 --- a/src/pages/create/createTrip.page.tsx +++ b/src/pages/create/createTrip.page.tsx @@ -6,7 +6,7 @@ export const CreateTrip = () => { const [inputValue, setInputValue] = useState('나의 여정'); const [showSelectDate, setShowSelectDate] = useState(false); - const handleChange = (e) => { + const handleChange = (e: React.ChangeEvent) => { setInputValue(e.target.value); }; @@ -24,7 +24,7 @@ export const CreateTrip = () => { return (
-
여행 생성하기
+
여행 생성하기
{ /> + {}} + />
); }; diff --git a/src/router/mainRouter.tsx b/src/router/mainRouter.tsx index 85c184b2..cebc13ab 100644 --- a/src/router/mainRouter.tsx +++ b/src/router/mainRouter.tsx @@ -5,7 +5,6 @@ import Detail from '@pages/detail/detail.page'; import ReviewComment from '@pages/reviewComment/reviewComment.page'; import ReviewPosting from '@pages/reviewPosting/reviewPosting.page'; import MainLayout from './routerLayout'; -import { SelectDate } from '@components/createTrip/SelectDate'; import { CreateTrip } from '@pages/create/createTrip.page'; const MainRouter = () => { @@ -19,7 +18,6 @@ const MainRouter = () => { } /> } /> } /> - } /> From d1f2ac10ef059782ecc7df25009f95220018400a Mon Sep 17 00:00:00 2001 From: Hojin Date: Thu, 11 Jan 2024 22:26:31 +0900 Subject: [PATCH 03/46] =?UTF-8?q?Feat:=20=EC=86=8C=EC=BC=93=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EB=AA=85=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/socket.ts | 5 +- src/utils/socket.ts | 159 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 src/utils/socket.ts diff --git a/src/api/socket.ts b/src/api/socket.ts index 0b325e36..6c9b3ea2 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -1,6 +1,7 @@ import * as StompJs from '@stomp/stompjs'; -import SockJS from 'sockjs-client'; export const socketClient = new StompJs.Client({ - webSocketFactory: () => new SockJS('https://ws.weplanplans.site/ws-stomp'), + brokerURL: import.meta.env.VITE_SOCKET_URL, }); + + diff --git a/src/utils/socket.ts b/src/utils/socket.ts new file mode 100644 index 00000000..3b57a1ba --- /dev/null +++ b/src/utils/socket.ts @@ -0,0 +1,159 @@ +import { useEffect } from 'react'; +import { socketClient } from '@api/socket'; + +const message = { + startDate: '2024-01-03', + endDate: '2024-01-05', + numberOfPeople: 2, + tripName: 'success', + tripStatus: 'BEFORE', + area: '서울', + subarea: '장호진', + budget: 10000, +}; + +// 이미들어가있는 아이템 중복으로 못하게해야됨 +const itemMessage = { + visitDate: '2024-01-03', + newTripItems: [ + { + tourItemId: 5, + }, + ], +}; + +const data = { + visitDate: '2024-01-07', +}; + +const price = { + price: 15000, +}; + +const Order = { + visitDate: '2024-01-05', + tripItemOrder: [ + { + tripItemId: 1, + seqNum: 1, + }, + { + tripItemId: 2, + seqNum: 2, + }, + ], +}; + +const member = { + memberId: 1, +}; + +const trans = { + transportation: 'CAR', +}; + +const tripId = 1; +const visitDate = '2024-01-03'; +const tripItemId = 1; + +const connect = () => { + socketClient.onConnect = () => { + socketClient.subscribe(`/sub/${tripId}/info`, (message) => { + console.log(`기본정보 변경 이벤트:`, message.body); + }); + + socketClient.subscribe( + `/sub/${tripId}/tripItems/${visitDate}`, + (message) => { + console.log(`방문날짜별 여정 여행 아이템 정보:`, message.body); + }, + ); + + socketClient.subscribe(`/sub/${tripId}/path/${visitDate}`, (message) => { + console.log(`방문날짜별 여정경로 정보:`, message.body); + }); + + socketClient.subscribe(`/sub/${tripId}/connectedMember`, (message) => { + console.log(`연결된 멤버 정보 :`, message.body); + }); + + socketClient.subscribe(`/sub/${tripId}/budget`, (message) => { + console.log(`목표 경비, 실제 발생 비용:`, message.body); + }); + + socketClient.publish({ + // 여정 기본 정보 변경 이벤트 발생시 ✅ + destination: `/pub/trips/${tripId}/info`, + body: JSON.stringify(message), + }); + + socketClient.publish({ + // 여정에 여행 아이템 추가 이벤트 발생시 ✅ + destination: `/pub/trips/${tripId}/addTripItems`, + body: JSON.stringify(itemMessage), + }); + + socketClient.publish({ + // 여행 아이템 예상 가격 업데이트 이벤트 발생시 ✅ + destination: `/pub/tripItems/${tripItemId}/updatePrice`, + body: JSON.stringify(price), + }); + + socketClient.publish({ + // 여행 아이템 방문 순서 변경 이벤트 발생시 ✅ + destination: `/pub/trips/${tripId}/updateTripItemOrder`, + body: JSON.stringify(Order), + }); + + socketClient.publish({ + // 여행 아이템 방문 교통 수단 변경 이벤트 발생시 ✅ + destination: `/pub/tripItems/${tripItemId}/updateTransportation`, + body: JSON.stringify(trans), + }); + + socketClient.publish({ + // 여행 아이템 방문 날짜 변경 이벤트 발생시 ✅ + destination: `/pub/tripItems/${tripItemId}/updateVisitDate`, + body: JSON.stringify(data), + }); + + socketClient.publish({ + // 여행 아이템 삭제 이벤트 발생시 ✅ + destination: `/pub/tripItems/${tripItemId}/deleteItem`, + }); + + socketClient.publish({ + // 멤버 여정 페이지로 입장 이벤트 발생시 ✅ + destination: `/pub/trips/${tripId}/connectMember`, + body: JSON.stringify(member), + }); + + socketClient.publish({ + // 멤버 여정 페이지 퇴장 이벤트 발생시 ✅ + destination: `/pub/trips/${tripId}/disconnectMember`, + body: JSON.stringify(member), + }); + + socketClient.publish({ + // 여정 편집 페이지 입장 이벤트 발생시 ✅ + destination: `/pub/trips/${tripId}/enterMember`, + body: JSON.stringify(member), + }); + + socketClient.publish({ + // 날짜별 여행 아이템 & 경로 조회 ✅ + destination: `/pub/trips/${tripId}/getPathAndItems`, + body: JSON.stringify(data), + }); + }; + + socketClient.activate(); +}; + +useEffect(() => { + connect(); + + return () => { + socketClient.deactivate(); + }; +}, []); From 98bb34f18f766cdf732a10336165fc7c8f738bfe Mon Sep 17 00:00:00 2001 From: joanShim Date: Thu, 11 Jan 2024 23:30:03 +0900 Subject: [PATCH 04/46] =?UTF-8?q?Fix:=20=EB=92=A4=EB=A1=9C=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DatePicker/Calendar.tsx | 8 ++++---- src/components/createTrip/SelectDate.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/DatePicker/Calendar.tsx b/src/components/DatePicker/Calendar.tsx index 058b3bf0..2e7af75b 100644 --- a/src/components/DatePicker/Calendar.tsx +++ b/src/components/DatePicker/Calendar.tsx @@ -85,7 +85,7 @@ const Calendar: React.FC = () => { let afterClass = ''; if (isStart || isEnd) { - dayClass = 'rounded-full bg-main2 text-white z-10'; + dayClass = 'rounded-full w-[48px] bg-main2 text-white z-10'; } else if (isMiddle) { dayClass = 'bg-[#DAFBFF] z-0'; beforeClass = isSecondDayInRange(date) @@ -140,7 +140,7 @@ const Calendar: React.FC = () => { } return ( -
+
{format(monthDate, 'yyyy년 MM월', { locale: ko })}
@@ -156,9 +156,9 @@ const Calendar: React.FC = () => { <>
{startDate && endDate - ? `${format(startDate, 'MM. dd', { locale: ko })} - ${format( + ? `${format(startDate, 'MM.dd', { locale: ko })} - ${format( endDate, - 'MM. dd', + 'MM.dd', { locale: ko }, )} (${differenceInDays(endDate, startDate)}박 ${ differenceInDays(endDate, startDate) + 1 diff --git a/src/components/createTrip/SelectDate.tsx b/src/components/createTrip/SelectDate.tsx index ce57efdc..6d7e319b 100644 --- a/src/components/createTrip/SelectDate.tsx +++ b/src/components/createTrip/SelectDate.tsx @@ -1,11 +1,13 @@ import { ButtonPrimary } from '@components/common/button/Button'; import Calendar from '@components/DatePicker/Calendar'; -import BackHeader from '@components/common/header/BackHeader'; +import { BackIcon } from '@components/common/icons/Icons'; export const SelectDate = ({ onClose }: { onClose: () => void }) => { return (
- +
+ +
완료 From bfea9cff50e672911c619d2dae0960538aed9428 Mon Sep 17 00:00:00 2001 From: joanShim Date: Thu, 11 Jan 2024 23:34:17 +0900 Subject: [PATCH 05/46] =?UTF-8?q?Feat:=20=EB=A9=94=EC=9D=B8=20FAB=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B2=BD=EB=A1=9C=20=EC=9D=B4=EB=8F=99=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Tours/CreateTripButton.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/Tours/CreateTripButton.tsx b/src/components/Tours/CreateTripButton.tsx index f131de28..4851ece0 100644 --- a/src/components/Tours/CreateTripButton.tsx +++ b/src/components/Tours/CreateTripButton.tsx @@ -1,7 +1,16 @@ +import { useNavigate } from 'react-router-dom'; + const CreateTripButton = () => { + const navigate = useNavigate(); + + const onClick = () => { + navigate('/create'); + }; return (
- +
); }; From 39d894476d3e0cee00a3f6eec6a2f293386f96af Mon Sep 17 00:00:00 2001 From: joanShim Date: Thu, 11 Jan 2024 23:35:38 +0900 Subject: [PATCH 06/46] =?UTF-8?q?Feat:=20=EB=A9=94=EC=9D=B8=20FAB=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B2=BD=EB=A1=9C=20=EC=9D=B4=EB=8F=99=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Tours/CreateTripButton.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/Tours/CreateTripButton.tsx b/src/components/Tours/CreateTripButton.tsx index 4851ece0..60e444d1 100644 --- a/src/components/Tours/CreateTripButton.tsx +++ b/src/components/Tours/CreateTripButton.tsx @@ -3,12 +3,13 @@ import { useNavigate } from 'react-router-dom'; const CreateTripButton = () => { const navigate = useNavigate(); - const onClick = () => { - navigate('/create'); - }; return (
-
From 875b5b075674d945839e504d6e0c462ef70664cc Mon Sep 17 00:00:00 2001 From: joanShim Date: Thu, 11 Jan 2024 23:52:34 +0900 Subject: [PATCH 07/46] =?UTF-8?q?Fix:=20=EC=9D=B8=ED=92=8B=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/create/createTrip.page.tsx | 29 +++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/pages/create/createTrip.page.tsx b/src/pages/create/createTrip.page.tsx index 190c1b26..1d8a2685 100644 --- a/src/pages/create/createTrip.page.tsx +++ b/src/pages/create/createTrip.page.tsx @@ -1,11 +1,16 @@ import BackHeader from '@components/common/header/BackHeader'; import { useState } from 'react'; import { SelectDate } from '../../components/createTrip/SelectDate'; +import { CloseIcon } from '@components/common/icons/Icons'; export const CreateTrip = () => { const [inputValue, setInputValue] = useState('나의 여정'); const [showSelectDate, setShowSelectDate] = useState(false); + const clearInput = () => { + setInputValue(''); + }; + const handleChange = (e: React.ChangeEvent) => { setInputValue(e.target.value); }; @@ -25,13 +30,23 @@ export const CreateTrip = () => {
여행 생성하기
- +
+ + {inputValue && ( +
+ +
+ )} +
Date: Fri, 12 Jan 2024 11:18:07 +0900 Subject: [PATCH 08/46] =?UTF-8?q?Feat:=20Nav=20=ED=99=88=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C=20ScrollToTop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/nav/Nav.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/common/nav/Nav.tsx b/src/components/common/nav/Nav.tsx index 9633820b..0c4783f9 100644 --- a/src/components/common/nav/Nav.tsx +++ b/src/components/common/nav/Nav.tsx @@ -28,12 +28,15 @@ const Nav = () => {
@@ -66,7 +66,7 @@ const WishItem: React.FC = ({ wishList }) => {
- {likedCount.toLocaleString()} + {likedCount ? likedCount.toLocaleString() : likedCount}
From 7841c0d1b793d2e053175e92acb7817f5ca2f8ee Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Fri, 12 Jan 2024 16:35:47 +0900 Subject: [PATCH 18/46] =?UTF-8?q?feat:=20=EC=83=89=EA=B9=94=20=EC=84=9E?= =?UTF-8?q?=EC=9D=B8=20=EC=BA=98=EB=A6=B0=EB=8D=94=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/icons/Icons.tsx | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index ee39a645..46163553 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -119,6 +119,80 @@ export const CalendarIcon: React.FC = ({ ); }; +export const CalendarIcon2: React.FC = ({ size = 25 }) => { + return ( + + + + + + + + + + + + ); +}; + export const HeartIcon: React.FC = ({ size = 25, color = 'black', From b2b329d33d9794251f5d5b2bddfb76936f0487eb Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Fri, 12 Jan 2024 16:36:05 +0900 Subject: [PATCH 19/46] =?UTF-8?q?feat:=20nav=EB=B0=94=20mytrip=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=95=84=EC=9D=B4=EC=BD=98=20active?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/nav/Nav.tsx | 45 ++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/src/components/common/nav/Nav.tsx b/src/components/common/nav/Nav.tsx index a4f56085..cf3bf6aa 100644 --- a/src/components/common/nav/Nav.tsx +++ b/src/components/common/nav/Nav.tsx @@ -1,5 +1,11 @@ import { useLocation, useNavigate } from 'react-router-dom'; -import { CalendarIcon, HeartIcon, HomeIcon, UserIcon } from '../icons/Icons'; +import { + CalendarIcon, + CalendarIcon2, + HeartIcon, + HomeIcon, + UserIcon, +} from '../icons/Icons'; import { useEffect, useState } from 'react'; import Alert from '../alert/Alert'; @@ -35,12 +41,37 @@ const Nav = () => {

-
navigate('/')} - className="cursor-pointer flex-col items-center justify-center px-2"> - -

일정

-
+ + {isLoggedIn ? ( +
navigate('/mytrip')} + className="cursor-pointer flex-col items-center justify-center px-2"> +
+ {isActive('/mytrip') ? : } +
+

여정

+
+ ) : ( + + 나의 여정 조회를 위해 로그인이 필요합니다. +
+ 로그인 하시겠습니까? + + } + onConfirm={handleConfirm}> +
+
+ +
+

+ 여정 +

+
+
+ )} {isLoggedIn ? (
Date: Fri, 12 Jan 2024 16:36:24 +0900 Subject: [PATCH 20/46] =?UTF-8?q?feat:=20=EB=82=98=EC=9D=98=20=EC=97=AC?= =?UTF-8?q?=EC=A0=95=20API=20=EC=97=B0=EB=8F=99=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MyTrip/MyTrip.tsx | 58 +++++++++++++++++++++++++ src/components/MyTrip/MyTripItem.tsx | 64 ++++++++++++++++++++++++++++ src/components/MyTrip/MyTripList.tsx | 57 +++++++++++++++++++++++++ src/pages/myTrip/myTrip.page.tsx | 7 +++ 4 files changed, 186 insertions(+) create mode 100644 src/components/MyTrip/MyTrip.tsx create mode 100644 src/components/MyTrip/MyTripItem.tsx create mode 100644 src/components/MyTrip/MyTripList.tsx create mode 100644 src/pages/myTrip/myTrip.page.tsx diff --git a/src/components/MyTrip/MyTrip.tsx b/src/components/MyTrip/MyTrip.tsx new file mode 100644 index 00000000..549a3186 --- /dev/null +++ b/src/components/MyTrip/MyTrip.tsx @@ -0,0 +1,58 @@ +import { useInfiniteQuery } from '@tanstack/react-query'; +import { getMemberTrips } from '@api/member'; +import NoDataMessage from '@components/common/noData/NoDataMessage'; +import MyTripList from './MyTripList'; +import { PenIcon } from '@components/common/icons/Icons'; + +const MyTrip = () => { + const { fetchNextPage, hasNextPage, data, isLoading, error } = + useInfiniteQuery({ + queryKey: ['wishList'], + queryFn: ({ pageParam = 0 }) => getMemberTrips(pageParam, 10), + initialPageParam: 0, + getNextPageParam: (lastPage) => { + if ( + lastPage && + lastPage.data && + lastPage.data && + lastPage.data.pageable + ) { + const currentPage = lastPage.data.pageable.pageNumber; + const totalPages = lastPage.data.totalPages; + + if (currentPage < totalPages - 1) { + return currentPage + 1; + } + } + return undefined; + }, + }); + + if (error) { + return
데이터를 불러오는 중 오류가 발생했습니다.
; + } + + return ( +
+
+

나의 여정

+
+ {data?.pages[0].data.content.length > 0 ? ( + + ) : ( + } + /> + )} +
+ ); +}; + +export default MyTrip; diff --git a/src/components/MyTrip/MyTripItem.tsx b/src/components/MyTrip/MyTripItem.tsx new file mode 100644 index 00000000..52e4bcd0 --- /dev/null +++ b/src/components/MyTrip/MyTripItem.tsx @@ -0,0 +1,64 @@ +import { MyTripType } from '@/@types/trips.types'; +import { MoreIcon } from '@components/common/icons/Icons'; + +interface MyTripItemProps { + myTripList: MyTripType; +} + +const MyTripItem: React.FC = ({ myTripList }) => { + const { + tripName, + startDate, + endDate, + numberOfTripMembers, + tripStatus, + tripThumbnailUrl, + } = myTripList; + + const ACTIVE_TRIP = '여행 중'; + + return ( +
+
+
+ 여행지 이미지 +
+ +
+
+
+
+
+ + {tripStatus} + +
+
+ {tripName} +
+
+ {startDate} ~ {endDate} +
+
+
+ {numberOfTripMembers}명과 공유중 +
+
+
+
+
+
+ ); +}; + +export default MyTripItem; diff --git a/src/components/MyTrip/MyTripList.tsx b/src/components/MyTrip/MyTripList.tsx new file mode 100644 index 00000000..fbe9a401 --- /dev/null +++ b/src/components/MyTrip/MyTripList.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { MyTripType } from '@/@types/trips.types'; +import InfiniteScroll from 'react-infinite-scroller'; +import { v4 as uuidv4 } from 'uuid'; +import ToursItemSkeleton from '@components/Tours/ToursItemSkeleton'; +import MyTripItem from './MyTripItem'; + +interface MyTripListProps { + myTripsData: { pages: Array<{ data: { content: MyTripType[] } }> }; + fetchNextPage: () => void; + hasNextPage: boolean; + isLoading: boolean; +} + +const MyTripList: React.FC = ({ + myTripsData, + fetchNextPage, + hasNextPage, + isLoading, +}) => { + if (!myTripsData || myTripsData.pages.length === 0) { + return
데이터를 불러오는 중 오류가 발생했습니다.
; + } + + return ( + fetchNextPage()} + hasMore={hasNextPage} + loader={ +
+
+
Loading...
+
+
+ }> +
+ {isLoading + ? Array.from({ length: 10 }, (_, index) => ( + + )) + : myTripsData.pages.map((group) => ( + + {group?.data.content.map((myTripList: MyTripType) => ( + + ))} + + ))} +
+
+ ); +}; + +export default MyTripList; diff --git a/src/pages/myTrip/myTrip.page.tsx b/src/pages/myTrip/myTrip.page.tsx new file mode 100644 index 00000000..a530143c --- /dev/null +++ b/src/pages/myTrip/myTrip.page.tsx @@ -0,0 +1,7 @@ +import MyTrip from '@components/MyTrip/MyTrip'; + +const MyTripPage = () => { + return ; +}; + +export default MyTripPage; From d05654e26df6c45f73c1c1012d22e7a9f70e50da Mon Sep 17 00:00:00 2001 From: sue Date: Fri, 12 Jan 2024 17:14:41 +0900 Subject: [PATCH 21/46] =?UTF-8?q?Design:=20Tab=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/tab/Tab.tsx | 4 ++-- src/router/routerLayout.tsx | 1 + tailwind.config.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/common/tab/Tab.tsx b/src/components/common/tab/Tab.tsx index 9972076d..a560f7cb 100644 --- a/src/components/common/tab/Tab.tsx +++ b/src/components/common/tab/Tab.tsx @@ -14,7 +14,7 @@ const Tab = ({ lists, contents }: TabProps) => ( return ( {list} @@ -25,7 +25,7 @@ const Tab = ({ lists, contents }: TabProps) => ( return ( {content} diff --git a/src/router/routerLayout.tsx b/src/router/routerLayout.tsx index 91d6bd86..7831224d 100644 --- a/src/router/routerLayout.tsx +++ b/src/router/routerLayout.tsx @@ -2,6 +2,7 @@ import { Header } from '@components/common/header'; import { Outlet, useLocation } from 'react-router-dom'; import { Nav } from '@components/common/nav'; import { InputComment } from '@components/common/nav'; +import '../index.css'; const MainLayout = () => { const location = useLocation(); diff --git a/tailwind.config.js b/tailwind.config.js index 88a5f6c7..98e0361e 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -7,7 +7,7 @@ export default { main1: '#062139', main2: '#29DDF6', sub1: '#FFEC3E', - sub2: 'FF2167', + sub2: '#FF2167', gray1: '#f8f8f8', gray2: '#ededed', gray3: '#d7d7d7', From 2ae2a5ddd8fb9e1063ad85e8d920cbf7a382aea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Fri, 12 Jan 2024 20:09:39 +0900 Subject: [PATCH 22/46] =?UTF-8?q?Feat:=20=EC=97=AC=ED=96=89=EC=B7=A8?= =?UTF-8?q?=ED=96=A5=20=EB=A7=88=ED=81=AC=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/TripPreference.tsx | 186 +++++++++++++++++++++ src/components/Trip/TripSectionTop.tsx | 3 +- src/components/common/nav/InputComment.tsx | 2 +- 3 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 src/components/Trip/TripPreference.tsx diff --git a/src/components/Trip/TripPreference.tsx b/src/components/Trip/TripPreference.tsx new file mode 100644 index 00000000..11c6d454 --- /dev/null +++ b/src/components/Trip/TripPreference.tsx @@ -0,0 +1,186 @@ +import React, { useEffect } from 'react'; +import { getTripsSurvey } from '@api/trips'; +import { useQuery } from '@tanstack/react-query'; +import { useParams } from 'react-router-dom'; +import { MoreIcon } from '@components/common/icons/Icons'; +import { RightIcon } from '@components/common/icons/Icons'; + +const TripPreference: React.FC = () => { + const params = useParams(); + const tripId = Number(params.id); + const { data: tripPreference, isLoading } = useQuery({ + queryKey: ['tripPreference', tripId], + queryFn: () => getTripsSurvey(tripId), + }); + + if (isLoading) { + return
Loading...
; + } + + useEffect(() => { + console.log('tripPreference', tripPreference); + }, [tripPreference]); + + return ( +
+ +
+
n명 참여
+
+ +
+
+ {tripPreference?.data?.data && ( +
+
+
계획성
+
+
철저하게
+
(그래프)
+
여유롭게
+
+
+
+ {( + (tripPreference.data.data.planningCount / + tripPreference.data.data.planningTotalCount) * + 100 + ).toFixed(0)} + % +
+
+ {( + ((tripPreference.data.data.planningTotalCount - + tripPreference.data.data.planningCount) / + tripPreference.data.data.planningTotalCount) * + 100 + ).toFixed(0)} + % +
+
+
+ +
+
활동시간
+
+
아침형
+
(그래프)
+
저녁형
+
+
+
+ {( + (tripPreference.data.data.activeHoursCount / + tripPreference.data.data.activeHoursTotalCount) * + 100 + ).toFixed(0)} + % +
+
+ {( + ((tripPreference.data.data.activeHoursTotalCount - + tripPreference.data.data.activeHoursCount) / + tripPreference.data.data.activeHoursTotalCount) * + 100 + ).toFixed(0)} + % +
+
+
+ +
+
숙소
+
+
분위기
+
(그래프)
+
가격
+
+
+
+ {( + (tripPreference.data.data.accommodationCount / + tripPreference.data.data.accommodationTotalCount) * + 100 + ).toFixed(0)} + % +
+
+ {( + ((tripPreference.data.data.accommodationTotalCount - + tripPreference.data.data.accommodationCount) / + tripPreference.data.data.accommodationTotalCount) * + 100 + ).toFixed(0)} + % +
+
+
+ +
+
음식
+
+
노포
+
(그래프)
+
인테리어
+
+
+
+ {( + (tripPreference.data.data.foodCount / + tripPreference.data.data.foodTotalCount) * + 100 + ).toFixed(0)} + % +
+
+ {( + ((tripPreference.data.data.foodTotalCount - + tripPreference.data.data.foodCount) / + tripPreference.data.data.foodTotalCount) * + 100 + ).toFixed(0)} + % +
+
+
+ +
+
관광지
+
+
액티비티
+
(그래프)
+
휴양
+
+
+
+ {( + (tripPreference.data.data.tripStyleCount / + tripPreference.data.data.tripStyleTotalCount) * + 100 + ).toFixed(0)} + % +
+
+ {( + ((tripPreference.data.data.tripStyleTotalCount - + tripPreference.data.data.tripStyleCount) / + tripPreference.data.data.tripStyleTotalCount) * + 100 + ).toFixed(0)} + % +
+
+
+
+ )} +
+ ); +}; + +export default TripPreference; +// 현재 내 값/토탈 * 100 = 답 diff --git a/src/components/Trip/TripSectionTop.tsx b/src/components/Trip/TripSectionTop.tsx index ed283e77..9b9dc6ef 100644 --- a/src/components/Trip/TripSectionTop.tsx +++ b/src/components/Trip/TripSectionTop.tsx @@ -1,4 +1,5 @@ import Tab from '@components/common/tab/Tab'; +import TripPreference from './TripPreference'; const TripSectionTop = () => { return ( @@ -6,7 +7,7 @@ const TripSectionTop = () => {
여정 생성 완료 페이지
우리의 여행취향
,
우리의 관심목록
]} + contents={[,
우리의 관심목록
]} /> ); diff --git a/src/components/common/nav/InputComment.tsx b/src/components/common/nav/InputComment.tsx index eb21cbf6..9e7f0af5 100644 --- a/src/components/common/nav/InputComment.tsx +++ b/src/components/common/nav/InputComment.tsx @@ -94,7 +94,7 @@ export const InputComment: React.FC = () => { } }; return ( -
+
From 27ee2b6e6269df383dcfaa5ac6e28fcecf7799b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Sat, 13 Jan 2024 00:16:20 +0900 Subject: [PATCH 23/46] =?UTF-8?q?Fix:=20=EB=8C=93=EA=B8=80=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=B0=BD=20=EC=B5=9C=ED=95=98=EB=8B=A8=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Review/ReviewComments.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Review/ReviewComments.tsx b/src/components/Review/ReviewComments.tsx index 8cde28ec..208fbd83 100644 --- a/src/components/Review/ReviewComments.tsx +++ b/src/components/Review/ReviewComments.tsx @@ -104,6 +104,7 @@ export default function ReviewComments() { } })}
+
From 07f80cdc003c843143c431676d8b372c1c058bb9 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 13 Jan 2024 00:39:55 +0900 Subject: [PATCH 24/46] =?UTF-8?q?Feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=8B=89=EB=84=A4=EC=9E=84=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/member.types.ts | 6 +++--- src/pages/signup/signupInfo.page.tsx | 32 ++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/@types/member.types.ts b/src/@types/member.types.ts index a7ef7fd7..3b8146ac 100644 --- a/src/@types/member.types.ts +++ b/src/@types/member.types.ts @@ -1,8 +1,8 @@ interface MemberRequest { nickname: string; profileImageUrl: string; - ageType: string; - genderType: string; + ageType: string | null; + genderType: string | null; } interface SelectOption { @@ -22,7 +22,7 @@ interface MemberInfo { // | 'ABOVE_FIFTIES' // | 'DEFATULT' genderType: string | null; - // 'MALE' | 'FEMALE' | 'NON_BINARY' | 'DEFATULT'; + // 'MALE' | 'FEMALE' | 'NON_BINARY' | 'DEFAULT'; survey: Survey | null; } diff --git a/src/pages/signup/signupInfo.page.tsx b/src/pages/signup/signupInfo.page.tsx index de51184d..dcf543ec 100644 --- a/src/pages/signup/signupInfo.page.tsx +++ b/src/pages/signup/signupInfo.page.tsx @@ -1,13 +1,19 @@ import { getCheckNickname } from '@api/auth'; import { putMember } from '@api/member'; import { AuthTitle } from '@components/Auth'; -import { AuthInput } from '@components/Auth/AuthInput/AuthInputBox'; +import { + AuthInput, + ErrorMessage, +} from '@components/Auth/AuthInput/AuthInputBox'; import AuthDropDown from '@components/Auth/SignupInfo/AuthDropDown/AuthDropDown'; import { BackBox } from '@components/common'; import SubmitBtn from '@components/common/button/SubmitBtn'; import { CameraIcon } from '@components/common/icons/Icons'; +import { UserInfoState } from '@recoil/Auth.atom'; +import { useEffect } from 'react'; import { SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; const SignupInfo = () => { const { @@ -17,6 +23,7 @@ const SignupInfo = () => { watch, resetField, setError, + setValue, formState: { errors, isValid }, } = useForm({ mode: 'onChange', @@ -27,6 +34,16 @@ const SignupInfo = () => { const nicknamePatternValue = /^(?=.*[a-z0-9가-힣])[a-z0-9가-힣]{2,12}$/; + const nicknameError = errors.nickname; + const nicknameErrorMessage = nicknameError?.message; + + console.log(errors); + + const userInfo = useRecoilValue(UserInfoState); + useEffect(() => { + setValue('nickname', userInfo?.nickname); + }, [userInfo]); + const onNicknameBlur = async () => { if (nicknamePatternValue.test(getValues('nickname'))) { try { @@ -44,14 +61,14 @@ const SignupInfo = () => { }; const onInfoSubmit: SubmitHandler = async (data) => { - const {} = data; + const { nickname } = data; try { const res = await putMember({ - nickname: 'zkzkzkzk', - profileImageUrl: 'http://hfstdfg.jpg', - ageType: 'TWENTIES', - genderType: 'MALE', + nickname: nickname, + profileImageUrl: '', + ageType: null, + genderType: null, }); if (res.status === 200) { navigate('/'); @@ -140,6 +157,9 @@ const SignupInfo = () => { resetField={resetField} isInvalid={!!errors.nickname} /> + {nicknameErrorMessage && ( + {`${nicknameErrorMessage}`} + )}
From 7d8197d3441fbabe173d4873b60a5b7b8d01699c Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 13 Jan 2024 01:09:32 +0900 Subject: [PATCH 25/46] =?UTF-8?q?Refactor:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/auth.types.ts | 5 + src/assets/images/defaultProfileImg.svg | 7 + .../AuthInputBox/AuthNicknameInputBox.tsx | 61 +++++++ .../Auth/SignupInfo/UserInfoForm.tsx | 97 ++++++++++ .../Auth/SignupInfo/UserInfoImg.tsx | 42 +++++ src/pages/signup/signupInfo.page.tsx | 169 +----------------- 6 files changed, 214 insertions(+), 167 deletions(-) create mode 100644 src/assets/images/defaultProfileImg.svg create mode 100644 src/components/Auth/AuthInput/AuthInputBox/AuthNicknameInputBox.tsx create mode 100644 src/components/Auth/SignupInfo/UserInfoForm.tsx create mode 100644 src/components/Auth/SignupInfo/UserInfoImg.tsx diff --git a/src/@types/auth.types.ts b/src/@types/auth.types.ts index 21ad8c97..03d9bf8e 100644 --- a/src/@types/auth.types.ts +++ b/src/@types/auth.types.ts @@ -44,3 +44,8 @@ export interface AuthPwInputBoxProps extends AuthInputBoxProps { export interface AuthPwCheckInputBoxProps extends AuthInputBoxProps { getValues: UseFormGetValues; } + +export interface AuthNicknameInputBoxProps extends AuthInputBoxProps { + getValues: UseFormGetValues; + setError: UseFormSetError; +} diff --git a/src/assets/images/defaultProfileImg.svg b/src/assets/images/defaultProfileImg.svg new file mode 100644 index 00000000..39bf316b --- /dev/null +++ b/src/assets/images/defaultProfileImg.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/Auth/AuthInput/AuthInputBox/AuthNicknameInputBox.tsx b/src/components/Auth/AuthInput/AuthInputBox/AuthNicknameInputBox.tsx new file mode 100644 index 00000000..0efa08be --- /dev/null +++ b/src/components/Auth/AuthInput/AuthInputBox/AuthNicknameInputBox.tsx @@ -0,0 +1,61 @@ +import { getCheckNickname } from '@api/auth'; +import { AuthInputWrapper, AuthInput, ErrorMessage } from './AuthInputItem'; +import type { AuthNicknameInputBoxProps } from '@/@types/auth.types'; + +const AuthNicknameInputBox = ({ + register, + inputValue, + resetField, + errors, + setError, + getValues, +}: AuthNicknameInputBoxProps) => { + const nicknamePatternValue = /^(?=.*[a-z0-9가-힣])[a-z0-9가-힣]{2,12}$/; + + const nicknameError = errors.nickname; + const nicknameErrorMessage = nicknameError?.message; + + const onNicknameBlur = async () => { + if (nicknamePatternValue.test(getValues('nickname'))) { + try { + const res = await getCheckNickname(getValues('nickname')); + if (res.status === 200) { + const isExist = res.data.data.exists; + if (isExist) { + setError('nickname', { message: '이미 사용 중인 닉네임입니다.' }); + } + } + } catch (err) { + console.error(err); + } + } + }; + return ( + + + {nicknameErrorMessage && ( + {`${nicknameErrorMessage}`} + )} + + ); +}; + +export default AuthNicknameInputBox; diff --git a/src/components/Auth/SignupInfo/UserInfoForm.tsx b/src/components/Auth/SignupInfo/UserInfoForm.tsx new file mode 100644 index 00000000..98d73a51 --- /dev/null +++ b/src/components/Auth/SignupInfo/UserInfoForm.tsx @@ -0,0 +1,97 @@ +import { SubmitHandler, useForm } from 'react-hook-form'; +import UserInfoImg from './UserInfoImg'; +import { putMember } from '@api/member'; +import { useNavigate } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; +import { UserInfoState } from '@recoil/Auth.atom'; +import { useEffect } from 'react'; +import SubmitBtn from '@components/common/button/SubmitBtn'; +import AuthDropDown from './AuthDropDown/AuthDropDown'; +import AuthNicknameInputBox from '../AuthInput/AuthInputBox/AuthNicknameInputBox'; + +const UserInfoForm = () => { + const { + register, + handleSubmit, + getValues, + watch, + resetField, + setError, + setValue, + formState: { errors, isValid }, + } = useForm({ + mode: 'onChange', + criteriaMode: 'all', + }); + const navigate = useNavigate(); + + const userInfo = useRecoilValue(UserInfoState); + useEffect(() => { + setValue('nickname', userInfo?.nickname); + }, [userInfo]); + + const onInfoSubmit: SubmitHandler = async (data) => { + const { nickname } = data; + + try { + const res = await putMember({ + nickname: nickname, + profileImageUrl: '', + ageType: null, + genderType: null, + }); + if (res.status === 200) { + navigate('/'); + } + } catch (err) { + console.error('회원정보 수정 요청 중 에러 발생', err); + } + }; + + return ( +
+
+ + +
+ + +
+
+
+ 완료 +
+
+ ); +}; + +export default UserInfoForm; + +const genderArr: SelectOption[] = [ + { id: '1', value: '여' }, + { id: '2', value: '남' }, + { id: '3', value: '기타' }, +]; + +const ageArr: SelectOption[] = [ + { id: '1', value: '10대' }, + { id: '2', value: '20대' }, + { id: '3', value: '30대' }, + { id: '4', value: '40대' }, + { id: '5', value: '50대 이상' }, +]; diff --git a/src/components/Auth/SignupInfo/UserInfoImg.tsx b/src/components/Auth/SignupInfo/UserInfoImg.tsx new file mode 100644 index 00000000..87cfe984 --- /dev/null +++ b/src/components/Auth/SignupInfo/UserInfoImg.tsx @@ -0,0 +1,42 @@ +import { CameraIcon } from '@components/common/icons/Icons'; + +const UserInfoImg = () => { + const onImgChange = (e: React.ChangeEvent) => { + console.log(e); + + // let fileArr = e.target.files; + // setPostImg(Array.from(fileArr)); + + // let fileRead = new FileReader(); + // fileRead.onload = function(){ + // setPreviewImg(fileRead.result); + // }; + + // fileRead.readAsDataURL(file[0]); + }; + return ( +
+ + +
+ ); +}; + +export default UserInfoImg; diff --git a/src/pages/signup/signupInfo.page.tsx b/src/pages/signup/signupInfo.page.tsx index dcf543ec..0c608a1e 100644 --- a/src/pages/signup/signupInfo.page.tsx +++ b/src/pages/signup/signupInfo.page.tsx @@ -1,97 +1,11 @@ -import { getCheckNickname } from '@api/auth'; -import { putMember } from '@api/member'; import { AuthTitle } from '@components/Auth'; -import { - AuthInput, - ErrorMessage, -} from '@components/Auth/AuthInput/AuthInputBox'; -import AuthDropDown from '@components/Auth/SignupInfo/AuthDropDown/AuthDropDown'; +import UserInfoForm from '@components/Auth/SignupInfo/UserInfoForm'; import { BackBox } from '@components/common'; -import SubmitBtn from '@components/common/button/SubmitBtn'; -import { CameraIcon } from '@components/common/icons/Icons'; -import { UserInfoState } from '@recoil/Auth.atom'; -import { useEffect } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; -import { useRecoilValue } from 'recoil'; const SignupInfo = () => { - const { - register, - handleSubmit, - getValues, - watch, - resetField, - setError, - setValue, - formState: { errors, isValid }, - } = useForm({ - mode: 'onChange', - criteriaMode: 'all', - }); - const navigate = useNavigate(); - const nicknamePatternValue = /^(?=.*[a-z0-9가-힣])[a-z0-9가-힣]{2,12}$/; - - const nicknameError = errors.nickname; - const nicknameErrorMessage = nicknameError?.message; - - console.log(errors); - - const userInfo = useRecoilValue(UserInfoState); - useEffect(() => { - setValue('nickname', userInfo?.nickname); - }, [userInfo]); - - const onNicknameBlur = async () => { - if (nicknamePatternValue.test(getValues('nickname'))) { - try { - const res = await getCheckNickname(getValues('nickname')); - if (res.status === 200) { - const isExist = res.data.data.exists; - if (isExist) { - setError('nickname', { message: '이미 사용 중인 닉네임입니다.' }); - } - } - } catch (err) { - console.error(err); - } - } - }; - - const onInfoSubmit: SubmitHandler = async (data) => { - const { nickname } = data; - - try { - const res = await putMember({ - nickname: nickname, - profileImageUrl: '', - ageType: null, - genderType: null, - }); - if (res.status === 200) { - navigate('/'); - } - } catch (err) { - console.error('회원정보 수정 요청 중 에러 발생', err); - } - }; - - const onImgChange = (e: React.ChangeEvent) => { - console.log(e); - - // let fileArr = e.target.files; - // setPostImg(Array.from(fileArr)); - - // let fileRead = new FileReader(); - // fileRead.onload = function(){ - // setPreviewImg(fileRead.result); - // }; - - // fileRead.readAsDataURL(file[0]); - }; - return (
{ } /> -
-
-
- -
- -
- - {nicknameErrorMessage && ( - {`${nicknameErrorMessage}`} - )} -
- -
- - -
-
-
- 완료 -
-
+
); }; export default SignupInfo; - -const genderArr: SelectOption[] = [ - { id: '1', value: '여' }, - { id: '2', value: '남' }, - { id: '3', value: '기타' }, -]; - -const ageArr: SelectOption[] = [ - { id: '1', value: '10대' }, - { id: '2', value: '20대' }, - { id: '3', value: '30대' }, - { id: '4', value: '40대' }, - { id: '5', value: '50대 이상' }, -]; From d937ac3acc5e9cf3f64a7fc0d3ead72ed37e0190 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 13 Jan 2024 01:14:28 +0900 Subject: [PATCH 26/46] =?UTF-8?q?Rename:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=A0=95=EB=B3=B4=20=ED=8F=BC=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SignupInfo/{UserInfoForm.tsx => SignupInfoForm.tsx} | 6 +++--- src/pages/signup/signupInfo.page.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename src/components/Auth/SignupInfo/{UserInfoForm.tsx => SignupInfoForm.tsx} (94%) diff --git a/src/components/Auth/SignupInfo/UserInfoForm.tsx b/src/components/Auth/SignupInfo/SignupInfoForm.tsx similarity index 94% rename from src/components/Auth/SignupInfo/UserInfoForm.tsx rename to src/components/Auth/SignupInfo/SignupInfoForm.tsx index 98d73a51..79673e04 100644 --- a/src/components/Auth/SignupInfo/UserInfoForm.tsx +++ b/src/components/Auth/SignupInfo/SignupInfoForm.tsx @@ -9,7 +9,7 @@ import SubmitBtn from '@components/common/button/SubmitBtn'; import AuthDropDown from './AuthDropDown/AuthDropDown'; import AuthNicknameInputBox from '../AuthInput/AuthInputBox/AuthNicknameInputBox'; -const UserInfoForm = () => { +const SignupInfoForm = () => { const { register, handleSubmit, @@ -49,7 +49,7 @@ const UserInfoForm = () => { }; return ( -
+
{ ); }; -export default UserInfoForm; +export default SignupInfoForm; const genderArr: SelectOption[] = [ { id: '1', value: '여' }, diff --git a/src/pages/signup/signupInfo.page.tsx b/src/pages/signup/signupInfo.page.tsx index 0c608a1e..b5d89a8a 100644 --- a/src/pages/signup/signupInfo.page.tsx +++ b/src/pages/signup/signupInfo.page.tsx @@ -1,5 +1,5 @@ import { AuthTitle } from '@components/Auth'; -import UserInfoForm from '@components/Auth/SignupInfo/UserInfoForm'; +import SignupInfoForm from '@components/Auth/SignupInfo/SignupInfoForm'; import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; @@ -27,7 +27,7 @@ const SignupInfo = () => { } /> - +
); }; From 99e59c6078a29b7b6744054dbb57b2856042f9d3 Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 13 Jan 2024 01:15:31 +0900 Subject: [PATCH 27/46] =?UTF-8?q?Design:=20=EC=97=AC=EC=A0=95=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/icons/Icons.tsx | 225 ++++++++++++++++++-------- src/components/common/tab/Tab.tsx | 2 +- 2 files changed, 157 insertions(+), 70 deletions(-) diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index 18f154b1..443384c4 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -400,74 +400,40 @@ export const StarIcon: React.FC = ({ }; export const PlusIcon: React.FC = ({ - size = 25, + size = 20, color = 'black', fill = 'none', }) => { return ( - - - - - - - - - - - - - - - - - - - - - + viewBox="0 0 21 21" + fill={fill}> + + + ); }; @@ -899,14 +865,14 @@ export const SuccessIcon = () => { cy="40.2585" r="35.1238" stroke="#29DDF6" - stroke-width="4" + strokeWidth="4" /> { id="Vector 792_2" d="M21.8516 38.6183L35.7266 52.9746L60.0579 27.9297" stroke="#29DDF6" - stroke-width="5.33333" - stroke-linecap="round" + strokeWidth="5.33333" + strokeLinecap="round" /> @@ -944,7 +910,7 @@ export const EllipseIcon: React.FC = ({ size = 61 }) => { cy="29.7959" r="23.4783" stroke="#F8F8F8" - stroke-width="1.04348" + strokeWidth="1.04348" /> @@ -997,11 +963,132 @@ export const TopIcon: React.FC = () => { xmlns="http://www.w3.org/2000/svg"> ); }; + +export const ShareIcon: React.FC = ({ + width = 20, + height = 19, + fill = 'none', + color = 'black', +}) => { + return ( + + + + + + ); +}; + +export const PlanIcon: React.FC = ({ + size = 20, + color = 'black', + fill = 'none', +}) => { + return ( + + + + + + + ); +}; + +export const CarIcon: React.FC = ({ + size = 19, + color = 'black', + fill = 'none', +}) => { + return ( + + + + ); +}; + +export const BusIcon: React.FC = ({ + size = 18, + color = 'black', + fill = 'none', +}) => { + return ( + + + + ); +}; diff --git a/src/components/common/tab/Tab.tsx b/src/components/common/tab/Tab.tsx index a560f7cb..4bfa0bb8 100644 --- a/src/components/common/tab/Tab.tsx +++ b/src/components/common/tab/Tab.tsx @@ -25,7 +25,7 @@ const Tab = ({ lists, contents }: TabProps) => ( return ( {content} From baf61fa17785a356b801f07144271fec96ccf6c8 Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 13 Jan 2024 01:16:51 +0900 Subject: [PATCH 28/46] =?UTF-8?q?Design:=20=EC=97=AC=EC=A0=95=20Info=20?= =?UTF-8?q?=EB=A7=88=ED=81=AC=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/PlanTripButton.tsx | 15 +++++++++++++++ src/components/Trip/TripInfo.tsx | 21 +++++++++++++++++++++ src/components/Trip/TripSectionTop.tsx | 18 ++++++++++++++++-- src/components/common/BackBox/BackBox.tsx | 9 ++++++++- 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 src/components/Trip/PlanTripButton.tsx create mode 100644 src/components/Trip/TripInfo.tsx diff --git a/src/components/Trip/PlanTripButton.tsx b/src/components/Trip/PlanTripButton.tsx new file mode 100644 index 00000000..b2d5012b --- /dev/null +++ b/src/components/Trip/PlanTripButton.tsx @@ -0,0 +1,15 @@ +import { PlanIcon, RightIcon } from '@components/common/icons/Icons'; + +const PlanTripButton = () => { + return ( + + ); +}; + +export default PlanTripButton; diff --git a/src/components/Trip/TripInfo.tsx b/src/components/Trip/TripInfo.tsx new file mode 100644 index 00000000..c0f9a54f --- /dev/null +++ b/src/components/Trip/TripInfo.tsx @@ -0,0 +1,21 @@ +import { UserIcon } from '@components/common/icons/Icons'; + +const TripInfo = () => { + return ( +
+
+
+
강릉 여행 일정
+
+ + 5 +
+
+ +
+ 23.12.23 ~ 23.12.25 +
+ ); +}; + +export default TripInfo; diff --git a/src/components/Trip/TripSectionTop.tsx b/src/components/Trip/TripSectionTop.tsx index ed283e77..ba8ad3b9 100644 --- a/src/components/Trip/TripSectionTop.tsx +++ b/src/components/Trip/TripSectionTop.tsx @@ -1,9 +1,23 @@ import Tab from '@components/common/tab/Tab'; +import TripInfo from './TripInfo'; +import { BackBox } from '@components/common'; +import { useNavigate } from 'react-router-dom'; +import PlanTripButton from './PlanTripButton'; const TripSectionTop = () => { + const navigate = useNavigate(); + return ( -
-
여정 생성 완료 페이지
+
+ { + navigate(-1); + }} + /> + + 우리의 여행취향
,
우리의 관심목록
]} diff --git a/src/components/common/BackBox/BackBox.tsx b/src/components/common/BackBox/BackBox.tsx index 4f724838..4af0db0f 100644 --- a/src/components/common/BackBox/BackBox.tsx +++ b/src/components/common/BackBox/BackBox.tsx @@ -1,4 +1,4 @@ -import { LeftIcon } from '../icons/Icons'; +import { LeftIcon, ShareIcon } from '../icons/Icons'; import { ReactNode } from 'react'; interface Props { @@ -9,6 +9,7 @@ interface Props { skipHandler?: VoidFunction; showSave?: boolean; saveHandler?: VoidFunction; + showShare?: boolean; } const BackBox = ({ @@ -19,6 +20,7 @@ const BackBox = ({ skipHandler, showSave, saveHandler, + showShare, }: Props) => { const onBackClick = () => { backHandler && backHandler(); @@ -52,6 +54,11 @@ const BackBox = ({ 저장 )} + {showShare && ( + + )}
); }; From 57ad3c9ba483a2014ebb038f6b606ff89166dce3 Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 13 Jan 2024 01:17:27 +0900 Subject: [PATCH 29/46] =?UTF-8?q?Design:=20=EC=97=AC=EC=A0=95=20=EA=B3=84?= =?UTF-8?q?=ED=9A=8D=20=EB=A7=88=ED=81=AC=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/PlanSectionTop.tsx | 28 ++++++++++++++++++++++++++ src/pages/plan/planTrip.page.tsx | 8 ++------ 2 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 src/components/Plan/PlanSectionTop.tsx diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx new file mode 100644 index 00000000..28cb6b9d --- /dev/null +++ b/src/components/Plan/PlanSectionTop.tsx @@ -0,0 +1,28 @@ +import TripInfo from '@components/Trip/TripInfo'; +import { BackBox } from '@components/common'; +import { useNavigate } from 'react-router-dom'; +import TripBudget from './TripBudget'; +import Tab from '@components/common/tab/Tab'; + +const PlanSectionTop = () => { + const navigate = useNavigate(); + return ( +
+ { + navigate(-1); + }} + /> + + + Day1
,
Day2
,
Day3
]} + /> +
+ ); +}; + +export default PlanSectionTop; diff --git a/src/pages/plan/planTrip.page.tsx b/src/pages/plan/planTrip.page.tsx index b4813c87..c49f35dd 100644 --- a/src/pages/plan/planTrip.page.tsx +++ b/src/pages/plan/planTrip.page.tsx @@ -1,13 +1,9 @@ -import Tab from '@components/common/tab/Tab'; +import PlanSectionTop from '@components/Plan/PlanSectionTop'; const PlanTrip = () => { return ( <> -
여행 계획 페이지
- Day1
,
Day2
,
Day3
]} - /> + ); }; From a7169588f90abcb5f7324eb33666d5019651af9d Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 13 Jan 2024 01:18:18 +0900 Subject: [PATCH 30/46] =?UTF-8?q?Design:=20=EC=97=AC=ED=96=89=20=EA=B2=BD?= =?UTF-8?q?=EB=B9=84=20=EB=A7=88=ED=81=AC=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 25 ++++++++++++ src/components/Plan/TripBudget.tsx | 62 ++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 src/components/Plan/TripBudget.tsx diff --git a/package.json b/package.json index 1564a0c6..7bc3611e 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-tabs": "^1.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d60e833f..84212ab6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ dependencies: '@radix-ui/react-icons': specifier: ^1.3.0 version: 1.3.0(react@18.2.0) + '@radix-ui/react-progress': + specifier: ^1.0.3 + version: 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-radio-group': specifier: ^1.1.3 version: 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) @@ -2245,6 +2248,28 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-progress@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.6 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.45 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-radio-group@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==} peerDependencies: diff --git a/src/components/Plan/TripBudget.tsx b/src/components/Plan/TripBudget.tsx new file mode 100644 index 00000000..35892974 --- /dev/null +++ b/src/components/Plan/TripBudget.tsx @@ -0,0 +1,62 @@ +import * as Progress from '@radix-ui/react-progress'; +import { useEffect, useState } from 'react'; + +const TripBudget = () => { + const [targetBudget, setTargetBudget] = useState(10000); // 예시 목표 경비 + const [currentSpending, setCurrentSpending] = useState(0); // 초기 사용 경비 + + // 프로그레스 바 값 계산 + const progress = (currentSpending / targetBudget) * 100; + + useEffect(() => { + // 경비 수정 모달 추가 예정 + const timer = setTimeout(() => setCurrentSpending(3000), 300); + return () => clearTimeout(timer); + }, []); + + // 목표 경비 설정 함수 + const handleSetTargetBudget = (newTargetBudget: number) => { + setTargetBudget(newTargetBudget); + }; + + return ( +
+
사용 경비
+
+ + {currentSpending.toLocaleString()} + + +
+ + + + + +
+
+ 목표 경비 + +
+
+ {targetBudget.toLocaleString()} + +
+
+
+ ); +}; + +export default TripBudget; From bdce4342cd4bc642409802c25a4bbcd7895fc9e3 Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 13 Jan 2024 01:22:57 +0900 Subject: [PATCH 31/46] =?UTF-8?q?Design:=20Tab=20width=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 --- src/components/common/tab/Tab.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/common/tab/Tab.tsx b/src/components/common/tab/Tab.tsx index 4bfa0bb8..34fe447d 100644 --- a/src/components/common/tab/Tab.tsx +++ b/src/components/common/tab/Tab.tsx @@ -8,7 +8,7 @@ interface TabProps { const Tab = ({ lists, contents }: TabProps) => ( {lists.map((list, index) => { return ( @@ -25,7 +25,7 @@ const Tab = ({ lists, contents }: TabProps) => ( return ( {content} From 2eb237b00edcbff6745606a84d0cdbbe7f0439a0 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 13 Jan 2024 01:37:06 +0900 Subject: [PATCH 32/46] =?UTF-8?q?Feat:=20=ED=9A=8C=EC=9B=90=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EB=8B=89=EB=84=A4=EC=9E=84=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Auth/SignupInfo/SignupInfoForm.tsx | 4 +- .../Auth/SignupInfo/UserInfoImg.tsx | 2 +- src/components/Mypage/UserInfoForm.tsx | 107 ++++++++++++++++++ src/pages/mypage/editUserInfo.page.tsx | 5 +- 4 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 src/components/Mypage/UserInfoForm.tsx diff --git a/src/components/Auth/SignupInfo/SignupInfoForm.tsx b/src/components/Auth/SignupInfo/SignupInfoForm.tsx index 79673e04..9ac4f054 100644 --- a/src/components/Auth/SignupInfo/SignupInfoForm.tsx +++ b/src/components/Auth/SignupInfo/SignupInfoForm.tsx @@ -51,7 +51,9 @@ const SignupInfoForm = () => { return (
- +
+ +
{ // fileRead.readAsDataURL(file[0]); }; return ( -
+