|
-
+
|
{(item.maxLatency / 1000).toFixed(1)}ms
diff --git a/apps/web/src/components/dashboard/IoThreadChart.tsx b/apps/web/src/components/dashboard/IoThreadChart.tsx
index f1b4468a..93866363 100644
--- a/apps/web/src/components/dashboard/IoThreadChart.tsx
+++ b/apps/web/src/components/dashboard/IoThreadChart.tsx
@@ -80,16 +80,16 @@ export function IoThreadChart({ data, isMultiThreaded, hasEverSeenActivity }: Pr
diff --git a/apps/web/src/components/dashboard/MemoryChart.tsx b/apps/web/src/components/dashboard/MemoryChart.tsx
index 38e1e158..dd9fc47e 100644
--- a/apps/web/src/components/dashboard/MemoryChart.tsx
+++ b/apps/web/src/components/dashboard/MemoryChart.tsx
@@ -40,16 +40,16 @@ export function MemoryChart({ data }: Props) {
diff --git a/apps/web/src/components/dashboard/OpsChart.tsx b/apps/web/src/components/dashboard/OpsChart.tsx
index a160e120..a064866d 100644
--- a/apps/web/src/components/dashboard/OpsChart.tsx
+++ b/apps/web/src/components/dashboard/OpsChart.tsx
@@ -34,7 +34,7 @@ export function OpsChart({ data }: Props) {
diff --git a/apps/web/src/components/metrics/SlowLogPatternAnalysis.tsx b/apps/web/src/components/metrics/SlowLogPatternAnalysis.tsx
index 532b7856..32e4b08b 100644
--- a/apps/web/src/components/metrics/SlowLogPatternAnalysis.tsx
+++ b/apps/web/src/components/metrics/SlowLogPatternAnalysis.tsx
@@ -16,14 +16,14 @@ interface Props {
}
const COLORS = [
- '#ef4444',
- '#f97316',
- '#eab308',
- '#22c55e',
- '#06b6d4',
- '#3b82f6',
- '#8b5cf6',
- '#ec4899',
+ 'var(--chart-1)',
+ 'var(--chart-2)',
+ 'var(--chart-3)',
+ 'var(--chart-4)',
+ 'var(--chart-5)',
+ 'var(--chart-warning)',
+ 'var(--chart-info)',
+ 'var(--chart-critical)',
];
export function SlowLogPatternAnalysisView({ analysis }: Props) {
diff --git a/apps/web/src/components/migration/AnalysisForm.tsx b/apps/web/src/components/migration/AnalysisForm.tsx
index bca2b749..7c986565 100644
--- a/apps/web/src/components/migration/AnalysisForm.tsx
+++ b/apps/web/src/components/migration/AnalysisForm.tsx
@@ -94,7 +94,7 @@ export function AnalysisForm({ onStart }: Props) {
{sameConnection && (
-
+
Source and target must be different connections
)}
@@ -155,7 +155,7 @@ export function AnalysisForm({ onStart }: Props) {
{error && (
-
+
{error}
)}
diff --git a/apps/web/src/components/migration/ExecutionPanel.tsx b/apps/web/src/components/migration/ExecutionPanel.tsx
index 4368f265..6f97c4c2 100644
--- a/apps/web/src/components/migration/ExecutionPanel.tsx
+++ b/apps/web/src/components/migration/ExecutionPanel.tsx
@@ -23,11 +23,11 @@ function StatusBadge({ status }: { status: string }) {
case 'completed':
return Completed;
case 'failed':
- return Failed;
+ return Failed;
case 'cancelled':
return Cancelled;
default:
- return {status};
+ return {status};
}
}
@@ -109,7 +109,7 @@ export function ExecutionPanel({ executionId, onStopped }: Props) {
{execution.status === 'running' && (
@@ -134,7 +134,7 @@ export function ExecutionPanel({ executionId, onStopped }: Props) {
{/* Status banners */}
{execution.status === 'failed' && (
-
+
{execution.error ?? 'Migration failed'}
)}
diff --git a/apps/web/src/components/migration/ValidationPanel.tsx b/apps/web/src/components/migration/ValidationPanel.tsx
index 5ea65677..822d79a2 100644
--- a/apps/web/src/components/migration/ValidationPanel.tsx
+++ b/apps/web/src/components/migration/ValidationPanel.tsx
@@ -98,7 +98,7 @@ export function ValidationPanel({ validationId, onComplete }: Props) {
)}
{validation.status === 'failed' && (
-
+
{validation.error ?? 'Validation failed'}
)}
diff --git a/apps/web/src/components/migration/sections/BaselineSection.tsx b/apps/web/src/components/migration/sections/BaselineSection.tsx
index 3bf1e718..4aad1662 100644
--- a/apps/web/src/components/migration/sections/BaselineSection.tsx
+++ b/apps/web/src/components/migration/sections/BaselineSection.tsx
@@ -56,7 +56,7 @@ function StatusBadge({ status }: { status: BaselineMetricStatus }) {
case 'degraded':
return degraded;
case 'unavailable':
- return unavailable;
+ return unavailable;
}
}
diff --git a/apps/web/src/components/migration/sections/DataTypeSection.tsx b/apps/web/src/components/migration/sections/DataTypeSection.tsx
index 370a7f65..dc97c4bc 100644
--- a/apps/web/src/components/migration/sections/DataTypeSection.tsx
+++ b/apps/web/src/components/migration/sections/DataTypeSection.tsx
@@ -1,7 +1,7 @@
import type { MigrationAnalysisResult } from '@betterdb/shared';
import { PieChart, Pie, Cell, Tooltip, ResponsiveContainer, Legend } from 'recharts';
-const COLORS = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#06b6d4', '#6b7280'];
+const COLORS = ['var(--chart-1)', 'var(--chart-2)', 'var(--chart-warning)', 'var(--destructive)', 'var(--chart-3)', 'var(--chart-info)', 'var(--muted-foreground)'];
const TYPE_NAMES = ['string', 'hash', 'list', 'set', 'zset', 'stream', 'other'] as const;
function formatBytes(bytes: number): string {
diff --git a/apps/web/src/components/migration/sections/KeyCountSection.tsx b/apps/web/src/components/migration/sections/KeyCountSection.tsx
index fd236ff7..764f6ad5 100644
--- a/apps/web/src/components/migration/sections/KeyCountSection.tsx
+++ b/apps/web/src/components/migration/sections/KeyCountSection.tsx
@@ -17,7 +17,7 @@ export function KeyCountSection({ keyCount }: Props) {
? 'text-green-700'
: discrepancyPercent <= 5
? 'text-amber-700'
- : 'text-red-700';
+ : 'text-destructive';
const sign = discrepancy >= 0 ? '+' : '';
diff --git a/apps/web/src/components/migration/sections/SampleValidationSection.tsx b/apps/web/src/components/migration/sections/SampleValidationSection.tsx
index 6113a6c8..d6892b92 100644
--- a/apps/web/src/components/migration/sections/SampleValidationSection.tsx
+++ b/apps/web/src/components/migration/sections/SampleValidationSection.tsx
@@ -38,10 +38,10 @@ export function SampleValidationSection({ sample }: Props) {
{sample.missing > 0 && (
- {sample.missing} missing
+ {sample.missing} missing
)}
{sample.typeMismatches > 0 && (
- {sample.typeMismatches} type mismatch{sample.typeMismatches !== 1 ? 'es' : ''}
+ {sample.typeMismatches} type mismatch{sample.typeMismatches !== 1 ? 'es' : ''}
)}
{sample.valueMismatches > 0 && (
{sample.valueMismatches} value mismatch{sample.valueMismatches !== 1 ? 'es' : ''}
diff --git a/apps/web/src/components/migration/sections/SummarySection.tsx b/apps/web/src/components/migration/sections/SummarySection.tsx
index 9507a06b..a31acb66 100644
--- a/apps/web/src/components/migration/sections/SummarySection.tsx
+++ b/apps/web/src/components/migration/sections/SummarySection.tsx
@@ -17,8 +17,8 @@ function DbBadge({ dbType, dbVersion, connectionName }: {
const colorClass = dbType === 'valkey'
? 'bg-teal-100 text-teal-700'
: dbType === 'redis'
- ? 'bg-red-100 text-red-700'
- : 'bg-gray-100 text-gray-700';
+ ? 'bg-muted text-foreground'
+ : 'bg-muted text-foreground';
return (
diff --git a/apps/web/src/components/migration/sections/TtlSection.tsx b/apps/web/src/components/migration/sections/TtlSection.tsx
index a19a5b93..486a9af9 100644
--- a/apps/web/src/components/migration/sections/TtlSection.tsx
+++ b/apps/web/src/components/migration/sections/TtlSection.tsx
@@ -18,11 +18,11 @@ export function TtlSection({ job }: Props) {
}
const data = [
- { name: 'No Expiry', value: ttl.noExpiry, color: '#6b7280' },
- { name: '< 1 hour', value: ttl.expiresWithin1h, color: '#f59e0b' },
- { name: '< 24 hours', value: ttl.expiresWithin24h, color: '#3b82f6' },
- { name: '< 7 days', value: ttl.expiresWithin7d, color: '#10b981' },
- { name: '> 7 days', value: ttl.expiresAfter7d, color: '#8b5cf6' },
+ { name: 'No Expiry', value: ttl.noExpiry, color: 'var(--muted-foreground)' },
+ { name: '< 1 hour', value: ttl.expiresWithin1h, color: 'var(--chart-warning)' },
+ { name: '< 24 hours', value: ttl.expiresWithin24h, color: 'var(--chart-1)' },
+ { name: '< 7 days', value: ttl.expiresWithin7d, color: 'var(--chart-2)' },
+ { name: '> 7 days', value: ttl.expiresAfter7d, color: 'var(--chart-3)' },
];
return (
diff --git a/apps/web/src/components/migration/sections/VerdictSection.tsx b/apps/web/src/components/migration/sections/VerdictSection.tsx
index 3fab6243..a1dcd338 100644
--- a/apps/web/src/components/migration/sections/VerdictSection.tsx
+++ b/apps/web/src/components/migration/sections/VerdictSection.tsx
@@ -11,9 +11,9 @@ const SEVERITY_ICON_MAP: Record = {
- blocking: { icon: XCircle, color: 'text-red-600' },
+ blocking: { icon: XCircle, color: 'text-destructive' },
warning: { icon: AlertTriangle, color: 'text-amber-600' },
- info: { icon: Info, color: 'text-blue-600' },
+ info: { icon: Info, color: 'text-primary' },
};
interface Props {
@@ -39,8 +39,8 @@ export function VerdictSection({ job }: Props) {
let bannerMessage: string;
if (blockingCount > 0) {
- bannerBg = 'bg-red-50 border-red-200';
- bannerText = 'text-red-800';
+ bannerBg = 'bg-destructive/10 border-destructive/20';
+ bannerText = 'text-destructive';
BannerIcon = XCircle;
bannerMessage = `${blockingCount} blocking issue(s) — resolve before migrating.`;
} else if (warningCount > 0) {
diff --git a/apps/web/src/components/pages/metric-forecasting/MetricChart.tsx b/apps/web/src/components/pages/metric-forecasting/MetricChart.tsx
index 01540c8d..b8670f98 100644
--- a/apps/web/src/components/pages/metric-forecasting/MetricChart.tsx
+++ b/apps/web/src/components/pages/metric-forecasting/MetricChart.tsx
@@ -93,7 +93,7 @@ export function MetricChart({
)}
diff --git a/apps/web/src/components/pages/metric-forecasting/MetricForecastCard.tsx b/apps/web/src/components/pages/metric-forecasting/MetricForecastCard.tsx
index 5bf929a5..54aaab4f 100644
--- a/apps/web/src/components/pages/metric-forecasting/MetricForecastCard.tsx
+++ b/apps/web/src/components/pages/metric-forecasting/MetricForecastCard.tsx
@@ -3,9 +3,9 @@ import { Card } from '../../ui/card';
import { formatMetricValue, formatGrowthRate } from './formatters';
const TREND_COLORS = {
- rising: 'text-red-600 dark:text-red-400',
+ rising: 'text-destructive',
falling: 'text-green-600 dark:text-green-400',
- stable: 'text-blue-600 dark:text-blue-400',
+ stable: 'text-primary',
} as const;
export function MetricForecastCard({
diff --git a/apps/web/src/components/pages/metric-forecasting/MetricInsufficientData.tsx b/apps/web/src/components/pages/metric-forecasting/MetricInsufficientData.tsx
index 1c5c8898..2de9ee77 100644
--- a/apps/web/src/components/pages/metric-forecasting/MetricInsufficientData.tsx
+++ b/apps/web/src/components/pages/metric-forecasting/MetricInsufficientData.tsx
@@ -11,7 +11,7 @@ export function MetricInsufficientData({
}) {
return (
-
+
{forecast.insufficientDataMessage}
diff --git a/apps/web/src/components/pages/metric-forecasting/MetricSettingsPanel.tsx b/apps/web/src/components/pages/metric-forecasting/MetricSettingsPanel.tsx
index 547a0ab1..601ab75d 100644
--- a/apps/web/src/components/pages/metric-forecasting/MetricSettingsPanel.tsx
+++ b/apps/web/src/components/pages/metric-forecasting/MetricSettingsPanel.tsx
@@ -1,6 +1,6 @@
import type { MetricForecastSettings, MetricForecastSettingsUpdate, MetricKindMeta } from '@betterdb/shared';
import { Card } from '../../ui/card';
-import { Toggle } from '../../ui/toggle';
+import { Switch } from '../../ui/switch';
const WINDOW_PRESETS = [
{ label: '1h', value: 3600000 },
@@ -34,15 +34,15 @@ export function MetricSettingsPanel({
Instance Settings
{saveStatus === 'saved' && Saved}
- {saveStatus === 'error' && Error saving}
+ {saveStatus === 'error' && Error saving}
- onUpdate({ enabled: !settings.enabled })}
+ onCheckedChange={(checked) => onUpdate({ enabled: checked })}
/>
diff --git a/apps/web/src/components/ui/alert.tsx b/apps/web/src/components/ui/alert.tsx
new file mode 100644
index 00000000..2a176c75
--- /dev/null
+++ b/apps/web/src/components/ui/alert.tsx
@@ -0,0 +1,76 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@/lib/utils"
+
+const alertVariants = cva(
+ "group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
+ {
+ variants: {
+ variant: {
+ default: "bg-card text-card-foreground",
+ destructive:
+ "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+)
+
+function Alert({
+ className,
+ variant,
+ ...props
+}: React.ComponentProps<"div"> & VariantProps ) {
+ return (
+
+ )
+}
+
+function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+ svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+function AlertDescription({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export { Alert, AlertTitle, AlertDescription, AlertAction }
diff --git a/apps/web/src/components/ui/button.tsx b/apps/web/src/components/ui/button.tsx
new file mode 100644
index 00000000..6138844d
--- /dev/null
+++ b/apps/web/src/components/ui/button.tsx
@@ -0,0 +1,67 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+import { Slot } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+
+const buttonVariants = cva(
+ "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
+ outline:
+ "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
+ secondary:
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
+ ghost:
+ "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
+ destructive:
+ "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default:
+ "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
+ sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
+ lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
+ icon: "size-8",
+ "icon-xs":
+ "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
+ "icon-sm":
+ "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
+ "icon-lg": "size-9",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+function Button({
+ className,
+ variant = "default",
+ size = "default",
+ asChild = false,
+ ...props
+}: React.ComponentProps<"button"> &
+ VariantProps & {
+ asChild?: boolean
+ }) {
+ const Comp = asChild ? Slot.Root : "button"
+
+ return (
+
+ )
+}
+
+export { Button, buttonVariants }
diff --git a/apps/web/src/components/ui/dialog.tsx b/apps/web/src/components/ui/dialog.tsx
new file mode 100644
index 00000000..527af74c
--- /dev/null
+++ b/apps/web/src/components/ui/dialog.tsx
@@ -0,0 +1,166 @@
+import * as React from "react"
+import { Dialog as DialogPrimitive } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+import { Button } from "@/components/ui/button"
+import { XIcon } from "lucide-react"
+
+function Dialog({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogTrigger({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogPortal({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogClose({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogOverlay({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogContent({
+ className,
+ children,
+ showCloseButton = true,
+ ...props
+}: React.ComponentProps & {
+ showCloseButton?: boolean
+}) {
+ return (
+
+
+
+ {children}
+ {showCloseButton && (
+
+
+
+ )}
+
+
+ )
+}
+
+function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogFooter({
+ className,
+ showCloseButton = false,
+ children,
+ ...props
+}: React.ComponentProps<"div"> & {
+ showCloseButton?: boolean
+}) {
+ return (
+
+ {children}
+ {showCloseButton && (
+
+
+
+ )}
+
+ )
+}
+
+function DialogTitle({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogDescription({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogOverlay,
+ DialogPortal,
+ DialogTitle,
+ DialogTrigger,
+}
diff --git a/apps/web/src/components/ui/select.tsx b/apps/web/src/components/ui/select.tsx
new file mode 100644
index 00000000..f09dfb48
--- /dev/null
+++ b/apps/web/src/components/ui/select.tsx
@@ -0,0 +1,192 @@
+"use client"
+
+import * as React from "react"
+import { Select as SelectPrimitive } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
+
+function Select({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function SelectGroup({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function SelectValue({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function SelectTrigger({
+ className,
+ size = "default",
+ children,
+ ...props
+}: React.ComponentProps & {
+ size?: "sm" | "default"
+}) {
+ return (
+
+ {children}
+
+
+
+
+ )
+}
+
+function SelectContent({
+ className,
+ children,
+ position = "item-aligned",
+ align = "center",
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+ {children}
+
+
+
+
+ )
+}
+
+function SelectLabel({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function SelectItem({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+
+
+ {children}
+
+ )
+}
+
+function SelectSeparator({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function SelectScrollUpButton({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+function SelectScrollDownButton({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+export {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectLabel,
+ SelectScrollDownButton,
+ SelectScrollUpButton,
+ SelectSeparator,
+ SelectTrigger,
+ SelectValue,
+}
diff --git a/apps/web/src/components/ui/switch.tsx b/apps/web/src/components/ui/switch.tsx
new file mode 100644
index 00000000..877dbc82
--- /dev/null
+++ b/apps/web/src/components/ui/switch.tsx
@@ -0,0 +1,31 @@
+import * as React from "react"
+import { Switch as SwitchPrimitive } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+
+function Switch({
+ className,
+ size = "default",
+ ...props
+}: React.ComponentProps & {
+ size?: "sm" | "default"
+}) {
+ return (
+
+
+
+ )
+}
+
+export { Switch }
diff --git a/apps/web/src/components/ui/toggle.tsx b/apps/web/src/components/ui/toggle.tsx
deleted file mode 100644
index 88cfa6df..00000000
--- a/apps/web/src/components/ui/toggle.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { cn } from '../../lib/utils';
-
-interface ToggleProps {
- checked: boolean;
- onChange: () => void;
- className?: string;
-}
-
-export function Toggle({ checked, onChange, className }: ToggleProps) {
- return (
-
- );
-}
diff --git a/apps/web/src/components/webhooks/WebhookDeliveries.tsx b/apps/web/src/components/webhooks/WebhookDeliveries.tsx
index 5da7dd4d..dbe8de2e 100644
--- a/apps/web/src/components/webhooks/WebhookDeliveries.tsx
+++ b/apps/web/src/components/webhooks/WebhookDeliveries.tsx
@@ -68,12 +68,12 @@ export function WebhookDeliveries({ webhook, onClose }: WebhookDeliveriesProps)
Delivery History: {webhook.name}
- Loading deliveries...
+ Loading deliveries...
);
}
@@ -83,18 +83,18 @@ export function WebhookDeliveries({ webhook, onClose }: WebhookDeliveriesProps)
Delivery History: {webhook.name}
- Showing last 100 deliveries
+ Showing last 100 deliveries
@@ -102,7 +102,7 @@ export function WebhookDeliveries({ webhook, onClose }: WebhookDeliveriesProps)
{deliveries.length === 0 ? (
-
+
No deliveries found for this webhook.
) : (
@@ -131,13 +131,13 @@ export function WebhookDeliveries({ webhook, onClose }: WebhookDeliveriesProps)
className={`font-mono ${
delivery.statusCode >= 200 && delivery.statusCode < 300
? 'text-green-600'
- : 'text-red-600'
+ : 'text-destructive'
}`}
>
{delivery.statusCode}
) : (
- -
+ -
)}
{delivery.attempts}
@@ -155,7 +155,7 @@ export function WebhookDeliveries({ webhook, onClose }: WebhookDeliveriesProps)
@@ -172,7 +172,7 @@ export function WebhookDeliveries({ webhook, onClose }: WebhookDeliveriesProps)
{deliveries.length > 0 && (
Latest Delivery Details
-
+
Delivery ID: {deliveries[0].id}
diff --git a/apps/web/src/components/webhooks/WebhookForm.tsx b/apps/web/src/components/webhooks/WebhookForm.tsx
index abbd3f93..aa99b5f0 100644
--- a/apps/web/src/components/webhooks/WebhookForm.tsx
+++ b/apps/web/src/components/webhooks/WebhookForm.tsx
@@ -246,7 +246,7 @@ export function WebhookForm({ webhook, onSubmit, onCancel }: WebhookFormProps) {
className="w-full px-3 py-2 border rounded-md"
placeholder="wh_secret_abc123"
/>
-
+
Used for HMAC signature verification (X-Webhook-Signature header)
@@ -268,7 +268,7 @@ export function WebhookForm({ webhook, onSubmit, onCancel }: WebhookFormProps) {
{loadingTier ? (
-
+
Loading available events...
) : (
@@ -280,7 +280,7 @@ export function WebhookForm({ webhook, onSubmit, onCancel }: WebhookFormProps) {
return (
-
+
{TIER_DISPLAY[tier]} Tier
{!tierAllowed && (
@@ -299,8 +299,8 @@ export function WebhookForm({ webhook, onSubmit, onCancel }: WebhookFormProps) {
key={event}
className={`flex items-center space-x-2 p-2 rounded ${
isAllowed
- ? 'cursor-pointer hover:bg-gray-50'
- : 'cursor-not-allowed opacity-60 bg-gray-50'
+ ? 'cursor-pointer hover:bg-muted'
+ : 'cursor-not-allowed opacity-60 bg-muted'
}`}
>
{!isAllowed && (
|