import { useState, useEffect } from 'react' import { useNavigate } from 'react-router-dom' import { ChevronLeft, Info, Gift, Trophy, Star } from 'lucide-react' import { getLadderTop } from '../utils/api' import { hapticFeedback } from '../utils/telegram' import './MonthlyLadder.css' export default function MonthlyLadder({ user }) { const navigate = useNavigate() const [topUsers, setTopUsers] = useState([]) const [currentUser, setCurrentUser] = useState(null) const [currentUserRank, setCurrentUserRank] = useState(null) const [loading, setLoading] = useState(true) const [showInfo, setShowInfo] = useState(false) const [timeLeft, setTimeLeft] = useState({ days: 0, hours: 0, minutes: 0, seconds: 0 }) useEffect(() => { loadLadder() updateCountdown() const interval = setInterval(updateCountdown, 1000) return () => clearInterval(interval) }, []) const updateCountdown = () => { // Получить текущее московское время const getMoscowTime = () => { const now = new Date() // Москва = UTC+3 const moscowOffset = 3 * 60 * 60 * 1000 // 3 часа в миллисекундах const utcTime = now.getTime() + (now.getTimezoneOffset() * 60 * 1000) return new Date(utcTime + moscowOffset) } // Получить новогоднюю дату по московскому времени (1 января следующего года, 00:00 MSK) const getNewYearMoscow = () => { const moscowNow = getMoscowTime() const year = moscowNow.getFullYear() + 1 // Создаем дату 1 января следующего года в UTC, затем вычитаем смещение const moscowNewYear = new Date(Date.UTC(year, 0, 1, 0, 0, 0, 0)) const moscowOffset = 3 * 60 * 60 * 1000 return new Date(moscowNewYear.getTime() - moscowOffset) } const now = getMoscowTime() const newYear = getNewYearMoscow() const diff = newYear.getTime() - now.getTime() const days = Math.floor(diff / (1000 * 60 * 60 * 24)) const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)) const seconds = Math.floor((diff % (1000 * 60)) / 1000) setTimeLeft({ days, hours, minutes, seconds }) } const loadLadder = async () => { try { setLoading(true) const data = await getLadderTop(5) setTopUsers(data.topUsers || []) setCurrentUser(data.currentUser) setCurrentUserRank(data.currentUserRank) } catch (error) { console.error('Ошибка загрузки ладдера:', error) } finally { setLoading(false) } } const getRankIcon = (rank) => { switch (rank) { case 1: return case 2: return case 3: return default: return {rank} } } const getPrize = (rank) => { switch (rank) { case 1: return '$50' case 2: return '$30' case 3: return '$15' case 4: return '$5' case 5: return '$5' default: return null } } const formatTickets = (tickets) => { return tickets?.toLocaleString('ru-RU') || '0' } return (
{/* Хедер */}

Monthly Ladder

{/* Новогодний декор */}
❄️
❄️
❄️
❄️
❄️
❄️
{/* Отсчет до нового года */}

До Нового Года

{timeLeft.days} дней
:
{String(timeLeft.hours).padStart(2, '0')} часов
:
{String(timeLeft.minutes).padStart(2, '0')} минут
:
{String(timeLeft.seconds).padStart(2, '0')} секунд

Ваши посты, ваши арты, ваша слава. Остальное потом.

{/* Топ 5 пользователей */}

Топ 5

Призы: 1 место - $50, 2 место - $30, 3 место - $15, 4-5 места - $5

{loading ? (
) : (
{topUsers.map((topUser, index) => { const isCurrentUser = user && (topUser._id === user.id || topUser._id?.toString() === user.id?.toString()) const prize = getPrize(topUser.rank) return (
{getRankIcon(topUser.rank)}
{topUser.username}
{topUser.firstName || topUser.username} {isCurrentUser && }
{formatTickets(topUser.tickets)} билетов {prize && {prize}}
) })}
)}
{/* Текущий пользователь (если не в топе) */} {currentUser && currentUserRank > 5 && (

Ваша позиция

{currentUserRank}
{currentUser.username}
{currentUser.firstName || currentUser.username}
{formatTickets(currentUser.tickets)} билетов
)} {/* Модальное окно с информацией */} {showInfo && (
setShowInfo(false)}>
e.stopPropagation()}>

За что начисляются баллы

1. Посты

+15 баллов за создание поста

Лимит: 5 постов в день

2. Лайки

Ставишь лайки: +1 балл за лайк

Лимит: 50 в день

Получаешь лайки: +2 балла за лайк под твоей записью

Лимит учёта: 100 лайков в день

3. Комментарии

Пишешь комментарии: +4 балла за комментарий длиной 10+ символов

Лимит: 20 комментариев в день

Получаешь комментарии: +6 баллов за комментарий под твоим постом

4. Рефералы

+100 баллов за одного валидного реферала

Лимит: 3 реферала в день

5. Ваше творчество (арты)

Публикация: +40 баллов за арт, прошедший модерацию

Лимит: 1 арт в день / 5 в неделю

Реакции на арт:

+8 баллов за лайк под артом

+12 баллов за комментарий под артом (1 комментарий от одного человека в сутки)

Лимит: до 100 баллов в сутки с реакций на один арт

Немного правил

Лайки/комменты от аккаунтов младше 24 часов не считаем

Комменты <10 символов = 0 баллов

Ограничение на баллы по входящим реакциям, чтобы боты не устроили ферму

)}
) }