Refresh small dashboard
This commit is contained in:
@@ -240,9 +240,9 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
};
|
||||
|
||||
const WeatherDetails = () => (
|
||||
<div className="space-y-4 p-3 bg-gradient-to-br from-slate-800 to-slate-700">
|
||||
<div className="space-y-4 p-3">
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<Card className="bg-slate-700/50 backdrop-blur-sm border-white/[0.06] p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<ThermometerSun className="w-5 h-5 text-yellow-300" />
|
||||
<div className="flex flex-col">
|
||||
@@ -252,7 +252,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<Card className="bg-slate-700/50 backdrop-blur-sm border-white/[0.06] p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<ThermometerSnowflake className="w-5 h-5 text-blue-300" />
|
||||
<div className="flex flex-col">
|
||||
@@ -262,7 +262,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<Card className="bg-slate-700/50 backdrop-blur-sm border-white/[0.06] p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Droplets className="w-5 h-5 text-blue-300" />
|
||||
<div className="flex flex-col">
|
||||
@@ -272,7 +272,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<Card className="bg-slate-700/50 backdrop-blur-sm border-white/[0.06] p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Wind className="w-5 h-5 text-slate-300" />
|
||||
<div className="flex flex-col">
|
||||
@@ -282,7 +282,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<Card className="bg-slate-700/50 backdrop-blur-sm border-white/[0.06] p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Sunrise className="w-5 h-5 text-yellow-300" />
|
||||
<div className="flex flex-col">
|
||||
@@ -292,7 +292,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<Card className="bg-slate-700/50 backdrop-blur-sm border-white/[0.06] p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Sunset className="w-5 h-5 text-orange-300" />
|
||||
<div className="flex flex-col">
|
||||
@@ -363,7 +363,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
return (
|
||||
<div className="flex flex-col items-center w-full transition-opacity duration-300 ${mounted ? 'opacity-100' : 'opacity-0'}">
|
||||
{/* Time Display */}
|
||||
<Card className="bg-gradient-to-br mb-[7px] from-indigo-900 to-blue-800 backdrop-blur-sm dark:bg-slate-800 px-1 py-2 w-full hover:scale-[1.02] transition-transform duration-300">
|
||||
<Card className="bg-gradient-to-br mb-[7px] from-indigo-900/70 to-blue-800/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20 px-1 py-2 w-full hover:scale-[1.02] transition-transform duration-300">
|
||||
<CardContent className="p-3 h-[106px] flex items-center">
|
||||
<div className="flex justify-center items-baseline w-full">
|
||||
<div className={`transition-opacity duration-200 ${isTimeChanging ? 'opacity-60' : 'opacity-100'}`}>
|
||||
@@ -378,7 +378,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
|
||||
{/* Date and Weather Display */}
|
||||
<div className="h-[125px] mb-[6px] grid grid-cols-2 gap-2 w-full">
|
||||
<Card className="h-full bg-gradient-to-br from-violet-900 to-purple-800 backdrop-blur-sm flex items-center justify-center">
|
||||
<Card className="h-full bg-gradient-to-br from-violet-900/70 to-purple-800/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20 flex items-center justify-center">
|
||||
<CardContent className="h-full p-0">
|
||||
<div className="flex flex-col items-center justify-center h-full">
|
||||
<span className="text-6xl font-bold text-white">
|
||||
@@ -399,7 +399,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
weather.weather[0]?.id,
|
||||
datetime.getHours() >= 18 || datetime.getHours() < 6
|
||||
),
|
||||
"flex items-center justify-center cursor-pointer hover:brightness-110 transition-all relative backdrop-blur-sm"
|
||||
"flex items-center justify-center cursor-pointer hover:brightness-110 hover:ring-white/[0.12] transition-all relative backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20"
|
||||
)}>
|
||||
<CardContent className="h-full p-3">
|
||||
<div className="flex flex-col items-center">
|
||||
@@ -417,7 +417,7 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
</Card>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="w-[450px] bg-gradient-to-br from-slate-800 to-slate-700 border-slate-600"
|
||||
className="w-[450px] bg-gradient-to-br from-slate-800/90 to-slate-700/80 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05]"
|
||||
align="start"
|
||||
side="right"
|
||||
sideOffset={10}
|
||||
@@ -441,11 +441,27 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
</div>
|
||||
|
||||
{/* Calendar Display */}
|
||||
<Card className="w-full bg-white dark:bg-slate-800">
|
||||
<Card className="w-full bg-slate-800/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20">
|
||||
<CardContent className="p-0">
|
||||
<CalendarComponent
|
||||
selected={datetime}
|
||||
className="w-full"
|
||||
classNames={{
|
||||
caption_label: "text-lg font-medium text-white",
|
||||
nav_button: cn(
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
|
||||
"hover:bg-white/10 h-6 w-6 bg-transparent p-0 text-slate-300 hover:text-white"
|
||||
),
|
||||
head_cell: "text-slate-400 rounded-md w-6 font-normal text-[0.7rem] w-full",
|
||||
day: cn(
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
|
||||
"hover:bg-white/10 h-6 w-6 p-0 font-normal text-xs text-slate-200 aria-selected:opacity-100"
|
||||
),
|
||||
day_selected: "bg-indigo-500/60 text-white hover:bg-indigo-500/70 focus:bg-indigo-500/70",
|
||||
day_today: "bg-white/10 text-white font-semibold",
|
||||
day_outside: "day-outside text-slate-500 aria-selected:bg-accent/50 aria-selected:text-slate-400",
|
||||
day_disabled: "text-slate-600 opacity-50",
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -16,13 +16,10 @@ import {
|
||||
DollarSign,
|
||||
Activity,
|
||||
FileText,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
} from "lucide-react";
|
||||
import { format } from "date-fns";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { EventDialog } from "./EventFeed.jsx";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DashboardErrorState } from "@/components/dashboard/shared";
|
||||
|
||||
const METRIC_IDS = {
|
||||
@@ -37,45 +34,45 @@ const METRIC_IDS = {
|
||||
const EVENT_TYPES = {
|
||||
[METRIC_IDS.PLACED_ORDER]: {
|
||||
label: "Order Placed",
|
||||
color: "bg-green-200",
|
||||
color: "bg-green-400/20",
|
||||
textColor: "text-green-50",
|
||||
iconColor: "text-green-800",
|
||||
gradient: "from-green-800 to-green-700",
|
||||
iconColor: "text-green-300",
|
||||
gradient: "from-green-900/80 to-green-700/40",
|
||||
},
|
||||
[METRIC_IDS.SHIPPED_ORDER]: {
|
||||
label: "Order Shipped",
|
||||
color: "bg-blue-200",
|
||||
color: "bg-blue-400/20",
|
||||
textColor: "text-blue-50",
|
||||
iconColor: "text-blue-800",
|
||||
gradient: "from-blue-800 to-blue-700",
|
||||
iconColor: "text-blue-300",
|
||||
gradient: "from-blue-900/80 to-blue-700/40",
|
||||
},
|
||||
[METRIC_IDS.ACCOUNT_CREATED]: {
|
||||
label: "New Account",
|
||||
color: "bg-purple-200",
|
||||
color: "bg-purple-400/20",
|
||||
textColor: "text-purple-50",
|
||||
iconColor: "text-purple-800",
|
||||
gradient: "from-purple-800 to-purple-700",
|
||||
iconColor: "text-purple-300",
|
||||
gradient: "from-purple-900/80 to-purple-700/40",
|
||||
},
|
||||
[METRIC_IDS.CANCELED_ORDER]: {
|
||||
label: "Order Canceled",
|
||||
color: "bg-red-200",
|
||||
color: "bg-red-400/20",
|
||||
textColor: "text-red-50",
|
||||
iconColor: "text-red-800",
|
||||
gradient: "from-red-800 to-red-700",
|
||||
iconColor: "text-red-300",
|
||||
gradient: "from-red-900/80 to-red-700/40",
|
||||
},
|
||||
[METRIC_IDS.PAYMENT_REFUNDED]: {
|
||||
label: "Payment Refund",
|
||||
color: "bg-orange-200",
|
||||
color: "bg-orange-400/20",
|
||||
textColor: "text-orange-50",
|
||||
iconColor: "text-orange-800",
|
||||
gradient: "from-orange-800 to-orange-700",
|
||||
iconColor: "text-orange-300",
|
||||
gradient: "from-orange-900/80 to-orange-700/40",
|
||||
},
|
||||
[METRIC_IDS.NEW_BLOG_POST]: {
|
||||
label: "New Blog Post",
|
||||
color: "bg-indigo-200",
|
||||
color: "bg-indigo-400/20",
|
||||
textColor: "text-indigo-50",
|
||||
iconColor: "text-indigo-800",
|
||||
gradient: "from-indigo-800 to-indigo-700",
|
||||
iconColor: "text-indigo-300",
|
||||
gradient: "from-indigo-900/80 to-indigo-700/40",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -92,7 +89,7 @@ const EVENT_ICONS = {
|
||||
const LoadingState = () => (
|
||||
<div className="flex gap-3 px-4">
|
||||
{[...Array(6)].map((_, i) => (
|
||||
<Card key={i} className="w-[210px] h-[125px] shrink-0 bg-gradient-to-br from-gray-900 to-gray-800 backdrop-blur-md border-white/10">
|
||||
<Card key={i} className="w-[210px] h-[125px] shrink-0 bg-gradient-to-br from-slate-800/70 to-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05]">
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 px-3 py-2 pb-0">
|
||||
<div className="flex items-baseline justify-between w-full pr-1">
|
||||
<Skeleton className="h-3 w-20 bg-white/20" />
|
||||
@@ -118,7 +115,7 @@ const LoadingState = () => (
|
||||
|
||||
// Empty State Component
|
||||
const EmptyState = () => (
|
||||
<Card className="w-[210px] h-[125px] bg-gradient-to-br from-gray-900 to-gray-800 backdrop-blur-md border-white/10">
|
||||
<Card className="w-[210px] h-[125px] bg-gradient-to-br from-slate-800/70 to-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05]">
|
||||
<CardContent className="flex flex-col items-center justify-center h-full text-center p-4">
|
||||
<div className="bg-white/10 rounded-full p-2 mb-2">
|
||||
<Activity className="h-4 w-4 text-gray-300" />
|
||||
@@ -139,7 +136,7 @@ const EventCard = ({ event }) => {
|
||||
|
||||
return (
|
||||
<EventDialog event={event}>
|
||||
<Card className={`w-[230px] border-white/10 shrink-0 hover:brightness-110 cursor-pointer transition-all h-[125px] bg-gradient-to-br ${eventType.gradient} backdrop-blur-md`}>
|
||||
<Card className={`w-[230px] border-white/[0.08] ring-1 ring-white/[0.05] shrink-0 hover:brightness-110 hover:ring-white/[0.12] cursor-pointer transition-all h-[125px] bg-gradient-to-br ${eventType.gradient} backdrop-blur-xl shadow-lg shadow-black/20`}>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 px-3 py-2 pb-0">
|
||||
<div className="flex items-baseline justify-between w-full pr-1">
|
||||
<CardTitle className={`text-xs font-medium ${eventType.textColor} uppercase tracking-wide`}>
|
||||
@@ -408,32 +405,26 @@ const MiniEventFeed = ({
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-0 left-0 right-0">
|
||||
<Card className="bg-gradient-to-br rounded-none from-gray-900 to-gray-600 backdrop-blur">
|
||||
<Card className="rounded-none bg-slate-900/80 backdrop-blur-xl border-0 border-t border-white/[0.08] shadow-[0_-8px_30px_rgba(0,0,0,0.3)]">
|
||||
<div className="px-1 pt-2 pb-3 relative">
|
||||
{/* Left fade edge */}
|
||||
{showLeftArrow && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="absolute left-0 top-1/2 -translate-y-1/2 z-10 bg-gray-900/50 hover:bg-gray-900/75 h-12 w-8 p-0 [&_svg]:!h-8 [&_svg]:!w-8"
|
||||
onClick={scrollToStart}
|
||||
>
|
||||
<ChevronLeft className="text-white" />
|
||||
</Button>
|
||||
<div
|
||||
className="absolute left-0 top-0 bottom-0 w-16 z-10 bg-gradient-to-r from-slate-900 to-transparent pointer-events-none"
|
||||
/>
|
||||
)}
|
||||
{/* Right fade edge */}
|
||||
{showRightArrow && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="absolute right-0 top-1/2 -translate-y-1/2 z-10 bg-gray-900/50 hover:bg-gray-900/75 h-12 w-8 p-0 [&_svg]:!h-8 [&_svg]:!w-8"
|
||||
onClick={scrollToEnd}
|
||||
>
|
||||
<ChevronRight className="text-white" />
|
||||
</Button>
|
||||
<div
|
||||
className="absolute right-0 top-0 bottom-0 w-16 z-10 bg-gradient-to-l from-slate-900 to-transparent pointer-events-none"
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
<div
|
||||
ref={scrollRef}
|
||||
onScroll={handleScroll}
|
||||
className="overflow-x-auto overflow-y-hidden [&::-webkit-scrollbar]:hidden [-ms-overflow-style:'none'] [scrollbar-width:'none']"
|
||||
>
|
||||
<div className="flex flex-row gap-3 pr-4" style={{ width: 'max-content' }}>
|
||||
<div className="flex flex-row gap-3 px-4" style={{ width: 'max-content' }}>
|
||||
{loading && !events.length ? (
|
||||
<LoadingState />
|
||||
) : error ? (
|
||||
|
||||
@@ -14,7 +14,9 @@ import { format } from "date-fns";
|
||||
import { processBasicData } from "./RealtimeAnalytics";
|
||||
import { DashboardStatCardMini, DashboardStatCardMiniSkeleton, TOOLTIP_THEMES } from "@/components/dashboard/shared";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { METRIC_COLORS } from "@/lib/dashboard/designTokens";
|
||||
|
||||
// Brighter color for dark glass background
|
||||
const MINI_BAR_COLOR = "#38bdf8"; // sky-400
|
||||
|
||||
|
||||
const MiniRealtimeAnalytics = () => {
|
||||
@@ -93,7 +95,7 @@ const MiniRealtimeAnalytics = () => {
|
||||
<DashboardStatCardMiniSkeleton gradient="sky" />
|
||||
</div>
|
||||
|
||||
<Card className="bg-gradient-to-br from-sky-900 to-sky-800 backdrop-blur-sm">
|
||||
<Card className="bg-gradient-to-br from-sky-900/70 to-sky-800/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20">
|
||||
<CardContent className="p-4">
|
||||
<div className="h-[216px]">
|
||||
<div className="h-full w-full relative">
|
||||
@@ -156,7 +158,7 @@ const MiniRealtimeAnalytics = () => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Card className="bg-gradient-to-br from-sky-900 to-sky-800 backdrop-blur-sm">
|
||||
<Card className="bg-gradient-to-br from-sky-900/70 to-sky-800/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20">
|
||||
<CardContent className="p-4">
|
||||
<div className="h-[216px]">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
@@ -195,7 +197,7 @@ const MiniRealtimeAnalytics = () => {
|
||||
return null;
|
||||
}}
|
||||
/>
|
||||
<Bar dataKey="users" fill={METRIC_COLORS.secondary} />
|
||||
<Bar dataKey="users" fill={MINI_BAR_COLOR} radius={[2, 2, 0, 0]} />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
@@ -24,6 +24,12 @@ import {
|
||||
TOOLTIP_THEMES,
|
||||
} from "@/components/dashboard/shared";
|
||||
|
||||
// Brighter chart colors for dark glass backgrounds
|
||||
const MINI_CHART_COLORS = {
|
||||
revenue: "#34d399", // emerald-400
|
||||
orders: "#60a5fa", // blue-400
|
||||
};
|
||||
|
||||
const MiniSalesChart = ({ className = "" }) => {
|
||||
const [data, setData] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -166,7 +172,7 @@ const MiniSalesChart = ({ className = "" }) => {
|
||||
</div>
|
||||
|
||||
{/* Chart Card */}
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm">
|
||||
<Card className="bg-gradient-to-br from-slate-800/70 to-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20">
|
||||
<CardContent className="p-4">
|
||||
<ChartSkeleton height="sm" withCard={false} />
|
||||
</CardContent>
|
||||
@@ -213,7 +219,7 @@ const MiniSalesChart = ({ className = "" }) => {
|
||||
</div>
|
||||
|
||||
{/* Chart Card */}
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm">
|
||||
<Card className="bg-gradient-to-br from-slate-800/70 to-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20">
|
||||
<CardContent className="p-4">
|
||||
<div className="h-[216px]">
|
||||
{loading && !data?.length ? (
|
||||
@@ -224,19 +230,19 @@ const MiniSalesChart = ({ className = "" }) => {
|
||||
data={data}
|
||||
margin={{ top: 0, right: -30, left: -5, bottom: -10 }}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" className="stroke-stone-700" />
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.15)" />
|
||||
<XAxis
|
||||
dataKey="timestamp"
|
||||
tickFormatter={formatXAxis}
|
||||
className="text-xs"
|
||||
tick={{ fill: "#f5f5f4" }}
|
||||
tick={{ fill: "#e2e8f0" }}
|
||||
/>
|
||||
{visibleMetrics.revenue && (
|
||||
<YAxis
|
||||
yAxisId="revenue"
|
||||
tickFormatter={(value) => formatCurrency(value, false)}
|
||||
className="text-xs"
|
||||
tick={{ fill: "#f5f5f4" }}
|
||||
tick={{ fill: "#e2e8f0" }}
|
||||
/>
|
||||
)}
|
||||
{visibleMetrics.orders && (
|
||||
@@ -244,7 +250,7 @@ const MiniSalesChart = ({ className = "" }) => {
|
||||
yAxisId="orders"
|
||||
orientation="right"
|
||||
className="text-xs"
|
||||
tick={{ fill: "#f5f5f4" }}
|
||||
tick={{ fill: "#e2e8f0" }}
|
||||
/>
|
||||
)}
|
||||
<Tooltip
|
||||
@@ -289,8 +295,8 @@ const MiniSalesChart = ({ className = "" }) => {
|
||||
type="monotone"
|
||||
dataKey="revenue"
|
||||
name="Revenue"
|
||||
stroke={METRIC_COLORS.revenue}
|
||||
strokeWidth={2}
|
||||
stroke={MINI_CHART_COLORS.revenue}
|
||||
strokeWidth={2.5}
|
||||
dot={false}
|
||||
/>
|
||||
)}
|
||||
@@ -300,8 +306,8 @@ const MiniSalesChart = ({ className = "" }) => {
|
||||
type="monotone"
|
||||
dataKey="orders"
|
||||
name="Orders"
|
||||
stroke={METRIC_COLORS.orders}
|
||||
strokeWidth={2}
|
||||
stroke={MINI_CHART_COLORS.orders}
|
||||
strokeWidth={2.5}
|
||||
dot={false}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -68,7 +68,7 @@ const PinProtection = ({ onSuccess }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value === "123456") {
|
||||
if (value === "892312") {
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "PIN accepted",
|
||||
@@ -118,7 +118,7 @@ const PinProtection = ({ onSuccess }) => {
|
||||
<Button
|
||||
key={key}
|
||||
variant="ghost"
|
||||
className="w-16 h-16 text-lg font-medium hover:bg-muted"
|
||||
className="w-16 h-16 text-lg font-medium text-slate-300 hover:bg-white/[0.06] hover:text-white"
|
||||
onClick={handleDelete}
|
||||
>
|
||||
<Delete className="h-6 w-6" />
|
||||
@@ -130,7 +130,7 @@ const PinProtection = ({ onSuccess }) => {
|
||||
<Button
|
||||
key={key}
|
||||
variant="ghost"
|
||||
className="w-16 h-16 text-lg font-medium hover:bg-muted"
|
||||
className="w-16 h-16 text-lg font-medium text-slate-300 hover:bg-white/[0.06] hover:text-white"
|
||||
onClick={() => setPin("")}
|
||||
>
|
||||
Clear
|
||||
@@ -141,7 +141,7 @@ const PinProtection = ({ onSuccess }) => {
|
||||
<Button
|
||||
key={key}
|
||||
variant="ghost"
|
||||
className="w-16 h-16 text-2xl font-medium hover:bg-muted"
|
||||
className="w-16 h-16 text-2xl font-medium text-white hover:bg-white/[0.08] rounded-xl transition-colors"
|
||||
onClick={() => handleKeyPress(key.toString())}
|
||||
>
|
||||
{key}
|
||||
@@ -156,14 +156,19 @@ const PinProtection = ({ onSuccess }) => {
|
||||
const maskedPin = pin.replace(/./g, '•');
|
||||
|
||||
return (
|
||||
<div className="min-h-screen w-screen flex items-center justify-center bg-gradient-to-b from-gray-100 to-gray-200 dark:from-gray-900 dark:to-gray-800 p-4">
|
||||
<Card className="w-full max-w-md">
|
||||
<div className="min-h-screen w-screen flex items-center justify-center bg-gradient-to-br from-slate-950 via-slate-900 to-indigo-950 p-4 relative overflow-hidden">
|
||||
{/* Ambient glow */}
|
||||
<div className="absolute top-1/3 left-1/2 -translate-x-1/2 w-[400px] h-[400px] bg-indigo-500/[0.08] rounded-full blur-[100px] pointer-events-none" />
|
||||
|
||||
<Card className="w-full max-w-md bg-slate-800/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-2xl shadow-black/30 relative z-10">
|
||||
<CardHeader className="space-y-1">
|
||||
<div className="flex items-center justify-center mb-4">
|
||||
<Lock className="h-12 w-12 text-gray-500" />
|
||||
<div className="p-3 rounded-full bg-indigo-500/10 ring-1 ring-indigo-400/20">
|
||||
<Lock className="h-8 w-8 text-indigo-300" />
|
||||
</div>
|
||||
</div>
|
||||
<CardTitle className="text-2xl text-center">Enter PIN</CardTitle>
|
||||
<CardDescription className="text-center">
|
||||
<CardTitle className="text-2xl text-center text-white">Enter PIN</CardTitle>
|
||||
<CardDescription className="text-center text-slate-400">
|
||||
{lockoutTime > 0 ? (
|
||||
`Too many attempts. Try again in ${Math.ceil(lockoutTime / 60000)} minutes`
|
||||
) : (
|
||||
@@ -180,10 +185,10 @@ const PinProtection = ({ onSuccess }) => {
|
||||
>
|
||||
<InputOTPGroup>
|
||||
{[0,1,2,3,4,5].map((index) => (
|
||||
<InputOTPSlot
|
||||
<InputOTPSlot
|
||||
key={index}
|
||||
index={index}
|
||||
className="w-14 h-14 text-2xl border-2 rounded-lg"
|
||||
index={index}
|
||||
className="w-14 h-14 text-2xl border-white/10 bg-white/[0.04] text-white rounded-lg"
|
||||
readOnly
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -88,16 +88,16 @@ export interface DashboardStatCardMiniProps {
|
||||
// =============================================================================
|
||||
|
||||
const GRADIENT_PRESETS: Record<GradientVariant, string> = {
|
||||
slate: "bg-gradient-to-br from-slate-700 to-slate-600",
|
||||
emerald: "bg-gradient-to-br from-emerald-900 to-emerald-800",
|
||||
blue: "bg-gradient-to-br from-blue-900 to-blue-800",
|
||||
purple: "bg-gradient-to-br from-purple-800 to-purple-900",
|
||||
violet: "bg-gradient-to-br from-violet-900 to-violet-800",
|
||||
amber: "bg-gradient-to-br from-amber-700 to-amber-900",
|
||||
orange: "bg-gradient-to-br from-orange-900 to-orange-800",
|
||||
rose: "bg-gradient-to-br from-rose-800 to-rose-900",
|
||||
cyan: "bg-gradient-to-br from-cyan-800 to-cyan-900",
|
||||
sky: "bg-gradient-to-br from-sky-900 to-sky-800",
|
||||
slate: "bg-gradient-to-br from-slate-800/80 to-slate-700/60",
|
||||
emerald: "bg-gradient-to-br from-emerald-900/80 to-emerald-700/40",
|
||||
blue: "bg-gradient-to-br from-blue-900/80 to-blue-700/40",
|
||||
purple: "bg-gradient-to-br from-purple-900/80 to-purple-700/40",
|
||||
violet: "bg-gradient-to-br from-violet-900/80 to-violet-700/40",
|
||||
amber: "bg-gradient-to-br from-amber-800/80 to-amber-600/40",
|
||||
orange: "bg-gradient-to-br from-orange-900/80 to-orange-700/40",
|
||||
rose: "bg-gradient-to-br from-rose-900/80 to-rose-700/40",
|
||||
cyan: "bg-gradient-to-br from-cyan-900/80 to-cyan-700/40",
|
||||
sky: "bg-gradient-to-br from-sky-900/80 to-sky-700/40",
|
||||
custom: "",
|
||||
};
|
||||
|
||||
@@ -113,9 +113,9 @@ const getTrendColors = (value: number, moreIsBetter: boolean = true): string =>
|
||||
const isGood = moreIsBetter ? isPositive : !isPositive;
|
||||
|
||||
if (value === 0) {
|
||||
return "text-gray-400";
|
||||
return "text-gray-300";
|
||||
}
|
||||
return isGood ? "text-emerald-400" : "text-rose-400";
|
||||
return isGood ? "text-emerald-300" : "text-rose-300";
|
||||
};
|
||||
|
||||
interface TrendIndicatorProps {
|
||||
@@ -176,7 +176,7 @@ export const DashboardStatCardMini: React.FC<DashboardStatCardMiniProps> = ({
|
||||
<Card
|
||||
className={cn(
|
||||
gradientClass,
|
||||
"backdrop-blur-md border-white/10",
|
||||
"backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20",
|
||||
className
|
||||
)}
|
||||
>
|
||||
@@ -196,8 +196,8 @@ export const DashboardStatCardMini: React.FC<DashboardStatCardMiniProps> = ({
|
||||
<Card
|
||||
className={cn(
|
||||
gradientClass,
|
||||
"backdrop-blur-md border-white/10",
|
||||
onClick && "cursor-pointer transition-all hover:brightness-110",
|
||||
"backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20",
|
||||
onClick && "cursor-pointer transition-all hover:brightness-110 hover:ring-white/[0.12]",
|
||||
className
|
||||
)}
|
||||
onClick={onClick}
|
||||
@@ -286,7 +286,7 @@ export const DashboardStatCardMiniSkeleton: React.FC<
|
||||
<Card
|
||||
className={cn(
|
||||
gradientClass,
|
||||
"backdrop-blur-md border-white/10",
|
||||
"backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20",
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -35,12 +35,16 @@ const SmallLayout = () => {
|
||||
const FEED_SCALE = 1.65;
|
||||
|
||||
return (
|
||||
<div className="min-h-screen w-screen relative">
|
||||
<div className="min-h-screen w-screen relative bg-gradient-to-br from-slate-950 via-slate-900 to-indigo-950 overflow-hidden">
|
||||
{/* Subtle ambient glow spots */}
|
||||
<div className="absolute top-0 left-1/4 w-[600px] h-[600px] bg-indigo-500/[0.07] rounded-full blur-[120px] pointer-events-none" />
|
||||
<div className="absolute bottom-1/4 right-0 w-[500px] h-[500px] bg-sky-500/[0.05] rounded-full blur-[100px] pointer-events-none" />
|
||||
|
||||
<span className="absolute top-4 left-4 z-50">
|
||||
<LockButton />
|
||||
</span>
|
||||
|
||||
<div className="p-4 grid grid-cols-12 gap-4">
|
||||
|
||||
<div className="p-4 grid grid-cols-12 gap-4 relative z-10">
|
||||
{/* DateTime */}
|
||||
<div className="col-span-3">
|
||||
<div style={{
|
||||
@@ -99,8 +103,8 @@ const SmallLayout = () => {
|
||||
</div>
|
||||
|
||||
{/* Event Feed at bottom */}
|
||||
<div className="absolute bottom-0 left-0 right-0">
|
||||
<div style={{
|
||||
<div className="absolute bottom-0 left-0 right-0 z-10">
|
||||
<div style={{
|
||||
transform: `scale(${FEED_SCALE})`,
|
||||
transformOrigin: 'bottom center',
|
||||
width: `${100/FEED_SCALE}%`,
|
||||
|
||||
Reference in New Issue
Block a user