Add modular dashboard widgets and layout editor
Some checks failed
Build Frontend / build (push) Failing after 7s
Some checks failed
Build Frontend / build (push) Failing after 7s
Introduces a modular dashboard system with draggable, configurable widgets including revenue, low stock, recent customers, and pending chats. Adds a dashboard editor for layout customization, widget visibility, and settings. Refactors dashboard content to use the new widget system and improves UI consistency and interactivity.
This commit is contained in:
138
components/ui/empty-state.tsx
Normal file
138
components/ui/empty-state.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
Package,
|
||||
ShoppingBag,
|
||||
Users,
|
||||
Truck,
|
||||
MessageCircle,
|
||||
Plus,
|
||||
Share2,
|
||||
LucideIcon
|
||||
} from "lucide-react"
|
||||
import Link from "next/link"
|
||||
|
||||
interface EmptyStateProps {
|
||||
icon?: LucideIcon
|
||||
title: string
|
||||
description: string
|
||||
actionLabel?: string
|
||||
actionHref?: string
|
||||
actionOnClick?: () => void
|
||||
secondaryActionLabel?: string
|
||||
secondaryActionHref?: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* EmptyState - Reusable component for empty tables/lists
|
||||
* Shows an icon, title, description, and optional action button
|
||||
*/
|
||||
export function EmptyState({
|
||||
icon: Icon = Package,
|
||||
title,
|
||||
description,
|
||||
actionLabel,
|
||||
actionHref,
|
||||
actionOnClick,
|
||||
secondaryActionLabel,
|
||||
secondaryActionHref,
|
||||
className = ""
|
||||
}: EmptyStateProps) {
|
||||
return (
|
||||
<div className={`flex flex-col items-center justify-center py-12 px-4 text-center ${className}`}>
|
||||
<div className="h-16 w-16 rounded-full bg-muted/50 flex items-center justify-center mb-4">
|
||||
<Icon className="h-8 w-8 text-muted-foreground/50" />
|
||||
</div>
|
||||
<h3 className="text-lg font-medium mb-2">{title}</h3>
|
||||
<p className="text-sm text-muted-foreground max-w-sm mb-6">{description}</p>
|
||||
<div className="flex items-center gap-3">
|
||||
{actionLabel && (
|
||||
actionHref ? (
|
||||
<Button asChild>
|
||||
<Link href={actionHref}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
{actionLabel}
|
||||
</Link>
|
||||
</Button>
|
||||
) : actionOnClick ? (
|
||||
<Button onClick={actionOnClick}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
{actionLabel}
|
||||
</Button>
|
||||
) : null
|
||||
)}
|
||||
{secondaryActionLabel && secondaryActionHref && (
|
||||
<Button variant="outline" asChild>
|
||||
<Link href={secondaryActionHref}>
|
||||
<Share2 className="h-4 w-4 mr-2" />
|
||||
{secondaryActionLabel}
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Preset empty states for common scenarios
|
||||
export function OrdersEmptyState() {
|
||||
return (
|
||||
<EmptyState
|
||||
icon={ShoppingBag}
|
||||
title="No orders yet"
|
||||
description="When customers place orders, they'll appear here. Share your store link to start selling!"
|
||||
secondaryActionLabel="Share Store"
|
||||
secondaryActionHref="/dashboard/storefront"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export function ProductsEmptyState({ onAddProduct }: { onAddProduct?: () => void }) {
|
||||
return (
|
||||
<EmptyState
|
||||
icon={Package}
|
||||
title="No products yet"
|
||||
description="Add your first product to start selling. You can add products manually or import from a file."
|
||||
actionLabel="Add Product"
|
||||
actionOnClick={onAddProduct}
|
||||
actionHref={onAddProduct ? undefined : "/dashboard/products/add"}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export function CustomersEmptyState() {
|
||||
return (
|
||||
<EmptyState
|
||||
icon={Users}
|
||||
title="No customers yet"
|
||||
description="Once customers interact with your store, they'll appear here. Share your store link to attract customers!"
|
||||
secondaryActionLabel="Share Store"
|
||||
secondaryActionHref="/dashboard/storefront"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export function ShippingEmptyState({ onAddMethod }: { onAddMethod?: () => void }) {
|
||||
return (
|
||||
<EmptyState
|
||||
icon={Truck}
|
||||
title="No shipping methods"
|
||||
description="Add shipping methods so customers know how they'll receive their orders."
|
||||
actionLabel="Add Shipping Method"
|
||||
actionOnClick={onAddMethod}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export function ChatsEmptyState() {
|
||||
return (
|
||||
<EmptyState
|
||||
icon={MessageCircle}
|
||||
title="No conversations yet"
|
||||
description="Customer chats will appear here when they message you through Telegram."
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user