feat: integrate sonner for toast notifications and enhance UI feedback
Added the sonner library for toast notifications across various components, improving user feedback for actions such as saving settings, syncing rules, and handling errors. Updated the layout to include a Toaster component for consistent notification display. Refactored alert messages in the backups, gre, and filters pages to utilize the new notification system, enhancing overall user experience.
This commit is contained in:
+19
-15
@@ -5,6 +5,7 @@ import { PageHeader } from "@/components/page-header"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
|
||||
import { Flag } from "@/components/flag"
|
||||
import { StatusDot } from "@/components/status-dot"
|
||||
import { Sparkline } from "@/components/sparkline"
|
||||
@@ -1001,12 +1002,12 @@ function ResourcesTab({ resources, serversList, liveApi }: { resources: ServerRe
|
||||
|
||||
{/* ── Alert banner ──────────────────────────────────────────────────── */}
|
||||
{alerts.length > 0 && (
|
||||
<div className="flex items-start gap-3 rounded-lg border border-red-500/30 bg-red-500/5 px-4 py-3">
|
||||
<ServerCrashIcon className="size-4 text-red-500 shrink-0 mt-0.5" />
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-xs font-semibold text-red-600 dark:text-red-400 mb-1">
|
||||
{alerts.length} {alerts.length === 1 ? "сервер требует внимания" : "сервера требуют внимания"}
|
||||
</p>
|
||||
<Alert variant="destructive">
|
||||
<ServerCrashIcon />
|
||||
<AlertTitle className="text-xs mb-1">
|
||||
{alerts.length} {alerts.length === 1 ? "сервер требует внимания" : "сервера требуют внимания"}
|
||||
</AlertTitle>
|
||||
<AlertDescription>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{alerts.map(r => {
|
||||
const s = r.server!
|
||||
@@ -1016,16 +1017,15 @@ function ResourcesTab({ resources, serversList, liveApi }: { resources: ServerRe
|
||||
if (r.hddPct >= 85) issues.push(`HDD ${r.hddPct}%`)
|
||||
if ((r.temp ?? 0) >= 70) issues.push(`${r.temp}°C`)
|
||||
return (
|
||||
<span key={r.serverId} className="inline-flex items-center gap-1 text-[11px] font-mono
|
||||
rounded border border-red-500/30 bg-red-500/10 px-2 py-0.5 text-red-400">
|
||||
<span key={r.serverId} className="inline-flex items-center gap-1 text-[11px] font-mono rounded border border-destructive/30 bg-destructive/10 px-2 py-0.5">
|
||||
<Flag code={s.country} size={10} />
|
||||
{s.name} — {issues.join(", ")}
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{/* ── KPI summary ───────────────────────────────────────────────────── */}
|
||||
@@ -2330,8 +2330,11 @@ export default function UptimePage() {
|
||||
|
||||
{/* ── error ── */}
|
||||
{speedError && (
|
||||
<div className="mx-6 mt-4 text-xs text-destructive bg-destructive/10 border border-destructive/20 rounded-md px-3 py-2">
|
||||
{speedError}
|
||||
<div className="mx-6 mt-4">
|
||||
<Alert variant="destructive" className="py-2 text-xs">
|
||||
<AlertCircleIcon />
|
||||
<AlertDescription>{speedError}</AlertDescription>
|
||||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -2650,9 +2653,10 @@ export default function UptimePage() {
|
||||
|
||||
{opError && (
|
||||
<div className="px-6 pt-4">
|
||||
<div className="text-xs text-destructive bg-destructive/10 border border-destructive/20 rounded-md px-3 py-2">
|
||||
{opError}
|
||||
</div>
|
||||
<Alert variant="destructive" className="py-2 text-xs">
|
||||
<AlertCircleIcon />
|
||||
<AlertDescription>{opError}</AlertDescription>
|
||||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user