feat: 절기 정밀화, AI 해석 추가, 공유 기능 개선
절기 날짜 정밀화: - solarlunar 라이브러리 추가 - 천문학적 계산 기반 정확한 절기 날짜 계산 - 각 절기별 정확한 날짜 범위 검색 - 폴백 메커니즘으로 안정성 확보 AI 상세 해석 시스템: - ai-interpretation.ts 라이브러리 생성 - 일간 기반 성격 분석 (10개 천간별 상세 해석) - 오행 균형 분석 및 점수 계산 - 십성 기반 다차원 분석 - 직업 운세 (오행 + 십성 조합) - 대인 관계 (십성 기반) - 재물 운세 (정재/편재 분석) - 건강 운세 (오행 균형) - 맞춤형 조언 생성 결과 페이지 AI 해석 섹션: - 오행 균형 시각화 (막대 그래프) - 장점/주의할 점 구분 표시 - 4가지 운세 카드 (직업/대인/재물/건강) - AI 조언 그리드 레이아웃 - 전문가 상담 권장 안내 공유 기능 개선: - localhost 감지 로직 추가 - localhost인 경우: - 카카오톡: 텍스트 형식으로 사주 정보 공유 - 링크 복사: 사주 정보 텍스트 복사 - 사용자에게 개발 환경임을 안내 - 배포 환경: 기존대로 URL 공유 - 더 나은 사용자 경험 제공 기술 개선: - solarlunar 라이브러리 (정밀 절기 계산) - 타입 안전성 강화 - 모듈화된 해석 로직 - 성능 최적화 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import ShareButtons from '../components/ShareButtons';
|
||||
import { calculateDaeun, getCurrentDaeun, getDaeunDescription } from '@/lib/daeun-calculator';
|
||||
import { getCurrentSolarTerm, getSolarTermName, getSolarTermMonthBranch } from '@/lib/solar-terms';
|
||||
import { EARTHLY_BRANCHES_KR } from '@/lib/saju-calculator';
|
||||
import { generateInterpretation, calculateElementScore } from '@/lib/ai-interpretation';
|
||||
|
||||
interface PageProps {
|
||||
searchParams: Promise<{
|
||||
@@ -34,6 +35,10 @@ export default async function ResultPage({ searchParams }: PageProps) {
|
||||
const monthBranchIndex = getSolarTermMonthBranch(yearNum, monthNum, dayNum);
|
||||
const monthBranchName = EARTHLY_BRANCHES_KR[monthBranchIndex];
|
||||
|
||||
// AI 해석 생성
|
||||
const interpretation = generateInterpretation(sajuData);
|
||||
const elementScores = calculateElementScore(sajuData);
|
||||
|
||||
// 대운 계산
|
||||
const daeunList = calculateDaeun(
|
||||
yearNum,
|
||||
@@ -246,6 +251,171 @@ export default async function ResultPage({ searchParams }: PageProps) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* AI 상세 해석 */}
|
||||
<div className="bg-gradient-to-br from-purple-50 to-indigo-50 rounded-3xl shadow-2xl p-8 md:p-12 mb-8">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-2 text-center flex items-center justify-center">
|
||||
<span className="text-4xl mr-3">🤖</span>
|
||||
AI 상세 해석
|
||||
</h2>
|
||||
<p className="text-center text-gray-600 mb-8">사주 데이터 분석 기반 맞춤 해석</p>
|
||||
|
||||
{/* 오행 균형 */}
|
||||
<div className="bg-white rounded-2xl p-6 mb-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
|
||||
<span className="text-2xl mr-2">⚖️</span>
|
||||
오행 균형
|
||||
</h3>
|
||||
<div className="grid grid-cols-5 gap-3">
|
||||
{Object.entries(elementScores).map(([element, score]) => (
|
||||
<div key={element} className="text-center">
|
||||
<div className="text-2xl font-bold mb-1">{element}</div>
|
||||
<div className="text-sm text-gray-600 mb-2">
|
||||
{element === '木' && '목'}
|
||||
{element === '火' && '화'}
|
||||
{element === '土' && '토'}
|
||||
{element === '金' && '금'}
|
||||
{element === '水' && '수'}
|
||||
</div>
|
||||
<div className="w-full bg-gray-200 rounded-full h-2 mb-1">
|
||||
<div
|
||||
className={`h-2 rounded-full ${
|
||||
element === sajuData.day.element
|
||||
? 'bg-gradient-to-r from-indigo-500 to-purple-500'
|
||||
: 'bg-gray-400'
|
||||
}`}
|
||||
style={{ width: `${score}%` }}
|
||||
></div>
|
||||
</div>
|
||||
<div className="text-xs font-semibold text-gray-700">{score}%</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 장단점 */}
|
||||
<div className="grid md:grid-cols-2 gap-6 mb-6">
|
||||
<div className="bg-white rounded-2xl p-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
|
||||
<span className="text-2xl mr-2">💪</span>
|
||||
장점
|
||||
</h3>
|
||||
<ul className="space-y-2">
|
||||
{interpretation.strengths.map((strength, i) => (
|
||||
<li key={i} className="flex items-start text-gray-700">
|
||||
<span className="text-green-600 mr-2">✓</span>
|
||||
<span>{strength}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-2xl p-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
|
||||
<span className="text-2xl mr-2">⚠️</span>
|
||||
주의할 점
|
||||
</h3>
|
||||
<ul className="space-y-2">
|
||||
{interpretation.weaknesses.map((weakness, i) => (
|
||||
<li key={i} className="flex items-start text-gray-700">
|
||||
<span className="text-orange-600 mr-2">!</span>
|
||||
<span>{weakness}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 직업, 대인관계, 재물, 건강 */}
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
{/* 직업 */}
|
||||
<div className="bg-white rounded-2xl p-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
|
||||
<span className="text-2xl mr-2">💼</span>
|
||||
직업 운세
|
||||
</h3>
|
||||
<ul className="space-y-2">
|
||||
{interpretation.career.map((item, i) => (
|
||||
<li key={i} className="flex items-start text-gray-700 text-sm">
|
||||
<span className="text-blue-600 mr-2">•</span>
|
||||
<span>{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* 대인관계 */}
|
||||
<div className="bg-white rounded-2xl p-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
|
||||
<span className="text-2xl mr-2">👥</span>
|
||||
대인 관계
|
||||
</h3>
|
||||
<ul className="space-y-2">
|
||||
{interpretation.relationships.map((item, i) => (
|
||||
<li key={i} className="flex items-start text-gray-700 text-sm">
|
||||
<span className="text-pink-600 mr-2">•</span>
|
||||
<span>{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* 재물 */}
|
||||
<div className="bg-white rounded-2xl p-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
|
||||
<span className="text-2xl mr-2">💰</span>
|
||||
재물 운세
|
||||
</h3>
|
||||
<ul className="space-y-2">
|
||||
{interpretation.wealth.map((item, i) => (
|
||||
<li key={i} className="flex items-start text-gray-700 text-sm">
|
||||
<span className="text-yellow-600 mr-2">•</span>
|
||||
<span>{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* 건강 */}
|
||||
<div className="bg-white rounded-2xl p-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
|
||||
<span className="text-2xl mr-2">🏥</span>
|
||||
건강 운세
|
||||
</h3>
|
||||
<ul className="space-y-2">
|
||||
{interpretation.health.map((item, i) => (
|
||||
<li key={i} className="flex items-start text-gray-700 text-sm">
|
||||
<span className="text-red-600 mr-2">•</span>
|
||||
<span>{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 조언 */}
|
||||
<div className="bg-white rounded-2xl p-6 mt-6">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
|
||||
<span className="text-2xl mr-2">💡</span>
|
||||
AI의 조언
|
||||
</h3>
|
||||
<div className="grid md:grid-cols-2 gap-3">
|
||||
{interpretation.advice.map((item, i) => (
|
||||
<div key={i} className="flex items-start text-gray-700 text-sm bg-indigo-50 p-3 rounded-lg">
|
||||
<span className="text-indigo-600 mr-2">→</span>
|
||||
<span>{item}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 p-4 bg-purple-100 rounded-xl">
|
||||
<p className="text-xs text-gray-700 text-center">
|
||||
💡 AI 해석은 전통 사주 이론을 기반으로 생성되었습니다. 참고용으로 활용하시고,
|
||||
중요한 결정은 전문가와 상담하시기 바랍니다.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 대운 (大運) */}
|
||||
<div className="bg-white rounded-3xl shadow-2xl p-8 md:p-12 mb-8">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-8 text-center">
|
||||
|
||||
Reference in New Issue
Block a user