- {exchangeRate.base === 'KRW' ? '1,000' : '1'} {getCurrencySymbol(exchangeRate.base)} =
+ {!hasError && (
+
+
+
+ {exchangeRate.base === 'KRW' ? '1,000' : '1'} {getCurrencySymbol(exchangeRate.base)} =
+
+
+ {exchangeRate.base === 'KRW'
+ ? (exchangeRate.rate * 1000).toLocaleString('ko-KR', {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2,
+ })
+ : exchangeRate.rate.toLocaleString('ko-KR', {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 4,
+ })}
+
+
{getCurrencySymbol(exchangeRate.target)}
-
- {exchangeRate.base === 'KRW'
- ? (exchangeRate.rate * 1000).toLocaleString('ko-KR', {
- minimumFractionDigits: 2,
+
+ )}
+
+ {/* 계산기 입력 */}
+
+
+
+
+ {base}
+
+
+
+
+
+
+ {calculateResult().toLocaleString('ko-KR', {
+ minimumFractionDigits: 0,
maximumFractionDigits: 2,
- })
- : exchangeRate.rate.toLocaleString('ko-KR', {
- minimumFractionDigits: 2,
- maximumFractionDigits: 4,
})}
-
-
{getCurrencySymbol(exchangeRate.target)}
-
-
-
- {/* 계산 예시 */}
-
-
-
10,000 {base}
-
- {(10000 * (base === 'KRW' ? exchangeRate.rate : 1 / exchangeRate.rate)).toLocaleString('ko-KR', {
- minimumFractionDigits: 0,
- maximumFractionDigits: 2,
- })}{' '}
- {target}
+
+
{target}
+
-
-
100,000 {base}
-
- {(100000 * (base === 'KRW' ? exchangeRate.rate : 1 / exchangeRate.rate)).toLocaleString('ko-KR', {
- minimumFractionDigits: 0,
- maximumFractionDigits: 2,
- })}{' '}
- {target}
-
-
-
-
{/* 데이터 출처 */}
-
+
출처: {exchangeRate.source}
diff --git a/frontend/components/dashboard/widgets/WeatherWidget.tsx b/frontend/components/dashboard/widgets/WeatherWidget.tsx
index ef195aaa..19753387 100644
--- a/frontend/components/dashboard/widgets/WeatherWidget.tsx
+++ b/frontend/components/dashboard/widgets/WeatherWidget.tsx
@@ -18,6 +18,7 @@ import {
RefreshCw,
Check,
ChevronsUpDown,
+ Settings,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
@@ -34,11 +35,37 @@ export default function WeatherWidget({
refreshInterval = 600000,
}: WeatherWidgetProps) {
const [open, setOpen] = useState(false);
+ const [settingsOpen, setSettingsOpen] = useState(false);
const [selectedCity, setSelectedCity] = useState(city);
const [weather, setWeather] = useState
(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [lastUpdated, setLastUpdated] = useState(null);
+
+ // 표시할 날씨 정보 선택
+ const [selectedItems, setSelectedItems] = useState([
+ 'temperature',
+ 'feelsLike',
+ 'humidity',
+ 'windSpeed',
+ 'pressure',
+ ]);
+
+ // 날씨 항목 정의
+ const weatherItems = [
+ { id: 'temperature', label: '기온', icon: Sun },
+ { id: 'feelsLike', label: '체감온도', icon: Sun },
+ { id: 'humidity', label: '습도', icon: Droplets },
+ { id: 'windSpeed', label: '풍속', icon: Wind },
+ { id: 'pressure', label: '기압', icon: Gauge },
+ ];
+
+ // 항목 토글
+ const toggleItem = (itemId: string) => {
+ setSelectedItems((prev) =>
+ prev.includes(itemId) ? prev.filter((id) => id !== itemId) : [...prev, itemId]
+ );
+ };
// 도시 목록 (전국 시/군/구 단위)
const cities = [
@@ -278,9 +305,9 @@ export default function WeatherWidget({
}
return (
-
+
{/* 헤더 */}
-
+
@@ -334,6 +361,46 @@ export default function WeatherWidget({
: ''}
+
+
+
+
+
+
+
표시 항목
+ {weatherItems.map((item) => {
+ const Icon = item.icon;
+ return (
+
+ );
+ })}
+
+
+
- {/* 날씨 아이콘 및 온도 */}
-
-
- {getWeatherIcon(weather.weatherMain)}
-
-
- {weather.temperature}°C
+ {/* 반응형 그리드 레이아웃 - 자동 조정 */}
+
+ {/* 날씨 아이콘 및 온도 */}
+
+
+
+ {(() => {
+ const iconClass = "h-5 w-5";
+ switch (weather.weatherMain.toLowerCase()) {
+ case 'clear':
+ return ;
+ case 'clouds':
+ return ;
+ case 'rain':
+ case 'drizzle':
+ return ;
+ case 'snow':
+ return ;
+ default:
+ return ;
+ }
+ })()}
+
+
+
+ {weather.temperature}°C
+
+
+ {weather.weatherDescription}
+
-
- {weather.weatherDescription}
-
-
- {/* 상세 정보 */}
-
-
-
-
-
체감 온도
-
- {weather.feelsLike}°C
-
+ {/* 기온 - 선택 가능 */}
+ {selectedItems.includes('temperature') && (
+
+
+
+
기온
+
+ {weather.temperature}°C
+
+
-
-
-
-
-
습도
-
- {weather.humidity}%
-
+ )}
+
+ {/* 체감 온도 */}
+ {selectedItems.includes('feelsLike') && (
+
+
+
+
체감온도
+
+ {weather.feelsLike}°C
+
+
-
-
-
-
-
풍속
-
- {weather.windSpeed} m/s
-
+ )}
+
+ {/* 습도 */}
+ {selectedItems.includes('humidity') && (
+
+
+
+
습도
+
+ {weather.humidity}%
+
+
-
-
-
-
-
기압
-
- {weather.pressure} hPa
-
+ )}
+
+ {/* 풍속 */}
+ {selectedItems.includes('windSpeed') && (
+
+
+
+
풍속
+
+ {weather.windSpeed} m/s
+
+
-
+ )}
+
+ {/* 기압 */}
+ {selectedItems.includes('pressure') && (
+
+
+
+
기압
+
+ {weather.pressure} hPa
+
+
+
+ )}
);