Skip to content
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"start": "next start",
"lint": "next lint",
"svgr": "npx @svgr/cli --icon --no-svgo --no-dimensions --typescript --ext tsx -d src/assets/svg public/svg",
"swagger-typescript-api": "swagger-typescript-api -p https://api-dev-v2.vacgom.co.kr/swagger-ui/index.html -r -o ./types --modular -d --extract-request-body --extract-response-body --extract-response-error --axios"
"swagger-typescript-api": "swagger-typescript-api -p https://api-dev-v2.vacgom.co.kr/swagger-ui/index.html -r -o ./types --modular -d --extract-request-body --extract-response-body --extract-response-error --axios",
"generate-types": "openapi-typescript https://api-dev-v2.vacgom.co.kr -o ./src/type/schema.d.ts"
},
"dependencies": {
"@emotion/css": "^11.11.2",
Expand Down
3 changes: 1 addition & 2 deletions src/api/axios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ const TIMEOUT_TIME = 10_000;
// },
// (error) =>
// // 요청 전 에러 처리
// // add error handling before sending the request
// Promise.reject(
// (error.response && error.response.data) || 'Something went wrong',
// ),
// );
//

// axiosInstance.interceptors.response.use(
// (response) => response,
// async (error) => {
Expand Down
1 change: 1 addition & 0 deletions src/api/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const PATH_API = {
BABIES_IMAGES: '/babies/images',
USERS: '/users',
USERS_INVITATION: '/users/invitation',
INVITATION: '/invitation',
};

/**
Expand Down
1 change: 1 addition & 0 deletions src/api/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export const QUERY_KEY = {
BABIES_IMAGES: PATH_API.BABIES_IMAGES,
USERS: PATH_API.USERS,
USERS_INVITATION: PATH_API.USERS_INVITATION,
INVITATION: PATH_API.INVITATION,
};
40 changes: 40 additions & 0 deletions src/api/users/usePostInvitation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
UseMutationOptions,
useMutation,
useQueryClient,
} from '@tanstack/react-query';
import { components } from '@/types/type';

import { useRouter } from 'next/navigation';
import { QUERY_KEY } from '@/api/queryKeys';
import { axiosInstance } from '@/api/axios';
import { PATH_API } from '@/api/path';

type invitationResponse = components['schemas']['InvitationDto.Request.Get'];
type invitationRequest =
components['schemas']['BaseResponseListBabyDto.Response.Detail'];

export const usePostInvitation = (
options?: Omit<
UseMutationOptions<invitationResponse, any, invitationRequest>,
'mutationKey'
>,
) => {
const queryClient = useQueryClient();

return useMutation<invitationResponse, any, invitationRequest>({
mutationKey: [QUERY_KEY.INVITATION],
mutationFn: async (payload: invitationRequest) => {
console.log('payload:', payload);
const response = await axiosInstance.post(PATH_API.INVITATION, payload);
return response.data as invitationResponse;
},
onSuccess: (data) => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEY.INVITATION] });
},
onError: (error) => {
console.error('Mutation 에러:', error);
},
...options,
});
};
8 changes: 5 additions & 3 deletions src/api/users/usePostUsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import {
useMutation,
useQueryClient,
} from '@tanstack/react-query';
import { components } from '@/types/type';
import { components, paths } from '@/types/type';

import { useRouter } from 'next/navigation';
import { QUERY_KEY } from '@/api/queryKeys';
import { axiosInstance } from '@/api/axios';
import { PATH_API } from '@/api/path';

// API 요청 및 응답 타입 정의
type UsersResponse = components['schemas']['SignupDto.Response'];
type UserRequest = components['schemas']['SignupDto.Request'];
type UsersResponse =
paths['/api/v3/users']['post']['responses']['200']['content']['*/*']['data'];
type UserRequest =
paths['/api/v3/users']['post']['requestBody']['content']['application/json'];

export const usePostUsers = (
options?: Omit<
Expand Down
12 changes: 7 additions & 5 deletions src/component/molecule/BabyInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,19 @@ const BabyInfo: React.FC<BabyInfoType> = ({
<SexSelectWrap>
<Button
label={'남자아이'}
variant={params.gender === 'man' ? 'Line_Gray_Select' : 'Line_Gray'}
variant={
params.gender === 'MALE' ? 'Line_Gray_Select' : 'Line_Gray'
}
size={'large'}
onClick={() => onChangeValue('gender', 'man')}
onClick={() => onChangeValue('gender', 'MALE')}
/>
<Button
label={'여자아이'}
variant={
params.gender === 'woman' ? 'Line_Gray_Select' : 'Line_Gray'
params.gender === 'FEMALE' ? 'Line_Gray_Select' : 'Line_Gray'
}
size={'large'}
onClick={() => onChangeValue('gender', 'woman')}
onClick={() => onChangeValue('gender', 'FEMALE')}
/>
</SexSelectWrap>
</BabyInfoValue>
Expand All @@ -139,7 +141,7 @@ const BabyInfo: React.FC<BabyInfoType> = ({
onChange={(e) => {
onChangeValue('birthday', e.target.value);
}}
// readOnly={true}
onClick={onClickDate}
variant={'white'}
leftIcon={<IcoCalendar />}
/>
Expand Down
1 change: 0 additions & 1 deletion src/component/molecule/WorningToastWrap/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { css } from '@emotion/react';
import { Colors, fontGenerator } from '@/styles';

export const WarningToastWrapContainer = styled.main`
//margin: 10px 20px;
& > div {
bottom: 76px;
margin: 10px;
Expand Down
2 changes: 0 additions & 2 deletions src/pages/TestNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ export function TestNavigation() {
<button
onClick={async () => {
const date = await bridge.getDate();
console.log(date);

alert(date);
}}
>
Expand Down
5 changes: 4 additions & 1 deletion src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import { Global, ThemeProvider } from '@emotion/react';
import GlobalStyle from '@/styles/globalStyles';
import { theme } from '@/styles/theme';
import ReactQueryProviders from '@/api/react-query-provider';
import { LocalStorage } from '@/utills/useUtil';
import { PATH } from '@/routes/path';
import { useEffect } from 'react';

function MyApp({ Component, pageProps }: AppProps) {
const router = useRouter(); // Initialize router

// const checkToken = () => {
// const accessToken = LocalStorage.getItem('accessToken');
// if (!accessToken) {
// router.push(PATH.root); // Use router.push instead of window.location.href
// router.push(PATH.HOME);
// }
// };
//
Expand Down
14 changes: 10 additions & 4 deletions src/pages/info/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import {
import BottomButtonProvider from '@/component/molecule/BottomButtonProvider';
import { IcoAddBlue } from '@/assets/svg';
import BabyInfo from '@/component/molecule/BabyInfo';
import { checkParamsFilled, checkParamsListFilled } from '@/utills/useUtil';
import {
checkParamsFilled,
checkParamsListFilled,
formatDate,
} from '@/utills/useUtil';
import { usePostUsers } from '@/api/users/usePostUsers';
import { PATH } from '@/routes/path';
import useSignupStore from '@/store/signup/babySignup';
Expand All @@ -36,7 +40,7 @@ export default function Terms() {
setParams((prevState) => [
...prevState,
{
id: prevState.length + 1, // 새로운 ID
id: prevState.length + 1,
name: '',
gender: '',
birthday: '',
Expand Down Expand Up @@ -71,8 +75,10 @@ export default function Terms() {
key={body.id}
params={body}
onChangeValue={(field, value) => onChangeValue(body.id, field, value)}
onClickDate={() => {
// 브릿지 연결
onClickDate={async () => {
const date = await bridge.getDate();
alert(date);
onChangeValue(body.id, 'birthday', formatDate(date));
}}
/>
))}
Expand Down
4 changes: 3 additions & 1 deletion src/pages/invite-check/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export default function InviteCheck() {
label={'우리 아이가 아니에요'}
size={'large'}
variant={'OutlineWhite'}
onClick={bridge.back}
onClick={() => {
router.push(PATH.invite);
}}
/>
<Button
label={'등록하기'}
Expand Down
19 changes: 10 additions & 9 deletions src/pages/invite/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import { useVacBridge } from '@/bridge/VacBridgeProvider';
import BackHeader from '@/component/molecule/BackHeader';
import React, { useState } from 'react';
import { OnChangeValueType, ParamsType } from '@/types/globalTypes';
import { useRouter } from 'next/navigation';
import { HeadlineTitle, InputWrap } from '@/pages/invite/style';
import InputForm from '@/component/atom/InputForm';
import BottomButtonProvider from '@/component/molecule/BottomButtonProvider';
import { PATH } from '@/routes/path';
import { usePostUsersInvitation } from '@/api/users/usePostUsersInvitation';
import { usePostInvitation } from '@/api/users/usePostInvitation';
import WarningToastWrap from '@/component/molecule/WorningToastWrap';

export default function Terms() {
const router = useRouter();
const bridge = useVacBridge();
const [inviteCode, setInviteCode] = useState<string>('');
const { mutate: useSignupInvite } = usePostUsersInvitation();
const [error, setError] = useState<string>('');
const { mutate } = usePostInvitation();

const handleSubmit = () => {
useSignupInvite(
mutate(
{
registerToken: '',
nickname: '',
babyIds: [inviteCode],
invitationCode: inviteCode,
},
{
onSuccess: () => {
onSuccess: (data) => {
router.push(PATH.invite_confirm);
},
onError: (error) => {
console.log(error);
setError(error.response.data.errorMessage);
},
},
);
Expand All @@ -49,10 +49,11 @@ export default function Terms() {
/>
<BottomButtonProvider
label={'다음'}
isActive={inviteCode}
isActive={!!inviteCode}
disabled={!inviteCode}
onClick={handleSubmit}
/>
<WarningToastWrap errorMessage={error} setErrorMessage={setError} />
</InputWrap>
</>
);
Expand Down
44 changes: 25 additions & 19 deletions src/pages/nickname/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export default function Terms() {
const [nickname, setNickName] = useState<string>('');
const [error, setError] = useState('');
const { babies } = useSignupStore((state) => state);
console.log(babies);

// yup 스키마 정의
const nicknameSchema = yup
Expand All @@ -32,25 +31,18 @@ export default function Terms() {

const validateNickname = (nickname: string) => {
try {
nicknameSchema.validateSync(nickname); // 유효성 검사
setError(''); // 에러 초기화
nicknameSchema.validateSync(nickname);
setError('');
return true;
} catch (err) {
if (err instanceof yup.ValidationError) {
setError(err.message); // 에러 메시지 설정
setError(err.message);
}
return false;
}
};

const { mutate: useSignup } = usePostUsers({
onSuccess: () => {
router.push(PATH.welcome);
},
onError: (error) => {
console.log(error);
},
});
const { mutate: useSignup } = usePostUsers();

const handleSubmit = () => {
const transformData = babies.map((baby) => ({
Expand All @@ -59,13 +51,27 @@ export default function Terms() {
birthday: baby.birthday,
profileImg: baby.profileImg,
}));
// 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOm51bGwsInN1YiI6IlJFR0lTVEVSX1RPS0VOIiwiaXNzIjoidmFjZ29tIiwiaWF0IjoxNzM2MzU2OTI1LCJuYmYiOjE3MzYzNTY5MjUsImV4cCI6MTczNjM1NzUyNSwic29jaWFsSWQiOiJ0ZXN0U29jaWFsSWQtNTg1NzQyMjMxIiwicHJvdmlkZXIiOiJLQUtBTyJ9.ni-nVVY1gxIXNgAAlgFHT5h_Yuk6m6Bb3mv_Ucl1eSw',

useSignup({
registerToken:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOm51bGwsInN1YiI6IlJFR0lTVEVSX1RPS0VOIiwiaXNzIjoidmFjZ29tIiwiaWF0IjoxNzM1ODMzMDk2LCJuYmYiOjE3MzU4MzMwOTYsImV4cCI6MTczNTgzMzY5Niwic29jaWFsSWQiOiIzNzc0Mzc1NTE3IiwicHJvdmlkZXIiOiJrYWthbyJ9.BV80hhuHVNxvCnhIgV7hizLwEujY7QsX4pdBQ8Edppo',
nickname,
babies: transformData,
});
const registerToken = bridge.getRegisterToken();

useSignup(
{
registerToken: registerToken,
nickname,
babies: transformData,
},
{
onSuccess: (data) => {
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
router.push(PATH.welcome);
},
onError: (error) => {
setError(error.response.data.error);
},
},
);
};

return (
Expand All @@ -87,7 +93,7 @@ export default function Terms() {
/>
<BottomButtonProvider
label={'다음'}
isActive={nickname}
isActive={!!nickname}
disabled={!nickname}
onClick={() => {
validateNickname(nickname) && handleSubmit();
Expand Down
27 changes: 27 additions & 0 deletions src/store/signup/invitationBabyResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import { ParamsType } from '@/types/globalTypes';

interface State {
babies: ParamsType[];
}
interface Action {
setBabies: (text: ParamsType[]) => void;
}

const useSignupStore = create<State & Action>()(
devtools((set) => {
return {
// state
babies: [],

// actions
setBabies: (text: ParamsType[]) => {
set({ babies: text });
console.log(text);
},
};
}),
);

export default useSignupStore;
Loading