diff --git a/src/renderer/pages/DailyReward.tsx b/src/renderer/pages/DailyReward.tsx index cdec473..5bd9ee1 100644 --- a/src/renderer/pages/DailyReward.tsx +++ b/src/renderer/pages/DailyReward.tsx @@ -16,19 +16,38 @@ import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; import TodayRoundedIcon from '@mui/icons-material/TodayRounded'; import CustomTooltip from '../components/Notifications/CustomTooltip'; import CoinsDisplay from '../components/CoinsDisplay'; -import { claimDaily, fetchDailyStatus, DailyStatusResponse, fetchDailyClaimDays } from '../api'; +import { + claimDaily, + fetchDailyStatus, + DailyStatusResponse, + fetchDailyClaimDays, +} from '../api'; const RU_MONTHS = [ - 'Январь','Февраль','Март','Апрель','Май','Июнь', - 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь', + 'Январь', + 'Февраль', + 'Март', + 'Апрель', + 'Май', + 'Июнь', + 'Июль', + 'Август', + 'Сентябрь', + 'Октябрь', + 'Ноябрь', + 'Декабрь', ]; const RU_WEEKDAYS = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс']; const pad2 = (n: number) => String(n).padStart(2, '0'); -const keyOf = (d: Date) => `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`; -const startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()); +const keyOf = (d: Date) => + `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`; +const startOfDay = (d: Date) => + new Date(d.getFullYear(), d.getMonth(), d.getDate()); const isSameDay = (a: Date, b: Date) => - a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate(); + a.getFullYear() === b.getFullYear() && + a.getMonth() === b.getMonth() && + a.getDate() === b.getDate(); const weekdayMonFirst = (date: Date) => (date.getDay() + 6) % 7; const EKATERINBURG_TZ = 'Asia/Yekaterinburg'; @@ -82,7 +101,9 @@ type DailyStatusCompat = DailyStatusResponse & { export default function DailyReward({ onClaimed }: Props) { const today = useMemo(() => startOfDay(new Date()), []); - const [view, setView] = useState(() => new Date(today.getFullYear(), today.getMonth(), 1)); + const [view, setView] = useState( + () => new Date(today.getFullYear(), today.getMonth(), 1), + ); const [selected, setSelected] = useState(today); // перенесённая логика статуса/клейма @@ -96,14 +117,19 @@ export default function DailyReward({ onClaimed }: Props) { const viewYear = view.getFullYear(); const viewMonth = view.getMonth(); - const grid = useMemo(() => buildCalendarGrid(viewYear, viewMonth), [viewYear, viewMonth]); + const grid = useMemo( + () => buildCalendarGrid(viewYear, viewMonth), + [viewYear, viewMonth], + ); const streak = status?.streak ?? 0; const wasOnlineToday = status?.was_online_today ?? false; const canClaim = (status?.can_claim ?? false) && wasOnlineToday; - const goPrev = () => setView((v) => new Date(v.getFullYear(), v.getMonth() - 1, 1)); - const goNext = () => setView((v) => new Date(v.getFullYear(), v.getMonth() + 1, 1)); + const goPrev = () => + setView((v) => new Date(v.getFullYear(), v.getMonth() - 1, 1)); + const goNext = () => + setView((v) => new Date(v.getFullYear(), v.getMonth() + 1, 1)); const goToday = () => { const t = new Date(today.getFullYear(), today.getMonth(), 1); setView(t); @@ -156,13 +182,16 @@ export default function DailyReward({ onClaimed }: Props) { }, [clientSecondsLeft]); const todaysReward = useMemo(() => { - const effectiveStreak = canClaim ? Math.max(1, streak === 0 ? 1 : streak) : streak; + const effectiveStreak = canClaim + ? Math.max(1, streak === 0 ? 1 : streak) + : streak; return calcRewardByStreak(effectiveStreak); }, [streak, canClaim]); const subtitle = useMemo(() => { if (!status) return ''; - if (!wasOnlineToday) return 'Награда откроется после входа на сервер сегодня.'; + if (!wasOnlineToday) + return 'Награда откроется после входа на сервер сегодня.'; if (canClaim) return 'Можно забрать прямо сейчас 🎁'; return `До следующей награды: ${formatHHMMSS(clientSecondsLeft)}`; }, [status, wasOnlineToday, canClaim, clientSecondsLeft]); @@ -180,7 +209,9 @@ export default function DailyReward({ onClaimed }: Props) { onClaimed?.(added); } else { if (res.reason === 'not_online_today') { - setError('Чтобы забрать награду — зайдите на сервер сегодня хотя бы на минуту.'); + setError( + 'Чтобы забрать награду — зайдите на сервер сегодня хотя бы на минуту.', + ); } else { setError(res.reason || 'Награда недоступна'); } @@ -197,7 +228,17 @@ export default function DailyReward({ onClaimed }: Props) { }; return ( - + - - + + - + {RU_MONTHS[viewMonth]} {viewYear} @@ -300,7 +358,14 @@ export default function DailyReward({ onClaimed }: Props) { {/* Calendar */} - + {RU_WEEKDAYS.map((w, i) => ( = 5 ? 'rgba(255,255,255,0.75)' : 'rgba(255,255,255,0.6)', + color: + i >= 5 ? 'rgba(255,255,255,0.75)' : 'rgba(255,255,255,0.6)', userSelect: 'none', }} > @@ -317,7 +383,13 @@ export default function DailyReward({ onClaimed }: Props) { ))} - + {grid.map(({ date, inCurrentMonth }) => { const d = startOfDay(date); const isToday = isSameDay(d, today); @@ -336,12 +408,19 @@ export default function DailyReward({ onClaimed }: Props) { borderRadius: 3, position: 'relative', overflow: 'hidden', - border: isSelected ? '1px solid rgba(242,113,33,0.85)' : 'none', - bgcolor: inCurrentMonth ? 'rgba(0,0,0,0.24)' : 'rgba(0,0,0,0.12)', - transition: 'transform 0.18s ease, background-color 0.18s ease, border-color 0.18s ease', + border: isSelected + ? '1px solid rgba(242,113,33,0.85)' + : 'none', + bgcolor: inCurrentMonth + ? 'rgba(0,0,0,0.24)' + : 'rgba(0,0,0,0.12)', + transition: + 'transform 0.18s ease, background-color 0.18s ease, border-color 0.18s ease', transform: isSelected ? 'scale(1.02)' : 'scale(1)', '&:hover': { - bgcolor: inCurrentMonth ? 'rgba(255,255,255,0.06)' : 'rgba(255,255,255,0.04)', + bgcolor: inCurrentMonth + ? 'rgba(255,255,255,0.06)' + : 'rgba(255,255,255,0.04)', transform: 'translateY(-1px)', }, }} @@ -351,7 +430,8 @@ export default function DailyReward({ onClaimed }: Props) { sx={{ position: 'absolute', inset: -20, - background: 'radial-gradient(circle at 50% 50%, rgba(233,64,205,0.22), transparent 55%)', + background: + 'radial-gradient(circle at 50% 50%, rgba(233,64,205,0.22), transparent 55%)', pointerEvents: 'none', }} /> @@ -373,7 +453,9 @@ export default function DailyReward({ onClaimed }: Props) { sx={{ fontSize: 14, fontWeight: 800, - color: inCurrentMonth ? '#fff' : 'rgba(255,255,255,0.35)', + color: inCurrentMonth + ? '#fff' + : 'rgba(255,255,255,0.35)', lineHeight: 1, }} > @@ -386,8 +468,8 @@ export default function DailyReward({ onClaimed }: Props) { color: claimed ? 'rgba(156, 255, 198, 0.9)' : isToday - ? 'rgba(242,113,33,0.95)' - : 'rgba(255,255,255,0.45)', + ? 'rgba(242,113,33,0.95)' + : 'rgba(255,255,255,0.45)', fontWeight: 700, userSelect: 'none', }} @@ -415,52 +497,67 @@ export default function DailyReward({ onClaimed }: Props) { {/* Footer actions */} - + - - Выбрано: {selectedKey} + + Выбрано:{' '} + + {selectedKey} + - - - - - + + +