feat(cabinet): дать пользователю самому удалять задачи из кабинета
All checks were successful
Deploy / test (push) Successful in 3m3s
Deploy / deploy (push) Successful in 20s

Раньше удалить задачу мог только админ через свою панель — обычный
пользователь с зависшей (например, навечно застрявшей в processing)
задачей не мог убрать её из кабинета вообще. Кнопка удаления на
карточке + снято искусственное ограничение "нельзя удалить, пока
processing" (все воркеры уже корректно проверяют task is None перед
записью, удаление во время реальной обработки безопасно).
This commit is contained in:
jze9
2026-08-25 15:24:46 +05:00
parent 5eac465917
commit 29301c3a4c
3 changed files with 30 additions and 10 deletions

View File

@@ -1,13 +1,14 @@
import { Link } from 'react-router-dom';
import { formatDistanceToNow } from 'date-fns';
import { ru } from 'date-fns/locale';
import { Search, FileText, BookOpen, AlignLeft, ChevronRight } from 'lucide-react';
import { Search, FileText, BookOpen, AlignLeft, ChevronRight, Trash2 } from 'lucide-react';
import { clsx } from 'clsx';
import { StatusBadge } from './StatusBadge';
import type { Task } from '../types';
interface TaskCardProps {
task: Task;
onDelete?: (publicId: string) => void;
}
const TYPE_CONFIG = {
@@ -63,7 +64,7 @@ function getTaskSummary(task: Task): string {
return 'Результат готов';
}
export function TaskCard({ task }: TaskCardProps) {
export function TaskCard({ task, onDelete }: TaskCardProps) {
const config = TYPE_CONFIG[task.type] || TYPE_CONFIG.search;
const Icon = config.icon;
const summary = getTaskSummary(task);
@@ -94,6 +95,21 @@ export function TaskCard({ task }: TaskCardProps) {
</p>
</div>
{/* Удалить */}
{onDelete && (
<button
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (confirm('Удалить задачу?')) onDelete(task.public_id);
}}
title="Удалить"
className="p-1.5 rounded-lg text-gray-300 hover:text-red-600 hover:bg-red-50 flex-shrink-0 transition-colors"
>
<Trash2 className="w-4 h-4" />
</button>
)}
{/* Стрелка */}
<ChevronRight className="w-4 h-4 text-gray-300 group-hover:text-brand-500 flex-shrink-0 transition-colors" />
</div>

View File

@@ -1,5 +1,5 @@
import { Navigate, useNavigate, Link } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Crown, Search, Shield, BookOpen, ShieldAlert, Settings as SettingsIcon } from 'lucide-react';
import toast from 'react-hot-toast';
import { TaskCard } from '../components/TaskCard';
@@ -17,6 +17,16 @@ const PLAN_BADGE_STYLES = {
export function Cabinet() {
const { isAuthenticated, user } = useAuthStore();
const navigate = useNavigate();
const qc = useQueryClient();
const deleteTask = useMutation({
mutationFn: (publicId: string) => tasksApi.delete(publicId),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['tasks'] });
toast.success('Задача удалена');
},
onError: () => toast.error('Не удалось удалить задачу'),
});
const openAdmin = async () => {
try {
@@ -144,7 +154,7 @@ export function Cabinet() {
{tasks && tasks.length > 0 && (
<div className="space-y-2">
{tasks.map((task) => (
<TaskCard key={task.public_id} task={task} />
<TaskCard key={task.public_id} task={task} onDelete={(id) => deleteTask.mutate(id)} />
))}
</div>
)}