Skip to content

Commit 889b5db

Browse files
committed
refact: API 호출 전 데이터 검증 추가
1 parent 1997f8b commit 889b5db

File tree

3 files changed

+27
-28
lines changed

3 files changed

+27
-28
lines changed

src/features/ticket/model/TicketContext.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import { createContext, ReactNode, useContext, useState } from 'react';
2+
import { CreateTicketRequest } from './ticketCreation';
23

34
export interface TicketState {
4-
ticketState: {
5-
startDate: string;
6-
endDate: string;
7-
startTime: string;
8-
endTime: string;
9-
};
10-
setTicketState: React.Dispatch<React.SetStateAction<TicketState['ticketState']>>;
5+
ticketState: CreateTicketRequest;
6+
setTicketState: React.Dispatch<React.SetStateAction<CreateTicketRequest>>;
117
setTicketChannelId: (ticketChannelId: number) => void;
128
}
139

1410
const TicketContext = createContext<TicketState | undefined>(undefined);
1511

1612
export const TicketProvider = ({ children }: { children: ReactNode }) => {
17-
const [ticketState, setTicketState] = useState<TicketState['ticketState']>({
13+
const [ticketState, setTicketState] = useState<CreateTicketRequest>({
14+
eventId: 0,
15+
ticketType: '',
16+
ticketName: '',
17+
ticketDescription: '',
18+
ticketPrice: 0,
19+
availableQuantity: 0,
1820
startDate: '',
1921
endDate: '',
2022
startTime: '06:00',
@@ -38,4 +40,4 @@ export const useTicketState = () => {
3840
throw new Error('useTicketState must be used within a TicketProvider');
3941
}
4042
return context;
41-
};
43+
};

src/features/ticket/model/TicketDatePicker.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const TicketDatePicker = ({ className, ticketState, setTicketState, isLabel = fa
2525
for (let i = 0; i < 24; i++) {
2626
for (let j = 0; j < 4; j++) {
2727
const hour = i.toString().padStart(2, '0');
28-
const minute = (j * 15).toString().padEnd(2, '0');
28+
const minute = (j * 15).toString().padStart(2, '0');
2929
options.push(`${hour}:${minute}`);
3030
}
3131
}
@@ -44,7 +44,6 @@ const TicketDatePicker = ({ className, ticketState, setTicketState, isLabel = fa
4444

4545
useEffect(() => {
4646
if (setTicketState) {
47-
// Update state only when values change
4847
setTicketState(prev => {
4948
const newStartDate = startDate ? formatDate(startDate) : '';
5049
const newEndDate = endDate ? formatDate(endDate) : '';
@@ -54,7 +53,6 @@ const TicketDatePicker = ({ className, ticketState, setTicketState, isLabel = fa
5453
prev.startTime !== startTime ||
5554
prev.endTime !== endTime
5655
) {
57-
// Call the parent function to pass updated values
5856
onDateChange({
5957
startDate: newStartDate,
6058
endDate: newEndDate,
@@ -69,7 +67,7 @@ const TicketDatePicker = ({ className, ticketState, setTicketState, isLabel = fa
6967
endTime,
7068
};
7169
}
72-
return prev; // Return previous state if no change
70+
return prev;
7371
});
7472
}
7573
}, [startDate, endDate, startTime, endTime, setTicketState, onDateChange]);

src/pages/dashboard/ui/ticket/TicketCreatePage.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ const TicketCreatePage = () => {
2121
startTime: '',
2222
endTime: '',
2323
});
24-
const [eventState, setEventState] = useState({
25-
startDate: '',
26-
endDate: '',
27-
startTime: '',
28-
endTime: '',
29-
});
3024

3125
const handleTicketTypeChange = (type: string) => {
3226
let mappedType: string;
@@ -44,6 +38,9 @@ const TicketCreatePage = () => {
4438
// 필드값 업데이트
4539
const handleInputChange = (field: keyof CreateTicketRequest) => (e: React.ChangeEvent<HTMLInputElement>) => {
4640
const value = e.target.value;
41+
if ((field === 'ticketPrice' || field === 'availableQuantity') && Number(value) < 0) {
42+
return;
43+
}
4744
setTicketData((prev) => ({
4845
...prev,
4946
[field]: field === 'ticketPrice' || field === 'availableQuantity' ? Number(value) : value,
@@ -52,7 +49,6 @@ const TicketCreatePage = () => {
5249

5350
// 시간 업데이트
5451
const handleDateChange = (dates: { startDate: string; endDate: string; startTime: string; endTime: string }) => {
55-
setEventState(dates);
5652
setTicketData((prevState) => ({
5753
...prevState,
5854
startDate: dates.startDate,
@@ -76,11 +72,17 @@ const TicketCreatePage = () => {
7672

7773
// API 호출
7874
const handleSaveClick = async () => {
75+
if (!ticketData.ticketName || !ticketData.ticketDescription || ticketData.ticketPrice < 0 || !ticketData.availableQuantity) {
76+
alert('모든 필수 입력 항목을 작성해주세요.');
77+
return;
78+
}
7979
try {
8080
const response = await createTicket(ticketData);
8181
console.log('티켓 저장 성공:', response);
82+
alert('티켓이 성공적으로 저장되었습니다.');
8283
} catch (err) {
8384
console.error('티켓 저장에 실패했습니다.', err);
85+
alert('티켓 저장에 실패했습니다. 다시 시도해주세요.');
8486
}
8587
};
8688

@@ -97,7 +99,7 @@ const TicketCreatePage = () => {
9799
<div>
98100
<div className="w-32 md:w-40 my-1">
99101
<p className="font-semibold px-1 mb-1 text-gray-700">티켓 종류</p>
100-
<ChoiceChip {...TwoOptions.args} onSelect={handleTicketTypeChange}/>
102+
<ChoiceChip {...TwoOptions.args} onSelect={handleTicketTypeChange} />
101103
</div>
102104
<p className="block px-1 mb-1 text-placeholderText text-11 md:text-13">
103105
참가자가 선착순으로 발행된 티켓을 구매합니다.
@@ -139,13 +141,11 @@ const TicketCreatePage = () => {
139141
{/*캘린더가 들어갈 자리*/}
140142
<div className="flex flex-col gap-2">
141143
<p className="px-1 text-gray-700 font-semibold">판매 기간</p>
142-
<TicketDatePicker isLabel={true} ticketState={eventState}
143-
setTicketState={setEventState} onDateChange={handleDateChange}/>
144+
<TicketDatePicker isLabel={true} ticketState={ticketData}
145+
setTicketState={setTicketData} onDateChange={handleDateChange} />
144146
</div>
147+
145148
<div className="flex-grow"></div>
146-
<div className="ticket-data-output">
147-
<pre>{JSON.stringify(ticketData, null, 2)}</pre>
148-
</div>
149149

150150
<div className="w-full ">
151151
<Button label="저장하기" onClick={handleSaveClick} className="w-full h-12 rounded-full" />
@@ -155,5 +155,4 @@ const TicketCreatePage = () => {
155155
);
156156
};
157157

158-
export default TicketCreatePage;
159-
158+
export default TicketCreatePage;

0 commit comments

Comments
 (0)