Исправление отображения проектов в условиях
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m21s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m21s
This commit is contained in:
@@ -334,6 +334,7 @@ type WishlistRequest struct {
|
||||
}
|
||||
|
||||
type UnlockConditionRequest struct {
|
||||
ID *int `json:"id,omitempty"` // ID существующего условия (для сохранения чужих условий)
|
||||
Type string `json:"type"`
|
||||
TaskID *int `json:"task_id,omitempty"`
|
||||
ProjectID *int `json:"project_id,omitempty"`
|
||||
@@ -2865,6 +2866,12 @@ func (a *App) initAuthDB() error {
|
||||
// Не возвращаем ошибку, чтобы приложение могло запуститься
|
||||
}
|
||||
|
||||
// Apply migration 025: Remove wishlist conditions without user_id
|
||||
if err := a.applyMigration025(); err != nil {
|
||||
log.Printf("Warning: Failed to apply migration 025: %v", err)
|
||||
// Не возвращаем ошибку, чтобы приложение могло запуститься
|
||||
}
|
||||
|
||||
// Clean up expired refresh tokens (only those with expiration date set)
|
||||
a.DB.Exec("DELETE FROM refresh_tokens WHERE expires_at IS NOT NULL AND expires_at < NOW()")
|
||||
|
||||
@@ -3268,6 +3275,50 @@ func (a *App) applyMigration024() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyMigration025 применяет миграцию 025_remove_conditions_without_user_id.sql
|
||||
func (a *App) applyMigration025() error {
|
||||
log.Printf("Applying migration 025: Remove wishlist conditions without user_id")
|
||||
|
||||
// Проверяем, есть ли условия без user_id
|
||||
var count int
|
||||
err := a.DB.QueryRow(`
|
||||
SELECT COUNT(*)
|
||||
FROM wishlist_conditions
|
||||
WHERE user_id IS NULL
|
||||
`).Scan(&count)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check conditions without user_id: %w", err)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
log.Printf("Migration 025 already applied (no conditions without user_id), skipping")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Found %d conditions without user_id, removing them", count)
|
||||
|
||||
// Читаем SQL из файла миграции
|
||||
migrationPath := "migrations/025_remove_conditions_without_user_id.sql"
|
||||
if _, err := os.Stat(migrationPath); os.IsNotExist(err) {
|
||||
// Пробуем альтернативный путь (в Docker)
|
||||
migrationPath = "/migrations/025_remove_conditions_without_user_id.sql"
|
||||
}
|
||||
|
||||
migrationSQL, err := os.ReadFile(migrationPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read migration file %s: %w", migrationPath, err)
|
||||
}
|
||||
|
||||
// Выполняем миграцию
|
||||
if _, err := a.DB.Exec(string(migrationSQL)); err != nil {
|
||||
return fmt.Errorf("failed to execute migration 025: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("Migration 025 applied successfully, removed %d conditions without user_id", count)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) initPlayLifeDB() error {
|
||||
// Создаем таблицу projects
|
||||
createProjectsTable := `
|
||||
@@ -9372,7 +9423,7 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
|
||||
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
|
||||
LEFT JOIN tasks t ON tc.task_id = t.id
|
||||
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
|
||||
WHERE wi.user_id = $1
|
||||
AND wi.deleted = FALSE
|
||||
AND ($2 = TRUE OR wi.completed = FALSE)
|
||||
@@ -9457,6 +9508,10 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
|
||||
if projectName.Valid {
|
||||
condition.ProjectName = &projectName.String
|
||||
}
|
||||
if projectID.Valid {
|
||||
projectIDVal := int(projectID.Int64)
|
||||
condition.ProjectID = &projectIDVal
|
||||
}
|
||||
if requiredPoints.Valid {
|
||||
condition.RequiredPoints = &requiredPoints.Float64
|
||||
}
|
||||
@@ -9633,18 +9688,43 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
|
||||
}
|
||||
|
||||
// saveWishlistConditions сохраняет условия для желания
|
||||
// userID - автор условий (пользователь, который создает/обновляет условия)
|
||||
func (a *App) saveWishlistConditions(
|
||||
tx *sql.Tx,
|
||||
wishlistItemID int,
|
||||
userID int,
|
||||
conditions []UnlockConditionRequest,
|
||||
) error {
|
||||
// Удаляем старые условия
|
||||
_, err := tx.Exec(`
|
||||
DELETE FROM wishlist_conditions
|
||||
// Получаем все существующие условия с их user_id перед удалением
|
||||
existingConditions := make(map[int]int) // map[conditionID]userID
|
||||
rows, err := tx.Query(`
|
||||
SELECT id, user_id
|
||||
FROM wishlist_conditions
|
||||
WHERE wishlist_item_id = $1
|
||||
`, wishlistItemID)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error getting existing conditions: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var condID int
|
||||
var condUserID sql.NullInt64
|
||||
if err := rows.Scan(&condID, &condUserID); err != nil {
|
||||
return fmt.Errorf("error scanning existing condition: %w", err)
|
||||
}
|
||||
if condUserID.Valid {
|
||||
existingConditions[condID] = int(condUserID.Int64)
|
||||
}
|
||||
}
|
||||
|
||||
// Удаляем только условия текущего пользователя
|
||||
_, err = tx.Exec(`
|
||||
DELETE FROM wishlist_conditions
|
||||
WHERE wishlist_item_id = $1 AND user_id = $2
|
||||
`, wishlistItemID, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting user conditions: %w", err)
|
||||
}
|
||||
|
||||
if len(conditions) == 0 {
|
||||
@@ -9654,8 +9734,8 @@ func (a *App) saveWishlistConditions(
|
||||
// Подготавливаем statement для вставки условий
|
||||
stmt, err := tx.Prepare(`
|
||||
INSERT INTO wishlist_conditions
|
||||
(wishlist_item_id, task_condition_id, score_condition_id, display_order)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
(wishlist_item_id, user_id, task_condition_id, score_condition_id, display_order)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -9743,9 +9823,20 @@ func (a *App) saveWishlistConditions(
|
||||
scoreConditionID = scID
|
||||
}
|
||||
|
||||
// Определяем user_id для условия:
|
||||
// - Если условие имеет id и это условие существовало - используем его оригинальный user_id
|
||||
// - Иначе - используем userID текущего пользователя
|
||||
conditionUserID := userID
|
||||
if condition.ID != nil {
|
||||
if originalUserID, exists := existingConditions[*condition.ID]; exists {
|
||||
conditionUserID = originalUserID
|
||||
}
|
||||
}
|
||||
|
||||
// Создаём связь
|
||||
_, err = stmt.Exec(
|
||||
wishlistItemID,
|
||||
conditionUserID,
|
||||
taskConditionID,
|
||||
scoreConditionID,
|
||||
displayOrder,
|
||||
@@ -9937,7 +10028,7 @@ func (a *App) createWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Сохраняем условия
|
||||
if len(req.UnlockConditions) > 0 {
|
||||
err = a.saveWishlistConditions(tx, wishlistID, req.UnlockConditions)
|
||||
err = a.saveWishlistConditions(tx, wishlistID, userID, req.UnlockConditions)
|
||||
if err != nil {
|
||||
log.Printf("Error saving wishlist conditions: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error saving wishlist conditions: %v", err), http.StatusInternalServerError)
|
||||
@@ -10088,7 +10179,7 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
|
||||
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
|
||||
LEFT JOIN tasks t ON tc.task_id = t.id
|
||||
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
|
||||
WHERE wi.id = $1
|
||||
AND wi.deleted = FALSE
|
||||
ORDER BY wc.display_order, wc.id
|
||||
@@ -10185,6 +10276,12 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if projectName.Valid {
|
||||
condition.ProjectName = &projectName.String
|
||||
}
|
||||
if projectID.Valid {
|
||||
projectIDVal := int(projectID.Int64)
|
||||
condition.ProjectID = &projectIDVal
|
||||
points, _ := a.calculateProjectPointsFromDate(int(projectID.Int64), startDate, conditionOwnerID)
|
||||
condition.CurrentPoints = &points
|
||||
}
|
||||
if requiredPoints.Valid {
|
||||
condition.RequiredPoints = &requiredPoints.Float64
|
||||
}
|
||||
@@ -10192,10 +10289,6 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
|
||||
dateStr := startDate.Time.Format("2006-01-02")
|
||||
condition.StartDate = &dateStr
|
||||
}
|
||||
if projectID.Valid {
|
||||
points, _ := a.calculateProjectPointsFromDate(int(projectID.Int64), startDate, conditionOwnerID)
|
||||
condition.CurrentPoints = &points
|
||||
}
|
||||
}
|
||||
|
||||
item.UnlockConditions = append(item.UnlockConditions, condition)
|
||||
@@ -10358,7 +10451,7 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Сохраняем условия
|
||||
err = a.saveWishlistConditions(tx, itemID, req.UnlockConditions)
|
||||
err = a.saveWishlistConditions(tx, itemID, userID, req.UnlockConditions)
|
||||
if err != nil {
|
||||
log.Printf("Error saving wishlist conditions: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error saving wishlist conditions: %v", err), http.StatusInternalServerError)
|
||||
@@ -10397,7 +10490,7 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
|
||||
LEFT JOIN tasks t ON tc.task_id = t.id
|
||||
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
|
||||
WHERE wi.id = $1
|
||||
AND wi.deleted = FALSE
|
||||
ORDER BY wc.display_order, wc.id
|
||||
@@ -10500,6 +10593,12 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if projectName.Valid {
|
||||
condition.ProjectName = &projectName.String
|
||||
}
|
||||
if projectID.Valid {
|
||||
projectIDVal := int(projectID.Int64)
|
||||
condition.ProjectID = &projectIDVal
|
||||
points, _ := a.calculateProjectPointsFromDate(int(projectID.Int64), startDate, conditionOwnerID)
|
||||
condition.CurrentPoints = &points
|
||||
}
|
||||
if requiredPoints.Valid {
|
||||
condition.RequiredPoints = &requiredPoints.Float64
|
||||
}
|
||||
@@ -10507,10 +10606,6 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
dateStr := startDate.Time.Format("2006-01-02")
|
||||
condition.StartDate = &dateStr
|
||||
}
|
||||
if projectID.Valid {
|
||||
points, _ := a.calculateProjectPointsFromDate(int(projectID.Int64), startDate, conditionOwnerID)
|
||||
condition.CurrentPoints = &points
|
||||
}
|
||||
}
|
||||
|
||||
item.UnlockConditions = append(item.UnlockConditions, condition)
|
||||
@@ -10944,11 +11039,13 @@ func (a *App) copyWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var link sql.NullString
|
||||
var imagePath sql.NullString
|
||||
var ownerID int
|
||||
var boardID sql.NullInt64
|
||||
var authorID sql.NullInt64
|
||||
err = a.DB.QueryRow(`
|
||||
SELECT user_id, name, price, link, image_path
|
||||
SELECT user_id, name, price, link, image_path, board_id, author_id
|
||||
FROM wishlist_items
|
||||
WHERE id = $1 AND deleted = FALSE
|
||||
`, itemID).Scan(&ownerID, &name, &price, &link, &imagePath)
|
||||
`, itemID).Scan(&ownerID, &name, &price, &link, &imagePath, &boardID, &authorID)
|
||||
|
||||
if err == sql.ErrNoRows || ownerID != userID {
|
||||
sendErrorWithCORS(w, "Wishlist item not found", http.StatusNotFound)
|
||||
@@ -11039,11 +11136,23 @@ func (a *App) copyWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
linkVal = link.String
|
||||
}
|
||||
|
||||
// Определяем значения для board_id и author_id
|
||||
var boardIDVal, authorIDVal interface{}
|
||||
if boardID.Valid {
|
||||
boardIDVal = int(boardID.Int64)
|
||||
}
|
||||
if authorID.Valid {
|
||||
authorIDVal = int(authorID.Int64)
|
||||
} else {
|
||||
// Если author_id не был установлен, используем текущего пользователя
|
||||
authorIDVal = userID
|
||||
}
|
||||
|
||||
err = tx.QueryRow(`
|
||||
INSERT INTO wishlist_items (user_id, name, price, link, completed, deleted)
|
||||
VALUES ($1, $2, $3, $4, FALSE, FALSE)
|
||||
INSERT INTO wishlist_items (user_id, board_id, author_id, name, price, link, completed, deleted)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, FALSE, FALSE)
|
||||
RETURNING id
|
||||
`, userID, name+" (копия)", priceVal, linkVal).Scan(&newWishlistID)
|
||||
`, ownerID, boardIDVal, authorIDVal, name+" (копия)", priceVal, linkVal).Scan(&newWishlistID)
|
||||
if err != nil {
|
||||
log.Printf("Error creating wishlist copy: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error creating wishlist copy: %v", err), http.StatusInternalServerError)
|
||||
@@ -11052,7 +11161,7 @@ func (a *App) copyWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Сохраняем условия
|
||||
if len(conditions) > 0 {
|
||||
err = a.saveWishlistConditions(tx, newWishlistID, conditions)
|
||||
err = a.saveWishlistConditions(tx, newWishlistID, userID, conditions)
|
||||
if err != nil {
|
||||
log.Printf("Error saving wishlist conditions: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error saving wishlist conditions: %v", err), http.StatusInternalServerError)
|
||||
@@ -12022,7 +12131,7 @@ func (a *App) getBoardCompletedHandler(w http.ResponseWriter, r *http.Request) {
|
||||
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
|
||||
LEFT JOIN tasks t ON tc.task_id = t.id
|
||||
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
|
||||
LEFT JOIN users u ON wc.user_id = u.id
|
||||
WHERE wi.board_id = $1
|
||||
AND wi.deleted = FALSE
|
||||
@@ -12178,6 +12287,7 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
|
||||
wi.image_path,
|
||||
wi.link,
|
||||
wi.completed,
|
||||
COALESCE(wi.author_id, wi.user_id) AS item_owner_id,
|
||||
wc.id AS condition_id,
|
||||
wc.display_order,
|
||||
wc.task_condition_id,
|
||||
@@ -12194,7 +12304,7 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
|
||||
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
|
||||
LEFT JOIN tasks t ON tc.task_id = t.id
|
||||
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
|
||||
WHERE wi.board_id = $1
|
||||
AND wi.deleted = FALSE
|
||||
AND wi.completed = FALSE
|
||||
@@ -12216,6 +12326,7 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
|
||||
var imagePath sql.NullString
|
||||
var link sql.NullString
|
||||
var completed bool
|
||||
var itemOwnerID sql.NullInt64
|
||||
var conditionID sql.NullInt64
|
||||
var displayOrder sql.NullInt64
|
||||
var taskConditionID sql.NullInt64
|
||||
@@ -12229,7 +12340,7 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
|
||||
var startDate sql.NullTime
|
||||
|
||||
err := rows.Scan(
|
||||
&itemID, &name, &price, &imagePath, &link, &completed,
|
||||
&itemID, &name, &price, &imagePath, &link, &completed, &itemOwnerID,
|
||||
&conditionID, &displayOrder, &taskConditionID, &scoreConditionID, &conditionUserID,
|
||||
&taskID, &taskName, &projectID, &projectName, &requiredPoints, &startDate,
|
||||
)
|
||||
@@ -12268,8 +12379,12 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
|
||||
DisplayOrder: int(displayOrder.Int64),
|
||||
}
|
||||
|
||||
// Используем user_id из условия, если он есть, иначе используем текущего пользователя
|
||||
conditionOwnerID := userID
|
||||
// Используем user_id из условия, если он есть, иначе используем владельца желания
|
||||
if !itemOwnerID.Valid {
|
||||
log.Printf("Warning: item_owner_id is NULL for wishlist item %d, skipping condition", itemID)
|
||||
continue
|
||||
}
|
||||
conditionOwnerID := int(itemOwnerID.Int64)
|
||||
if conditionUserID.Valid {
|
||||
conditionOwnerID = int(conditionUserID.Int64)
|
||||
}
|
||||
@@ -12291,6 +12406,13 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
|
||||
if projectName.Valid {
|
||||
condition.ProjectName = &projectName.String
|
||||
}
|
||||
if projectID.Valid {
|
||||
projectIDVal := int(projectID.Int64)
|
||||
condition.ProjectID = &projectIDVal
|
||||
// Считаем текущие баллы для владельца условия
|
||||
points, _ := a.calculateProjectPointsFromDate(int(projectID.Int64), startDate, conditionOwnerID)
|
||||
condition.CurrentPoints = &points
|
||||
}
|
||||
if requiredPoints.Valid {
|
||||
condition.RequiredPoints = &requiredPoints.Float64
|
||||
}
|
||||
@@ -12298,11 +12420,6 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
|
||||
dateStr := startDate.Time.Format("2006-01-02")
|
||||
condition.StartDate = &dateStr
|
||||
}
|
||||
// Считаем текущие баллы для владельца условия
|
||||
if projectID.Valid {
|
||||
points, _ := a.calculateProjectPointsFromDate(int(projectID.Int64), startDate, conditionOwnerID)
|
||||
condition.CurrentPoints = &points
|
||||
}
|
||||
}
|
||||
|
||||
item.UnlockConditions = append(item.UnlockConditions, condition)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
-- Migration: Remove wishlist conditions without user_id
|
||||
-- These conditions should not exist as every condition must have an owner
|
||||
-- This migration removes orphaned conditions that were created before the fix
|
||||
|
||||
-- ============================================
|
||||
-- Remove conditions without user_id
|
||||
-- ============================================
|
||||
DELETE FROM wishlist_conditions WHERE user_id IS NULL;
|
||||
|
||||
-- ============================================
|
||||
-- Comments
|
||||
-- ============================================
|
||||
COMMENT ON COLUMN wishlist_conditions.user_id IS 'Owner of this condition. Each user has their own goals on shared boards. Required field.';
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "play-life-web",
|
||||
"version": "3.14.5",
|
||||
"version": "3.14.6",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -450,15 +450,31 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Ошибка при копировании')
|
||||
const errorText = await response.text().catch(() => '')
|
||||
throw new Error(errorText || 'Ошибка при копировании')
|
||||
}
|
||||
|
||||
const newItem = await response.json()
|
||||
|
||||
setSelectedItem(null)
|
||||
|
||||
// Очищаем кэш для текущей доски, чтобы новое желание появилось в списке
|
||||
if (selectedBoardId) {
|
||||
try {
|
||||
localStorage.removeItem(`${ITEMS_CACHE_KEY}_${selectedBoardId}`)
|
||||
} catch (err) {
|
||||
console.error('Error clearing cache:', err)
|
||||
}
|
||||
}
|
||||
|
||||
// Обновляем список
|
||||
await fetchItems()
|
||||
|
||||
// Открываем форму редактирования для нового желания
|
||||
onNavigate?.('wishlist-form', { wishlistId: newItem.id, boardId: selectedBoardId })
|
||||
} catch (err) {
|
||||
setError(err.message)
|
||||
console.error('Error copying wishlist item:', err)
|
||||
setError(err.message || 'Ошибка при копировании')
|
||||
setSelectedItem(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,9 +88,12 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
setImageUrl(data.image_url || null)
|
||||
if (data.unlock_conditions) {
|
||||
setUnlockConditions(data.unlock_conditions.map((cond, idx) => ({
|
||||
id: cond.id || null,
|
||||
type: cond.type,
|
||||
task_id: cond.type === 'task_completion' ? tasks.find(t => t.name === cond.task_name)?.id : null,
|
||||
project_id: cond.type === 'project_points' ? projects.find(p => p.project_name === cond.project_name)?.project_id : null,
|
||||
task_id: cond.type === 'task_completion' ? (cond.task_id || tasks.find(t => t.name === cond.task_name)?.id) : null,
|
||||
task_name: cond.task_name || null,
|
||||
project_id: cond.type === 'project_points' ? (cond.project_id || projects.find(p => p.project_name === cond.project_name)?.project_id) : null,
|
||||
project_name: cond.project_name || null,
|
||||
required_points: cond.required_points || null,
|
||||
start_date: cond.start_date || null,
|
||||
display_order: idx,
|
||||
@@ -239,9 +242,12 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
setImageFile(null) // Сбрасываем imageFile при загрузке существующего желания
|
||||
if (data.unlock_conditions) {
|
||||
setUnlockConditions(data.unlock_conditions.map((cond, idx) => ({
|
||||
id: cond.id || null,
|
||||
type: cond.type,
|
||||
task_id: cond.type === 'task_completion' ? tasks.find(t => t.name === cond.task_name)?.id : null,
|
||||
project_id: cond.type === 'project_points' ? projects.find(p => p.project_name === cond.project_name)?.project_id : null,
|
||||
task_id: cond.type === 'task_completion' ? (cond.task_id || tasks.find(t => t.name === cond.task_name)?.id) : null,
|
||||
task_name: cond.task_name || null,
|
||||
project_id: cond.type === 'project_points' ? (cond.project_id || projects.find(p => p.project_name === cond.project_name)?.project_id) : null,
|
||||
project_name: cond.project_name || null,
|
||||
required_points: cond.required_points || null,
|
||||
start_date: cond.start_date || null,
|
||||
display_order: idx,
|
||||
@@ -531,6 +537,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
price: price ? parseFloat(price) : null,
|
||||
link: link.trim() || null,
|
||||
unlock_conditions: unlockConditions.map(cond => ({
|
||||
id: cond.id || null,
|
||||
type: cond.type,
|
||||
task_id: cond.type === 'task_completion' ? cond.task_id : null,
|
||||
project_id: cond.type === 'project_points' ? cond.project_id : null,
|
||||
@@ -784,7 +791,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
>
|
||||
{cond.type === 'task_completion'
|
||||
? `Задача: ${tasks.find(t => t.id === cond.task_id)?.name || 'Не выбрана'}`
|
||||
: `Баллы: ${cond.required_points} в ${projects.find(p => p.project_id === cond.project_id)?.project_name || 'Не выбран'}${cond.start_date ? ` с ${new Date(cond.start_date + 'T00:00:00').toLocaleDateString('ru-RU')}` : ' за всё время'}`}
|
||||
: `Баллы: ${cond.required_points} в ${projects.find(p => p.project_id === cond.project_id)?.project_name || cond.project_name || 'Не выбран'}${cond.start_date ? ` с ${new Date(cond.start_date + 'T00:00:00').toLocaleDateString('ru-RU')}` : ' за всё время'}`}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user