Skip to content

Commit b9506e0

Browse files
committed
feat: 티켓 삭제 UI 구현 및 삭제 API 연동
1 parent 7a03428 commit b9506e0

File tree

3 files changed

+71
-27
lines changed

3 files changed

+71
-27
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const TicketListPage = () => {
4242
};
4343
fetchTickets();
4444
}, [eventId]);
45-
45+
4646
return (
4747
<DashboardLayout centerContent="WOOACON 2024">
4848
<div className="mt-8 px-7">
@@ -70,7 +70,7 @@ const TicketListPage = () => {
7070
<p className="font-bold text-base md:text-lg">티켓</p>
7171
</div>
7272
{tickets.length > 0 ? (
73-
tickets.map(value => <TicketItem key={value.ticketId} ticket={value} />)
73+
tickets.map(value => <TicketItem key={value.ticketId} ticket={value}/>)
7474
) : (
7575
<div className="text-gray5 font-thin">현재 등록된 티켓이 없습니다.</div>
7676
)}

src/widgets/dashboard/ui/TicketItem.tsx

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,64 @@
11
import AvailableTicket from '../../../../public/assets/dashboard/ticket/Ticket(gray).svg';
22
import PersonIcon from '../../../../public/assets/dashboard/ticket/PersonIcon.svg';
33
import { ReadTicket } from '../../../pages/dashboard/ui/ticket/TicketListPage';
4+
import { motion } from "framer-motion";
5+
import { useState } from 'react';
6+
import { deleteTicket } from '../../../features/ticket/api/ticket';
47

58
const TicketItem = ({ ticket }: { ticket: ReadTicket }) => {
9+
const [isDragging, setIsDragging] = useState(false);
10+
const handleDelete = async () => {
11+
const isConfirmed = window.confirm("티켓을 삭제하시겠습니까?");
12+
if (!isConfirmed) return;
13+
try {
14+
await deleteTicket.remove(ticket.ticketId);
15+
alert("티켓이 삭제되었습니다.");
16+
window.location.reload();
17+
} catch (error) {
18+
console.error("티켓 삭제 중 오류 발생:", error);
19+
}
20+
};
621
return (
7-
<div className="w-full h-14 bg-gray2 my-2 rounded-lg flex items-center justify-between p-5">
8-
<div className="flex gap-5">
9-
<p className="font-bold">{ticket.ticketPrice > 0 ? '일반' : '무료'}</p>
10-
<p>{ticket.ticketName}</p>
11-
</div>
12-
<div className="flex flex-col gap-1 text-gray-400 text-xs">
13-
<div className="flex gap-1 items-center justify-end">
14-
<img src={AvailableTicket} /> {ticket.availableQuantity}개 남음
22+
<div className="relative overflow-hidden w-full">
23+
<motion.div
24+
className="flex items-center bg-white p-4"
25+
drag="x"
26+
dragConstraints={{ left: -100, right: 0 }}
27+
onDragStart={() => setIsDragging(true)}
28+
onDragEnd={(event, info) => {
29+
if (info.offset.x < -50) {
30+
setIsDragging(true);
31+
} else {
32+
setIsDragging(false);
33+
}
34+
}}
35+
>
36+
<div className="flex gap-5">
37+
<p className="font-bold">{ticket.ticketPrice > 0 ? "일반" : "무료"}</p>
38+
<p>{ticket.ticketName}</p>
1539
</div>
16-
<div className="flex gap-1 items-center justify-end">
17-
<img src={PersonIcon} /> 1인당 최대 2장
40+
<div className="flex-grow" />
41+
<div className="flex flex-col gap-1 text-gray-400 text-xs">
42+
<div className="flex gap-1 items-center justify-end">
43+
<img src={AvailableTicket} alt="남은 티켓" /> {ticket.availableQuantity}개 남음
44+
</div>
45+
<div className="flex gap-1 items-center justify-end">
46+
<img src={PersonIcon} alt="1인당 최대 구매량" /> 1인당 최대 2장
47+
</div>
1848
</div>
19-
</div>
49+
</motion.div>
50+
51+
{/* 삭제 버튼 */}
52+
<motion.button
53+
className="absolute right-0 top-0 bottom-0 bg-red-500 text-white px-4 flex items-center justify-center transition-transform"
54+
initial={{ x: '100%' }}
55+
animate={{ x: isDragging ? 0 : 'calc(100% + 1px)' }}
56+
transition={{ duration: 0 }}
57+
onClick={handleDelete}
58+
>
59+
삭제
60+
</motion.button>
61+
2062
</div>
2163
);
2264
};

yarn.lock

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,12 +2242,12 @@ fraction.js@^4.3.7:
22422242
integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
22432243

22442244
framer-motion@^12.4.7:
2245-
version "12.4.7"
2246-
resolved "https://registry.npmjs.org/framer-motion/-/framer-motion-12.4.7.tgz"
2247-
integrity sha512-VhrcbtcAMXfxlrjeHPpWVu2+mkcoR31e02aNSR7OUS/hZAciKa8q6o3YN2mA1h+jjscRsSyKvX6E1CiY/7OLMw==
2245+
version "12.6.2"
2246+
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-12.6.2.tgz#560b1a23d71ed062a2f6d7c2a000a53ef6ee37b4"
2247+
integrity sha512-7LgPRlPs5aG8UxeZiMCMZz8firC53+2+9TnWV22tuSi38D3IFRxHRUqOREKckAkt6ztX+Dn6weLcatQilJTMcg==
22482248
dependencies:
2249-
motion-dom "^12.4.5"
2250-
motion-utils "^12.0.0"
2249+
motion-dom "^12.6.1"
2250+
motion-utils "^12.5.0"
22512251
tslib "^2.4.0"
22522252

22532253
fsevents@~2.3.2, fsevents@~2.3.3:
@@ -2770,17 +2770,17 @@ minimist@^1.2.6:
27702770
resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz"
27712771
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
27722772

2773-
motion-dom@^12.4.5:
2774-
version "12.4.5"
2775-
resolved "https://registry.npmjs.org/motion-dom/-/motion-dom-12.4.5.tgz"
2776-
integrity sha512-Q2xmhuyYug1CGTo0jdsL05EQ4RhIYXlggFS/yPhQQRNzbrhjKQ1tbjThx5Plv68aX31LsUQRq4uIkuDxdO5vRQ==
2773+
motion-dom@^12.6.1:
2774+
version "12.6.1"
2775+
resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-12.6.1.tgz#2b8f53c0af51db75301f88f25fc4d4546424ba60"
2776+
integrity sha512-8XVsriTUEVOepoIDgE/LDGdg7qaKXWdt+wQA/8z0p8YzJDLYL8gbimZ3YkCLlj7bB2i/4UBD/g+VO7y9ZY0zHQ==
27772777
dependencies:
2778-
motion-utils "^12.0.0"
2778+
motion-utils "^12.5.0"
27792779

2780-
motion-utils@^12.0.0:
2781-
version "12.0.0"
2782-
resolved "https://registry.npmjs.org/motion-utils/-/motion-utils-12.0.0.tgz"
2783-
integrity sha512-MNFiBKbbqnmvOjkPyOKgHUp3Q6oiokLkI1bEwm5QA28cxMZrv0CbbBGDNmhF6DIXsi1pCQBSs0dX8xjeER1tmA==
2780+
motion-utils@^12.5.0:
2781+
version "12.5.0"
2782+
resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-12.5.0.tgz#0e42a6b8030327166ca0d0ea0d5b86d64c21e51d"
2783+
integrity sha512-+hFFzvimn0sBMP9iPxBa9OtRX35ZQ3py0UHnb8U29VD+d8lQ8zH3dTygJWqK7av2v6yhg7scj9iZuvTS0f4+SA==
27842784

27852785
ms@^2.1.3:
27862786
version "2.1.3"
@@ -3365,6 +3365,7 @@ storybook@^8.4.6:
33653365
"@storybook/core" "8.4.6"
33663366

33673367
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
3368+
name string-width-cjs
33683369
version "4.2.3"
33693370
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
33703371
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -3383,6 +3384,7 @@ string-width@^5.0.1, string-width@^5.1.2:
33833384
strip-ansi "^7.0.1"
33843385

33853386
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
3387+
name strip-ansi-cjs
33863388
version "6.0.1"
33873389
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
33883390
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==

0 commit comments

Comments
 (0)