update dashboard ux

This commit is contained in:
root
2026-06-24 03:04:01 -04:00
parent 2739f14e45
commit 572d115003
11 changed files with 449 additions and 36 deletions
@@ -303,7 +303,9 @@ export default function Sidebar() {
const className = [
'flex items-center gap-3 rounded-2xl px-3 py-2.5 text-sm font-medium transition-colors',
paddingClass,
active ? 'bg-orange-500 text-white' : 'text-slate-400 hover:bg-blue-900/40 hover:text-white',
active
? 'bg-orange-500 text-white shadow-[0_0_12px_rgba(249,115,22,0.3)] dark:shadow-[0_0_16px_rgba(249,115,22,0.35)]'
: 'text-slate-400 hover:bg-blue-900/40 hover:text-white',
].join(' ')
if (item.itemType === 'EXTERNAL_LINK' && item.routeOrUrl) {
@@ -364,22 +366,31 @@ export default function Sidebar() {
<aside
className={[
'fixed inset-y-0 z-40 flex w-64 flex-col border-r border-blue-900/50 bg-[#0a1128]/94 backdrop-blur-xl transition-transform duration-300',
'fixed inset-y-0 z-40 flex w-64 flex-col border-r transition-colors duration-300',
theme === 'dark'
? 'border-blue-900/50 bg-blue-950/80 backdrop-blur-xl'
: 'border-stone-200/80 bg-white/92 backdrop-blur-xl shadow-[4px_0_20px_rgba(0,0,0,0.04)]',
isRtl ? 'right-0' : 'left-0',
'lg:translate-x-0',
open ? 'translate-x-0' : (isRtl ? 'translate-x-full' : '-translate-x-full'),
].join(' ')}
>
<a href={marketplaceUrl} target="_top" className="flex items-center gap-3 border-b border-blue-900/50 px-6 py-5">
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center overflow-hidden rounded-lg bg-orange-400">
<a
href={marketplaceUrl}
target="_top"
className="flex items-center gap-3 border-b px-6 py-5 transition-colors border-blue-900/50 dark:border-blue-900/50"
>
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br from-orange-400 to-orange-500 shadow-sm">
{brand?.logoUrl ? (
// eslint-disable-next-line @next/next/no-img-element
<img src={brand.logoUrl} alt={brand.displayName} className="h-8 w-8 object-cover" />
) : (
<Car className="h-4 w-4 text-blue-950" />
<Car className="h-4 w-4 text-white" />
)}
</div>
<span className={`truncate text-sm font-bold tracking-wide ${theme === 'light' ? 'text-blue-600' : 'text-white'}`}>
<span className={`truncate text-sm font-bold tracking-wide ${
theme === 'dark' ? 'text-white' : 'text-blue-950'
}`}>
{brand?.displayName ?? 'RentalDriveGo'}
</span>
</a>
@@ -394,7 +405,9 @@ export default function Sidebar() {
href={item.href}
className={[
'flex items-center gap-3 rounded-2xl px-3 py-2.5 text-sm font-medium transition-colors',
active ? 'bg-orange-500 text-white' : 'text-slate-400 hover:bg-blue-900/40 hover:text-white',
active
? 'bg-orange-500 text-white shadow-[0_0_12px_rgba(249,115,22,0.3)] dark:shadow-[0_0_16px_rgba(249,115,22,0.35)]'
: 'text-slate-400 hover:bg-blue-900/40 hover:text-white',
].join(' ')}
>
<Icon className="h-4 w-4 flex-shrink-0" />
@@ -189,7 +189,19 @@ export default function TopBar() {
return (
<header className="relative z-[70] flex h-16 items-center justify-between border-b border-stone-200/80 bg-white/78 px-6 backdrop-blur-xl transition-colors dark:border-blue-900 dark:bg-blue-950/76">
<h1 className="text-lg font-semibold text-blue-950 dark:text-stone-50">{title}</h1>
<div className="flex items-center gap-4 min-w-0">
<h1 className="text-lg font-semibold text-blue-950 dark:text-stone-50 shrink-0">{title}</h1>
<div className="hidden sm:block relative max-w-xs w-full">
<svg className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-stone-400 dark:text-stone-500 pointer-events-none" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
</svg>
<input
type="search"
placeholder="Search…"
className="w-full rounded-2xl border border-stone-200 bg-stone-50/60 pl-9 pr-4 py-2 text-sm text-stone-900 placeholder:text-stone-400 transition-colors focus:border-orange-300 focus:bg-white focus:outline-none focus:ring-2 focus:ring-orange-500/20 dark:border-blue-800 dark:bg-blue-950/30 dark:text-slate-100 dark:placeholder:text-slate-500 dark:focus:border-orange-400 dark:focus:bg-blue-950/50"
/>
</div>
</div>
<div className="flex items-center gap-3">
<div className="relative">
+37 -3
View File
@@ -9,6 +9,14 @@ interface StatCardProps {
icon: LucideIcon
iconColor?: string
iconBg?: string
/** Optional target value to show a progress bar beneath the value */
target?: number
/** Current progress (0100) when target is set */
progressPercent?: number
/** Show a subtle pulse/glow animation on the card */
pulse?: boolean
/** Apply a gradient to the value text */
valueGradient?: boolean
}
export default function StatCard({
@@ -19,16 +27,42 @@ export default function StatCard({
icon: Icon,
iconColor = 'text-orange-700 dark:text-orange-300',
iconBg = 'bg-orange-50 dark:bg-orange-950/30',
target,
progressPercent,
pulse,
valueGradient,
}: StatCardProps) {
const isPositive = change !== undefined && change >= 0
const isNegative = change !== undefined && change < 0
return (
<div className="card p-6">
<div className={`card p-6 ${pulse ? 'pulse-glow' : ''}`}>
<div className="flex items-start justify-between">
<div>
<div className="min-w-0 flex-1">
<p className="text-sm font-medium text-stone-500 dark:text-stone-400">{title}</p>
<p className="mt-1 text-2xl font-bold text-blue-950 dark:text-stone-50">{value}</p>
<p
className={[
'mt-1 text-2xl font-bold',
valueGradient
? 'bg-gradient-to-r from-blue-600 to-orange-500 bg-clip-text text-transparent dark:from-blue-400 dark:to-orange-300'
: 'text-blue-950 dark:text-stone-50',
].join(' ')}
>
{value}
</p>
{target !== undefined && progressPercent !== undefined && (
<div className="mt-2 flex items-center gap-2">
<div className="progress-bar flex-1">
<div
className="progress-fill orange"
style={{ width: `${Math.min(progressPercent, 100)}%` }}
/>
</div>
<span className="text-xs font-mono text-stone-500 dark:text-stone-400">
{Math.round(progressPercent)}%
</span>
</div>
)}
{change !== undefined && (
<div className="mt-2 flex items-center gap-1">
<span