Skip to content

Commit aef4aab

Browse files
committed
[WRFE0-70](feat): 래플, 이벤트 생성API연동 중
1 parent 5881db9 commit aef4aab

File tree

7 files changed

+143
-36
lines changed

7 files changed

+143
-36
lines changed

apps/front/wraffle-webview/app/products/create/event/page.tsx

+34-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
'use client';
22

3-
import type {EventCreateState} from '@/entities/product/model';
3+
import type {
4+
CreateEventPayload,
5+
EventCreateState,
6+
} from '@/entities/product/model';
47
import {
58
createEventDefaultValues,
69
createEventSchema,
710
} from '@/entities/product/model';
11+
import {useCreateProductMutation} from '@/features/product/create/api/useCreateQuery';
12+
import type {Payload} from '@/features/product/create/config/type';
813
import {GenericForm, Header, ProgressBar} from '@/shared/ui';
914
import {
1015
DateStep,
@@ -41,13 +46,31 @@ const EventCreate = () => {
4146
context: {},
4247
},
4348
});
44-
4549
const EventTotalStepIndex = 5;
4650

47-
// TODO
48-
// 생성 api 연동
49-
const onSubmit = (data: EventCreateState) => {
50-
console.log('go : ', data);
51+
const {mutateAsync: createProduct, data} = useCreateProductMutation();
52+
53+
const onSubmit = async (data: CreateEventPayload) => {
54+
const formatRaffleData: Payload = {
55+
type: 'event',
56+
title: data.title,
57+
categoryId: Number(data.categoryId),
58+
tagIds: data.tagIds,
59+
price: Number(data.price),
60+
startDate: String(data.startDate),
61+
endDate: String(data.endDate),
62+
announceAt: String(data.announceAt),
63+
winnerCount: Number(data.winnerCount),
64+
images: data.images,
65+
etc: data.etc,
66+
description: '', // 사용되지 않음
67+
products: data.products,
68+
};
69+
try {
70+
await createProduct(formatRaffleData);
71+
} catch (e) {
72+
console.error(e);
73+
}
5174
};
5275

5376
return (
@@ -64,7 +87,7 @@ const EventCreate = () => {
6487
)}
6588

6689
<GenericForm
67-
onSubmit={() => onSubmit(funnel.context)}
90+
onSubmit={onSubmit}
6891
formOptions={{
6992
mode: 'onChange',
7093
resolver: (data, context, options) => {
@@ -107,13 +130,14 @@ const EventCreate = () => {
107130
etcStep={({history}) => (
108131
<EtcStep onNext={etc => history.push('successStep', {etc})} />
109132
)}
110-
successStep={() => (
111-
<SuccessList type='event' productId={'1'} thumbnail={''} /> // productId,thumbnail api 연동후 작업
112-
)}
133+
successStep={() => <SuccessList type='event' productData={data} />}
113134
/>
114135
</GenericForm>
115136
</div>
116137
);
117138
};
118139

119140
export default EventCreate;
141+
142+
// success 라우터 따로 빼기
143+
// -> 이미지 링크를 어떻게 줘야

apps/front/wraffle-webview/app/products/create/raffle/page.tsx

+31-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
'use client';
22

3+
import type {
4+
CreateRafflePayload,
5+
RaffleCreateState,
6+
} from '@/entities/product/model';
37
import {
48
createRaffleDefaultValues,
59
createRaffleSchema,
6-
type RaffleCreateState,
710
} from '@/entities/product/model';
11+
import {useCreateProductMutation} from '@/features/product/create/api/useCreateQuery';
12+
import type {Payload} from '@/features/product/create/config/type';
813
import {GenericForm, Header, ProgressBar} from '@/shared/ui';
914
import {
1015
DateStep,
@@ -37,15 +42,33 @@ const RaffleCreate = () => {
3742
context: {},
3843
},
3944
});
40-
4145
const RaffleTotalStepIndex = 4;
4246

47+
const {mutateAsync: createProduct, data} = useCreateProductMutation();
48+
4349
console.log(funnel.context);
4450

45-
// TODO
46-
// 생성 api 연결
47-
const onSubmit = (data: RaffleCreateState) =>
48-
console.log('go to server : ', data);
51+
const onSubmit = async (data: CreateRafflePayload) => {
52+
const formatRaffleData: Payload = {
53+
type: 'raffle',
54+
title: data.title,
55+
categoryId: Number(data.categoryId),
56+
tagIds: data.tagIds,
57+
price: Number(data.price),
58+
startDate: String(data.startDate),
59+
endDate: String(data.endDate),
60+
announceAt: String(data.announceAt),
61+
winnerCount: Number(data.winnerCount),
62+
images: data.images,
63+
etc: data.etc,
64+
description: '', // 사용되지 않음
65+
};
66+
try {
67+
await createProduct(formatRaffleData);
68+
} catch (e) {
69+
console.error(e);
70+
}
71+
};
4972

5073
return (
5174
<div>
@@ -61,7 +84,7 @@ const RaffleCreate = () => {
6184
)}
6285

6386
<GenericForm
64-
onSubmit={() => onSubmit(funnel.context)}
87+
onSubmit={onSubmit}
6588
formOptions={{
6689
mode: 'onChange',
6790
resolver: (data, context, options) => {
@@ -99,9 +122,7 @@ const RaffleCreate = () => {
99122
etcStep={({history}) => (
100123
<EtcStep onNext={etc => history.push('successStep', {etc})} />
101124
)}
102-
successStep={() => (
103-
<SuccessList type='raffle' productId={'1'} thumbnail={''} /> // productId,thumbnail api 연동후 작업
104-
)}
125+
successStep={() => <SuccessList type='raffle' productData={data} />}
105126
/>
106127
</GenericForm>
107128
</div>

apps/front/wraffle-webview/src/entities/product/model/createEventSchema.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ const announceAtSchema = z.date();
1212
const winnerCountSchema = z.string().default('');
1313

1414
const productsSchema = z.object({
15-
title: z.string(),
15+
title: z.string().default(''),
1616
tagIds: z.number().array().default([]),
17-
imageUrl: z.string(),
17+
imageUrl: z.string().default(''),
1818
});
1919
const productsArraySchema = z.array(productsSchema).default([]);
2020

apps/front/wraffle-webview/src/entities/product/model/createRaffleSchema.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ const categoryIdSchema = z.string().default('');
66
const tagIdsSchema = z.number().array().default([]);
77
const priceSchema = z.string().default('');
88

9-
const startDateSchema = z.date().optional();
10-
const endDateSchema = z.date().optional();
11-
const announceAtSchema = z.date().optional();
9+
const startDateSchema = z.date();
10+
const endDateSchema = z.date();
11+
const announceAtSchema = z.date();
1212
const winnerCountSchema = z.string().default('');
1313

1414
const imagesSchema = z.string().array().default([]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type {
2+
EventPayload,
3+
Payload,
4+
ProductResponse,
5+
RafflePayload,
6+
} from '../config/type';
7+
import apiClient from '@/shared/api/apiClient';
8+
import {useMutation} from '@tanstack/react-query';
9+
10+
export const createProduct = async (payload: Payload) => {
11+
const {type, ...data} = payload;
12+
const url = type === 'raffle' ? '/raffles' : '/events';
13+
14+
const response = await apiClient.post<
15+
ProductResponse,
16+
RafflePayload | EventPayload
17+
>(url, {body: data, withAuth: true});
18+
return response.data;
19+
};
20+
21+
export const useCreateProductMutation = () => {
22+
return useMutation({
23+
mutationFn: (data: Payload) => createProduct(data),
24+
});
25+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
interface BasePayload {
2+
title: string;
3+
price: number;
4+
startDate: string;
5+
endDate: string;
6+
announceAt: string;
7+
winnerCount: number;
8+
description: string;
9+
etc: string;
10+
categoryId: number;
11+
tagIds: number[];
12+
images: string[];
13+
}
14+
15+
export interface RafflePayload extends BasePayload {}
16+
17+
interface Product {
18+
title: string;
19+
imageUrl: string;
20+
tagIds: number[];
21+
}
22+
23+
export interface EventPayload extends BasePayload {
24+
products: Product[];
25+
}
26+
27+
export type Payload =
28+
| ({type: 'raffle'} & RafflePayload)
29+
| ({type: 'event'} & EventPayload);
30+
31+
export interface ProductResponse {
32+
id: number;
33+
thumbnail: string;
34+
}

apps/front/wraffle-webview/src/widgets/product-list/create/ui/SuccessList.tsx

+14-11
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ import Link from 'next/link';
33
import {getTypeText} from '@/shared/util';
44
import {Button, Typography} from '@wraffle/ui';
55

6-
export const SuccessList = ({
7-
type,
8-
productId,
9-
thumbnail,
10-
}: {
11-
type: 'raffle' | 'event';
12-
productId: string;
13-
thumbnail: string;
14-
}) => {
6+
interface SuccessListProps {
7+
type: 'event' | 'raffle';
8+
productData?: {
9+
id: number;
10+
thumbnail: string;
11+
};
12+
}
13+
14+
export const SuccessList = ({type, productData}: SuccessListProps) => {
1515
const eventOrRaffleText = getTypeText(type);
1616

17+
if (!productData) {
18+
return <div>data loaidng</div>;
19+
}
1720
return (
1821
<div className='flex h-full flex-col items-center px-4 py-6'>
1922
<div className='mb-24 w-full text-left'>
@@ -27,15 +30,15 @@ export const SuccessList = ({
2730
</div>
2831

2932
<Image
30-
src={thumbnail}
33+
src={productData.thumbnail}
3134
width={250}
3235
height={250}
3336
alt='thumbnail-image'
3437
className='h-60 w-60 rounded-lg bg-blue-200 object-cover'
3538
/>
3639

3740
<div className='fixed inset-x-0 bottom-0 px-4 py-4'>
38-
<Link href={`/products/${productId}?type=${type}`}>
41+
<Link href={`/products/${productData.id}?type=${type}`} replace={true}>
3942
<Button className='h-[45px]'>
4043
{eventOrRaffleText.successWithoutReviewButton}
4144
</Button>

0 commit comments

Comments
 (0)