From 126f9ec919c8f79d96daea6b95d14a13d90c1d3a Mon Sep 17 00:00:00 2001 From: poignatov Date: Thu, 5 Feb 2026 12:33:16 +0300 Subject: [PATCH] =?UTF-8?q?4.20.3:=20=D0=94=D0=B0=D1=82=D0=B0=20next=5Fsho?= =?UTF-8?q?w=5Fat=20=D0=B2=20=D1=86=D0=B5=D0=BB=D1=8F=D1=85-=D0=B7=D0=B0?= =?UTF-8?q?=D0=B4=D0=B0=D1=87=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VERSION | 2 +- play-life-backend/main.go | 9 +++++- play-life-web/package.json | 2 +- .../src/components/WishlistDetail.css | 7 +++++ .../src/components/WishlistDetail.jsx | 30 +++++++++++++++++++ 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index f7e4d90..94a7e5e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.20.2 +4.20.3 diff --git a/play-life-backend/main.go b/play-life-backend/main.go index 3a86311..381c53f 100644 --- a/play-life-backend/main.go +++ b/play-life-backend/main.go @@ -431,6 +431,7 @@ type UnlockConditionDisplay struct { Type string `json:"type"` TaskID *int `json:"task_id,omitempty"` // ID задачи (для task_completion) TaskName *string `json:"task_name,omitempty"` + TaskNextShowAt *string `json:"task_next_show_at,omitempty"` // Дата следующего показа задачи (для task_completion) ProjectID *int `json:"project_id,omitempty"` // ID проекта (для project_points) ProjectName *string `json:"project_name,omitempty"` RequiredPoints *float64 `json:"required_points,omitempty"` @@ -11096,6 +11097,7 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) { wc.user_id AS condition_user_id, tc.task_id, t.name AS task_name, + t.next_show_at AS task_next_show_at, sc.project_id, p.name AS project_name, sc.required_points, @@ -11137,6 +11139,7 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) { var conditionUserID sql.NullInt64 var taskID sql.NullInt64 var taskName sql.NullString + var taskNextShowAt sql.NullTime var projectID sql.NullInt64 var projectName sql.NullString var requiredPoints sql.NullFloat64 @@ -11145,7 +11148,7 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) { err := rows.Scan( &itemID, &name, &price, &imagePath, &link, &completed, &itemProjectID, &itemProjectName, &conditionID, &displayOrder, &taskConditionID, &scoreConditionID, &conditionUserID, - &taskID, &taskName, &projectID, &projectName, &requiredPoints, &startDate, + &taskID, &taskName, &taskNextShowAt, &projectID, &projectName, &requiredPoints, &startDate, ) if err != nil { log.Printf("Error scanning wishlist item: %v", err) @@ -11230,6 +11233,10 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) { condition.TaskCompleted = &isCompleted } } + if taskNextShowAt.Valid { + nextShowAtStr := taskNextShowAt.Time.Format(time.RFC3339) + condition.TaskNextShowAt = &nextShowAtStr + } } else if scoreConditionID.Valid { condition.Type = "project_points" if projectName.Valid { diff --git a/play-life-web/package.json b/play-life-web/package.json index 3af9f0f..d454a42 100644 --- a/play-life-web/package.json +++ b/play-life-web/package.json @@ -1,6 +1,6 @@ { "name": "play-life-web", - "version": "4.20.2", + "version": "4.20.3", "type": "module", "scripts": { "dev": "vite", diff --git a/play-life-web/src/components/WishlistDetail.css b/play-life-web/src/components/WishlistDetail.css index d78711d..05e1fea 100644 --- a/play-life-web/src/components/WishlistDetail.css +++ b/play-life-web/src/components/WishlistDetail.css @@ -189,6 +189,13 @@ flex: 1; } +.condition-task-date { + margin-top: 0.125rem; + margin-left: calc(16px + 0.5rem); + font-size: 0.85rem; + color: #6b7280; +} + .condition-progress { margin-top: 0.125rem; margin-left: calc(16px + 0.5rem); diff --git a/play-life-web/src/components/WishlistDetail.jsx b/play-life-web/src/components/WishlistDetail.jsx index 269ca36..70b8e1e 100644 --- a/play-life-web/src/components/WishlistDetail.jsx +++ b/play-life-web/src/components/WishlistDetail.jsx @@ -416,6 +416,36 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p {conditionText} + {/* Показываем дату для целей-задач, если next_show_at > сегодня */} + {condition.type === 'task_completion' && condition.task_next_show_at && (() => { + const showDate = new Date(condition.task_next_show_at) + // Нормализуем дату: устанавливаем время в 00:00:00 в локальном времени + const showDateNormalized = new Date(showDate.getFullYear(), showDate.getMonth(), showDate.getDate()) + + const today = new Date() + const todayNormalized = new Date(today.getFullYear(), today.getMonth(), today.getDate()) + + // Показываем только если дата > сегодня + if (showDateNormalized.getTime() <= todayNormalized.getTime()) { + return null + } + + const tomorrowNormalized = new Date(todayNormalized) + tomorrowNormalized.setDate(tomorrowNormalized.getDate() + 1) + + let dateText + if (showDateNormalized.getTime() === tomorrowNormalized.getTime()) { + dateText = 'Завтра' + } else { + dateText = showDate.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long', year: 'numeric' }) + } + + return ( +
+ {dateText} +
+ ) + })()} {progress && progress.type === 'points' && !isMet && (