Files
sam-manage/resources/views/dashboard/partials/weather.blade.php
김보곤 c5f4c53a50 feat: [dashboard] 날씨 위젯에 강수확률 표시 추가
- 단기예보 POP (하루 최대값) + 중기예보 rnSt 병합
- 우산 아이콘 + 퍼센트 표시 (50% 이상 진한 파랑 강조)
- 강수확률 0%일 때는 표시하지 않음
2026-02-21 13:40:28 +09:00

124 lines
6.3 KiB
PHP

{{-- 주간 날씨 위젯 (HTMX 파티셜) --}}
@if(empty($forecasts))
<div class="flex items-center justify-center py-8 text-sm text-gray-400">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z"/>
</svg>
날씨 정보를 불러올 없습니다
</div>
@else
@php
$today = now()->format('Ymd');
$dayNames = ['일', '월', '화', '수', '목', '금', '토'];
// 전체 기온 범위 계산 (바 그래프용)
$allTmn = collect($forecasts)->pluck('tmn')->filter(fn($v) => $v !== null);
$allTmx = collect($forecasts)->pluck('tmx')->filter(fn($v) => $v !== null);
$globalMin = $allTmn->isNotEmpty() ? $allTmn->min() : 0;
$globalMax = $allTmx->isNotEmpty() ? $allTmx->max() : 20;
$range = max($globalMax - $globalMin, 1);
@endphp
<div class="flex gap-2 overflow-x-auto pb-1" style="flex-wrap: nowrap;">
@foreach($forecasts as $fc)
@php
$dt = \Carbon\Carbon::createFromFormat('Ymd', $fc['date']);
$isToday = ($fc['date'] === $today);
$dayName = $dayNames[$dt->dayOfWeek];
$isSunday = $dt->dayOfWeek === 0;
$isSaturday = $dt->dayOfWeek === 6;
$icon = $fc['icon'] ?? null;
$weatherText = $fc['weather_text'] ?? '';
$tmn = $fc['tmn'];
$tmx = $fc['tmx'];
$pop = $fc['pop'] ?? 0;
$hasData = ($tmn !== null || $tmx !== null || $icon !== null);
// 바 위치 계산 (%)
$barLeft = $tmn !== null ? round(($tmn - $globalMin) / $range * 100) : 0;
$barRight = $tmx !== null ? round(($tmx - $globalMin) / $range * 100) : 100;
$barWidth = max($barRight - $barLeft, 8);
// 강수 여부
$isPrecip = in_array($icon, ['rain', 'snow', 'sleet']);
@endphp
<div class="text-center rounded-xl border transition-all
{{ $isToday ? 'bg-blue-50 border-blue-200 shadow-md ring-1 ring-blue-100' : ($hasData ? 'bg-white border-gray-200 hover:shadow-sm' : 'bg-gray-50 border-gray-100') }}"
style="flex: 1 1 0; min-width: 100px; padding: 14px 10px;">
{{-- 요일 --}}
<div class="text-xs font-bold mb-0.5 tracking-wide
{{ $isToday ? 'text-blue-600' : ($isSunday ? 'text-red-500' : ($isSaturday ? 'text-blue-500' : 'text-gray-700')) }}">
{{ $isToday ? '오늘' : $dayName }}
</div>
{{-- 날짜 --}}
<div class="text-[11px] {{ $isToday ? 'text-blue-400' : 'text-gray-400' }} mb-3">
{{ $dt->format('m.d') }}
</div>
@if($hasData)
{{-- 날씨 아이콘 --}}
<div class="flex justify-center mb-1">
@if($icon)
@include('dashboard.partials.weather-icon', ['icon' => $icon])
@else
<div style="width: 40px; height: 40px;"></div>
@endif
</div>
{{-- 강수확률 --}}
@if($pop > 0)
<div class="flex items-center justify-center gap-0.5 mb-1.5">
{{-- 우산 아이콘 --}}
<svg style="width: 12px; height: 12px;" viewBox="0 0 24 24" fill="none" stroke="{{ $pop >= 50 ? '#2563eb' : '#93c5fd' }}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 2v1M4.93 4.93l.7.7M2 12h1M12 22c-1.66 0-3-1.34-3-3v-2"/>
<path d="M12 3a9 9 0 0 1 9 9H3a9 9 0 0 1 9-9z"/>
</svg>
<span class="text-[11px] font-semibold {{ $pop >= 50 ? 'text-blue-600' : 'text-blue-400' }}">{{ $pop }}%</span>
</div>
@else
<div class="mb-1.5" style="height: 18px;"></div>
@endif
{{-- 기온 그래프 --}}
@if($tmx !== null && $tmn !== null)
<div class="relative mx-auto mb-2" style="height: 6px; border-radius: 3px; background: #f3f4f6;">
<div style="
position: absolute;
left: {{ $barLeft }}%;
width: {{ $barWidth }}%;
height: 100%;
border-radius: 3px;
background: linear-gradient(90deg, #60a5fa, #f87171);
"></div>
</div>
@endif
{{-- 최고/최저 기온 --}}
<div class="flex items-center justify-center gap-1.5">
@if($tmx !== null)
<span class="text-sm font-bold text-red-500">{{ $tmx }}°</span>
@else
<span class="text-sm text-gray-300">-</span>
@endif
<span class="text-gray-300">/</span>
@if($tmn !== null)
<span class="text-sm font-medium text-blue-500">{{ $tmn }}°</span>
@else
<span class="text-sm text-gray-300">-</span>
@endif
</div>
@else
{{-- 데이터 없는 --}}
<div class="flex flex-col items-center justify-center" style="min-height: 120px;">
<svg class="w-6 h-6 text-gray-300 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 12H4M12 4v16"/>
</svg>
<span class="text-[11px] text-gray-300">준비 </span>
</div>
@endif
</div>
@endforeach
</div>
@endif