Исправление дублирования чужих целей в wishlist и защита от редактирования
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m16s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m16s
This commit is contained in:
@@ -10,7 +10,7 @@ const PROJECTS_API_URL = '/projects'
|
||||
const WISHLIST_FORM_STATE_KEY = 'wishlistFormPendingState'
|
||||
|
||||
function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, boardId }) {
|
||||
const { authFetch } = useAuth()
|
||||
const { authFetch, user } = useAuth()
|
||||
const [name, setName] = useState('')
|
||||
const [price, setPrice] = useState('')
|
||||
const [link, setLink] = useState('')
|
||||
@@ -97,6 +97,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
required_points: cond.required_points || null,
|
||||
start_date: cond.start_date || null,
|
||||
display_order: idx,
|
||||
user_id: cond.user_id || null,
|
||||
})))
|
||||
} else {
|
||||
setUnlockConditions([])
|
||||
@@ -251,6 +252,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
required_points: cond.required_points || null,
|
||||
start_date: cond.start_date || null,
|
||||
display_order: idx,
|
||||
user_id: cond.user_id || null,
|
||||
})))
|
||||
} else {
|
||||
setUnlockConditions([])
|
||||
@@ -469,6 +471,12 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
}
|
||||
|
||||
const handleEditCondition = (index) => {
|
||||
const condition = unlockConditions[index]
|
||||
// Проверяем, что условие принадлежит текущему пользователю
|
||||
if (condition.user_id && condition.user_id !== user?.id) {
|
||||
setToastMessage({ text: 'Нельзя редактировать чужие цели', type: 'error' })
|
||||
return
|
||||
}
|
||||
setEditingConditionIndex(index)
|
||||
setShowConditionForm(true)
|
||||
}
|
||||
@@ -493,6 +501,12 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
}
|
||||
|
||||
const handleRemoveCondition = (index) => {
|
||||
const condition = unlockConditions[index]
|
||||
// Проверяем, что условие принадлежит текущему пользователю
|
||||
if (condition.user_id && condition.user_id !== user?.id) {
|
||||
setToastMessage({ text: 'Нельзя удалять чужие цели', type: 'error' })
|
||||
return
|
||||
}
|
||||
setUnlockConditions(unlockConditions.filter((_, i) => i !== index))
|
||||
}
|
||||
|
||||
@@ -783,25 +797,32 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
<label>Цель</label>
|
||||
{unlockConditions.length > 0 && (
|
||||
<div className="conditions-list">
|
||||
{unlockConditions.map((cond, idx) => (
|
||||
<div key={idx} className="condition-item">
|
||||
<span
|
||||
className="condition-item-text"
|
||||
onClick={() => handleEditCondition(idx)}
|
||||
>
|
||||
{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.project_name || 'Не выбран'}${cond.start_date ? ` с ${new Date(cond.start_date + 'T00:00:00').toLocaleDateString('ru-RU')}` : ' за всё время'}`}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleRemoveCondition(idx)}
|
||||
className="remove-condition-button"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
{unlockConditions.map((cond, idx) => {
|
||||
const isOwnCondition = !cond.user_id || cond.user_id === user?.id
|
||||
return (
|
||||
<div key={idx} className="condition-item">
|
||||
<span
|
||||
className={`condition-item-text ${!isOwnCondition ? 'condition-item-other-user' : ''}`}
|
||||
onClick={() => isOwnCondition && handleEditCondition(idx)}
|
||||
style={{ cursor: isOwnCondition ? 'pointer' : 'default' }}
|
||||
title={!isOwnCondition ? 'Чужая цель - нельзя редактировать' : ''}
|
||||
>
|
||||
{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.project_name || 'Не выбран'}${cond.start_date ? ` с ${new Date(cond.start_date + 'T00:00:00').toLocaleDateString('ru-RU')}` : ' за всё время'}`}
|
||||
</span>
|
||||
{isOwnCondition && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleRemoveCondition(idx)}
|
||||
className="remove-condition-button"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user