Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions apps/what-today/src/components/activities/ActivitiesReview.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { StarIcon } from '@what-today/design-system';
import { motion } from 'motion/react';

import { type ActivityReview } from '@/schemas/activityReview';
interface ActivitiesReviewProps {
Expand All @@ -20,16 +21,25 @@ export default function ActivitiesReview({ review }: ActivitiesReviewProps) {
});

return (
<div className='rounded-xl border border-gray-50 px-20 py-20'>
<div className='mb-4 flex items-center gap-8'>
<div className='body-text font-bold'>{user.nickname}</div>
<div className='caption-text text-gray-400'>{formattedDate}</div>
</div>
<div className='mb-12'>
<RatingStars rating={rating} />
<motion.div
key={review.id}
initial={{ opacity: 0, y: 80 }}
transition={{ duration: 1 }}
viewport={{ once: true, amount: 0.1 }}
whileInView={{ opacity: 1, y: 0 }}
>
<div className='mb-20 rounded-xl border border-gray-50 px-20 py-20'>
<div className='mb-4 flex items-center gap-8'>
<div className='body-text font-bold'>{user.nickname}</div>
<div className='caption-text text-gray-400'>{formattedDate}</div>
</div>
<div className='mb-12'>
<RatingStars rating={rating} />
</div>
<p className='body-text whitespace-pre-wrap'>{content}</p>

</div>
<p className='body-text whitespace-pre-wrap'>{content}</p>
</div>
</motion.div>
);
}

Expand Down
61 changes: 39 additions & 22 deletions apps/what-today/src/pages/main/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
TourIcon,
WellbeingIcon,
} from '@what-today/design-system';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { motion } from 'motion/react';
import { useCallback, useEffect, useLayoutEffect, useMemo, useState } from 'react';
import React from 'react';
import { useNavigate } from 'react-router-dom';

Expand Down Expand Up @@ -55,6 +56,17 @@ export default function MainPage() {
const [selectedCategory, setSelectedCategory] = useState<string | number>('');
const navigate = useNavigate();

useLayoutEffect(() => {
if ('scrollRestoration' in window.history) {
window.history.scrollRestoration = 'manual';
}
}, []);

// 페이지 마운트 시 무조건 맨 위로
useLayoutEffect(() => {
window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
}, []);

// 반응형 카드 수
const handleResize = useCallback(() => {
setItemsPerPage(getCount());
Expand Down Expand Up @@ -124,7 +136,9 @@ export default function MainPage() {
// 이벤트 핸들러
const handlePageChange = useCallback(
(page: number) => {
if (page !== currentPage) setCurrentPage(page);
if (page !== currentPage) {
setCurrentPage(page);
}
},
[currentPage],
);
Expand All @@ -148,28 +162,10 @@ export default function MainPage() {
setCurrentPage(1);
}, []);

// 카드 렌더링 최적화
const renderCards = useCallback(() => {
return pagedItems.map((item, idx) => (
<MemoizedMainCard
key={`${item.id}-${currentPage}-${idx}`}
bannerImageUrl={item.bannerImageUrl}
category={item.category}
price={item.price}
rating={item.rating}
reviewCount={item.reviewCount}
title={item.title}
onClick={() => navigate(`/activities/${item.id}`)}
>
<MainCard.Image />
<MainCard.Content />
</MemoizedMainCard>
));
}, [pagedItems, currentPage, navigate]);

return (
<>
<div className='to-primary-500/40 absolute top-0 left-0 h-1/2 w-full bg-gradient-to-t from-transparent' />

<div className='relative z-10 flex h-auto flex-col gap-60'>
<MainBanner />

Expand Down Expand Up @@ -252,7 +248,28 @@ export default function MainPage() {
<NoResult />
</div>
) : (
renderCards()
pagedItems.map((item) => (
<motion.div
key={item.id}
initial={{ opacity: 0, y: 100 }}
transition={{ duration: 1 }}
viewport={{ once: true, amount: 0.1 }}
whileInView={{ opacity: 1, y: 0 }}
>
<MemoizedMainCard
bannerImageUrl={item.bannerImageUrl}
category={item.category}
price={item.price}
rating={item.rating}
reviewCount={item.reviewCount}
title={item.title}
onClick={() => navigate(`/activities/${item.id}`)}
>
<MainCard.Image />
<MainCard.Content />
</MemoizedMainCard>
</motion.div>
))
)}
</div>

Expand Down
36 changes: 22 additions & 14 deletions apps/what-today/src/pages/mypage/manage-activities/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useToast,
WarningLogo,
} from '@what-today/design-system';
import { motion } from 'motion/react';
import { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';

Expand Down Expand Up @@ -88,20 +89,27 @@ export default function ManageActivitiesPage() {
content = (
<>
{allActivities.map(({ id, title, price, bannerImageUrl, rating, reviewCount }) => (
<ExperienceCard
<motion.div
key={id}
bannerImageUrl={bannerImageUrl}
price={price}
rating={rating}
reviewCount={reviewCount}
title={title}
onDelete={() => {
setDeleteTargetId(id);
setIsDeleteOpen(true);
}}
onEdit={() => navigate(`/experiences/create/${id}`)}
onNavigate={() => navigate(`/activities/${id}`)}
/>
initial={{ opacity: 0, y: 80 }}
transition={{ duration: 1 }}
viewport={{ once: true, amount: 0.2 }}
whileInView={{ opacity: 1, y: 0 }}
>
<ExperienceCard
bannerImageUrl={bannerImageUrl}
price={price}
rating={rating}
reviewCount={reviewCount}
title={title}
onDelete={() => {
setDeleteTargetId(id);
setIsDeleteOpen(true);
}}
onEdit={() => navigate(`/experiences/create/${id}`)}
onNavigate={() => navigate(`/activities/${id}`)}
/>
</motion.div>
))}
<div ref={observerRef} />
{isFetchingNextPage && <div className='text-center text-gray-400'>체험목록 불러오는 중...</div>}
Expand All @@ -125,7 +133,7 @@ export default function ManageActivitiesPage() {
</Button>
</div>
</header>
<section aria-label='체험 카드 목록' className='flex flex-col gap-12'>
<section aria-label='체험 카드 목록' className='flex flex-col gap-12 overflow-y-hidden'>
{content}
</section>
<Modal.Root open={isDeleteOpen} onClose={() => setIsDeleteOpen(false)}>
Expand Down
2 changes: 1 addition & 1 deletion packages/design-system/src/components/skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { default as ExperienceCardSkeleton } from './ExperienceCardSkeleton';
export { default as NotificationCardSkeleton } from './NotificationCardSkeleton';
export { default as OngoingExperienceCardSkeleton } from './OngoingExperienceCardSkeleton';
export { default as UpcomingScheduleItemSkeleton } from './UpcomingScheduleItemSkeleton';
export { default as NotificationCardSkeleton } from './NotificationCardSkeleton';
6 changes: 3 additions & 3 deletions packages/design-system/src/pages/OngoingExperienceCardDoc.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import OngoingExperienceCard from '../components/OngoingExperienceCard';
// import OngoingExperienceCard from '../components/OngoingExperienceCard';
import DocTemplate, { DocCode } from '../layouts/DocTemplate';

/* Playground는 편집 가능한 코드 블록입니다. */
Expand Down Expand Up @@ -26,9 +26,9 @@ export default function OngoingExperienceCardDoc() {
<DocCode code={`<OngoingExperienceCard variant="primary">Click me</OngoingExperienceCard>`} />

<div className='flex gap-12'>
{/* <OngoingExperienceCard activities={[]} onClick={() => {}} onClickActivity={() => {}} />
<OngoingExperienceCard activities={[]} onClick={() => {}} onClickActivity={() => {}} />
<OngoingExperienceCard activities={[]} onClick={() => {}} onClickActivity={() => {}} />
<OngoingExperienceCard activities={[]} onClick={() => {}} onClickActivity={() => {}} />
<OngoingExperienceCard activities={[]} onClick={() => {}} onClickActivity={() => {}} /> */}
</div>
</>
);
Expand Down
4 changes: 2 additions & 2 deletions packages/design-system/src/pages/UpcomingScheduleDoc.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import UpcomingSchedule from '@/components/UpcomingSchedule';
// import UpcomingSchedule from '@/components/UpcomingSchedule';

import DocTemplate, { DocCode } from '../layouts/DocTemplate';

Expand Down Expand Up @@ -26,7 +26,7 @@ export default function UpcomingScheduleDoc() {
{/* 예시 코드 */}
<DocCode code={`<UpcomingSchedule variant="primary">Click me</UpcomingSchedule>`} />

<UpcomingSchedule reservation={[]} onClickReservation={() => {}} />
{/* <UpcomingSchedule reservation={[]} onClickReservation={() => {}} /> */}
</>
);
}