"use client";import { useState } from "react";import {ArrowLeft,Lightbulb,Clock,Target,TrendingUp,AlertCircle,Calculator,Flame,Gift,Home,Percent,Zap,} from "lucide-react";import { Button } from "@/components/ui/button";import {Card,CardContent,CardDescription,CardHeader,CardTitle,} from "@/components/ui/card";import { Slider } from "@/components/ui/slider";import {Select,SelectContent,SelectItem,SelectTrigger,SelectValue,} from "@/components/ui/select";import Link from "next/link";import {BarChart,Bar,XAxis,YAxis,CartesianGrid,Tooltip,ResponsiveContainer,Line,Cell,LineChart,} from "recharts";import { Switch } from "@radix-ui/react-switch";export default function ElectricSimulationPage() {const [electricReduction, setElectricReduction] = useState([10]);const [contractType, setContractType] = useState("general");//const [powerFactor, setPowerFactor] = useState([0.85])// 전기요금 절약 시뮬레이션 데이터const electricSimulation = [ { reduction: "현재", amount: 85000, savings: 0 }, { reduction: "5%", amount: 80750, savings: 4250 }, { reduction: "10%", amount: 76500, savings: 8500 }, { reduction: "15%", amount: 72250, savings: 12750 }, { reduction: "20%", amount: 68000, savings: 17000 }, { reduction: "25%", amount: 63750, savings: 21250 }, { reduction: "30%", amount: 59500, savings: 25500 }, ];// 시간대별 요금 비교const timeBasedRates = [ { time: "06-09", 일반형: 120, 심야형: 180, usage: 15 }, { time: "09-17", 일반형: 120, 심야형: 180, usage: 25 }, { time: "17-23", 일반형: 120, 심야형: 180, usage: 35 }, { time: "23-06", 일반형: 120, 심야형: 60, usage: 25 }, ];const [enabled, setEnabled] = useState(false);const [currentSeason, setCurrentSeason] = useState("winter"); // winter, summer, spring, fall// 전기요금 시뮬레이션 상태const [monthlyUsage, setMonthlyUsage] = useState([350]); // kWhconst [electricSavings, setElectricSavings] = useState({essentialDeduction: false, // 필수사용공제kepcoPayback: false, // 한전 페이백progressiveTierChange: false, // 누진제 구간 변경 });// 전기요금 누진제 구간별 요금 (계절별)const getElectricRates = (season: string) => {const isSummer = season === "summer";return {tier1: {limit: isSummer ? 300 : 200,baseCharge: 910,unitPrice: 120.0, },tier2: {limit: isSummer ? 450 : 400,baseCharge: 1600,unitPrice: 214.6, },tier3: {baseCharge: 7300,unitPrice: 307.3, }, }; };// 전기요금 계산 함수 (할인 적용 전)const calculateBaseElectricBill = (usage: number,progressiveType = 3,season = currentSeason ) => {const rates = getElectricRates(season);let bill = 0;let baseCharge = 0;if (progressiveType === 1) {// 1구간만 적용bill = usage * rates.tier1.unitPrice;baseCharge = rates.tier1.baseCharge; } else if (progressiveType === 2) {// 2구간까지 적용if (usage <= rates.tier1.limit) {bill = usage * rates.tier1.unitPrice;baseCharge = rates.tier1.baseCharge; } else {bill =rates.tier1.limit * rates.tier1.unitPrice + (usage - rates.tier1.limit) * rates.tier2.unitPrice;baseCharge = rates.tier2.baseCharge; } } else {// 3구간 모두 적용 (현행)if (usage <= rates.tier1.limit) {bill = usage * rates.tier1.unitPrice;baseCharge = rates.tier1.baseCharge; } else if (usage <= rates.tier2.limit) {bill =rates.tier1.limit * rates.tier1.unitPrice + (usage - rates.tier1.limit) * rates.tier2.unitPrice;baseCharge = rates.tier2.baseCharge; } else {bill =rates.tier1.limit * rates.tier1.unitPrice + (rates.tier2.limit - rates.tier1.limit) * rates.tier2.unitPrice + (usage - rates.tier2.limit) * rates.tier3.unitPrice;baseCharge = rates.tier3.baseCharge; } }return Math.round(bill + baseCharge); };// 전기요금 계산 함수 (할인 적용)const calculateElectricBill = (usage: number,progressiveType = 3,season = currentSeason ) => {let bill = calculateBaseElectricBill(usage, progressiveType, season);const rates = getElectricRates(season);// 할인 적용if (electricSavings.essentialDeduction && usage <= rates.tier1.limit) {bill *= 0.9; // 10% 할인 }if (electricSavings.kepcoPayback) {bill -= 2000; }return Math.round(bill); };// 현재 사용량의 구간 확인const getCurrentTier = (usage: number, season = currentSeason) => {const rates = getElectricRates(season);if (usage <= rates.tier1.limit) return 1;if (usage <= rates.tier2.limit) return 2;return 3; };// 누진제 변경 시뮬레이션 데이터 (현재 구간에 따라)const getProgressiveComparisonData = () => {const usage = monthlyUsage[0];const season = currentSeason;const currentTier = getCurrentTier(usage, season);if (currentTier === 3) {const tier3Bill = calculateElectricBill(usage, 3, season);const tier2Bill = calculateElectricBill(usage, 2, season);const tier1Bill = calculateElectricBill(usage, 1, season);return [ {type: "현재 (3구간)",amount: tier3Bill,color: "#FF6B35", }, {type: "2구간 적용시",amount: tier2Bill,color: "#666666", }, {type: "1구간 적용시",amount: tier1Bill,color: "#FFE300", }, ]; } else if (currentTier === 2) {const tier2Bill = calculateElectricBill(usage, 2, season);const tier1Bill = calculateElectricBill(usage, 1, season);return [ {type: "현재 (2구간)",amount: tier2Bill,color: "#666666", }, {type: "1구간 적용시",amount: tier1Bill,color: "#FFE300", }, ]; }return []; };// 필수사용공제 비교 데이터const getEssentialDeductionData = () => {const usage = monthlyUsage[0];const rates = getElectricRates(currentSeason);const isEligible = usage <= rates.tier1.limit;if (isEligible) {// 200kWh 이하: 혜택 미적용 vs 적용const withoutBenefit = calculateBaseElectricBill(usage, 3, currentSeason);const withBenefit = withoutBenefit * 0.9;return [ {type: "혜택 미적용",amount: withoutBenefit,color: "#666666", }, {type: "혜택 적용",amount: withBenefit,color: "#FFE300", }, ]; } else {// 200kWh 초과: 현재 vs 200kWh로 줄였을 때 혜택 적용const currentBill = calculateBaseElectricBill(usage, 3, currentSeason);const reducedUsageBill =calculateBaseElectricBill(rates.tier1.limit, 3, currentSeason) * 0.9;return [ {type: `현재 (${usage}kWh)`,amount: currentBill,color: "#666666", }, {type: `${rates.tier1.limit}kWh + 혜택`,amount: reducedUsageBill,color: "#FFE300", }, ]; } };// 전기요금 할인 혜택 절약 효과 계산const calculateElectricSavings = () => {const usage = monthlyUsage[0];const rates = getElectricRates(currentSeason);const baseElectricBill = calculateBaseElectricBill(usage, 3, currentSeason);let totalSavings = 0;// 누진제 구간 변경 혜택if (electricSavings.progressiveTierChange) {const currentTier = getCurrentTier(usage, currentSeason);if (currentTier === 3) {// 3구간 → 1구간으로 변경시 절약액const tier1Bill = calculateBaseElectricBill(usage, 1, currentSeason);totalSavings += Math.max(0, baseElectricBill - tier1Bill); } else if (currentTier === 2) {// 2구간 → 1구간으로 변경시 절약액const tier1Bill = calculateBaseElectricBill(usage, 1, currentSeason);totalSavings += Math.max(0, baseElectricBill - tier1Bill); } }// 필수사용공제 (200kWh 이하 시 10% 할인)if (electricSavings.essentialDeduction) {if (usage <= rates.tier1.limit) {// 현재 혜택 대상인 경우totalSavings += Math.round(baseElectricBill * 0.1); } else {// 혜택 대상이 아닌 경우: 200kWh로 줄이고 혜택 적용시와 현재의 차이const currentBill = baseElectricBill;const reducedUsageBill =calculateBaseElectricBill(rates.tier1.limit, 3, currentSeason) * 0.9;totalSavings += Math.max(0, currentBill - reducedUsageBill); } }// 한전 페이백if (electricSavings.kepcoPayback) {totalSavings += 2000; }return totalSavings; };// 누적 절약 데이터 (12개월)const generateCumulativeData = () => {const totalMonthlySaving = calculateElectricSavings();const data = [];let cumulative = 0;for (let i = 1; i <= 12; i++) {cumulative += totalMonthlySaving;data.push({month: `${i}월`,monthly: totalMonthlySaving,cumulative: cumulative, }); }return data; };const handleElectricSavingToggle = (savingId: keyof typeof electricSavings ) => {setElectricSavings((prev) => ({...prev,[savingId]: !prev[savingId], })); };return (<div className="min-h-screen bg-gray-50">{/* 헤더 */}<header className="bg-white shadow-sm"><div className="max-w-xl mx-auto px-4 py-4"><div className="flex items-center justify-between"><div className="flex items-center gap-3"><Link href="/savings"><Button variant="ghost" size="icon" className="h-8 w-8"><ArrowLeft className="h-4 w-4" /></Button></Link><div><h1 className="text-lg font-bold text-gray-900"> 전기요금 절약 시뮬레이션</h1><p className="text-xs text-gray-500"> 전기 절약 팁과 효과 확인</p></div></div><div className="flex items-center gap-3"><Link href="/simulation/gas"><Buttonvariant="outline"size="sm"className="flex items-center gap-2 bg-transparent"><Flame className="h-4 w-4" /> 도시가스</Button></Link><div className="w-8 h-8 bg-[#FFE300] rounded-full flex items-center justify-center"><Zap className="h-4 w-4 text-white" /></div></div></div></div></header><div className="max-w-xl mx-auto px-4 py-6 space-y-6">{/* 전기요금 현황 */}<Card className="border-0 rounded-2xl bg-[#FFE300] text-gray-700"><CardContent className="p-6"><div className="flex items-center justify-between mb-4"><div><h2 className="text-lg font-bold">전기요금 시뮬레이션</h2><p className="text-sm opacity-90"> 월 사용량: {monthlyUsage[0]}kWh ({getCurrentTier(monthlyUsage[0])}구간) |{currentSeason === "summer" ? "하계" : "기타계절"} 요금제 적용</p></div><div className="w-12 h-12 bg-white bg-opacity-20 rounded-full flex items-center justify-center"><Zap className="h-6 w-6" /></div></div><div className="grid grid-cols-2 gap-4"><div><div className="text-2xl font-bold"> ₩{calculateElectricBill(monthlyUsage[0]).toLocaleString()}</div><div className="text-sm opacity-90">현재 예상 요금</div></div><div><div className="text-2xl font-bold"> ₩{calculateElectricSavings().toLocaleString()}</div><div className="text-sm opacity-90">월 절약액</div></div></div></CardContent></Card>{/* 시간대별 요금제 비교 */}<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold flex items-center gap-2"><Clock className="h-5 w-5 text-gray-700" /> 시간대별 요금제 비교</CardTitle><CardDescription>일반형 vs 심야형 요금제 비교</CardDescription></CardHeader><CardContent className="space-y-4"><div className="flex gap-4"><Select value={contractType} onValueChange={setContractType}><SelectTrigger className="w-40"><SelectValue /></SelectTrigger><SelectContent><SelectItem value="general">일반형</SelectItem><SelectItem value="night">심야형</SelectItem></SelectContent></Select></div><div className="bg-gray-50 rounded-xl p-4"><div className="font-bold text-gray-900 mb-3">요금제 추천</div><div className="text-sm text-gray-700">{contractType === "general" ? (<> 현재 일반형 계약입니다. <br /> 심야 시간대 사용량이 많다면 심야형으로 변경을 고려해보세요.</> ) : (<> 심야형 계약 시 23시-06시 요금이 50% 할인됩니다. <br /> 겨울 난방 시에는 일반형이 더 유리할 수 있습니다.</> )}</div></div><div className="h-48"><ResponsiveContainerclassName="border border-gray-200 rounded-xl p-4 pt-6"width="100%"height="100%"><BarChart data={timeBasedRates}><CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" /><XAxis dataKey="time" tick={{ fontSize: 12 }} /><YAxis tick={{ fontSize: 12 }} /><Tooltipcontent={({ active, payload, label }) => {if (active && payload && payload.length) {return (<div className="bg-white p-3 border rounded-lg shadow-lg"><p className="font-medium">{label}</p>{payload.map((entry, index) => (<p key={index} style={{ color: entry.color }}>{entry.name}: {entry.value}원/kWh</p> ))}</div> ); }return null; }}/><BardataKey="일반형"fill={contractType === "general" ? "#FFE300" : "#666666"}name="일반형"/><BardataKey="심야형"fill={contractType === "night" ? "#FFE300" : "#666666"}name="심야형"/></BarChart></ResponsiveContainer></div></CardContent></Card>{/* 누진제 구간별 요금 비교 */}{getProgressiveComparisonData().length > 0 && (<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold flex items-center gap-2"><Calculator className="h-5 w-5" /> 누진제 구간 변경 시 절약 효과</CardTitle><CardDescription> 현재 구간에서 낮은 구간으로 변경 시 절약할 수 있는 금액</CardDescription></CardHeader><CardContent>{(() => {const rates = getElectricRates(currentSeason);const currentTier = getCurrentTier(monthlyUsage[0]);return (<><div className="mb-4 p-4 rounded-xl bg-gray-50"><div className="text-sm font-semibold text-gray-900 mb-2">{currentSeason === "summer" ? "하계" : "기타계절"}{" "} 누진제 구간 기준 (현재: {currentTier} 구간)</div><div className="grid grid-cols-3 gap-2 text-xs"><div className="text-center"><div className="font-medium">1구간</div><div>0~{rates.tier1.limit}kWh</div><div className="text-blue-600">{rates.tier1.unitPrice}원/kWh</div></div><div className="text-center"><div className="font-medium">2구간</div><div>{rates.tier1.limit + 1}~{rates.tier2.limit}kWh</div><div className="text-green-600">{rates.tier2.unitPrice}원/kWh</div></div><div className="text-center"><div className="font-medium">3구간</div><div>{rates.tier2.limit + 1}kWh 이상</div><div className="text-red-600">{rates.tier3.unitPrice}원/kWh</div></div></div></div><div className="border border-gray-200 rounded-xl p-4 mb-4"><div className="h-64 mb-4 relative"><ResponsiveContainer width="100%" height="100%"><BarChartdata={getProgressiveComparisonData()}margin={{top: 20,right: 30,left: 20,bottom: 5, }}><CartesianGridstrokeDasharray="3 3"stroke="#f0f0f0"/><XAxis dataKey="type" tick={{ fontSize: 12 }} /><YAxis tick={{ fontSize: 12 }} /><Tooltipformatter={(value) => [`₩${value.toLocaleString()}`,"요금", ]}/><Bar dataKey="amount" barSize={40}>{getProgressiveComparisonData().map( (entry, index) => (<Cellkey={`cell-${index}`}fill={entry.color}/> ) )}</Bar></BarChart></ResponsiveContainer>{/* 절약액 말풍선 */}{(() => {const data = getProgressiveComparisonData();const currentTier = getCurrentTier(monthlyUsage[0]);if (data.length >= 2) {let savings = 0;let message = "";if (currentTier === 3) {// 3구간 → 1구간 최대 절약액savings = data[0].amount - data[2].amount;message = "최대 절약액"; } else if (currentTier === 2) {// 2구간 → 1구간 절약액savings = data[0].amount - data[1].amount;message = "절약액"; }return (<div className="absolute top-4 right-4"><div className="bg-[#FFE300] text-[#1E1E1E] px-3 py-2 rounded-lg text-sm font-bold relative"> ₩{savings.toLocaleString()} {message}!<div className="absolute bottom-0 left-1/2 transform translate-y-full -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-[#FFE300]"></div></div></div> ); }return null; })()}</div><div className="grid grid-cols-1 gap-3">{getProgressiveComparisonData().map((item, index) => (<divkey={index}className="flex items-center justify-between p-3 bg-white rounded-lg"><div className="flex items-center gap-3"><divclassName="w-4 h-4 rounded-full"style={{ backgroundColor: item.color }}></div><div className="font-medium text-gray-900">{item.type}</div></div><divclassName="text-lg font-bold"style={{ color: item.color }}> ₩{item.amount.toLocaleString()}</div></div> ))}</div>{/* 3구간일 때 추가 설명 */}{getCurrentTier(monthlyUsage[0]) === 3 && (<div className="mt-3 p-3 bg-[#FFE300] bg-opacity-10 rounded-lg"><div className="text-sm text-gray-700"> 💡 <strong>3구간 사용자 혜택</strong><br />• 2구간 적용시: ₩{(getProgressiveComparisonData()[0].amount -getProgressiveComparisonData()[1].amount ).toLocaleString()}{" "} 절약<br />• 1구간 적용시: ₩{(getProgressiveComparisonData()[0].amount -getProgressiveComparisonData()[2].amount ).toLocaleString()}{" "} 절약 (최대)</div></div> )}</div></> ); })()}{getCurrentTier(monthlyUsage[0]) === 1 && (<div className="mt-4 p-4 bg-green-50 rounded-xl"><div className="flex items-center justify-center"><div className="text-center"><div className="text-2xl mb-2">🎉</div><div className="font-bold text-green-900"> 이미 최적 구간입니다!</div><div className="text-sm text-green-700"> 현재 1구간으로 가장 저렴한 요금을 적용받고 있습니다.</div></div></div></div> )}</CardContent></Card> )}{/* 할인 혜택 적용 */}<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold flex items-center gap-2"><Percent className="h-5 w-5" /> 할인 혜택 적용</CardTitle><CardDescription> 다양한 할인 혜택을 적용하여 요금을 절약하세요</CardDescription></CardHeader><CardContent className="space-y-6">{/* 필수사용공제 */}<div><div className="flex items-center justify-between p-4 bg-gray-50 rounded-xl mb-4"><div className="flex items-center gap-4"><div className="w-10 h-10rounded-full flex items-center justify-center"><Home className="h-5 w-5" /></div><div className="flex-1"><div className="font-bold text-gray-900">필수사용공제</div><div className="text-sm text-gray-600">{getElectricRates(currentSeason).tier1.limit}kWh 이하 시 10% 할인</div></div></div><Switchchecked={electricSavings.essentialDeduction}onCheckedChange={() =>handleElectricSavingToggle("essentialDeduction")}/></div>{/* 필수사용공제 비교 차트 */}<div className="border border-gray-200 rounded-xl p-4"><div className="text-sm font-medium text-gray-900 mb-4">{monthlyUsage[0] <=getElectricRates(currentSeason).tier1.limit ? `필수사용공제 혜택 비교 (현재 ${monthlyUsage[0]}kWh - 혜택 대상)` : `사용량 절약 + 필수사용공제 혜택 (현재 ${monthlyUsage[0]}kWh - 혜택 대상 아님)`}</div><div className="h-48 mb-4 relative"><ResponsiveContainer width="100%" height="100%"><BarChartdata={getEssentialDeductionData()}barSize={40}margin={{ top: 20, right: 30, left: 20, bottom: 5 }}><CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" /><XAxis dataKey="type" tick={{ fontSize: 12 }} /><YAxis tick={{ fontSize: 12 }} /><Tooltipformatter={(value) => [`₩${value.toLocaleString()}`,"요금", ]}/><Bar dataKey="amount" radius={[4, 4, 0, 0]}>{getEssentialDeductionData().map((entry, index) => (<Cell key={`cell-${index}`} fill={entry.color} /> ))}</Bar></BarChart></ResponsiveContainer>{/* 절약액 말풍선 */}{(() => {const data = getEssentialDeductionData();const savings = data[0].amount - data[1].amount;return (<div className="absolute top-4 right-4"><div className="bg-[#FFE300] text-[#1E1E1E] px-3 py-2 rounded-lg text-sm font-bold relative"> ₩{savings.toLocaleString()} 절약!<div className="absolute bottom-0 left-1/2 transform translate-y-full -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-[#FFE300]"></div></div></div> ); })()}</div>{(() => {const data = getEssentialDeductionData();const isEligible =monthlyUsage[0] <=getElectricRates(currentSeason).tier1.limit;return (<div className="space-y-3"><div className="grid grid-cols-1 gap-3">{data.map((item, index) => (<divkey={index}className="flex items-center justify-between p-3 bg-white rounded-lg"><div className="flex items-center gap-3"><divclassName="w-4 h-4 rounded-full"style={{ backgroundColor: item.color }}></div><div className="font-medium text-gray-900">{item.type}</div></div><divclassName="text-lg font-bold"style={{ color: item.color }}> ₩{item.amount.toLocaleString()}</div></div> ))}</div><div className="text-sm text-gray-600">{isEligible ? `현재 ${monthlyUsage[0]}kWh 사용으로 혜택 대상입니다` : `현재 ${monthlyUsage[0]}kWh → ${getElectricRates(currentSeason).tier1.limit}kWh로 줄이고 혜택 적용시`}</div></div> ); })()}</div></div>{/* 한전 페이백 */}<div className="flex items-center justify-between p-4 bg-gray-50 rounded-xl"><div className="flex items-center gap-4"><div className="w-10 h-10 rounded-full flex items-center justify-center"><Gift className="h-5 w-5" /></div><div className="flex-1"><div className="font-bold text-gray-900">한전 페이백</div><div className="text-sm text-gray-600">월 2,000원 할인</div></div></div><div className="flex items-center gap-2"><ahref="https://en-ter.co.kr/ec/main/main.do"target="_blank"rel="noopener noreferrer"><Buttonvariant="ghost"size="sm"className="h-7 px-2 text-xs bg-blue-50 hover:bg-blue-100 text-blue-600"> 바로가기</Button></a>{/* 한전 페이백 하게 되면 토글 누르고 2000원 절약하게 해주세요 */}<divclassName={`w-12 h-7 flex items-center rounded-full p-1 cursor-pointer transition-colors duration-300 ${enabled ? "bg-blue-500" : "bg-gray-300"}`}onClick={() => setEnabled(!enabled)}><divclassName={`bg-white w-5 h-5 rounded-full shadow-md transform transition-transform duration-300 ${enabled ? "translate-x-5" : "translate-x-0"}`}></div></div></div></div></CardContent></Card>{/* 누적 절약 그래프 */}<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold"> 연간 누적 절약 효과</CardTitle><CardDescription> 현재 설정으로 1년간 절약할 수 있는 금액</CardDescription></CardHeader><CardContent><div className="h-80"><ResponsiveContainer width="100%" height="100%"><LineChart data={generateCumulativeData()}><CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" /><XAxis dataKey="month" tick={{ fontSize: 12 }} /><YAxis tick={{ fontSize: 12 }} /><Tooltipformatter={(value, name) => [`₩${value.toLocaleString()}`,name === "monthly" ? "월 절약액" : "누적 절약액", ]}/><Bar dataKey="monthly" fill="#FFE300" name="월 절약액" /><Linetype="monotone"dataKey="cumulative"stroke="#666666"strokeWidth={3}dot={{ fill: "#666666", strokeWidth: 2, r: 4 }}name="누적 절약액"/></LineChart></ResponsiveContainer></div><div className="mt-4 p-4 bg-[#FFE300] bg-opacity-10 rounded-xl"><div className="flex items-center justify-between"><div><div className="font-bold text-gray-900"> 연간 총 절약 예상액</div><div className="text-sm text-gray-700"> 현재 적용된 절약 팁 기준</div></div><div className="text-2xl font-bold text-gray-900"> ₩{(calculateElectricSavings() * 12).toLocaleString()}</div></div></div></CardContent></Card></div></div> );}이 코드에서 '누진제 구간 변경 시 절약 효과', '필수사용공제', '한전페이백'를 선택했을 때 월 절약액과 연간 누적 절약 효과에 할인 금액이 반영되도록 해줘
Loading...
"use client"import { useState } from "react"import {ArrowLeft,Flame,TrendingUp,AlertCircle,Thermometer,Droplets,Home,CreditCard,Calendar,Snowflake,Sun,} from "lucide-react"import { Button } from "@/components/ui/button"import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"import { Switch } from "@/components/ui/switch"import Link from "next/link"import { Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, LineChart, Line } from "recharts"type Season = "winter" | "spring" | "summer" | "fall"const seasons: Season[] = ["winter", "spring", "summer", "fall"]type TipKey =| 'temperature'| 'humidity'| 'awayMode'| 'coldWater'| 'boilerCleaning'| 'warmClothes'| 'valveControl'| 'shower'| 'autoPayment'| 'cardChange'export default function GasSimulationPage() {const [gasReduction, setGasReduction] = useState([15])const [currentSeason, setCurrentSeason] = useState<'winter' | 'spring' | 'summer' | 'fall'>("winter") // winter, summer, spring, fall// 절약 팁 적용 상태const [savingTips, setSavingTips] = useState<Record<TipKey, boolean>>({temperature: false,humidity: false,awayMode: false,coldWater: false,boilerCleaning: false,warmClothes: false,valveControl: false,shower: false,autoPayment: false,cardChange: false, })// 계절별 기본 가스 요금 (동계가 높음)const baseGasBill = {winter: 85000,spring: 45000,summer: 25000,fall: 55000, }// 절약 팁별 절감 효과 (원/월)const savingEffects = {temperature: currentSeason === "winter" ? 12000 : currentSeason === "fall" ? 8000 : 0,humidity: currentSeason === "winter" ? 5000 : currentSeason === "fall" ? 3000 : 0,awayMode:currentSeason === "winter" ? 8000 : currentSeason === "fall" ? 5000 : currentSeason === "spring" ? 3000 : 0,coldWater: 4000, // 연중 동일boilerCleaning:currentSeason === "winter" ? 6000 : currentSeason === "fall" ? 4000 : currentSeason === "spring" ? 2000 : 0,warmClothes: currentSeason === "winter" ? 10000 : currentSeason === "fall" ? 6000 : 0,valveControl: currentSeason === "winter" ? 7000 : currentSeason === "fall" ? 4000 : 0,shower: 8000, // 연중 동일 (온수 사용)autoPayment: 500, // 연중 동일cardChange: 1000, // 연중 동일 }// 현재 적용된 절약 효과 계산const calculateTotalSavings = () => {return (Object.keys(savingTips) as TipKey[]).reduce((total, tip) => {return total + (savingTips[tip] ? savingEffects[tip] : 0) }, 0)}// 누적 절약 데이터 (12개월)const generateCumulativeData = () => {const totalMonthlySaving = calculateTotalSavings()const data = []let cumulative = 0for (let i = 1; i <= 12; i++) {cumulative += totalMonthlySavingdata.push({month: `${i}월`,monthly: totalMonthlySaving,cumulative: cumulative, }) }return data }// 계절별 절약 팁 데이터const seasonalTips: Record<Season, {id: TipKeytitle: stringdescription: stringicon: React.ReactNodesaving: numberdetail: string}[]> = {winter: [ {id: "temperature",title: "실내 적정 난방 온도 설정",description: "18~20℃로 설정하기",icon: <Thermometer className="h-5 w-5" />,saving: savingEffects.temperature,detail: "1도만 낮춰도 7% 절약 가능", }, {id: "humidity",title: "적정 습도 유지",description: "40~60% 습도 유지하기",icon: <Droplets className="h-5 w-5" />,saving: savingEffects.humidity,detail: "습도가 높으면 체감온도 상승", }, {id: "awayMode",title: "외출모드 활용",description: '외출시 보일러 "외출모드"로 전환',icon: <Home className="h-5 w-5" />,saving: savingEffects.awayMode,detail: "15도 정도로 자동 조절", }, {id: "warmClothes",title: "보온용품 착용",description: "실내 내복, 수면양말 등 착용",icon: <Snowflake className="h-5 w-5" />,saving: savingEffects.warmClothes,detail: "체감온도 2-3도 상승 효과", }, {id: "valveControl",title: "난방 밸브 조정",description: "사용하지 않는 방 밸브 잠그기",icon: <AlertCircle className="h-5 w-5" />,saving: savingEffects.valveControl,detail: "불필요한 난방 차단", }, {id: "boilerCleaning",title: "보일러 관리",description: "보일러 청소 및 배관 공기 빼기",icon: <AlertCircle className="h-5 w-5" />,saving: savingEffects.boilerCleaning,detail: "효율성 10-15% 향상", }, ],summer: [ {id: "shower",title: "샤워 시간 단축",description: "온수 사용 시간 줄이기",icon: <Droplets className="h-5 w-5" />,saving: savingEffects.shower,detail: "5분 단축 시 월 8,000원 절약", }, ],spring: [ {id: "awayMode",title: "간헐적 난방 사용",description: "필요시에만 난방 가동",icon: <Home className="h-5 w-5" />,saving: savingEffects.awayMode,detail: "봄철 온도 조절", }, {id: "boilerCleaning",title: "보일러 점검",description: "난방 시즌 전 점검 및 청소",icon: <AlertCircle className="h-5 w-5" />,saving: savingEffects.boilerCleaning,detail: "효율성 향상", }, ],fall: [ {id: "temperature",title: "초기 난방 온도 조절",description: "서서히 온도 올리기",icon: <Thermometer className="h-5 w-5" />,saving: savingEffects.temperature,detail: "급격한 온도 변화 방지", }, {id: "warmClothes",title: "보온용품 준비",description: "난방 전 보온용품 활용",icon: <Snowflake className="h-5 w-5" />,saving: savingEffects.warmClothes,detail: "난방 시작 시기 연기", }, ], }// 연중 공통 절약 팁const commonTips : {id: TipKeytitle: stringdescription: stringicon: React.ReactNodesaving: numberdetail: string}[]= [ {id: "coldWater",title: "냉수 사용 습관",description: '평상시 수도꼭지 "냉수"쪽으로',icon: <Droplets className="h-5 w-5" />,saving: savingEffects.coldWater,detail: "불필요한 온수 사용 방지", }, {id: "autoPayment",title: "자동이체 할인",description: "자동이체 신청으로 할인",icon: <CreditCard className="h-5 w-5" />,saving: savingEffects.autoPayment,detail: "월 500원 할인", }, {id: "cardChange",title: "카드 할인",description: "가스요금 할인 카드 사용",icon: <CreditCard className="h-5 w-5" />,saving: savingEffects.cardChange,detail: "월 1,000원 할인", }, ]const handleTipToggle = (tipId: TipKey) => {setSavingTips((prev) => ({...prev,[tipId]: !prev[tipId], })) }const getSeasonName = (season: 'winter' | 'spring' | 'summer' | 'fall') => {const names = {winter: "겨울",spring: "봄",summer: "여름",fall: "가을", }return names[season] }const getSeasonIcon = (season: 'winter' | 'spring' | 'summer' | 'fall') => {const icons = {winter: <Snowflake className="h-4 w-4" />,spring: <Sun className="h-4 w-4" />,summer: <Sun className="h-4 w-4" />,fall: <Calendar className="h-4 w-4" />, }return icons[season] }return (<div className="min-h-screen bg-gray-50">{/* 헤더 */}<header className="bg-white shadow-sm"><div className="max-w-4xl mx-auto px-4 py-4"><div className="flex items-center justify-between"><div className="flex items-center gap-3"><Link href="/simulation"><Button variant="ghost" size="icon" className="h-8 w-8"><ArrowLeft className="h-4 w-4" /></Button></Link><div><h1 className="text-lg font-bold text-gray-900">도시가스 시뮬레이션</h1><p className="text-xs text-gray-500">계절별 절약 팁과 효과 확인</p></div></div><div className="w-8 h-8 bg-orange-400 rounded-full flex items-center justify-center"><Flame className="h-4 w-4 text-white" /></div></div></div></header><div className="max-w-4xl mx-auto px-4 py-6 space-y-6">{/* 현재 절약 현황 */}<Card className="border-0 rounded-2xl bg-gradient-to-r from-orange-400 to-red-400 text-white"><CardContent className="p-6"><div className="flex items-center justify-between mb-4"><div><h2 className="text-lg font-bold">현재 절약 효과</h2><p className="text-sm opacity-90">{getSeasonName(currentSeason)}철 기준</p></div><div className="w-12 h-12 bg-white bg-opacity-20 rounded-full flex items-center justify-center"><Flame className="h-6 w-6" /></div></div><div className="grid grid-cols-2 gap-4"><div><div className="text-2xl font-bold">₩{calculateTotalSavings().toLocaleString()}</div><div className="text-sm opacity-90">월 절약액</div></div><div><div className="text-2xl font-bold">₩{(calculateTotalSavings() * 12).toLocaleString()}</div><div className="text-sm opacity-90">연간 절약액</div></div></div></CardContent></Card>{/* 연중 공통 절약 팁 */}<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold">연중 공통 절약 팁</CardTitle><CardDescription>계절에 관계없이 적용할 수 있는 절약 방법</CardDescription></CardHeader><CardContent className="space-y-4">{commonTips.map((tip) => (<div key={tip.id} className="flex items-center justify-between p-4 bg-gray-50 rounded-xl"><div className="flex items-center gap-4"><div className="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center">{tip.icon}</div><div className="flex-1"><div className="font-bold text-gray-900">{tip.title}</div><div className="text-sm text-gray-600">{tip.description}</div><div className="text-xs text-blue-600 mt-1">{tip.detail}</div></div></div><div className="flex items-center gap-3"><div className="text-right"><div className="text-lg font-bold text-green-600">₩{tip.saving.toLocaleString()}</div><div className="text-xs text-gray-500">월 절약</div></div><Switch checked={savingTips[tip.id]} onCheckedChange={() => handleTipToggle(tip.id)} /></div></div> ))}</CardContent></Card>{/* 계절 선택 */}<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold">계절별 절약 시뮬레이션</CardTitle><CardDescription>계절을 선택하여 맞춤 절약 팁을 확인하세요</CardDescription></CardHeader><CardContent><div className="grid grid-cols-4 gap-2">{seasons.map((season) => (<Buttonkey={season}variant={currentSeason === season ? "default" : "outline"}className={`h-12 rounded-xl ${currentSeason === season ? "bg-orange-500 hover:bg-orange-600 text-white" : "border-gray-200 bg-white hover:bg-gray-50"}`}onClick={() => setCurrentSeason(season)}><div className="flex items-center gap-2">{getSeasonIcon(season)}<span className="text-sm">{getSeasonName(season)}</span></div></Button> ))}</div></CardContent></Card>{/* 계절별 절약 팁 */}<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold flex items-center gap-2">{getSeasonIcon(currentSeason)}{getSeasonName(currentSeason)}철 절약 팁</CardTitle><CardDescription>{currentSeason === "winter" && "난방비 절약을 위한 핵심 팁들"}{currentSeason === "summer" && "온수 사용 절약 팁"}{currentSeason === "spring" && "봄철 가스 절약 방법"}{currentSeason === "fall" && "가을철 난방 준비 절약 팁"}</CardDescription></CardHeader><CardContent className="space-y-4">{seasonalTips[currentSeason]?.map((tip) => (<div key={tip.id} className="flex items-center justify-between p-4 bg-gray-50 rounded-xl"><div className="flex items-center gap-4"><div className="w-10 h-10 bg-orange-100 rounded-full flex items-center justify-center">{tip.icon}</div><div className="flex-1"><div className="font-bold text-gray-900">{tip.title}</div><div className="text-sm text-gray-600">{tip.description}</div><div className="text-xs text-orange-600 mt-1">{tip.detail}</div></div></div><div className="flex items-center gap-3">{tip.saving > 0 && (<div className="text-right"><div className="text-lg font-bold text-green-600">₩{tip.saving.toLocaleString()}</div><div className="text-xs text-gray-500">월 절약</div></div> )}<Switch checked={savingTips[tip.id]} onCheckedChange={() => handleTipToggle(tip.id)} /></div></div> ))}</CardContent></Card>{/* 샤워 시간 시뮬레이션 (여름철 특별) */}{currentSeason === "summer" && (<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold flex items-center gap-2"><Droplets className="h-5 w-5 text-blue-500" /> 샤워 시간 절약 시뮬레이션</CardTitle><CardDescription>샤워 시간을 줄여서 온수 사용량을 절약해보세요</CardDescription></CardHeader><CardContent><div className="bg-blue-50 rounded-xl p-4 mb-4"><div className="flex items-center justify-between mb-4"><div><div className="font-bold text-gray-900">현재 샤워 시간</div><div className="text-2xl font-bold text-blue-600">15분</div></div><div className="text-right"><div className="font-bold text-gray-900">목표 시간</div><div className="text-lg font-bold text-green-600">10분</div></div></div><div className="space-y-3"><div className="flex justify-between text-sm"><span>절약 시간: 5분</span><span>월 절약액: ₩8,000</span></div><div className="bg-green-100 rounded-lg p-3"><div className="text-sm text-green-800">💡 절약 팁</div><div className="text-sm text-green-700"> • 샤워 전 미리 물 온도 조절<br />• 비누칠할 때 물 잠시 끄기<br />• 타이머 사용으로 시간 관리</div></div></div></div></CardContent></Card> )}{/* 누적 절약 그래프 */}<Card className="border-0 rounded-2xl bg-white"><CardHeader><CardTitle className="text-lg font-bold">연간 누적 절약 효과</CardTitle><CardDescription>현재 설정으로 1년간 절약할 수 있는 금액</CardDescription></CardHeader><CardContent><div className="h-80"><ResponsiveContainer width="100%" height="100%"><LineChart data={generateCumulativeData()}><CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" /><XAxis dataKey="month" tick={{ fontSize: 12 }} /><YAxis tick={{ fontSize: 12 }} /><Tooltipformatter={(value, name) => [`₩${value.toLocaleString()}`,name === "monthly" ? "월 절약액" : "누적 절약액", ]}/><Bar dataKey="monthly" fill="#F97316" name="월 절약액" /><Linetype="monotone"dataKey="cumulative"stroke="#10B981"strokeWidth={3}dot={{ fill: "#10B981", strokeWidth: 2, r: 4 }}name="누적 절약액"/></LineChart></ResponsiveContainer></div><div className="mt-4 p-4 bg-green-50 rounded-xl"><div className="flex items-center justify-between"><div><div className="font-bold text-green-900">연간 총 절약 예상액</div><div className="text-sm text-green-700">현재 적용된 절약 팁 기준</div></div><div className="text-2xl font-bold text-green-600"> ₩{(calculateTotalSavings() * 12).toLocaleString()}</div></div></div></CardContent></Card>{/* 절약 팁 요약 */}<Card className="border-0 rounded-2xl bg-gradient-to-r from-blue-400 to-purple-400 text-white"><CardContent className="p-6"><div className="flex items-center gap-3 mb-4"><div className="w-8 h-8 bg-white bg-opacity-20 rounded-full flex items-center justify-center"><AlertCircle className="h-4 w-4" /></div><h3 className="text-lg font-bold">적용 중인 절약 팁</h3></div><div className="grid grid-cols-2 gap-4"><div><div className="text-2xl font-bold">{Object.values(savingTips).filter(Boolean).length}개</div><div className="text-sm opacity-90">활성화된 절약 팁</div></div><div><div className="text-2xl font-bold">₩{calculateTotalSavings().toLocaleString()}</div><div className="text-sm opacity-90">월 예상 절약액</div></div></div></CardContent></Card>{/* 하단 액션 버튼 */}<div className="grid grid-cols-2 gap-3 pb-6"><Link href="/simulation/electric"><Button className="h-12 bg-yellow-500 hover:bg-yellow-600 text-gray-900 rounded-2xl w-full"> 전기요금 시뮬레이션</Button></Link><Link href="/rewards"><Button variant="outline" className="h-12 rounded-2xl border-gray-200 bg-white w-full"><TrendingUp className="h-4 w-4 mr-2" /> 절약 숲 보기</Button></Link></div></div></div> )}이 코드에서 '여름'탭에서 '샤워 시간 절약 시뮬레이션'을 선택하면 연간 누적 절약 효과 그래프와 연간 절약액에 반영되도록 수정해줘. 그리고 겨울, 봄, 여름, 가을 별로 밑에 연간 누적 절약 효과 그래프가 다르게 보이게 하고 싶어. 그래프의 row에 '겨울'은 11월~2월, '봄'은 3월~5월, '여름'은 6월~8월, '가을'은 9월~11월로 해줘
계절별로 다른 그래프를 보여주고, 샤워 시간 절약이 실제 절약액에 반영되도록 코드를 수정해드리겠습니다.
주요 수정사항:
계절별 월 구분:
generateCumulativeData()
함수를 수정하여 각 월에 해당하는 계절의 절약 효과만 적용되도록 했습니다.getSavingEffects()
함수를 수정했습니다.이제 여름철에 샤워 시간을 조절하면 실시간으로 절약액이 반영되고, 계절별로 다른 그래프가 표시됩니다.