fromis_9/frontend-temp/src/components/mobile/schedule/BirthdayCard.jsx

86 lines
3 KiB
React
Raw Normal View History

import { memo } from 'react';
import { motion } from 'framer-motion';
import { dayjs, decodeHtmlEntities } from '@/utils';
/**
* Mobile용 생일 카드 컴포넌트
* @param {Object} schedule - 일정 데이터
* @param {boolean} showYear - 년도 표시 여부
* @param {number} delay - 애니메이션 딜레이 ()
* @param {function} onClick - 클릭 핸들러
*/
const BirthdayCard = memo(function BirthdayCard({ schedule, showYear = false, delay = 0, onClick }) {
const scheduleDate = dayjs(schedule.date);
const formatted = {
year: scheduleDate.year(),
month: scheduleDate.month() + 1,
day: scheduleDate.date(),
};
const CardContent = (
<div className="relative overflow-hidden bg-gradient-to-r from-pink-400 via-purple-400 to-indigo-400 rounded-xl shadow-md hover:shadow-lg transition-shadow cursor-pointer">
{/* 배경 장식 */}
<div className="absolute inset-0 overflow-hidden">
<div className="absolute -top-3 -right-3 w-16 h-16 bg-white/10 rounded-full" />
<div className="absolute -bottom-4 -left-4 w-20 h-20 bg-white/10 rounded-full" />
<div className="absolute bottom-3 left-8 text-sm">🎉</div>
</div>
<div className="relative flex items-center p-4 gap-3">
{/* 멤버 사진 */}
{schedule.member_image && (
<div className="flex-shrink-0">
<div className="w-14 h-14 rounded-full border-2 border-white/50 shadow-md overflow-hidden bg-white">
<img
src={schedule.member_image}
alt={schedule.member_names}
className="w-full h-full object-cover"
/>
</div>
</div>
)}
{/* 내용 */}
<div className="flex-1 text-white flex items-center gap-2 min-w-0">
<span className="text-2xl flex-shrink-0">🎂</span>
<h3 className="font-bold text-base tracking-wide truncate">
{decodeHtmlEntities(schedule.title)}
</h3>
</div>
{/* 날짜 뱃지 (showYear가 true일 때만 표시) */}
{showYear && (
<div className="flex-shrink-0 bg-white/20 backdrop-blur-sm rounded-lg px-3 py-1.5 text-center">
<div className="text-white/70 text-[10px] font-medium">{formatted.year}</div>
<div className="text-white/70 text-[10px] font-medium">{formatted.month}</div>
<div className="text-white text-xl font-bold">{formatted.day}</div>
</div>
)}
</div>
</div>
);
// delay가 있으면 motion 사용
if (delay > 0) {
return (
<motion.div
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay, type: 'spring', stiffness: 300, damping: 30 }}
onClick={onClick}
className="cursor-pointer"
>
{CardContent}
</motion.div>
);
}
return (
<div onClick={onClick} className="cursor-pointer">
{CardContent}
</div>
);
});
export default BirthdayCard;