E-Commerce
Mobile vs Desktop Card - Device Analytics
Analyze mobile versus desktop traffic and conversion rates. Monitor device-specific user behavior and performance.
Mobile vs Desktop Card
The Mobile vs Desktop Card Compare device analytics and user behavior.
Preview
Installation
ash npx shadcn@latest add https://vectormotion.vercel.app/registry/mobile-vs-desktop-card.json
Mobile vs Desktop Card
'use client';import React from "react";import { Smartphone, Monitor, TrendingUp } from "lucide-react";import { motion } from "motion/react";import { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs));}interface Device { device: "Mobile" | "Desktop" | "Tablet"; sessions: number; revenue: number; conversion: number; color: string; [key: string]: any;}interface MobileVsDesktopCardProps { className?: string; title?: string; description?: string; devices?: Device[];}const DEFAULT_TITLE = "Mobile vs Desktop";const DEFAULT_DESCRIPTION = "Device Analytics";const DEFAULT_DEVICES: Device[] = [ { device: "Mobile", sessions: 15420, revenue: 45200, conversion: 2.8, color: "bg-blue-500", }, { device: "Desktop", sessions: 12350, revenue: 62100, conversion: 4.2, color: "bg-purple-500", }, { device: "Tablet", sessions: 3200, revenue: 8900, conversion: 2.1, color: "bg-emerald-500", },];export const MobileVsDesktopCard: React.FC<MobileVsDesktopCardProps> = ({ className = "", title = DEFAULT_TITLE, description = DEFAULT_DESCRIPTION, devices = DEFAULT_DEVICES,}) => { const isInteractive = true; const index = 48; const totalSessions = devices.reduce((sum, d) => sum + d.sessions, 0); return ( <motion.div layoutId={isInteractive ? `card-${index}-${title}` : undefined} transition={{ duration: 0.4, ease: "easeOut" }} className={cn( "relative overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-6 shadow-sm transition-all flex flex-col group", isInteractive ? "cursor-pointer hover:border-zinc-300 dark:hover:border-zinc-700" : "", className, )} > <div className="mb-4 flex items-start justify-between relative z-10"> <div> <h3 className="font-semibold text-lg tracking-tight text-foreground"> {title} </h3> {description && ( <p className="text-sm text-muted-foreground mt-1">{description}</p> )} </div> <div className="rounded-full bg-zinc-100 dark:bg-zinc-800 p-2 text-foreground flex items-center justify-center"> <Smartphone className="h-5 w-5 text-blue-500" /> </div> </div> <div className="relative z-10 flex-1"> <div className="text-2xl font-bold text-foreground mb-1"> {(totalSessions / 1000).toFixed(1)}K </div> <p className="text-sm text-muted-foreground mb-4">Total sessions</p> <div className="space-y-3"> {devices.map((device, idx) => { const percentage = Math.round( (device.sessions / totalSessions) * 100, ); return ( <motion.div key={idx} initial={{ opacity: 0, y: 5 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4, delay: idx * 0.1 }} className="bg-muted rounded-lg p-3" > <div className="flex justify-between items-center mb-2"> <div className="flex items-center gap-2"> {device.device === "Mobile" ? ( <Smartphone className="h-4 w-4 text-blue-500" /> ) : device.device === "Desktop" ? ( <Monitor className="h-4 w-4 text-purple-500" /> ) : ( <Smartphone className="h-4 w-4 text-emerald-500" /> )} <span className="text-sm font-medium text-foreground"> {device.device} </span> </div> <span className="text-sm font-bold text-foreground"> {percentage}% </span> </div> <div className="grid grid-cols-3 gap-2 text-xs"> <div> <div className="text-muted-foreground">Sessions</div> <div className="font-medium text-foreground"> {(device.sessions / 1000).toFixed(1)}K </div> </div> <div> <div className="text-muted-foreground">Revenue</div> <div className="font-medium text-emerald-500"> ${(device.revenue / 1000).toFixed(0)}K </div> </div> <div> <div className="text-muted-foreground">CVR</div> <div className="font-medium text-foreground"> {device.conversion}% </div> </div> </div> </motion.div> ); })} </div> </div> </motion.div> );};Usage
This component is a data-rich dashboard card displaying e-commerce metrics with animated visualizations and dark mode support. Perfect for dashboards, landing pages, and analytics interfaces.
Prop
Type