5.9.0: Статус Отклонено для желаний
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m20s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m20s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "play-life-web",
|
||||
"version": "5.8.0",
|
||||
"version": "5.9.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -188,6 +188,31 @@
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.card-status-indicator {
|
||||
position: absolute;
|
||||
top: 0.25rem;
|
||||
left: 0.25rem;
|
||||
border-radius: 50%;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
z-index: 10;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.card-status-completed {
|
||||
background: #27ae60;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.card-status-rejected {
|
||||
background: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.wishlist .card-menu-button {
|
||||
position: absolute;
|
||||
top: 0.25rem;
|
||||
|
||||
@@ -616,6 +616,20 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
|
||||
className={`wishlist-card ${isFaded ? 'faded' : ''}`}
|
||||
onClick={() => handleItemClick(item)}
|
||||
>
|
||||
{item.completed && (
|
||||
<div className={`card-status-indicator ${item.rejected ? 'card-status-rejected' : 'card-status-completed'}`}>
|
||||
{item.rejected ? (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
) : (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="20 6 9 17 4 12"></polyline>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
className="card-menu-button"
|
||||
onClick={(e) => handleMenuClick(item, e)}
|
||||
|
||||
@@ -246,6 +246,7 @@
|
||||
.wishlist-detail-edit-button,
|
||||
.wishlist-detail-complete-button,
|
||||
.wishlist-detail-uncomplete-button,
|
||||
.wishlist-detail-reject-button,
|
||||
.wishlist-detail-delete-button {
|
||||
width: 100%;
|
||||
padding: 0.75rem 1.5rem;
|
||||
@@ -267,6 +268,12 @@
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.wishlist-detail-action-buttons {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.wishlist-detail-complete-button {
|
||||
flex: 1;
|
||||
background-color: #27ae60;
|
||||
@@ -283,6 +290,22 @@
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wishlist-detail-reject-button {
|
||||
flex: 1;
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.wishlist-detail-reject-button:hover:not(:disabled) {
|
||||
background-color: #c0392b;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.wishlist-detail-reject-button:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wishlist-detail-create-task-button {
|
||||
padding: 0.75rem;
|
||||
background-color: transparent;
|
||||
|
||||
@@ -78,6 +78,7 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
|
||||
if (onNavigate) {
|
||||
onNavigate('wishlist')
|
||||
}
|
||||
onClose?.()
|
||||
} catch (err) {
|
||||
console.error('Error completing wishlist:', err)
|
||||
setToastMessage({ text: err.message || 'Ошибка при завершении', type: 'error' })
|
||||
@@ -86,6 +87,34 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
|
||||
}
|
||||
}
|
||||
|
||||
const handleReject = async () => {
|
||||
if (!wishlistItem || !wishlistItem.unlocked) return
|
||||
|
||||
setIsCompleting(true)
|
||||
try {
|
||||
const response = await authFetch(`${API_URL}/${wishlistId}/reject`, {
|
||||
method: 'POST',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Ошибка при отклонении')
|
||||
}
|
||||
|
||||
if (onRefresh) {
|
||||
onRefresh()
|
||||
}
|
||||
if (onNavigate) {
|
||||
onNavigate('wishlist')
|
||||
}
|
||||
onClose?.()
|
||||
} catch (err) {
|
||||
console.error('Error rejecting wishlist:', err)
|
||||
setToastMessage({ text: err.message || 'Ошибка при отклонении', type: 'error' })
|
||||
} finally {
|
||||
setIsCompleting(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleUncomplete = async () => {
|
||||
if (!wishlistItem || !wishlistItem.completed) return
|
||||
|
||||
@@ -103,6 +132,7 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
|
||||
onRefresh()
|
||||
}
|
||||
fetchWishlistDetail()
|
||||
onClose?.()
|
||||
} catch (err) {
|
||||
console.error('Error uncompleting wishlist:', err)
|
||||
setToastMessage({ text: err.message || 'Ошибка при возобновлении желания', type: 'error' })
|
||||
@@ -687,13 +717,22 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
onClick={handleComplete}
|
||||
disabled={isCompleting}
|
||||
className="wishlist-detail-complete-button"
|
||||
>
|
||||
{isCompleting ? 'Завершение...' : 'Завершить'}
|
||||
</button>
|
||||
<div className="wishlist-detail-action-buttons">
|
||||
<button
|
||||
onClick={handleComplete}
|
||||
disabled={isCompleting}
|
||||
className="wishlist-detail-complete-button"
|
||||
>
|
||||
{isCompleting ? '...' : 'Завершить'}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleReject}
|
||||
disabled={isCompleting}
|
||||
className="wishlist-detail-reject-button"
|
||||
>
|
||||
{isCompleting ? '...' : 'Отклонить'}
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ position: 'relative', display: 'inline-block' }}>
|
||||
<button
|
||||
onClick={handleCreateTask}
|
||||
|
||||
Reference in New Issue
Block a user