refactor(hub): migrate dashboard to shadcn components

Replace manual CSS classes with shadcn Card, CardHeader, CardTitle,
CardContent, and Badge components. Remove inline <style> block —
use Tailwind utility classes via shadcn theme tokens. Add Biome
formatting across all components.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
asepharyana
2026-07-23 12:19:43 +07:00
co-authored by Claude Opus 4.8
parent 18bf58be1a
commit d94524b70d
65 changed files with 1832 additions and 1492 deletions
+28 -28
View File
@@ -1,10 +1,10 @@
import * as React from "react"
import { mergeProps } from "@base-ui/react/merge-props"
import { useRender } from "@base-ui/react/use-render"
import { cva, type VariantProps } from "class-variance-authority"
import * as React from "react";
import { mergeProps } from "@base-ui/react/merge-props";
import { useRender } from "@base-ui/react/use-render";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils"
import { Separator } from "@/components/ui/separator"
import { cn } from "@/lib/utils";
import { Separator } from "@/components/ui/separator";
function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
@@ -13,11 +13,11 @@ function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
data-slot="item-group"
className={cn(
"group/item-group flex w-full flex-col gap-4 has-data-[size=sm]:gap-2.5 has-data-[size=xs]:gap-2",
className
className,
)}
{...props}
/>
)
);
}
function ItemSeparator({
@@ -31,7 +31,7 @@ function ItemSeparator({
className={cn("my-2", className)}
{...props}
/>
)
);
}
const itemVariants = cva(
@@ -53,8 +53,8 @@ const itemVariants = cva(
variant: "default",
size: "default",
},
}
)
},
);
function Item({
className,
@@ -69,7 +69,7 @@ function Item({
{
className: cn(itemVariants({ variant, size, className })),
},
props
props,
),
render,
state: {
@@ -77,7 +77,7 @@ function Item({
variant,
size,
},
})
});
}
const itemMediaVariants = cva(
@@ -94,8 +94,8 @@ const itemMediaVariants = cva(
defaultVariants: {
variant: "default",
},
}
)
},
);
function ItemMedia({
className,
@@ -109,7 +109,7 @@ function ItemMedia({
className={cn(itemMediaVariants({ variant, className }))}
{...props}
/>
)
);
}
function ItemContent({ className, ...props }: React.ComponentProps<"div">) {
@@ -118,11 +118,11 @@ function ItemContent({ className, ...props }: React.ComponentProps<"div">) {
data-slot="item-content"
className={cn(
"flex flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0 [&+[data-slot=item-content]]:flex-none",
className
className,
)}
{...props}
/>
)
);
}
function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
@@ -131,11 +131,11 @@ function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
data-slot="item-title"
className={cn(
"line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
className
className,
)}
{...props}
/>
)
);
}
function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
@@ -144,11 +144,11 @@ function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
data-slot="item-description"
className={cn(
"line-clamp-2 text-left text-sm leading-normal font-normal text-muted-foreground group-data-[size=xs]/item:text-xs [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
className
className,
)}
{...props}
/>
)
);
}
function ItemActions({ className, ...props }: React.ComponentProps<"div">) {
@@ -158,7 +158,7 @@ function ItemActions({ className, ...props }: React.ComponentProps<"div">) {
className={cn("flex items-center gap-2", className)}
{...props}
/>
)
);
}
function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
@@ -167,11 +167,11 @@ function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
data-slot="item-header"
className={cn(
"flex basis-full items-center justify-between gap-2",
className
className,
)}
{...props}
/>
)
);
}
function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {
@@ -180,11 +180,11 @@ function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {
data-slot="item-footer"
className={cn(
"flex basis-full items-center justify-between gap-2",
className
className,
)}
{...props}
/>
)
);
}
export {
@@ -198,4 +198,4 @@ export {
ItemDescription,
ItemHeader,
ItemFooter,
}
};