Skip to content

Commit 3c7b6a7

Browse files
committed
feat: 초대장 상세 페이지 ui, url 변경
1 parent 6585876 commit 3c7b6a7

File tree

6 files changed

+219
-114
lines changed

6 files changed

+219
-114
lines changed

apps/tuk-web/src/app/gathering/[gatheringId]/invites/[proposalId]/page.tsx

Lines changed: 0 additions & 5 deletions
This file was deleted.

apps/tuk-web/src/app/gathering/[gatheringId]/invites/[proposalId]/src/components/GatheringProposal.tsx

Lines changed: 0 additions & 104 deletions
This file was deleted.

apps/tuk-web/src/app/invite/gathering/[gatheringId]/src/service/gathering-api.service.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ export class GatheringAPIService {
55
constructor(private fetch: RestAPIProtocol) {}
66

77
getGatheringName(gatheringId: number) {
8-
// throw new Error('강제 에러 발생: GatheringAPIService.getGatheringName');
9-
108
return this.fetch.get({
119
url: ':gatheringId/name',
1210
param: {
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
'use client';
2+
3+
import { useQuery } from '@tanstack/react-query';
4+
// import Link from 'next/link';
5+
import { useEffect, useState } from 'react';
6+
7+
import { ProposalItemType } from '@/app/gathering/[gatheringId]/invites/src/service/schema/get-gathering-proposals.schema';
8+
import { QuoteIcon } from '@/app/invite/meet/[meetId]/src/components/InviteProposal';
9+
import { proposalAPIService } from '@/app/invite/meet/[meetId]/src/service';
10+
import { useParam } from '@/shared/hooks/useParam';
11+
import { cn } from '@/shared/lib';
12+
13+
// import { CloseIcon32, Header } from '@/shared/components';
14+
15+
const GatheringProposal = () => {
16+
const proposalId = Number(useParam('proposalId'));
17+
18+
const [slideDown, setSlideDown] = useState(false);
19+
20+
const { data, isLoading, isError } = useQuery({
21+
queryKey: ['getProposalDetail', proposalId],
22+
queryFn: () => proposalAPIService.getProposalDetail(proposalId),
23+
});
24+
25+
useEffect(() => {
26+
if (!isLoading && !isError) {
27+
const id = requestAnimationFrame(() => setSlideDown(true));
28+
return () => cancelAnimationFrame(id);
29+
}
30+
}, [isLoading, isError]);
31+
32+
if (isLoading) return <div>loading</div>;
33+
34+
if (!data) return null;
35+
36+
return (
37+
<div className="relative h-screen w-full overflow-y-auto overflow-x-hidden">
38+
<div className="absolute left-[-259px] top-[244px] z-0 h-[406px] w-[898px] bg-gradient-to-b from-[#FFA098] via-[#FFAC85] to-[#FFFEFE] blur-[100px]" />
39+
40+
{/* <Header className="bg-transparent">
41+
<Header.Left />
42+
<Header.Right>
43+
<Header.Button>
44+
<CloseIcon32 />
45+
</Header.Button>
46+
</Header.Right>
47+
</Header> */}
48+
49+
<h2 className="serif-title-24-M px-5 text-[#222222]">
50+
보고싶은 마음이
51+
<br />
52+
도착했어요
53+
</h2>
54+
55+
<div className="relative mt-[70px] flex flex-col items-center justify-center">
56+
<div className="flex justify-center">{data && <Card proposalData={data.data} />}</div>
57+
58+
<div
59+
className={cn(
60+
'ease-outmotion-reduce:transition-none absolute bottom-[-100px] left-1/2 h-[421px] w-[408px] -translate-x-1/2 transition-transform duration-1000',
61+
slideDown ? 'translate-y-52' : 'translate-y-0'
62+
)}
63+
style={{ willChange: 'transform', transitionDelay: '150ms' }}
64+
>
65+
<div className="relative size-full">
66+
<div className="absolute inset-0 z-0">
67+
<CardFrame />
68+
</div>
69+
70+
<div className="serif-body-16-M absolute bottom-[100px] left-1/2 z-[1] -translate-x-1/2 text-center text-gray-900">
71+
{data.data.gatheringName}
72+
<br />
73+
친구들에게
74+
</div>
75+
</div>
76+
</div>
77+
</div>
78+
</div>
79+
);
80+
};
81+
82+
export default GatheringProposal;
83+
84+
const Card = ({ proposalData }: { proposalData: ProposalItemType }) => {
85+
const purposeLines = (proposalData.purpose ?? '').split('\n').filter(Boolean).slice(0, 3);
86+
87+
return (
88+
<div className="h-[368px] w-[278px] rounded-[10px] bg-gray-50 pt-4">
89+
<div className="flex flex-col items-center">
90+
<QuoteIcon />
91+
<h3 className="serif-body-16-M mt-[65px] text-gray-900">말이 안되는거 알지만</h3>
92+
</div>
93+
<div className="px-9">
94+
<p className="serif-body-16-M mt-[22px] text-gray-900">우리</p>
95+
<div className="mt-[15px] flex flex-col gap-[5px]">
96+
{purposeLines.map((line, i) => (
97+
<p key={i} className="serif-body-16-M text-gray-900">
98+
{line}
99+
</p>
100+
))}
101+
</div>
102+
<p className="serif-body-16-M mt-[15px] text-gray-900">어때</p>
103+
</div>
104+
</div>
105+
);
106+
};
107+
108+
const CardFrame = () => {
109+
return (
110+
<svg
111+
xmlns="http://www.w3.org/2000/svg"
112+
width="408"
113+
height="421"
114+
viewBox="0 0 408 421"
115+
fill="none"
116+
>
117+
<foreignObject x="0" y="0" width="408" height="421">
118+
<div
119+
style={{
120+
backdropFilter: 'blur(15px)',
121+
clipPath: 'url(#bgblur_0_2340_21174_clip_path)',
122+
height: '100%',
123+
width: '100%',
124+
}}
125+
/>
126+
</foreignObject>
127+
<g filter="url(#filter0_d_2340_21174)" data-figma-bg-blur-radius="30">
128+
<mask id="path-1-inside-1_2340_21174" fill="white">
129+
<path d="M348 46C353.523 46 358 50.4772 358 56V357C358 362.523 353.523 367 348 367H60C54.4772 367 50 362.523 50 357V56C50 50.4772 54.4772 46 60 46H166.428C171.924 46 176.216 50.5948 178.305 55.6788C182.543 65.9967 193.239 73.3201 205.766 73.3203C218.293 73.3203 228.989 65.9968 233.227 55.6788C235.316 50.5948 239.609 46 245.105 46H348Z" />
130+
</mask>
131+
<path
132+
d="M348 46C353.523 46 358 50.4772 358 56V357C358 362.523 353.523 367 348 367H60C54.4772 367 50 362.523 50 357V56C50 50.4772 54.4772 46 60 46H166.428C171.924 46 176.216 50.5948 178.305 55.6788C182.543 65.9967 193.239 73.3201 205.766 73.3203C218.293 73.3203 228.989 65.9968 233.227 55.6788C235.316 50.5948 239.609 46 245.105 46H348Z"
133+
fill="url(#paint0_linear_2340_21174)"
134+
fillOpacity="0.2"
135+
shapeRendering="crispEdges"
136+
/>
137+
<path
138+
d="M348 46V45V46ZM358 56H359H358ZM358 357H359H358ZM348 367V368V367ZM60 367V368V367ZM50 357H49H50ZM50 56L49 56V56H50ZM60 46V45V46ZM205.766 73.3203L205.766 74.3203H205.766V73.3203ZM178.305 55.6788L179.23 55.2988L178.305 55.6788ZM348 46V47C352.971 47 357 51.0294 357 56H358H359C359 49.9249 354.075 45 348 45V46ZM358 56H357V357H358H359V56H358ZM358 357H357C357 361.971 352.971 366 348 366V367V368C354.075 368 359 363.075 359 357H358ZM348 367V366H60V367V368H348V367ZM60 367V366C55.0294 366 51 361.971 51 357H50H49C49 363.075 53.9249 368 60 368V367ZM50 357H51V56H50H49V357H50ZM50 56L51 56C51 51.0294 55.0294 47 60 47V46V45C53.9249 45 49 49.9249 49 56L50 56ZM60 46V47H166.428V46V45H60V46ZM178.305 55.6788L177.38 56.0587C181.779 66.7682 192.851 74.3201 205.766 74.3203L205.766 73.3203L205.766 72.3203C193.626 72.3201 183.307 65.2252 179.23 55.2988L178.305 55.6788ZM205.766 73.3203V74.3203C218.68 74.3203 229.753 66.7683 234.152 56.0587L233.227 55.6788L232.302 55.2988C228.225 65.2253 217.905 72.3203 205.766 72.3203V73.3203ZM245.105 46V47H348V46V45H245.105V46ZM233.227 55.6788L234.152 56.0587C236.175 51.134 240.205 47 245.105 47V46V45C239.012 45 234.456 50.0556 232.302 55.2988L233.227 55.6788ZM166.428 46V47C171.327 47 175.357 51.134 177.38 56.0587L178.305 55.6788L179.23 55.2988C177.076 50.0556 172.521 45 166.428 45V46Z"
139+
fill="url(#paint1_linear_2340_21174)"
140+
mask="url(#path-1-inside-1_2340_21174)"
141+
/>
142+
</g>
143+
<defs>
144+
<filter
145+
id="filter0_d_2340_21174"
146+
x="0"
147+
y="0"
148+
width="408"
149+
height="421"
150+
filterUnits="userSpaceOnUse"
151+
colorInterpolationFilters="sRGB"
152+
>
153+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
154+
<feColorMatrix
155+
in="SourceAlpha"
156+
type="matrix"
157+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
158+
result="hardAlpha"
159+
/>
160+
<feOffset dy="4" />
161+
<feGaussianBlur stdDeviation="25" />
162+
<feComposite in2="hardAlpha" operator="out" />
163+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" />
164+
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2340_21174" />
165+
<feBlend
166+
mode="normal"
167+
in="SourceGraphic"
168+
in2="effect1_dropShadow_2340_21174"
169+
result="shape"
170+
/>
171+
</filter>
172+
<clipPath id="bgblur_0_2340_21174_clip_path" transform="translate(0 0)">
173+
<path d="M348 46C353.523 46 358 50.4772 358 56V357C358 362.523 353.523 367 348 367H60C54.4772 367 50 362.523 50 357V56C50 50.4772 54.4772 46 60 46H166.428C171.924 46 176.216 50.5948 178.305 55.6788C182.543 65.9967 193.239 73.3201 205.766 73.3203C218.293 73.3203 228.989 65.9968 233.227 55.6788C235.316 50.5948 239.609 46 245.105 46H348Z" />
174+
</clipPath>
175+
<linearGradient
176+
id="paint0_linear_2340_21174"
177+
x1="204"
178+
y1="46"
179+
x2="204"
180+
y2="367"
181+
gradientUnits="userSpaceOnUse"
182+
>
183+
<stop stopColor="white" />
184+
<stop offset="1" stopColor="white" />
185+
</linearGradient>
186+
<linearGradient
187+
id="paint1_linear_2340_21174"
188+
x1="50"
189+
y1="373.999"
190+
x2="334.88"
191+
y2="27.0176"
192+
gradientUnits="userSpaceOnUse"
193+
>
194+
<stop stopColor="#E1E1E1" />
195+
<stop offset="1" stopColor="white" stopOpacity="0.2" />
196+
</linearGradient>
197+
</defs>
198+
</svg>
199+
);
200+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import GatheringProposal from '@/app/proposal/[proposalId]/detail/components/GatheringProposal';
2+
3+
export default function GathringProposalPage() {
4+
return <GatheringProposal />;
5+
}

apps/tuk-web/src/shared/lib/api/rest/index.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,26 @@ import { getBridgeSender } from '@/shared/lib/app-bridge/bridgeSender';
66
export { RestAPI } from './rest';
77
export type { RestAPIConfig, RestAPIProtocol } from './types';
88

9+
// const defaultJsonInstance = (baseURL: string) =>
10+
// new RestAPIInstance(baseURL, {
11+
// withCredentials: false,
12+
// authHeader: () => {
13+
// if (typeof window === 'undefined') return null;
14+
// const token = sessionStorage.getItem('accessToken');
15+
// return token ? { Authorization: `Bearer ${token}` } : null;
16+
// },
17+
// bridgeSend: msg => getBridgeSender()?.(msg),
18+
// });
19+
920
const defaultJsonInstance = (baseURL: string) =>
1021
new RestAPIInstance(baseURL, {
1122
withCredentials: false,
1223
authHeader: () => {
1324
if (typeof window === 'undefined') return null;
14-
const token = sessionStorage.getItem('accessToken');
15-
return token ? { Authorization: `Bearer ${token}` } : null;
25+
const token =
26+
'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIzMiIsIm1lbWJlcklkIjoiMzIiLCJ0b2tlblR5cGUiOiJBQ0NFU1MiLCJpYXQiOjE3NTUwMDM4NTQsImV4cCI6MTc1NzU5NTg1NH0.sXHpNsim8-nIUdCjnAcOIZGsg2gUo8rnpkBmN-z5dKU';
27+
return token ? { Authorization: `Bearer ${token.trim()}` } : null;
1628
},
17-
bridgeSend: msg => getBridgeSender()?.(msg),
1829
});
1930

2031
const formInstance = (baseURL: string) =>

0 commit comments

Comments
 (0)