(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
98
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 64 lines 1.9 kB view raw
1import React from "react"; 2import { clsx } from "clsx"; 3 4interface EmptyStateProps { 5 icon?: React.ReactNode; 6 title?: string; 7 message: string; 8 action?: React.ReactNode | { label: string; onClick: () => void }; 9 className?: string; 10} 11 12export default function EmptyState({ 13 icon, 14 title, 15 message, 16 action, 17 className, 18}: EmptyStateProps) { 19 return ( 20 <div 21 className={clsx( 22 "relative text-center py-14 px-6 overflow-hidden", 23 "bg-gradient-to-b from-surface-50/80 to-surface-50/20 dark:from-surface-800/60 dark:to-surface-800/20 rounded-2xl", 24 "border border-dashed border-surface-200 dark:border-surface-700", 25 className, 26 )} 27 > 28 {icon && ( 29 <div className="relative flex justify-center mb-4"> 30 <div className="absolute inset-0 flex justify-center items-center"> 31 <div className="h-16 w-16 rounded-full bg-primary-100/60 dark:bg-primary-900/20 blur-xl" /> 32 </div> 33 <div className="relative text-surface-400 dark:text-surface-500"> 34 {icon} 35 </div> 36 </div> 37 )} 38 {title && ( 39 <h3 className="text-lg font-display font-semibold text-surface-900 dark:text-white mb-2"> 40 {title} 41 </h3> 42 )} 43 <p className="text-surface-500 dark:text-surface-400 max-w-sm mx-auto leading-relaxed"> 44 {message} 45 </p> 46 {action && ( 47 <div className="mt-6"> 48 {typeof action === "object" && 49 "label" in action && 50 "onClick" in action ? ( 51 <button 52 onClick={action.onClick} 53 className="inline-flex items-center gap-2 px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg transition-colors" 54 > 55 {action.label} 56 </button> 57 ) : ( 58 action 59 )} 60 </div> 61 )} 62 </div> 63 ); 64}