4.15.0: Добавлена принадлежность желаний к проектам
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m33s

This commit is contained in:
poignatov
2026-02-04 15:46:05 +03:00
parent b9482dc86d
commit c22e56e68a
8 changed files with 252 additions and 18 deletions

View File

@@ -1,8 +1,9 @@
import React, { useState, useEffect, useRef } from 'react'
import React, { useState, useEffect, useRef, useMemo } from 'react'
import { useAuth } from './auth/AuthContext'
import BoardSelector from './BoardSelector'
import LoadingError from './LoadingError'
import WishlistDetail from './WishlistDetail'
import { sortProjectsLikeCurrentWeek } from '../utils/projectUtils'
import './Wishlist.css'
const API_URL = '/api/wishlist'
@@ -45,6 +46,7 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
const [completedLoading, setCompletedLoading] = useState(false)
const [selectedItem, setSelectedItem] = useState(null)
const [selectedWishlistForDetail, setSelectedWishlistForDetail] = useState(null)
const [currentWeekData, setCurrentWeekData] = useState(null)
const fetchingRef = useRef(false)
const fetchingCompletedRef = useRef(false)
const initialFetchDoneRef = useRef(false)
@@ -234,6 +236,24 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
}
}
// Загрузка данных текущей недели для сортировки проектов
const fetchCurrentWeek = async () => {
try {
const response = await authFetch('/api/current-week')
if (response.ok) {
const data = await response.json()
// Обрабатываем ответ: приходит массив с одним объектом [{total: ..., projects: [...]}]
if (Array.isArray(data) && data.length > 0) {
setCurrentWeekData(data[0])
} else if (data && typeof data === 'object') {
setCurrentWeekData(data)
}
}
} catch (err) {
console.error('Error loading current week data:', err)
}
}
// Первая инициализация
useEffect(() => {
if (!initialFetchDoneRef.current) {
@@ -247,6 +267,9 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
// Загружаем доски с сервера
fetchBoards()
// Загружаем данные текущей недели для сортировки проектов
fetchCurrentWeek()
}
}, [])
@@ -557,6 +580,60 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
)
}
// Группируем желания по проектам
const groupedItems = useMemo(() => {
const groups = {}
const noProjectItems = []
items.forEach(item => {
if (item.project_id && item.project_name) {
const projectId = item.project_id
if (!groups[projectId]) {
groups[projectId] = {
projectId: projectId,
projectName: item.project_name,
items: []
}
}
groups[projectId].items.push(item)
} else {
noProjectItems.push(item)
}
})
// Сортируем группы проектов
const projectIds = Object.keys(groups)
if (currentWeekData && projectIds.length > 0) {
const projectNames = projectIds.map(id => groups[id].projectName)
const sortedProjectNames = sortProjectsLikeCurrentWeek(projectNames, currentWeekData)
// Создаем отсортированный массив групп
const sortedGroups = []
sortedProjectNames.forEach(projectName => {
const group = Object.values(groups).find(g => g.projectName === projectName)
if (group) {
sortedGroups.push(group)
}
})
// Добавляем группы, которых нет в currentWeekData (если есть)
Object.values(groups).forEach(group => {
if (!sortedProjectNames.includes(group.projectName)) {
sortedGroups.push(group)
}
})
return { groups: sortedGroups, noProjectItems }
}
// Если нет данных текущей недели, сортируем по алфавиту
const sortedGroups = Object.values(groups).sort((a, b) =>
a.projectName.localeCompare(b.projectName)
)
return { groups: sortedGroups, noProjectItems }
}, [items, currentWeekData])
const renderItem = (item) => {
const isFaded = (!item.unlocked && !item.completed) || item.completed
@@ -646,9 +723,24 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
</div>
) : (
<>
<div className="wishlist-grid">
{items.map(renderItem)}
</div>
{/* Группы проектов */}
{groupedItems.groups.map(group => (
<div key={group.projectId} className="wishlist-project-group">
<div className="wishlist-project-group-title">{group.projectName}</div>
<div className="wishlist-project-group-items">
{group.items.map(renderItem)}
</div>
</div>
))}
{/* Желания без проекта */}
{groupedItems.noProjectItems.length > 0 && (
<div className="wishlist-no-project">
<div className="wishlist-grid">
{groupedItems.noProjectItems.map(renderItem)}
</div>
</div>
)}
{/* Завершённые */}
{completedCount > 0 && (