4.20.3: Дата next_show_at в целях-задачах
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m37s

This commit is contained in:
poignatov
2026-02-05 12:33:16 +03:00
parent 736f08887a
commit 126f9ec919
5 changed files with 47 additions and 3 deletions

View File

@@ -1 +1 @@
4.20.2 4.20.3

View File

@@ -431,6 +431,7 @@ type UnlockConditionDisplay struct {
Type string `json:"type"` Type string `json:"type"`
TaskID *int `json:"task_id,omitempty"` // ID задачи (для task_completion) TaskID *int `json:"task_id,omitempty"` // ID задачи (для task_completion)
TaskName *string `json:"task_name,omitempty"` 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) ProjectID *int `json:"project_id,omitempty"` // ID проекта (для project_points)
ProjectName *string `json:"project_name,omitempty"` ProjectName *string `json:"project_name,omitempty"`
RequiredPoints *float64 `json:"required_points,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, wc.user_id AS condition_user_id,
tc.task_id, tc.task_id,
t.name AS task_name, t.name AS task_name,
t.next_show_at AS task_next_show_at,
sc.project_id, sc.project_id,
p.name AS project_name, p.name AS project_name,
sc.required_points, sc.required_points,
@@ -11137,6 +11139,7 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
var conditionUserID sql.NullInt64 var conditionUserID sql.NullInt64
var taskID sql.NullInt64 var taskID sql.NullInt64
var taskName sql.NullString var taskName sql.NullString
var taskNextShowAt sql.NullTime
var projectID sql.NullInt64 var projectID sql.NullInt64
var projectName sql.NullString var projectName sql.NullString
var requiredPoints sql.NullFloat64 var requiredPoints sql.NullFloat64
@@ -11145,7 +11148,7 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
err := rows.Scan( err := rows.Scan(
&itemID, &name, &price, &imagePath, &link, &completed, &itemProjectID, &itemProjectName, &itemID, &name, &price, &imagePath, &link, &completed, &itemProjectID, &itemProjectName,
&conditionID, &displayOrder, &taskConditionID, &scoreConditionID, &conditionUserID, &conditionID, &displayOrder, &taskConditionID, &scoreConditionID, &conditionUserID,
&taskID, &taskName, &projectID, &projectName, &requiredPoints, &startDate, &taskID, &taskName, &taskNextShowAt, &projectID, &projectName, &requiredPoints, &startDate,
) )
if err != nil { if err != nil {
log.Printf("Error scanning wishlist item: %v", err) 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 condition.TaskCompleted = &isCompleted
} }
} }
if taskNextShowAt.Valid {
nextShowAtStr := taskNextShowAt.Time.Format(time.RFC3339)
condition.TaskNextShowAt = &nextShowAtStr
}
} else if scoreConditionID.Valid { } else if scoreConditionID.Valid {
condition.Type = "project_points" condition.Type = "project_points"
if projectName.Valid { if projectName.Valid {

View File

@@ -1,6 +1,6 @@
{ {
"name": "play-life-web", "name": "play-life-web",
"version": "4.20.2", "version": "4.20.3",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -189,6 +189,13 @@
flex: 1; flex: 1;
} }
.condition-task-date {
margin-top: 0.125rem;
margin-left: calc(16px + 0.5rem);
font-size: 0.85rem;
color: #6b7280;
}
.condition-progress { .condition-progress {
margin-top: 0.125rem; margin-top: 0.125rem;
margin-left: calc(16px + 0.5rem); margin-left: calc(16px + 0.5rem);

View File

@@ -416,6 +416,36 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
</svg> </svg>
<span className="condition-text">{conditionText}</span> <span className="condition-text">{conditionText}</span>
</div> </div>
{/* Показываем дату для целей-задач, если 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 (
<div className="condition-task-date">
{dateText}
</div>
)
})()}
{progress && progress.type === 'points' && !isMet && ( {progress && progress.type === 'points' && !isMet && (
<div className="condition-progress"> <div className="condition-progress">
<div className="progress-bar"> <div className="progress-bar">