update dashboard ux
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -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 (0–100) 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
|
||||
|
||||
Reference in New Issue
Block a user