import React, { useState, useEffect, useRef } from 'react'; import { PiggyBank, Utensils, ArrowLeft, RefreshCw, Wallet, ChefHat } from 'lucide-react'; // --- API 설정 및 헬퍼 함수 --- const apiKey = ""; // 실행 환경에서 주입됨 const generateContent = async (prompt, systemInstruction) => { const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-09-2025:generateContent?key=${apiKey}`; const payload = { contents: [{ parts: [{ text: prompt }] }], systemInstruction: { parts: [{ text: systemInstruction }] }, }; const attemptFetch = async (retries = 5, delay = 1000) => { try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const data = await response.json(); return data.candidates?.[0]?.content?.parts?.[0]?.text || "결과를 불러올 수 없습니다."; } catch (error) { if (retries === 0) throw error; await new Promise((resolve) => setTimeout(resolve, delay)); return attemptFetch(retries - 1, delay * 2); } }; return attemptFetch(); }; // --- 랜덤 저축 멘트 리스트 --- const quotes = [ "딱 {amt}원만 넣어볼까요? 습관적으로 마시는 카페 라떼 한 잔 대신 시원한 물 한 잔으로 건강과 돈을 모두 챙겨봐요.", "오늘의 저축액은 {amt}원. 무심코 집어 들던 마이쮸나 젤리 하나만 포기해도 당신의 통장은 웃게 됩니다. 티끌모아 태산!", "{amt}원 저축 도전! 배달 음식의 '배달 팁'만 아껴도 이만큼이 모여요. 오늘은 직접 픽업하러 가는 건 어떨까요?", "오늘은 {amt}원을 파킹통장에 넣어보세요. 다이소에서 '그냥 예뻐서' 샀던 소품들이 사실은 통장 구멍의 주범일지 몰라요.", "{amt}원 저축! 가까운 거리는 버스 대신 걸으면서 '공짜 유산소 운동'을 했다고 생각하면 기분이 더 좋아질 거예요.", "오늘은 {amt}원 세이브. 세일한다고 산 '한 철용' 저가 의류보다, 차곡차곡 모인 이 자본이 당신의 미래를 더 빛나게 할 거예요.", "강의실 가기 전 {amt}원 저축! 학교 자판기 음료수 대신 텀블러를 챙기는 것만으로도 '갓생'에 한 걸음 더 다가갈 수 있어요.", "오늘은 {amt}원 저축 어때요? 고칼로리 편의점 도시락보다 가벼운 식단으로 바디 관리와 자산 관리를 동시에 시작하세요.", "딱 {amt}원만 파킹통장으로! 스마트폰 케이스를 바꿀까 고민하던 그 마음을 숫자로 바꿔보세요.", "오늘의 미션: {amt}원 저축. 야식 한 번만 참아도 내일 아침의 몸무게와 통장 잔고가 모두 가벼워질 거예요.", "{amt}원 저축하세요! 유행하는 두쫀쿠 대신 건강한 차 한잔으로 타협해 보는 건 어떨까요?", "{amt}원 저축! 혹시 보지도 않으면서 매달 결제되는 구독 서비스가 있진 않나요? 지금 정리하면 매달 이만큼이 공짜로 생겨요.", "오늘은 {amt}원을 넣어보세요. 비 올 때 무심코 샀던 편의점 간식 값이에요.", "{amt}원 저축 도전! 이미 화장대에 가득한 비슷한 색깔의 립밤이나 화장품, 더 늘리지 않아도 충분히 아름다워요." ]; const getSavingsQuote = (amount) => { if (amount <= 5000 && Math.random() < 0.3) { return `오늘은 ${amount.toLocaleString()}원을 저축해 보세요! 편의점 음료수의 유혹만 참아도 충분히 가능한 금액이에요.`; } const q = quotes[Math.floor(Math.random() * quotes.length)]; return q.replace(/{amt}/g, amount.toLocaleString()); }; // --- 컴포넌트 --- export default function App() { const [view, setView] = useState('home'); // 'home', 'savings', 'recipe' const [maxAmount, setMaxAmount] = useState(5000); const [savedAmount, setSavedAmount] = useState(null); const [quote, setQuote] = useState(null); const [ingredients, setIngredients] = useState(""); const [recipeResult, setRecipeResult] = useState(null); const [loading, setLoading] = useState(false); // 로딩 초기화 및 뷰 전환 헬퍼 const navigateTo = (target) => { setView(target); setLoading(false); setSavedAmount(null); setQuote(null); setRecipeResult(null); }; const handleRandomSave = () => { setLoading(true); setSavedAmount(null); // 로딩 물채우기 애니메이션을 보여주기 위한 딜레이 (2.5초) setTimeout(() => { const minAmount = 500; // 100원 단위로 랜덤 추출 const steps = Math.floor((maxAmount - minAmount) / 100); const randomStep = Math.floor(Math.random() * (steps + 1)); const amount = minAmount + (randomStep * 100); setSavedAmount(amount); setQuote(getSavingsQuote(amount)); setLoading(false); }, 2500); }; const handleRecipeRecommend = async () => { if (!ingredients.trim()) return; setLoading(true); setRecipeResult(null); const systemInstruction = `너는 사용자의 냉장고 속에 남은 식재료를 분석하여 가장 현실적이고 맛있는 식단을 제안하는 '스마트 홈셰프'야. 사용자의 목표는 남은 재료를 버리지 않고 활용하는 것이며, 요리 과정은 최대한 간단해야 해. [핵심 원칙] 1. 선택적 조합: 입력된 모든 재료를 한꺼번에 다 쓸 필요는 없어. 궁합이 맞는 재료끼리 묶어서 1~3가지의 서로 다른 식단 옵션을 제안해줘. 2. 기본 양념 허용: 간장, 설탕, 소금, 식용유, 마늘, 고추장 등 일반적인 가정집에 있을 법한 기본 양념은 재료 목록에 없어도 사용하는 것으로 간주해. 3. 난이도 조절: 1인 가구나 대학생도 쉽게 따라 할 수 있는 간단한 조리법 위주로 생각할 것. 4. 설명 추가: 단순히 메뉴 이름만 말하지 말고, 왜 그 재료들을 선택했는지 한 줄 설명을 덧붙여줘. [입출력 예시] 입력: [두부, 김치, 스팸, 양파] 추천 1: 스팸 김치 짜글이 (스팸의 짭짤함과 김치의 산미가 어우러져 밥 한 공기 뚝딱 할 수 있는 최고의 메뉴예요.) 추천 2: 두부 김치 두루치기 (두부를 데치고 볶은 김치를 곁들이면 건강하면서도 든든한 한 끼가 됩니다.) 입력: [토마토, 계란, 낙지, 쭈꾸미, 고추, 칼국수면] 추천 1: 토마토 달걀 볶음 (토달볶) (재료가 없을 때 가장 가볍고 영양가 있게 즐길 수 있는 중식 스타일의 한 끼예요.) 추천 2: 매콤 쭈꾸미 비빔 칼국수 (쭈꾸미와 고추를 볶아 매콤한 양념을 만든 뒤, 삶은 칼국수 면을 비벼 먹으면 별미예요.) 추천 3: 낙지 연포탕 스타일 칼국수 (낙지와 고추를 넣어 시원하고 칼칼한 국물을 낸 뒤 칼국수 면을 넣어 끓여보세요.)`; const prompt = `냉장고 재료: [${ingredients}]\n이 재료들로 만들 수 있는 간단하고 맛있는 무지출 식단을 추천해줘.`; try { const result = await generateContent(prompt, systemInstruction); setRecipeResult(result); } catch (error) { setRecipeResult("오류가 발생했습니다. 잠시 후 다시 시도해주세요."); } finally { setLoading(false); } }; return (
{/* CSS Styles for Water Loading Animation and Custom Slider */}