feat: F025 button & action logic audit — global toast, confirm dialog, wired mutations
- Add ToastProvider (global MUI Snackbar stack) + toastStore (Zustand) - Add ConfirmDialog reusable component for destructive actions - Wire toast feedback to all async mutations: review status, AI output status, match approval, shortlist add/remove/title/finalize, signal review actions - Fix dead UserMenu buttons (Profil, Einstellungen) — show info toast - Migrate local Snackbar instances in AddToShortlistDialog and FutureSignalDetailPanel to global toast store Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Box, Button, Chip, CircularProgress, Divider, IconButton, LinearProgress, Paper, Snackbar, Typography } from '@mui/material'
|
||||
import { Box, Button, Chip, CircularProgress, Divider, IconButton, LinearProgress, Paper, Typography } from '@mui/material'
|
||||
import { X } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { SignalTypeBadge } from './SignalTypeBadge'
|
||||
@@ -7,6 +7,7 @@ import { SignalReviewStatusBadge } from './SignalReviewStatusBadge'
|
||||
import { FutureSignalDisclaimer } from './FutureSignalDisclaimer'
|
||||
import { useUpdateSignalReviewStatus } from '../../hooks/useFutureSignals'
|
||||
import { useShortlistStore } from '../../stores/shortlistStore'
|
||||
import { useToastStore } from '../../stores/toastStore'
|
||||
import { reviewService } from '../../services/reviewService'
|
||||
import { ReviewStatus } from '../../domain/enums'
|
||||
import type { FutureSignal } from '../../domain/futureSignal'
|
||||
@@ -51,22 +52,37 @@ interface Props {
|
||||
export function FutureSignalDetailPanel({ signal, onClose }: Props) {
|
||||
const updateStatus = useUpdateSignalReviewStatus()
|
||||
const { openAddDialog } = useShortlistStore()
|
||||
const [snackbar, setSnackbar] = useState<string | null>(null)
|
||||
const showToast = useToastStore((s) => s.showToast)
|
||||
const [reviewTaskSent, setReviewTaskSent] = useState(false)
|
||||
|
||||
const reviewStatus = signal.reviewStatus ?? ReviewStatus.UNREVIEWED
|
||||
const isRejected = reviewStatus === ReviewStatus.REJECTED
|
||||
const isApproved = reviewStatus === ReviewStatus.APPROVED
|
||||
|
||||
const STATUS_TOAST: Record<string, string> = {
|
||||
IN_REVIEW: 'Signal zur Prüfung markiert.',
|
||||
APPROVED: 'Signal genehmigt.',
|
||||
REJECTED: 'Signal abgelehnt.',
|
||||
FLAGGED: 'Signal markiert.',
|
||||
}
|
||||
|
||||
async function handleStatus(status: typeof ReviewStatus[keyof typeof ReviewStatus]) {
|
||||
await updateStatus.mutateAsync({ id: signal.id, status })
|
||||
setSnackbar(`Status aktualisiert: ${status}`)
|
||||
try {
|
||||
await updateStatus.mutateAsync({ id: signal.id, status })
|
||||
showToast(STATUS_TOAST[status] ?? 'Status aktualisiert.')
|
||||
} catch {
|
||||
showToast('Statusänderung fehlgeschlagen.', 'error')
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSendReview() {
|
||||
await reviewService.createReviewTask(signal.id)
|
||||
setReviewTaskSent(true)
|
||||
setSnackbar('Prüfungsaufgabe erstellt')
|
||||
try {
|
||||
await reviewService.createReviewTask(signal.id)
|
||||
setReviewTaskSent(true)
|
||||
showToast('Prüfungsaufgabe erstellt.')
|
||||
} catch {
|
||||
showToast('Prüfungsaufgabe konnte nicht erstellt werden.', 'error')
|
||||
}
|
||||
}
|
||||
|
||||
function handleShortlist() {
|
||||
@@ -242,13 +258,6 @@ export function FutureSignalDetailPanel({ signal, onClose }: Props) {
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Snackbar
|
||||
open={!!snackbar}
|
||||
autoHideDuration={2500}
|
||||
onClose={() => setSnackbar(null)}
|
||||
message={snackbar}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user