Skip to content
79 changes: 75 additions & 4 deletions app/baby/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { useState, useEffect } from "react"
import { useRouter } from "next/navigation"
import { useState, useEffect, Suspense } from "react"
import { useRouter, useSearchParams } from "next/navigation"
import Container from "../components/Container"
import { useChild } from "../contexts/ChildContext"
import {
Expand Down Expand Up @@ -34,20 +34,50 @@ import ErrorMessage from "../components/ErrorMessage"
import EmptyState from "../components/EmptyState"
import TimeSlotSelector from "../components/TimeSlotSelector"
import DiaryCard from "../components/DiaryCard"
import EmotionForecastPopup from "../components/EmotionForecastPopup"
import EmotionResultPopup from "../components/EmotionResultPopup"

// 공통 타입 사용

export default function Present() {
function BabyPageContent() {
const router = useRouter()
const searchParams = useSearchParams()
const { selectedChild, isLoading } = useChild()
const [selectedDate, setSelectedDate] = useState<string | null>(null)
const [selectedTimeSlot, setSelectedTimeSlot] = useState<TimeSlot>('morning')
const [currentMonth, setCurrentMonth] = useState(new Date())
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const [forecastData, setForecastData] = useState<Record<string, any>>({})
const [showForecastPopup, setShowForecastPopup] = useState(false)
const [showRecordPopup, setShowRecordPopup] = useState(false)
const [popupEmotions, setPopupEmotions] = useState<any[]>([])


// URL 파라미터 확인하여 팝업 표시
useEffect(() => {
const showForecast = searchParams.get('showForecastPopup')
const showRecord = searchParams.get('showRecordPopup')

if (showForecast === 'true') {
const savedEmotions = localStorage.getItem('forecastEmotions')
if (savedEmotions) {
const emotions = JSON.parse(savedEmotions)
setPopupEmotions(emotions)
setShowForecastPopup(true)
// URL에서 파라미터 제거
router.replace('/baby')
}
} else if (showRecord === 'true') {
const savedEmotions = localStorage.getItem('forecastRecordEmotions')
if (savedEmotions) {
const emotions = JSON.parse(savedEmotions)
setPopupEmotions(emotions)
setShowRecordPopup(true)
// URL에서 파라미터 제거
router.replace('/baby')
}
}
}, [searchParams, router])

const isTomorrow = (date: Date) => {
const tomorrow = new Date();
Expand Down Expand Up @@ -524,6 +554,47 @@ export default function Present() {
{/* 하단 여백 */}
<div className="h-8"></div>

{/* 예보 결과 팝업 */}
<EmotionForecastPopup
isOpen={showForecastPopup}
onClose={() => {
setShowForecastPopup(false);
localStorage.removeItem('forecastEmotions'); // 저장된 감정 데이터 정리
}}
forecasts={popupEmotions.map((emotion: any) => ({
timeSlot: emotion.step,
emotion: emotion.emotion.name,
temperature: emotion.emotion.temp,
image: emotion.emotion.image,
category: emotion.category
}))}
/>

{/* 예보 기록 결과 팝업 */}
<EmotionResultPopup
isVisible={showRecordPopup}
onClose={() => {
setShowRecordPopup(false);
localStorage.removeItem('forecastRecordEmotions'); // 저장된 감정 데이터 정리
}}
emotions={popupEmotions}
/>

</Container>
)
}

export default function Present() {
return (
<Suspense fallback={
<div className="min-h-screen flex items-center justify-center bg-white">
<div className="text-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mx-auto mb-4"></div>
<p className="text-gray-600">로딩 중...</p>
</div>
</div>
}>
<BabyPageContent />
</Suspense>
);
}
26 changes: 22 additions & 4 deletions app/components/EmotionForecastPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export default function EmotionForecastPopup({ isOpen, onClose, forecasts }: Emo
const router = useRouter();
const [dragDirection, setDragDirection] = useState<'left' | 'right' | null>(null);
const [hasSwiped, setHasSwiped] = useState(false);
const [slideDirection, setSlideDirection] = useState<'left' | 'right' | null>(null);

const handleClose = () => {
onClose();
Expand Down Expand Up @@ -112,10 +113,12 @@ export default function EmotionForecastPopup({ isOpen, onClose, forecasts }: Emo

if (info.offset.x > threshold) {
// 오른쪽으로 드래그 - 이전 슬라이드
setSlideDirection('right');
setCurrentIndex((prev) => (prev - 1 + forecasts.length) % forecasts.length);
setHasSwiped(true);
} else if (info.offset.x < -threshold) {
// 왼쪽으로 드래그 - 다음 슬라이드
setSlideDirection('left');
setCurrentIndex((prev) => (prev + 1) % forecasts.length);
setHasSwiped(true);
}
Expand All @@ -133,8 +136,7 @@ export default function EmotionForecastPopup({ isOpen, onClose, forecasts }: Emo
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-black bg-opacity-40 backdrop-blur-md flex items-center justify-center z-50 p-4"
onClick={handleClose}
className="fixed inset-0 bg-black bg-opacity-20 backdrop-blur-sm flex items-center justify-center z-50 p-4"
>
<motion.div
initial={{ scale: 0.8, opacity: 0 }}
Expand All @@ -147,9 +149,15 @@ export default function EmotionForecastPopup({ isOpen, onClose, forecasts }: Emo
{/* Slide Container */}
<motion.div
key={currentIndex}
initial={{ x: 300, opacity: 0 }}
initial={{
x: slideDirection === 'left' ? 300 : slideDirection === 'right' ? -300 : 0,
opacity: 0
}}
animate={{ x: 0, opacity: 1 }}
exit={{ x: -300, opacity: 0 }}
exit={{
x: slideDirection === 'left' ? -300 : slideDirection === 'right' ? 300 : 0,
opacity: 0
}}
transition={{
type: "spring",
stiffness: 300,
Expand Down Expand Up @@ -225,6 +233,16 @@ export default function EmotionForecastPopup({ isOpen, onClose, forecasts }: Emo
)}
</motion.div>
</motion.div>

{/* 종료 버튼 */}
<div className="absolute bottom-20 left-1/2 transform -translate-x-1/2">
<button
onClick={handleClose}
className="bg-white bg-opacity-20 hover:bg-opacity-30 text-black font-medium py-3 px-6 rounded-full transition-all duration-300 backdrop-blur-sm border border-white border-opacity-30"
>
돌아가기
</button>
</div>
</motion.div>
</AnimatePresence>
);
Expand Down
Loading