import { useState, useEffect } from 'react' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { motion, AnimatePresence } from 'framer-motion' import { Plus, Settings, Flame, Calendar, ChevronRight, Archive, ArchiveRestore } from 'lucide-react' import { format } from 'date-fns' import { ru } from 'date-fns/locale' import { habitsApi } from '../api/habits' import CreateHabitModal from '../components/CreateHabitModal' import EditHabitModal from '../components/EditHabitModal' import Navigation from '../components/Navigation' import clsx from 'clsx' export default function Habits({ embedded = false }) { const [showCreateModal, setShowCreateModal] = useState(false) const [editingHabit, setEditingHabit] = useState(null) const [showArchived, setShowArchived] = useState(false) const [habitStats, setHabitStats] = useState({}) const queryClient = useQueryClient() const { data: habits = [], isLoading } = useQuery({ queryKey: ['habits', showArchived], queryFn: () => habitsApi.list().then(h => showArchived ? h : h.filter(x => !x.is_archived)), }) const { data: archivedHabits = [] } = useQuery({ queryKey: ['habits-archived'], queryFn: () => habitsApi.list().then(h => h.filter(x => x.is_archived)), enabled: showArchived, }) useEffect(() => { if (habits.length > 0) loadStats() }, [habits]) const loadStats = async () => { const statsMap = {} await Promise.all(habits.map(async (habit) => { try { const stats = await habitsApi.getHabitStats(habit.id) statsMap[habit.id] = stats } catch (e) {} })) setHabitStats(statsMap) } const archiveMutation = useMutation({ mutationFn: ({ id, archived }) => habitsApi.update(id, { is_archived: archived }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['habits'] }) queryClient.invalidateQueries({ queryKey: ['habits-archived'] }) queryClient.invalidateQueries({ queryKey: ['stats'] }) }, }) const getFrequencyLabel = (habit) => { if (habit.frequency === 'daily') return 'Ежедневно' if (habit.frequency === 'weekly' && habit.target_days) { const days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'] return habit.target_days.map(d => days[d - 1]).join(', ') } if (habit.frequency === 'interval') return `Каждые ${habit.target_count} дн.` if (habit.frequency === 'custom') return `Каждые ${habit.target_count} дн.` return habit.frequency } const activeHabits = habits.filter(h => !h.is_archived) const archivedList = habits.filter(h => h.is_archived) return (
{!embedded &&

Мои привычки

{activeHabits.length} активных

}
{isLoading ? (
{[1, 2, 3].map((i) => (
))}
) : activeHabits.length === 0 && !showArchived ? (

Нет привычек

Создай свою первую привычку!

) : ( <>
{activeHabits.map((habit, index) => ( setEditingHabit(habit)} onArchive={() => archiveMutation.mutate({ id: habit.id, archived: true })} /> ))}
{archivedList.length > 0 && (
{showArchived && ( {archivedList.map((habit, index) => (
{habit.icon || '✨'}

{habit.name}

{getFrequencyLabel(habit)}

))}
)}
)} )}
{!embedded && } setShowCreateModal(false)} /> setEditingHabit(null)} habit={editingHabit} />
) } function HabitListItem({ habit, index, stats, frequencyLabel, onEdit, onArchive }) { return (
{habit.icon || '✨'}

{habit.name}

{frequencyLabel} {stats && stats.current_streak > 0 && ( {stats.current_streak} дн. )}
{stats && (

{stats.this_month}

в месяц

)}
) }