snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
All checks were successful
Release / Create Version PR or Publish Stable Release (push) Has been skipped
Release / Publish Prerelease to NPM (push) Has been skipped
Monitor Registries / Monitor registry health (push) Has been skipped

This commit is contained in:
upstream-mirror
2026-09-15 22:44:43 +05:00
commit 1416db152c
5727 changed files with 630238 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
import {
AlertCircleIcon,
ArrowRight01Icon,
SquareLock02Icon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Field, FieldGroup, FieldLabel } from "@/styles/base-rhea/ui/field"
import { Input } from "@/styles/base-rhea/ui/input"
import {
Item,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/styles/base-rhea/ui/item"
export function AccountAccess() {
return (
<Card>
<CardHeader>
<CardTitle>Account Access</CardTitle>
<CardDescription>
Update your credentials or re-authenticate.
</CardDescription>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel htmlFor="email-address">Email Address</FieldLabel>
<Input
id="email-address"
type="email"
placeholder="artist@studio.inc"
/>
</Field>
<Field>
<div className="flex items-center justify-between">
<FieldLabel htmlFor="current-password">
Current Password
</FieldLabel>
<a
href="#"
className="text-xs font-medium tracking-wider text-muted-foreground uppercase hover:text-foreground"
>
Forgot?
</a>
</div>
<Input
id="current-password"
type="password"
placeholder="••••••••••••••••••••••••"
/>
</Field>
</FieldGroup>
</CardContent>
<CardFooter className="flex-col gap-4">
<Button className="w-full">
<HugeiconsIcon icon={SquareLock02Icon} strokeWidth={2} />
Update Security
</Button>
<Item variant="muted" render={<a href="#" />}>
<ItemMedia variant="icon">
<HugeiconsIcon
icon={AlertCircleIcon}
className="text-destructive"
strokeWidth={2}
/>
</ItemMedia>
<ItemContent>
<ItemTitle>Danger Zone</ItemTitle>
<ItemDescription className="line-clamp-1">
Archive account and remove catalog
</ItemDescription>
</ItemContent>
<HugeiconsIcon
icon={ArrowRight01Icon}
className="size-4"
strokeWidth={2}
/>
</Item>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,46 @@
import { Badge } from "@/styles/base-rhea/ui/badge"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
const areaPath = "M0 52L18 40L36 46L54 70L72 50L100 49V86H0Z"
const strokePath = "M0 52L18 40L36 46L54 70L72 50L100 49"
export function AnalyticsCard() {
return (
<Card className="mx-auto w-full max-w-sm data-[size=sm]:pb-0" size="sm">
<CardHeader>
<CardTitle>Analytics</CardTitle>
<CardDescription>
418.2K Visitors <Badge>+10%</Badge>
</CardDescription>
<CardAction>
<Button variant="outline" size="sm">
View Analytics
</Button>
</CardAction>
</CardHeader>
<svg
viewBox="0 0 100 86"
preserveAspectRatio="none"
className="aspect-[1/0.35] w-full text-chart-1"
role="img"
aria-label="Visitor trend"
>
<path d={areaPath} fill="currentColor" opacity="0.28" />
<path
d={strokePath}
fill="none"
stroke="currentColor"
strokeWidth="1.5"
vectorEffect="non-scaling-stroke"
/>
</svg>
</Card>
)
}

View File

@@ -0,0 +1,75 @@
import { Badge } from "@/styles/base-rhea/ui/badge"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Item, ItemContent } from "@/styles/base-rhea/ui/item"
import { Separator } from "@/styles/base-rhea/ui/separator"
const netRoyalties = 1248.75
const processingFee = 37.46
const totalClaimable = netRoyalties - processingFee
const formatCurrency = (amount: number) =>
amount.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})
export function ClaimableBalance() {
return (
<Card>
<CardHeader>
<CardDescription>Claimable Balance</CardDescription>
<CardTitle className="text-4xl tabular-nums">
${formatCurrency(totalClaimable)}
</CardTitle>
<Badge variant="outline">
<span className="size-2 rounded-full bg-yellow-500" />
Pending Setup
</Badge>
</CardHeader>
<CardContent className="flex flex-1 flex-col justify-end">
<Item variant="muted" className="flex-col items-stretch">
<ItemContent className="gap-3">
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Net Royalties
</span>
<span className="text-sm font-medium tabular-nums">
${formatCurrency(netRoyalties)}
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Processing Fee
</span>
<span className="text-sm font-medium tabular-nums">
-${formatCurrency(processingFee)}
</span>
</div>
<Separator />
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Total Ready to Claim
</span>
<span className="text-sm font-semibold tabular-nums">
${formatCurrency(totalClaimable)} USD
</span>
</div>
</ItemContent>
</Item>
</CardContent>
<CardFooter>
<CardDescription>
Once your bank is connected, balances over $10.00 are automatically
eligible for monthly distribution on the 15th of each month.
</CardDescription>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,88 @@
import { Badge } from "@/styles/base-rhea/ui/badge"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Item, ItemContent, ItemDescription } from "@/styles/base-rhea/ui/item"
const chartData = [
{ month: "Dec", amount: 800 },
{ month: "Jan", amount: 1100 },
{ month: "Feb", amount: 900 },
{ month: "Mar", amount: 1300 },
{ month: "Apr", amount: 750 },
]
export function ContributionHistory() {
const maxAmount = Math.max(...chartData.map((item) => item.amount))
return (
<Card>
<CardHeader>
<CardTitle>Contribution History</CardTitle>
<CardDescription>Last 6 months of activity</CardDescription>
</CardHeader>
<CardContent>
<div
className="flex h-[200px] w-full items-end gap-3"
role="img"
aria-label="Last 6 months of contribution activity"
>
{chartData.map((item, index) => (
<div
key={item.month}
className="flex h-full flex-1 flex-col justify-end gap-2"
>
<div
data-index={index}
className="data-[index=5]:bg-chart-6 min-h-2 rounded-lg data-[index=0]:bg-chart-1 data-[index=1]:bg-chart-2 data-[index=2]:bg-chart-3 data-[index=3]:bg-chart-4 data-[index=4]:bg-chart-5"
style={{ height: `${(item.amount / maxAmount) * 100}%` }}
/>
<span className="text-center text-xs text-muted-foreground">
{item.month}
</span>
</div>
))}
</div>
</CardContent>
<CardContent>
<div className="grid w-full grid-cols-1 gap-3 xl:grid-cols-2">
<Item variant="muted" className="flex-col items-stretch">
<ItemContent className="gap-1">
<ItemDescription className="text-xs font-medium tracking-wider text-muted-foreground uppercase">
Upcoming
</ItemDescription>
<span className="cn-font-heading text-base font-semibold">
May 2024
</span>
<span className="text-sm text-muted-foreground">Scheduled</span>
</ItemContent>
</Item>
<Item
variant="muted"
className="hidden flex-col items-stretch xl:flex"
>
<ItemContent className="gap-1">
<ItemDescription className="text-xs font-medium tracking-wider text-muted-foreground uppercase">
Savings Plan
</ItemDescription>
<span className="cn-font-heading text-base font-semibold">
Accelerated
</span>
<span className="text-sm text-muted-foreground">Recurring</span>
</ItemContent>
</Item>
</div>
</CardContent>
<CardFooter>
<Button className="w-full">View Full Report</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,116 @@
import { Cancel01Icon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import {
Item,
ItemContent,
ItemDescription,
ItemGroup,
ItemTitle,
} from "@/styles/base-rhea/ui/item"
const HOLDINGS = [
{
name: "Vanguard",
shares: "450 Shares",
amount: "$1,842.10",
data: [
{ q: "Q1", value: 380 },
{ q: "Q2", value: 420 },
{ q: "Q3", value: 390 },
{ q: "Q4", value: 652 },
],
},
{
name: "S&P 500 VOO",
shares: "112 Shares",
amount: "$928.40",
data: [
{ q: "Q1", value: 180 },
{ q: "Q2", value: 210 },
{ q: "Q3", value: 320 },
{ q: "Q4", value: 218 },
],
},
{
name: "Apple AAPL",
shares: "85 Shares",
amount: "$340.00",
data: [
{ q: "Q1", value: 60 },
{ q: "Q2", value: 70 },
{ q: "Q3", value: 120 },
{ q: "Q4", value: 90 },
],
},
{
name: "Realty Income",
shares: "320 Shares",
amount: "$1,139.50",
data: [
{ q: "Q1", value: 240 },
{ q: "Q2", value: 260 },
{ q: "Q3", value: 280 },
{ q: "Q4", value: 360 },
],
},
]
export function DividendIncome() {
return (
<Card>
<CardHeader>
<CardTitle>Q2 Dividend Income</CardTitle>
<CardDescription>
Quarterly dividend payouts across your portfolio holdings.
</CardDescription>
<CardAction>
<Button
variant="ghost"
size="icon-sm"
className="bg-muted"
aria-label="Dismiss dividend income"
>
<HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<ItemGroup>
{HOLDINGS.map((holding) => (
<Item key={holding.name} role="listitem" variant="muted">
<ItemContent>
<ItemTitle>{holding.name}</ItemTitle>
<ItemDescription>{holding.shares}</ItemDescription>
</ItemContent>
<div
className="hidden h-8 w-24 items-end gap-1 md:flex"
role="img"
aria-label={`${holding.name} quarterly dividends`}
>
{holding.data.map((item) => (
<div
key={item.q}
className="min-h-1 flex-1 rounded-t-sm bg-chart-2"
style={{
height: `${(item.value / Math.max(...holding.data.map((point) => point.value))) * 100}%`,
}}
/>
))}
</div>
</Item>
))}
</ItemGroup>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,37 @@
import { Add01Icon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import { Card, CardContent } from "@/styles/base-rhea/ui/card"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/styles/base-rhea/ui/empty"
export function EmptyDistributeTrack() {
return (
<Card>
<CardContent>
<Empty className="p-4">
<EmptyMedia variant="icon">
<HugeiconsIcon icon={Add01Icon} strokeWidth={2} />
</EmptyMedia>
<EmptyHeader>
<EmptyTitle>Distribute Track</EmptyTitle>
<EmptyDescription>
Upload your first master to start reaching listeners on Spotify,
Apple Music, and more.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button>Create Release</Button>
</EmptyContent>
</Empty>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,122 @@
import { MessageScrollerDemo } from "@/examples/radix/message-scroller-demo"
import { AccountAccess } from "./account-access"
import { AnalyticsCard } from "./analytics-card"
import { ClaimableBalance } from "./claimable-balance"
import { ContributionHistory } from "./contribution-history"
import { DividendIncome } from "./dividend-income"
import { EmptyDistributeTrack } from "./empty-distribute-track"
import { NewMilestone } from "./new-milestone"
import { NotificationSettings } from "./notification-settings"
import { Payments } from "./payments"
import { PayoutThreshold } from "./payout-threshold"
import { PowerUsage } from "./power-usage"
import { QrConnect } from "./qr-connect"
import { SavingsTargets } from "./savings-targets"
import { SidebarNav } from "./sidebar-nav"
import { AccountAccess as SkeletonAccountAccess } from "./skeleton/account-access"
import { AnalyticsCard as SkeletonAnalyticsCard } from "./skeleton/analytics-card"
import { ClaimableBalance as SkeletonClaimableBalance } from "./skeleton/claimable-balance"
import { ContributionHistory as SkeletonContributionHistory } from "./skeleton/contribution-history"
import { DividendIncome as SkeletonDividendIncome } from "./skeleton/dividend-income"
import { EmptyDistributeTrack as SkeletonEmptyDistributeTrack } from "./skeleton/empty-distribute-track"
import { NewMilestone as SkeletonNewMilestone } from "./skeleton/new-milestone"
import { NotificationSettings as SkeletonNotificationSettings } from "./skeleton/notification-settings"
import { Payments as SkeletonPayments } from "./skeleton/payments"
import { PayoutThreshold as SkeletonPayoutThreshold } from "./skeleton/payout-threshold"
import { PowerUsage as SkeletonPowerUsage } from "./skeleton/power-usage"
import { QrConnect as SkeletonQrConnect } from "./skeleton/qr-connect"
import { SavingsTargets as SkeletonSavingsTargets } from "./skeleton/savings-targets"
import { TransferFunds as SkeletonTransferFunds } from "./skeleton/transfer-funds"
import { UIElements as SkeletonUIElements } from "./skeleton/ui-elements"
import { TransferFunds } from "./transfer-funds"
import { UIElements } from "./ui-elements"
function CardsSkeletonRails() {
return (
<div
aria-hidden="true"
className="pointer-events-none absolute inset-x-0 top-12 z-10 hidden min-[2200px]:block [&_[data-slot=skeleton]:nth-child(even)]:hidden"
>
<div className="absolute top-0 left-[calc(50%-950px-var(--rail-width)-var(--gap))] grid w-(--rail-width) grid-cols-[repeat(2,var(--rail-column))] gap-(--gap) opacity-50 [--rail-column:20rem] [--rail-width:calc(var(--rail-column)*2+var(--gap))]">
<div className="flex flex-col gap-(--gap)">
<SkeletonContributionHistory />
<SkeletonClaimableBalance />
<SkeletonDividendIncome />
<SkeletonPayoutThreshold />
</div>
<div className="flex flex-col gap-(--gap)">
<SkeletonUIElements />
<SkeletonSavingsTargets />
<SkeletonNewMilestone />
<SkeletonPayoutThreshold />
<SkeletonAccountAccess />
</div>
</div>
<div className="absolute top-0 right-[calc(50%-950px-var(--rail-width)-var(--gap))] grid w-(--rail-width) grid-cols-[repeat(2,var(--rail-column))] gap-(--gap) opacity-50 [--rail-column:20rem] [--rail-width:calc(var(--rail-column)*2+var(--gap))]">
<div className="flex flex-col gap-(--gap)">
<SkeletonNewMilestone />
<SkeletonPayoutThreshold />
<SkeletonAccountAccess />
<SkeletonQrConnect />
<SkeletonTransferFunds />
<SkeletonPayments />
<SkeletonEmptyDistributeTrack />
</div>
<div className="flex flex-col gap-(--gap)">
<SkeletonQrConnect />
<SkeletonTransferFunds />
<SkeletonPayments />
<SkeletonEmptyDistributeTrack />
<SkeletonAnalyticsCard />
<SkeletonNotificationSettings />
<SkeletonPowerUsage />
</div>
</div>
</div>
)
}
export function CardsDemo() {
return (
<div
data-slot="demo"
className="theme-neutral relative flex w-full max-w-none flex-col gap-(--gap) overflow-hidden bg-muted p-12 pb-0! [--gap:--spacing(8)] 3xl:[--gap:--spacing(8)] min-[1900px]:p-12 min-[1900px]:[--gap:--spacing(10)]! lg:p-6 lg:[--gap:--spacing(6)] dark:bg-background"
>
<CardsSkeletonRails />
<div className="relative z-10 mx-auto grid gap-(--gap) **:data-[slot=card]:w-full min-[1400px]:grid-cols-4! min-[1900px]:grid-cols-5! md:max-w-3xl md:grid-cols-2 lg:max-w-none lg:grid-cols-3 xl:max-w-[1600px] 2xl:max-w-[1900px]">
<div className="flex flex-col items-start gap-(--gap)">
<UIElements />
<SidebarNav />
<SavingsTargets />
</div>
<div className="hidden flex-col gap-(--gap) lg:flex">
<ContributionHistory />
<ClaimableBalance />
<DividendIncome />
</div>
<div className="hidden flex-col gap-(--gap) min-[1400px]:flex">
<NewMilestone />
<PayoutThreshold />
<AccountAccess />
</div>
<div className="hidden flex-col gap-(--gap) md:flex">
<QrConnect />
<div className="**:[.text-center.text-xs]:hidden">
<MessageScrollerDemo />
</div>
{/* <TransferFunds /> */}
<Payments />
</div>
<div className="hidden flex-col gap-(--gap) min-[1900px]:flex">
<EmptyDistributeTrack />
<AnalyticsCard />
<NotificationSettings />
<PowerUsage />
</div>
</div>
<div className="absolute inset-x-0 top-0 z-1 h-120 bg-linear-to-b from-background via-muted to-transparent dark:hidden" />
<div className="absolute inset-x-0 bottom-0 z-20 h-48 bg-linear-to-t from-background via-muted/80 to-transparent lg:h-80 xl:h-64 dark:via-background/80" />
</div>
)
}

View File

@@ -0,0 +1,52 @@
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Field, FieldGroup, FieldLabel } from "@/styles/base-rhea/ui/field"
import { Input } from "@/styles/base-rhea/ui/input"
export function NewMilestone() {
return (
<Card>
<CardHeader>
<CardTitle>Set a new milestone</CardTitle>
<CardDescription>
Define your financial target and we&apos;ll help you pace your
savings.
</CardDescription>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel htmlFor="goal-name">Goal Name</FieldLabel>
<Input
id="goal-name"
placeholder="e.g. New Car, Home Downpayment"
/>
</Field>
<div className="grid grid-cols-2 gap-3">
<Field>
<FieldLabel htmlFor="target-amount">Target Amount</FieldLabel>
<Input id="target-amount" defaultValue="$15,000" />
</Field>
<Field>
<FieldLabel htmlFor="target-date">Target Date</FieldLabel>
<Input id="target-date" defaultValue="Dec 2025" />
</Field>
</div>
</FieldGroup>
</CardContent>
<CardFooter className="flex-col gap-2">
<Button className="w-full">Create Goal</Button>
<Button variant="outline" className="w-full">
Cancel
</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,76 @@
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Checkbox } from "@/styles/base-rhea/ui/checkbox"
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/styles/base-rhea/ui/field"
const NOTIFICATIONS = [
{
id: "transactions",
label: "Transaction alerts",
description: "Deposits, withdrawals, and transfers.",
defaultChecked: true,
},
{
id: "security",
label: "Security alerts",
description: "Login attempts and account changes.",
defaultChecked: true,
},
{
id: "goals",
label: "Goal milestones",
description: "Updates at 25%, 50%, 75%, and 100%.",
defaultChecked: false,
},
{
id: "market",
label: "Market updates",
description: "Daily portfolio summary and price alerts.",
defaultChecked: false,
},
]
export function NotificationSettings() {
return (
<Card>
<CardHeader>
<CardTitle>Notifications</CardTitle>
<CardDescription>
Choose which email and push alerts you want to receive.
</CardDescription>
</CardHeader>
<CardContent>
<FieldGroup>
{NOTIFICATIONS.map((n) => (
<Field key={n.id} orientation="horizontal">
<Checkbox
id={`notify-${n.id}`}
defaultChecked={n.defaultChecked}
/>
<FieldContent>
<FieldLabel htmlFor={`notify-${n.id}`}>{n.label}</FieldLabel>
<FieldDescription>{n.description}</FieldDescription>
</FieldContent>
</Field>
))}
</FieldGroup>
</CardContent>
<CardFooter>
<Button className="w-full">Save Preferences</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,139 @@
import {
ArrowRight01Icon,
Calendar03Icon,
MoreHorizontalCircle01Icon,
RefreshIcon,
Settings01Icon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/styles/base-rhea/ui/breadcrumb"
import { Button } from "@/styles/base-rhea/ui/button"
import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/styles/base-rhea/ui/dropdown-menu"
import {
Item,
ItemContent,
ItemDescription,
ItemGroup,
ItemMedia,
ItemTitle,
} from "@/styles/base-rhea/ui/item"
export function Payments() {
return (
<Card>
<CardHeader className="flex flex-col gap-3">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button
size="icon-sm"
variant="ghost"
aria-label="Account options"
/>
}
>
<HugeiconsIcon
icon={MoreHorizontalCircle01Icon}
strokeWidth={2}
/>
<span className="sr-only">Account options</span>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuGroup>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Statements</DropdownMenuItem>
<DropdownMenuItem>Documents</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Payments</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</CardHeader>
<CardContent>
<ItemGroup>
<div role="listitem" className="w-full">
<Item variant="muted" render={<a href="#" />}>
<ItemMedia variant="icon">
<HugeiconsIcon icon={Settings01Icon} strokeWidth={2} />
</ItemMedia>
<ItemContent>
<ItemTitle>Change transfer limit</ItemTitle>
<ItemDescription>
Adjust how much you can send from your balance.
</ItemDescription>
</ItemContent>
<HugeiconsIcon
icon={ArrowRight01Icon}
className="size-4 shrink-0 text-muted-foreground"
strokeWidth={2}
/>
</Item>
</div>
<div role="listitem" className="w-full">
<Item variant="muted" render={<a href="#" />}>
<ItemMedia variant="icon">
<HugeiconsIcon icon={Calendar03Icon} strokeWidth={2} />
</ItemMedia>
<ItemContent>
<ItemTitle>Scheduled transfers</ItemTitle>
<ItemDescription>
Set up a transfer to send at a later date.
</ItemDescription>
</ItemContent>
<HugeiconsIcon
icon={ArrowRight01Icon}
className="size-4 shrink-0 text-muted-foreground"
strokeWidth={2}
/>
</Item>
</div>
<div role="listitem" className="w-full">
<Item variant="muted" render={<a href="#" />}>
<ItemMedia variant="icon">
<HugeiconsIcon icon={RefreshIcon} strokeWidth={2} />
</ItemMedia>
<ItemContent>
<ItemTitle>Recurring card payments</ItemTitle>
<ItemDescription>
Manage your repeated card transactions.
</ItemDescription>
</ItemContent>
<HugeiconsIcon
icon={ArrowRight01Icon}
className="size-4 shrink-0 text-muted-foreground"
strokeWidth={2}
/>
</Item>
</div>
</ItemGroup>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,112 @@
import { Cancel01Icon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/styles/base-rhea/ui/field"
import { Progress } from "@/styles/base-rhea/ui/progress"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/styles/base-rhea/ui/select"
import { Textarea } from "@/styles/base-rhea/ui/textarea"
const CURRENCIES = [
{ label: "USD — United States Dollar", value: "usd" },
{ label: "EUR — Euro", value: "eur" },
{ label: "GBP — British Pound", value: "gbp" },
{ label: "JPY — Japanese Yen", value: "jpy" },
]
export function PayoutThreshold() {
return (
<Card>
<CardHeader>
<CardTitle>Payout Threshold</CardTitle>
<CardDescription>
Set the minimum balance required before a payout is triggered.
</CardDescription>
<CardAction>
<Button
variant="ghost"
size="icon-sm"
className="bg-muted"
aria-label="Dismiss payout threshold"
>
<HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel htmlFor="preferred-currency">
Preferred Currency
</FieldLabel>
<Select items={CURRENCIES} defaultValue="usd">
<SelectTrigger id="preferred-currency" className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{CURRENCIES.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</Field>
<Field>
<div className="flex items-baseline justify-between">
<FieldLabel id="min-payout-label">
Minimum Payout Amount
</FieldLabel>
<span className="text-2xl font-semibold tabular-nums">
$2500.00
</span>
</div>
<Progress
value={25}
aria-labelledby="min-payout-label"
aria-valuetext="$2,500 of $10,000"
/>
<div className="flex items-center justify-between">
<FieldDescription>$50 (MIN)</FieldDescription>
<FieldDescription>$10,000 (MAX)</FieldDescription>
</div>
</Field>
<Field>
<FieldLabel htmlFor="payout-notes">Notes</FieldLabel>
<Textarea
id="payout-notes"
placeholder="Add any notes for this payout configuration..."
className="min-h-[100px]"
/>
</Field>
</FieldGroup>
</CardContent>
<CardFooter>
<Button className="w-full">Save Threshold</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,67 @@
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Separator } from "@/styles/base-rhea/ui/separator"
const chartData = [
{ hour: "6a", usage: 1.2 },
{ hour: "8a", usage: 2.8 },
{ hour: "10a", usage: 3.1 },
{ hour: "12p", usage: 2.4 },
{ hour: "2p", usage: 3.4 },
{ hour: "4p", usage: 2.9 },
{ hour: "6p", usage: 3.8 },
{ hour: "8p", usage: 3.2 },
]
export function PowerUsage() {
const maxUsage = Math.max(...chartData.map((item) => item.usage))
return (
<Card>
<CardHeader>
<CardTitle>Power Usage</CardTitle>
<CardDescription>Whole Home</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div
className="flex h-[140px] w-full items-end gap-2"
role="img"
aria-label="Power usage by hour"
>
{chartData.map((item) => (
<div
key={item.hour}
className="flex h-full flex-1 flex-col justify-end gap-1.5"
>
<div
className="min-h-2 rounded-t bg-chart-2"
style={{ height: `${(item.usage / maxUsage) * 100}%` }}
/>
<span className="text-center text-xs text-muted-foreground">
{item.hour}
</span>
</div>
))}
</div>
<Separator />
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-0.5">
<span className="text-sm text-muted-foreground">
Currently Using
</span>
<span className="text-lg font-semibold tabular-nums">3.4 kW</span>
</div>
<div className="flex flex-col gap-0.5">
<span className="text-sm text-muted-foreground">Solar Gen</span>
<span className="text-lg font-semibold tabular-nums">+1.2 kW</span>
</div>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,64 @@
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
const qrCells = [
"111111100101101111111",
"100000101001001000001",
"101110101111101011101",
"101110100100001011101",
"101110101010101011101",
"100000100111001000001",
"111111101010101111111",
"000000001101000000000",
"101011111001111010110",
"010100001110010101001",
"111010111011101111010",
"001101000101000010101",
"110111101111010111011",
"000000001001010001010",
"111111101101111101001",
"100000100010001001111",
"101110101011101110100",
"101110100110100010011",
"101110101000111101110",
"100000101101000011001",
"111111101011101101111",
]
export function QrConnect() {
return (
<Card>
<CardContent className="flex justify-center pt-6">
<div className="rounded-xl border bg-white p-4">
<svg
viewBox="0 0 21 21"
className="size-40 text-black"
role="img"
aria-label="Connect device QR code"
shapeRendering="crispEdges"
>
<rect width="21" height="21" fill="white" />
{qrCells.map((row, y) =>
[...row].map((cell, x) =>
cell === "1" ? (
<rect key={`${x}-${y}`} x={x} y={y} width="1" height="1" />
) : null
)
)}
</svg>
</div>
</CardContent>
<CardHeader className="text-center">
<CardTitle>Scan to connect your mobile device</CardTitle>
<CardDescription className="text-balance">
Open the Ledger mobile app and scan this code to link your device.
</CardDescription>
</CardHeader>
</Card>
)
}

View File

@@ -0,0 +1,81 @@
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import {
Item,
ItemContent,
ItemDescription,
ItemFooter,
ItemGroup,
} from "@/styles/base-rhea/ui/item"
import { Progress } from "@/styles/base-rhea/ui/progress"
export function SavingsTargets() {
return (
<Card>
<CardHeader>
<CardTitle>Savings Targets</CardTitle>
<CardDescription>
Active milestones for 2024 across your portfolio. Monitor how close
you are to each savings goal.
</CardDescription>
</CardHeader>
<CardContent>
<ItemGroup className="gap-3">
<Item
role="listitem"
variant="muted"
className="flex-col items-stretch"
>
<ItemContent className="gap-3">
<ItemDescription className="cn-font-heading text-xs font-medium tracking-wider text-muted-foreground uppercase">
Retirement
</ItemDescription>
<span className="text-3xl font-semibold tabular-nums">
$420,000
</span>
<Progress value={65} aria-label="Retirement savings progress" />
</ItemContent>
<ItemFooter>
<span className="text-sm text-muted-foreground">
65% achieved
</span>
<span className="text-sm font-medium tabular-nums">$273,000</span>
</ItemFooter>
</Item>
<Item
role="listitem"
variant="muted"
className="flex-col items-stretch"
>
<ItemContent className="gap-3">
<ItemDescription className="cn-font-heading text-xs font-medium tracking-wider text-muted-foreground uppercase">
Real Estate
</ItemDescription>
<span className="text-3xl font-semibold tabular-nums">
$85,000
</span>
<Progress value={32} aria-label="Real estate savings progress" />
</ItemContent>
<ItemFooter>
<span className="text-sm text-muted-foreground">
32% achieved
</span>
<span className="text-sm font-medium tabular-nums">$27,200</span>
</ItemFooter>
</Item>
</ItemGroup>
</CardContent>
<CardFooter>
<CardDescription className="text-center">
You have not met your targets for this year.
</CardDescription>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,218 @@
import * as React from "react"
import {
ActivityIcon,
Analytics01Icon,
AnalyticsUpIcon,
ArrowDataTransferHorizontalIcon,
BankIcon,
BookOpen02Icon,
Calendar03Icon,
ChartBarLineIcon,
CreditCardIcon,
File02Icon,
Globe02Icon,
HelpCircleIcon,
Message01Icon,
Notification03Icon,
PaintBoardIcon,
PieChartIcon,
ShieldIcon,
Target02Icon,
UserIcon,
Wallet01Icon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { cn } from "cn"
import { Card } from "@/styles/base-rhea/ui/card"
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarProvider,
} from "@/styles/base-rhea/ui/sidebar"
function SidebarSection({
label,
children,
className,
}: {
label: string
children: React.ReactNode
className?: string
}) {
return (
<Card className={cn("w-full overflow-hidden rounded-3xl py-0", className)}>
<SidebarProvider className="min-h-0">
<Sidebar collapsible="none" className="w-full bg-transparent">
<SidebarContent className="gap-0 overflow-hidden">
<SidebarGroup>
<SidebarGroupLabel>{label}</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu className="gap-1">{children}</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
</SidebarProvider>
</Card>
)
}
export function SidebarNav() {
return (
<div className="grid w-full grid-cols-2 gap-4 xl:gap-6">
<SidebarSection
label="Overview"
className="xl:col-start-1 xl:row-start-2"
>
<SidebarMenuItem>
<SidebarMenuButton isActive>
<HugeiconsIcon icon={Analytics01Icon} strokeWidth={2} />
Analytics
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon
icon={ArrowDataTransferHorizontalIcon}
strokeWidth={2}
/>
Transactions
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={AnalyticsUpIcon} strokeWidth={2} />
Investments
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={BankIcon} strokeWidth={2} />
Accounts
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={PieChartIcon} strokeWidth={2} />
Spending
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarSection>
<SidebarSection
label="Planning"
className="xl:col-start-1 xl:row-start-1"
>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={File02Icon} strokeWidth={2} />
Documents
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Wallet01Icon} strokeWidth={2} />
Budget
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={ChartBarLineIcon} strokeWidth={2} />
Reports
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Target02Icon} strokeWidth={2} />
Goals
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Calendar03Icon} strokeWidth={2} />
Calendar
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarSection>
<SidebarSection
label="Support"
className="flex xl:col-start-2 xl:row-start-1"
>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={HelpCircleIcon} strokeWidth={2} />
Help Center
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={BookOpen02Icon} strokeWidth={2} />
Docs
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Message01Icon} strokeWidth={2} />
Contact Us
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={ActivityIcon} strokeWidth={2} />
Status
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Globe02Icon} strokeWidth={2} />
Community
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarSection>
<SidebarSection
label="Account"
className="flex xl:col-start-2 xl:row-start-2"
>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={UserIcon} strokeWidth={2} />
Profile
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton isActive>
<HugeiconsIcon icon={CreditCardIcon} strokeWidth={2} />
Billing
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Notification03Icon} strokeWidth={2} />
Notifications
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={ShieldIcon} strokeWidth={2} />
Security
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={PaintBoardIcon} strokeWidth={2} />
Appearance
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarSection>
</div>
)
}

View File

@@ -0,0 +1,35 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function AccountAccess() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-36 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-6">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-24 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between">
<Skeleton className="h-3 w-32 rounded-md" />
<Skeleton className="h-3 w-12 rounded-md" />
</div>
<Skeleton className="h-9 w-full rounded-lg" />
</div>
</CardContent>
<CardFooter className="flex-col gap-4">
<Skeleton className="h-9 w-full rounded-lg" />
<Skeleton className="h-14 w-full rounded-xl" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,17 @@
import { Card, CardAction, CardHeader } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function AnalyticsCard() {
return (
<Card className="mx-auto w-full max-w-sm data-[size=sm]:pb-0" size="sm">
<CardHeader className="gap-2">
<Skeleton className="h-5 w-24 rounded-md" />
<Skeleton className="h-4 w-40 rounded-md" />
<CardAction>
<Skeleton className="h-7 w-28 rounded-lg" />
</CardAction>
</CardHeader>
<Skeleton className="mx-6 mb-6 aspect-[1/0.35] w-auto rounded-lg" />
</Card>
)
}

View File

@@ -0,0 +1,41 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function ClaimableBalance() {
return (
<Card>
<CardHeader className="gap-3">
<Skeleton className="h-4 w-36 rounded-md" />
<Skeleton className="h-12 w-56 rounded-lg" />
<Skeleton className="h-6 w-32 rounded-full" />
</CardHeader>
<CardContent className="flex flex-1 flex-col justify-end">
<div className="flex flex-col gap-3 rounded-xl bg-muted p-4">
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-20 rounded-md bg-muted-foreground/15" />
</div>
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-32 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-16 rounded-md bg-muted-foreground/15" />
</div>
<Skeleton className="h-px w-full rounded-none bg-muted-foreground/15" />
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-36 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-24 rounded-md bg-muted-foreground/15" />
</div>
</div>
</CardContent>
<CardFooter className="flex-col gap-2">
<Skeleton className="h-3 w-full rounded-md" />
<Skeleton className="h-3 w-11/12 rounded-md" />
<Skeleton className="h-3 w-3/4 rounded-md" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,53 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const bars = [60, 80, 65, 95, 50, 100]
export function ContributionHistory() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-44 rounded-md" />
<Skeleton className="h-4 w-52 rounded-md" />
</CardHeader>
<CardContent>
<div className="flex h-[200px] w-full items-end gap-3">
{bars.map((height, i) => (
<div
key={i}
className="flex h-full flex-1 flex-col justify-end gap-2"
>
<Skeleton
className="w-full rounded-t-md rounded-b-none"
style={{ height: `${height}%` }}
/>
<Skeleton className="mx-auto h-3 w-6 rounded-md" />
</div>
))}
</div>
</CardContent>
<CardContent>
<div className="grid w-full grid-cols-1 gap-3 xl:grid-cols-2">
<div className="flex flex-col gap-2 rounded-xl bg-muted p-4">
<Skeleton className="h-3 w-20 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-5 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-24 rounded-md bg-muted-foreground/15" />
</div>
<div className="hidden flex-col gap-2 rounded-xl bg-muted p-4 xl:flex">
<Skeleton className="h-3 w-24 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-5 w-32 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-28 rounded-md bg-muted-foreground/15" />
</div>
</div>
</CardContent>
<CardFooter>
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,49 @@
import {
Card,
CardAction,
CardContent,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const rows = [0, 1, 2, 3]
const miniBars = [40, 60, 80, 50]
export function DividendIncome() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-48 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
<CardAction>
<Skeleton className="size-8 rounded-md" />
</CardAction>
</CardHeader>
<CardContent>
<div className="flex flex-col gap-2">
{rows.map((row) => (
<div
key={row}
className="flex items-center gap-3 rounded-xl bg-muted p-3"
>
<div className="flex flex-1 flex-col gap-2">
<Skeleton className="h-4 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-20 rounded-md bg-muted-foreground/15" />
</div>
<div className="hidden h-8 w-24 items-end gap-1 md:flex">
{miniBars.map((h, i) => (
<Skeleton
key={i}
className="flex-1 rounded-t-sm rounded-b-none bg-muted-foreground/15"
style={{ height: `${h}%` }}
/>
))}
</div>
<Skeleton className="hidden h-4 w-16 rounded-md bg-muted-foreground/15 md:block" />
</div>
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,20 @@
import { Card, CardContent } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function EmptyDistributeTrack() {
return (
<Card>
<CardContent>
<div className="flex flex-col items-center gap-4 p-4">
<Skeleton className="size-12 rounded-xl" />
<div className="flex flex-col items-center gap-2">
<Skeleton className="h-5 w-40 rounded-md" />
<Skeleton className="h-3 w-64 rounded-md" />
<Skeleton className="h-3 w-48 rounded-md" />
</div>
<Skeleton className="h-9 w-32 rounded-lg" />
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,56 @@
import { AccountAccess } from "./account-access"
import { AnalyticsCard } from "./analytics-card"
import { ClaimableBalance } from "./claimable-balance"
import { ContributionHistory } from "./contribution-history"
import { DividendIncome } from "./dividend-income"
import { EmptyDistributeTrack } from "./empty-distribute-track"
import { NewMilestone } from "./new-milestone"
import { NotificationSettings } from "./notification-settings"
import { Payments } from "./payments"
import { PayoutThreshold } from "./payout-threshold"
import { PowerUsage } from "./power-usage"
import { QrConnect } from "./qr-connect"
import { SavingsTargets } from "./savings-targets"
import { SidebarNav } from "./sidebar-nav"
import { TransferFunds } from "./transfer-funds"
import { UIElements } from "./ui-elements"
export function CardsSkeletonDemo() {
return (
<div
data-slot="demo"
className="theme-neutral relative flex w-full max-w-none flex-col gap-(--gap) bg-muted p-12 pb-0! [--gap:--spacing(8)] 3xl:[--gap:--spacing(8)] min-[1900px]:[--gap:--spacing(10)]! lg:p-8 lg:[--gap:--spacing(6)] xl:p-12 dark:bg-muted/30"
>
<div className="relative z-10 mx-auto grid gap-(--gap) **:data-[slot=card]:w-full min-[1900px]:grid-cols-5! md:max-w-3xl md:grid-cols-2 lg:max-w-none lg:grid-cols-3 xl:max-w-[1600px] xl:grid-cols-4 2xl:max-w-[1900px]">
<div className="flex flex-col items-start gap-(--gap)">
<UIElements />
<SidebarNav />
<SavingsTargets />
</div>
<div className="hidden flex-col gap-(--gap) lg:flex">
<ContributionHistory />
<ClaimableBalance />
<DividendIncome />
</div>
<div className="hidden flex-col gap-(--gap) 3xl:flex!">
<NewMilestone />
<PayoutThreshold />
<AccountAccess />
</div>
<div className="hidden flex-col gap-(--gap) md:flex">
<QrConnect />
<TransferFunds />
<Payments />
</div>
<div className="hidden flex-col gap-(--gap) xl:flex">
<EmptyDistributeTrack />
<AnalyticsCard />
<NotificationSettings />
<PowerUsage />
</div>
</div>
<div className="absolute inset-x-0 top-0 z-1 h-80 bg-linear-to-b from-background via-muted to-transparent dark:via-muted/30" />
<div className="absolute inset-x-0 bottom-0 z-20 h-80 bg-linear-to-t from-background via-muted to-transparent dark:via-muted/30" />
</div>
)
}

View File

@@ -0,0 +1,38 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function NewMilestone() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-44 rounded-md" />
<Skeleton className="h-4 w-72 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-20 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="grid grid-cols-2 gap-3">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-24 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-20 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
</div>
</CardContent>
<CardFooter className="flex-col gap-2">
<Skeleton className="h-9 w-full rounded-lg" />
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,34 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const rows = [0, 1, 2, 3]
export function NotificationSettings() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-32 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-4">
{rows.map((row) => (
<div key={row} className="flex items-start gap-3">
<Skeleton className="size-4 rounded-sm" />
<div className="flex flex-1 flex-col gap-2">
<Skeleton className="h-4 w-40 rounded-md" />
<Skeleton className="h-3 w-56 rounded-md" />
</div>
</div>
))}
</CardContent>
<CardFooter>
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,37 @@
import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const rows = [0, 1, 2]
export function Payments() {
return (
<Card>
<CardHeader className="flex flex-col gap-3">
<div className="flex items-center gap-2">
<Skeleton className="h-4 w-12 rounded-md" />
<Skeleton className="size-1.5 rounded-full" />
<Skeleton className="size-7 rounded-md" />
<Skeleton className="size-1.5 rounded-full" />
<Skeleton className="h-4 w-20 rounded-md" />
</div>
</CardHeader>
<CardContent>
<div className="flex flex-col gap-2">
{rows.map((row) => (
<div
key={row}
className="flex items-center gap-3 rounded-xl bg-muted p-3"
>
<Skeleton className="size-9 rounded-lg bg-muted-foreground/15" />
<div className="flex flex-1 flex-col gap-2">
<Skeleton className="h-4 w-40 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-56 rounded-md bg-muted-foreground/15" />
</div>
<Skeleton className="size-4 rounded-md bg-muted-foreground/15" />
</div>
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,43 @@
import {
Card,
CardAction,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function PayoutThreshold() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-44 rounded-md" />
<Skeleton className="h-4 w-72 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-32 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-3">
<div className="flex items-baseline justify-between">
<Skeleton className="h-3 w-40 rounded-md" />
<Skeleton className="h-7 w-24 rounded-md" />
</div>
<Skeleton className="h-2 w-full rounded-full" />
<div className="flex items-center justify-between">
<Skeleton className="h-3 w-16 rounded-md" />
<Skeleton className="h-3 w-20 rounded-md" />
</div>
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-16 rounded-md" />
<Skeleton className="h-[100px] w-full rounded-lg" />
</div>
</CardContent>
<CardFooter>
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,54 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const bars = [30, 70, 80, 60, 90, 75, 100, 85]
export function PowerUsage() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-32 rounded-md" />
<Skeleton className="h-4 w-24 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex h-[140px] w-full items-end gap-2">
{bars.map((height, i) => (
<div
key={i}
className="flex h-full flex-1 flex-col justify-end gap-1.5"
>
<Skeleton
className="w-full rounded-t rounded-b-none"
style={{ height: `${height}%` }}
/>
<Skeleton className="mx-auto h-3 w-5 rounded-md" />
</div>
))}
</div>
<Skeleton className="h-px w-full rounded-none" />
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-1.5">
<Skeleton className="h-3 w-28 rounded-md" />
<Skeleton className="h-5 w-20 rounded-md" />
</div>
<div className="flex flex-col gap-1.5">
<Skeleton className="h-3 w-20 rounded-md" />
<Skeleton className="h-5 w-24 rounded-md" />
</div>
</div>
</CardContent>
<CardFooter className="flex-col items-start gap-2">
<Skeleton className="h-3 w-24 rounded-md" />
<div className="flex w-full items-center gap-2">
<Skeleton className="h-2 flex-1 rounded-full" />
<Skeleton className="h-3 w-10 rounded-md" />
</div>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,17 @@
import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function QrConnect() {
return (
<Card>
<CardContent className="flex justify-center pt-6">
<Skeleton className="size-44 rounded-xl" />
</CardContent>
<CardHeader className="items-center gap-2 text-center">
<Skeleton className="h-5 w-56 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
<Skeleton className="h-4 w-48 rounded-md" />
</CardHeader>
</Card>
)
}

View File

@@ -0,0 +1,44 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const rows = [0, 1]
export function SavingsTargets() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-36 rounded-md" />
<div className="flex flex-col gap-1.5">
<Skeleton className="h-4 w-full max-w-64 rounded-md" />
<Skeleton className="h-4 w-48 rounded-md" />
</div>
</CardHeader>
<CardContent>
<div className="flex flex-col gap-3">
{rows.map((row) => (
<div
key={row}
className="flex flex-col gap-3 rounded-xl bg-muted p-4"
>
<Skeleton className="h-3 w-24 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-8 w-36 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-2 w-full rounded-full bg-muted-foreground/15" />
<div className="flex items-center justify-between">
<Skeleton className="h-3 w-24 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-20 rounded-md bg-muted-foreground/15" />
</div>
</div>
))}
</div>
</CardContent>
<CardFooter className="justify-center">
<Skeleton className="h-3 w-56 rounded-md" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,39 @@
import { Card } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const groupA = [0, 1, 2, 3, 4]
const groupB = [0, 1, 2, 3, 4]
function NavSkeleton({ groups }: { groups: number[][] }) {
return (
<div className="flex flex-col gap-1 p-2">
{groups.map((items, gi) => (
<div key={gi} className="flex flex-col gap-1 px-2 py-1.5">
<Skeleton className="mb-1 h-3 w-20 rounded-md" />
{items.map((item) => (
<div key={item} className="flex items-center gap-2 px-2 py-2">
<Skeleton className="size-4 rounded-md" />
<Skeleton className="h-3 w-24 rounded-md" />
</div>
))}
{gi < groups.length - 1 && (
<Skeleton className="my-1 h-px w-full rounded-none" />
)}
</div>
))}
</div>
)
}
export function SidebarNav() {
return (
<div className="grid w-full items-start gap-4 xl:grid-cols-2 xl:gap-6">
<Card className="w-full overflow-hidden rounded-3xl py-0">
<NavSkeleton groups={[groupA, groupB]} />
</Card>
<Card className="hidden w-full overflow-hidden rounded-3xl py-0 xl:flex">
<NavSkeleton groups={[groupA, groupB]} />
</Card>
</div>
)
}

View File

@@ -0,0 +1,55 @@
import {
Card,
CardAction,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function TransferFunds() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-36 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
<CardAction>
<Skeleton className="size-8 rounded-md" />
</CardAction>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-32 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-24 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-20 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-3 rounded-xl bg-muted p-4">
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-24 rounded-md bg-muted-foreground/15" />
</div>
<Skeleton className="h-px w-full rounded-none bg-muted-foreground/15" />
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-12 rounded-md bg-muted-foreground/15" />
</div>
<Skeleton className="h-px w-full rounded-none bg-muted-foreground/15" />
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-24 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-20 rounded-md bg-muted-foreground/15" />
</div>
</div>
</CardContent>
<CardFooter>
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,45 @@
import { Card, CardContent } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function UIElements() {
return (
<Card className="w-full">
<CardContent className="flex flex-col gap-6">
<Skeleton className="h-8 w-full rounded-2xl" />
<div className="flex flex-wrap gap-2">
<Skeleton className="h-9 w-20 rounded-lg" />
<Skeleton className="h-9 w-24 rounded-lg" />
<Skeleton className="h-9 w-20 rounded-lg" />
</div>
<div className="flex flex-col gap-3">
<Skeleton className="h-9 w-full rounded-lg" />
<Skeleton className="h-20 w-full rounded-lg" />
</div>
<div className="flex items-center gap-2">
<div className="flex gap-2">
<Skeleton className="h-5 w-12 rounded-full" />
<Skeleton className="h-5 w-16 rounded-full" />
<Skeleton className="hidden h-5 w-14 rounded-full 4xl:block" />
</div>
<div className="ml-auto flex gap-3">
<Skeleton className="size-4 rounded-full" />
<Skeleton className="size-4 rounded-full" />
</div>
<div className="flex gap-3">
<Skeleton className="size-4 rounded-sm" />
<Skeleton className="hidden size-4 rounded-sm 4xl:block" />
</div>
<Skeleton className="ml-auto h-5 w-9 rounded-full 4xl:hidden" />
</div>
<div className="flex items-center gap-4">
<Skeleton className="h-9 w-24 rounded-lg" />
<div className="flex">
<Skeleton className="h-9 w-28 rounded-l-lg rounded-r-none" />
<Skeleton className="ml-px h-9 w-9 rounded-l-none rounded-r-lg" />
</div>
<Skeleton className="ml-auto hidden h-5 w-9 rounded-full 4xl:block" />
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,139 @@
import { Cancel01Icon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Field, FieldGroup, FieldLabel } from "@/styles/base-rhea/ui/field"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
InputGroupText,
} from "@/styles/base-rhea/ui/input-group"
import { Item, ItemContent } from "@/styles/base-rhea/ui/item"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/styles/base-rhea/ui/select"
import { Separator } from "@/styles/base-rhea/ui/separator"
const FROM_ACCOUNTS = [
{ label: "Main Checking (··8402) — $12,450.00", value: "checking" },
{ label: "Business (··7731) — $8,920.00", value: "business" },
]
const TO_ACCOUNTS = [
{ label: "High Yield Savings (··1192) — $42,100.00", value: "savings" },
{ label: "Investment (··3349) — $18,200.00", value: "investment" },
]
export function TransferFunds() {
return (
<Card>
<CardHeader>
<CardTitle>Transfer Funds</CardTitle>
<CardDescription>
Move money between your connected accounts.
</CardDescription>
<CardAction>
<Button
variant="ghost"
size="icon-sm"
className="bg-muted"
aria-label="Dismiss transfer funds"
>
<HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel htmlFor="transfer-amount">
Amount to Transfer
</FieldLabel>
<InputGroup>
<InputGroupAddon>
<InputGroupText>$</InputGroupText>
</InputGroupAddon>
<InputGroupInput id="transfer-amount" defaultValue="1,200.00" />
</InputGroup>
</Field>
<Field>
<FieldLabel htmlFor="from-account">From Account</FieldLabel>
<Select items={FROM_ACCOUNTS} defaultValue="checking">
<SelectTrigger id="from-account" className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{FROM_ACCOUNTS.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel htmlFor="to-account">To Account</FieldLabel>
<Select items={TO_ACCOUNTS} defaultValue="savings">
<SelectTrigger id="to-account" className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{TO_ACCOUNTS.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</Field>
<Item variant="muted" className="flex-col items-stretch">
<ItemContent className="gap-3">
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Estimated arrival
</span>
<span className="text-sm font-medium">Today, Apr 14</span>
</div>
<Separator />
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Transaction fee
</span>
<span className="text-sm font-medium tabular-nums">$0.00</span>
</div>
<Separator />
<div className="flex items-center justify-between">
<span className="text-sm font-medium">Total amount</span>
<span className="text-sm font-semibold tabular-nums">
$1,200.00
</span>
</div>
</ItemContent>
</Item>
</FieldGroup>
</CardContent>
<CardFooter>
<Button className="w-full">Confirm Transfer</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,176 @@
"use client"
import {
ArrowRight02Icon,
ArrowUp01Icon,
Search01Icon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/styles/base-rhea/ui/alert-dialog"
import { Badge } from "@/styles/base-rhea/ui/badge"
import { Button } from "@/styles/base-rhea/ui/button"
import { ButtonGroup } from "@/styles/base-rhea/ui/button-group"
import { Card, CardContent } from "@/styles/base-rhea/ui/card"
import { Checkbox } from "@/styles/base-rhea/ui/checkbox"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/styles/base-rhea/ui/dropdown-menu"
import { Field, FieldGroup } from "@/styles/base-rhea/ui/field"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
InputGroupText,
} from "@/styles/base-rhea/ui/input-group"
import { RadioGroup, RadioGroupItem } from "@/styles/base-rhea/ui/radio-group"
import { Switch } from "@/styles/base-rhea/ui/switch"
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@/styles/base-rhea/ui/tabs"
import { Textarea } from "@/styles/base-rhea/ui/textarea"
export function UIElements() {
return (
<Card className="w-full">
<CardContent className="flex flex-col gap-6">
<div className="flex gap-2">
<Button>
Button{" "}
<HugeiconsIcon
icon={ArrowRight02Icon}
strokeWidth={2}
data-icon="inline-end"
/>
</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
</div>
<FieldGroup>
<Field>
<InputGroup>
<InputGroupInput placeholder="Name" />
<InputGroupAddon align="inline-end">
<InputGroupText>
<HugeiconsIcon icon={Search01Icon} strokeWidth={2} />
</InputGroupText>
</InputGroupAddon>
</InputGroup>
</Field>
<Field className="flex-1">
<Textarea placeholder="Message" className="resize-none" />
</Field>
</FieldGroup>
<div className="flex items-center gap-2">
<div className="flex gap-2">
<Badge>Badge</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="outline" className="hidden 4xl:flex">
Outline
</Badge>
</div>
<RadioGroup
defaultValue="apple"
className="ml-auto flex w-fit gap-3"
aria-label="Fruit preference"
>
<RadioGroupItem value="apple" aria-label="Apple" />
<RadioGroupItem value="banana" aria-label="Banana" />
</RadioGroup>
<div className="flex gap-3">
<Checkbox defaultChecked aria-label="Enable email alerts" />
<Checkbox
className="hidden 4xl:flex"
aria-label="Enable push alerts"
/>
</div>
<Switch
defaultChecked
className="flex 4xl:hidden"
aria-label="Enable compact notifications"
/>
</div>
<div className="flex items-center gap-4">
<AlertDialog>
<AlertDialogTrigger render={<Button variant="outline" />}>
<span className="hidden md:flex style-sera:md:hidden">
Alert Dialog
</span>
<span className="flex md:hidden style-sera:md:flex">Dialog</span>
</AlertDialogTrigger>
<AlertDialogContent size="sm" className="theme-neutral">
<AlertDialogHeader>
<AlertDialogTitle>Allow accessory to connect?</AlertDialogTitle>
<AlertDialogDescription>
Do you want to allow the USB accessory to connect to this
device and your data?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Don&apos;t allow</AlertDialogCancel>
<AlertDialogAction>Allow</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ButtonGroup className="ml-auto">
<Button variant="outline">
<span className="style-sera:hidden">Button Group</span>
<span className="hidden style-sera:block">Group</span>
</Button>
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button
variant="outline"
size="icon"
aria-label="Open quick actions"
/>
}
>
<HugeiconsIcon icon={ArrowUp01Icon} strokeWidth={2} />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" side="top" className="w-40">
<DropdownMenuGroup>
<DropdownMenuLabel>Quick Actions</DropdownMenuLabel>
<DropdownMenuItem>Mute Conversation</DropdownMenuItem>
<DropdownMenuItem>Mark as Read</DropdownMenuItem>
<DropdownMenuItem>Block User</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem variant="destructive">
Delete Conversation
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>
<Switch
defaultChecked
className="hidden 4xl:flex"
aria-label="Enable advanced setting"
/>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,121 @@
import { type Metadata } from "next"
import Image from "next/image"
import Link from "next/link"
import { siteConfig } from "@/lib/config"
import { Announcement } from "@/components/announcement"
import {
PageActions,
PageHeader,
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
import { Button } from "@/styles/radix-luma/ui/button"
import { CardsDemo } from "./cards"
const title = "The Foundation for your Design System"
const metadataTitle = `${siteConfig.name} - ${title}`
const description = siteConfig.description
const websiteJsonLd = {
"@context": "https://schema.org",
"@type": "WebSite",
"@id": `${siteConfig.url}/#website`,
url: siteConfig.url,
name: siteConfig.name,
alternateName: ["shadcn", "ui.shadcn.com"],
description: siteConfig.description,
inLanguage: "en-US",
sameAs: [siteConfig.links.github, siteConfig.links.twitter],
}
export const dynamic = "force-static"
export const revalidate = false
export const metadata: Metadata = {
title: {
absolute: metadataTitle,
},
description,
alternates: {
canonical: "/",
},
openGraph: {
type: "website",
url: siteConfig.url,
title: metadataTitle,
description,
siteName: siteConfig.name,
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
twitter: {
card: "summary_large_image",
title: metadataTitle,
description,
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
}
export default function IndexPage() {
return (
<div className="flex flex-1 flex-col">
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(websiteJsonLd).replace(/</g, "\\u003c"),
}}
/>
<PageHeader className="md:**:[.container]:pb-8 lg:**:[.container]:pb-12">
<Announcement />
<PageHeaderHeading className="max-w-4xl">{title}</PageHeaderHeading>
<PageHeaderDescription>{description}</PageHeaderDescription>
<PageActions>
<Button asChild className="h-[35px]">
<Link href="/docs/installation">Get Started</Link>
</Button>
<Button asChild variant="secondary">
<Link href="/docs/components">View Components</Link>
</Button>
</PageActions>
</PageHeader>
<div className="container-wrapper flex-1 p-0">
<div className="container overflow-hidden md:px-0 lg:max-w-none">
<section className="-mx-4 w-[140vw] overflow-hidden md:hidden">
<Image
src="/images/full-light.png"
width={2560}
height={2764}
alt="Dashboard"
className="block h-auto w-full dark:hidden"
priority
/>
<Image
src="/images/full-dark.png"
width={2560}
height={2764}
alt="Dashboard"
className="hidden h-auto w-full dark:block"
priority
/>
</section>
<section className="hidden md:block">
<CardsDemo />
</section>
</div>
</div>
</div>
)
}