Files
saju-web/app/fortune/page.tsx
2026-02-17 08:15:41 +09:00

246 lines
11 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Link from 'next/link';
import { calculateSaju } from '@/lib/saju-calculator';
import PDFButton from '../components/PDFButton';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
interface PageProps {
searchParams: Promise<{
year: string;
month: string;
day: string;
hour?: string;
gender: 'male' | 'female';
calendarType: 'solar' | 'lunar';
}>;
}
export default async function FortunePage({ searchParams }: PageProps) {
const params = await searchParams;
const { year, month, day, hour, gender } = params;
const yearNum = parseInt(year);
const monthNum = parseInt(month);
const dayNum = parseInt(day);
const hourNum = hour ? parseInt(hour) : null;
const sajuData = calculateSaju(yearNum, monthNum, dayNum, hourNum, gender);
// 오늘 날짜
const today = new Date();
const todayYear = today.getFullYear();
const todayMonth = today.getMonth() + 1;
const todayDay = today.getDate();
// 오늘의 간지 계산 (시간은 12시로 고정)
const todayGanzi = calculateSaju(todayYear, todayMonth, todayDay, 12, gender);
// 안전하게 stem 접근
const todayStem = todayGanzi?.day?.stem || '甲';
const todayBranch = todayGanzi?.day?.branch || '子';
const userStem = sajuData?.day?.stem || '甲';
// 운세 점수 계산 (간단한 알고리즘)
const calculateFortuneScore = (category: string): number => {
const seed = userStem.charCodeAt(0) + todayStem.charCodeAt(0) + category.charCodeAt(0);
return 60 + (seed % 40);
};
const fortuneCategories = [
{ name: '종합운', icon: '⭐', score: calculateFortuneScore('종합'), color: 'bg-gradient-to-r from-[#173658] to-[#1e426a]' },
{ name: '금전운', icon: '💰', score: calculateFortuneScore('금전'), color: 'bg-gradient-to-r from-green-600 to-emerald-600' },
{ name: '애정운', icon: '💕', score: calculateFortuneScore('애정'), color: 'bg-gradient-to-r from-pink-600 to-rose-600' },
{ name: '건강운', icon: '🏥', score: calculateFortuneScore('건강'), color: 'bg-gradient-to-r from-red-600 to-orange-600' },
{ name: '직장운', icon: '💼', score: calculateFortuneScore('직장'), color: 'bg-gradient-to-r from-blue-600 to-cyan-600' },
{ name: '학업운', icon: '📚', score: calculateFortuneScore('학업'), color: 'bg-gradient-to-r from-purple-600 to-indigo-600' },
];
const getScoreText = (score: number): string => {
if (score >= 90) return '최고';
if (score >= 80) return '좋음';
if (score >= 70) return '보통';
if (score >= 60) return '주의';
return '나쁨';
};
const getScoreColor = (score: number): string => {
if (score >= 90) return 'text-green-600';
if (score >= 80) return 'text-blue-600';
if (score >= 70) return 'text-yellow-600';
if (score >= 60) return 'text-orange-600';
return 'text-red-600';
};
// 행운의 방향과 색깔 (일간 기준)
const getLuckyDirection = (stem: string): string => {
const directions: { [key: string]: string } = {
'甲': '동쪽', '乙': '동쪽',
'丙': '남쪽', '丁': '남쪽',
'戊': '중앙', '己': '중앙',
'庚': '서쪽', '辛': '서쪽',
'壬': '북쪽', '癸': '북쪽',
};
return directions[stem] || '동쪽';
};
const getLuckyColor = (element: string): string => {
const colors: { [key: string]: string } = {
'木': '녹색',
'火': '빨강색',
'土': '노란색',
'金': '흰색',
'水': '검정색',
};
return colors[element] || '녹색';
};
const getLuckyNumber = (stem: string): number => {
return (stem.charCodeAt(0) % 9) + 1;
};
return (
<div className="min-h-screen bg-[#F3E7E3]">
<Header />
{/* Content */}
<div id="pdf-content" className="container-custom pt-24 pb-12">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-3xl md:text-4xl font-bold text-[#173658] mb-4">
</h1>
<p className="text-xl text-[#5d6d7e]">
{todayYear} {todayMonth} {todayDay} ({todayStem}{todayBranch})
</p>
<p className="text-lg text-[#5d6d7e] mt-2">
{sajuData.birthDate.year} {gender === 'male' ? '남성' : '여성'}
</p>
</div>
{/* 운세 점수 카드들 */}
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
{fortuneCategories.map((category) => (
<div key={category.name} className="glass-panel-light rounded-2xl p-6 card-hover">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-3">
<span className="text-4xl">{category.icon}</span>
<h3 className="text-xl font-bold text-[#173658]">{category.name}</h3>
</div>
<span className={`text-2xl font-bold ${getScoreColor(category.score)}`}>
{category.score}
</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-3 mb-2">
<div
className={`${category.color} h-3 rounded-full transition-all duration-500`}
style={{ width: `${category.score}%` }}
></div>
</div>
<p className="text-sm text-[#5d6d7e] text-right font-bold">{getScoreText(category.score)}</p>
</div>
))}
</div>
{/* 오늘의 한마디 */}
<div className="bg-gradient-to-r from-[#173658] to-[#1e426a] rounded-2xl p-8 md:p-12 mb-8 text-white pattern-overlay">
<h2 className="text-2xl md:text-3xl font-bold mb-6 text-center">💬 </h2>
<p className="text-lg md:text-xl leading-relaxed text-center">
{sajuData.day.element === '木' && '나무가 자라듯 꾸준히 노력하면 좋은 결과가 있을 것입니다. 새로운 시작에 좋은 날입니다.'}
{sajuData.day.element === '火' && '활발한 기운이 가득한 날입니다. 적극적으로 행동하면 좋은 기회를 잡을 수 있습니다.'}
{sajuData.day.element === '土' && '안정적인 하루가 될 것입니다. 차근차근 계획을 세우고 실행하면 좋습니다.'}
{sajuData.day.element === '金' && '명확한 판단이 필요한 날입니다. 원칙을 지키며 행동하면 좋은 결과가 있을 것입니다.'}
{sajuData.day.element === '水' && '유연한 사고가 도움이 되는 날입니다. 주변 사람들과의 소통을 중요하게 여기세요.'}
</p>
</div>
{/* 행운의 요소들 */}
<div className="grid md:grid-cols-3 gap-6 mb-8">
{/* 행운의 방향 */}
<div className="glass-panel-light rounded-2xl p-8 text-center card-hover">
<div className="text-5xl mb-4">🧭</div>
<h3 className="text-2xl font-bold text-[#173658] mb-3"> </h3>
<p className="text-3xl font-bold text-[#d4af37]">{getLuckyDirection(userStem)}</p>
<p className="text-sm text-[#5d6d7e] mt-2"> </p>
</div>
{/* 행운의 색깔 */}
<div className="glass-panel-light rounded-2xl p-8 text-center card-hover">
<div className="text-5xl mb-4">🎨</div>
<h3 className="text-2xl font-bold text-[#173658] mb-3"> </h3>
<p className="text-3xl font-bold text-[#d4af37]">{getLuckyColor(sajuData.day.element)}</p>
<p className="text-sm text-[#5d6d7e] mt-2"> </p>
</div>
{/* 행운의 숫자 */}
<div className="glass-panel-light rounded-2xl p-8 text-center card-hover">
<div className="text-5xl mb-4">🎲</div>
<h3 className="text-2xl font-bold text-[#173658] mb-3"> </h3>
<p className="text-3xl font-bold text-[#d4af37]">{getLuckyNumber(userStem)}</p>
<p className="text-sm text-[#5d6d7e] mt-2"> </p>
</div>
</div>
{/* 주의사항 */}
<div className="glass-panel-light rounded-2xl p-8 mb-8">
<h3 className="text-2xl font-bold text-[#173658] mb-6 flex items-center">
<span className="text-3xl mr-3"></span>
</h3>
<ul className="space-y-3 text-[#5d6d7e]">
<li className="flex items-start">
<span className="text-[#d4af37] mr-2 font-bold"></span>
<span> .</span>
</li>
<li className="flex items-start">
<span className="text-[#d4af37] mr-2 font-bold"></span>
<span> .</span>
</li>
<li className="flex items-start">
<span className="text-[#d4af37] mr-2 font-bold"></span>
<span> .</span>
</li>
</ul>
</div>
{/* 다른 메뉴 */}
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-4">
<Link
href={`/result?${new URLSearchParams(params as any).toString()}`}
className="glass-panel-light rounded-xl p-6 card-hover text-center"
>
<div className="text-4xl mb-3">📜</div>
<h3 className="text-lg font-bold text-[#173658] mb-1"></h3>
<p className="text-[#5d6d7e] text-sm"> </p>
</Link>
<Link
href="/compatibility"
className="glass-panel-light rounded-xl p-6 card-hover text-center"
>
<div className="text-4xl mb-3">💕</div>
<h3 className="text-lg font-bold text-[#173658] mb-1"> </h3>
<p className="text-[#5d6d7e] text-sm"> </p>
</Link>
<Link
href="/tojeong"
className="glass-panel-light rounded-xl p-6 card-hover text-center"
>
<div className="text-4xl mb-3">🎋</div>
<h3 className="text-lg font-bold text-[#173658] mb-1"></h3>
<p className="text-[#5d6d7e] text-sm"> </p>
</Link>
<PDFButton
elementId="pdf-content"
filename={`오늘의운세_${todayYear}${todayMonth}${todayDay}.pdf`}
buttonText="PDF 저장"
/>
</div>
</div>
<Footer />
</div>
);
}