diff --git a/frontend/src/app/settings/git-projects/page.tsx b/frontend/src/app/settings/git-projects/page.tsx index 004d227..77fdd27 100644 --- a/frontend/src/app/settings/git-projects/page.tsx +++ b/frontend/src/app/settings/git-projects/page.tsx @@ -28,6 +28,7 @@ import { useAuth } from "@/auth/clerk"; import { ForgejoConnectionsTable } from "@/components/git/ForgejoConnectionsTable"; import { ForgejoRepositoriesTable } from "@/components/git/ForgejoRepositoriesTable"; import { DashboardPageLayout } from "@/components/templates/DashboardPageLayout"; +import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { ConfirmActionDialog } from "@/components/ui/confirm-action-dialog"; import { @@ -37,6 +38,7 @@ import { DialogTitle, } from "@/components/ui/dialog"; import { getApiBaseUrl } from "@/lib/api-base"; +import { cn } from "@/lib/utils"; import { deleteForgejoConnection, deleteForgejoRepository, @@ -71,6 +73,72 @@ type AttentionItem = { href?: string; }; +type SettingsTone = "accent" | "success" | "warning" | "danger" | "neutral"; + +const toneStyles: Record< + SettingsTone, + { + panel: string; + icon: string; + rail: string; + text: string; + } +> = { + accent: { + panel: + "border-[color:rgba(96,165,250,0.24)] bg-[linear-gradient(145deg,rgba(96,165,250,0.1),var(--surface)_58%)]", + icon: "border-[color:rgba(96,165,250,0.3)] bg-[color:var(--accent-soft)] text-[color:var(--accent-strong)]", + rail: "bg-[linear-gradient(90deg,rgba(96,165,250,0),rgba(96,165,250,0.82),rgba(96,165,250,0))]", + text: "text-[color:var(--accent-strong)]", + }, + success: { + panel: + "border-[color:rgba(52,211,153,0.22)] bg-[linear-gradient(145deg,rgba(52,211,153,0.09),var(--surface)_58%)]", + icon: "border-[color:rgba(52,211,153,0.3)] bg-[color:rgba(52,211,153,0.14)] text-[color:var(--success)]", + rail: "bg-[linear-gradient(90deg,rgba(52,211,153,0),rgba(52,211,153,0.78),rgba(52,211,153,0))]", + text: "text-[color:var(--success)]", + }, + warning: { + panel: + "border-[color:rgba(251,191,36,0.24)] bg-[linear-gradient(145deg,rgba(251,191,36,0.09),var(--surface)_58%)]", + icon: "border-[color:rgba(251,191,36,0.32)] bg-[color:rgba(251,191,36,0.14)] text-[color:var(--warning)]", + rail: "bg-[linear-gradient(90deg,rgba(251,191,36,0),rgba(251,191,36,0.82),rgba(251,191,36,0))]", + text: "text-[color:var(--warning)]", + }, + danger: { + panel: + "border-[color:rgba(248,113,113,0.24)] bg-[linear-gradient(145deg,rgba(248,113,113,0.09),var(--surface)_58%)]", + icon: "border-[color:rgba(248,113,113,0.3)] bg-[color:rgba(248,113,113,0.12)] text-[color:var(--danger)]", + rail: "bg-[linear-gradient(90deg,rgba(248,113,113,0),rgba(248,113,113,0.78),rgba(248,113,113,0))]", + text: "text-[color:var(--danger)]", + }, + neutral: { + panel: + "border-[color:var(--border)] bg-[linear-gradient(180deg,rgba(255,255,255,0.035),rgba(255,255,255,0)_72%),var(--surface)]", + icon: "border-[color:var(--border-strong)] bg-[color:var(--surface-muted)] text-muted", + rail: "bg-[linear-gradient(90deg,rgba(96,165,250,0),rgba(96,165,250,0.28),rgba(52,211,153,0.2),rgba(96,165,250,0))]", + text: "text-muted", + }, +}; + +function ToneRail({ tone }: { tone: SettingsTone }) { + return ( + + ); +} + +function panelClass(tone: SettingsTone = "neutral") { + return cn( + "relative overflow-hidden rounded-xl border p-4 shadow-lush md:p-5", + toneStyles[tone].panel, + ); +} + const repositoryName = (repository: ForgejoRepository) => repository.display_name || `${repository.owner}/${repository.repo}`; @@ -114,16 +182,23 @@ function SectionHeader({ title, description, action, + tone = "accent", }: { icon: ReactNode; title: string; description: string; action?: ReactNode; + tone?: SettingsTone; }) { return (
@@ -158,7 +241,7 @@ function StatCard({ {value}
{metric.label}
@@ -281,11 +389,35 @@ function AttentionPanel({ const hasWebhookItems = items.some((item) => item.kind === "webhook"); return ( -
@@ -393,11 +525,13 @@ function LastImportPanel({
}) {
const lastImport = importRuns[0] ?? null;
return (
-