UNPKG

lightning-auth-and-payment

Version:

Lightning Network authentication and payment processing library for modern web applications

355 lines 22.3 kB
"use strict"; 'use client'; Object.defineProperty(exports, "__esModule", { value: true }); exports.LightningCard = LightningCard; exports.LightningPaymentCard = LightningPaymentCard; exports.LightningUserCard = LightningUserCard; exports.LightningWalletCard = LightningWalletCard; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const lucide_react_1 = require("lucide-react"); const card_1 = require("./ui/card"); const badge_1 = require("./ui/badge"); const button_1 = require("./ui/button"); const formatting_1 = require("../utils/formatting"); /** * Size configuration for cards */ const sizeConfig = { xs: { className: 'p-2', iconSize: 'w-3 h-3', titleSize: 'text-sm', descriptionSize: 'text-xs', }, sm: { className: 'p-3', iconSize: 'w-4 h-4', titleSize: 'text-base', descriptionSize: 'text-sm', }, md: { className: 'p-4', iconSize: 'w-5 h-5', titleSize: 'text-lg', descriptionSize: 'text-sm', }, lg: { className: 'p-6', iconSize: 'w-6 h-6', titleSize: 'text-xl', descriptionSize: 'text-base', }, xl: { className: 'p-8', iconSize: 'w-8 h-8', titleSize: 'text-2xl', descriptionSize: 'text-lg', }, }; /** * Enhanced variant configuration */ const variantConfig = { default: { icon: lucide_react_1.Zap, className: 'border-slate-200 dark:border-slate-800', iconColor: 'text-orange-500', bgColor: 'bg-white dark:bg-slate-900', glowColor: 'shadow-orange-500/20', }, payment: { icon: lucide_react_1.Receipt, className: 'border-green-200 dark:border-green-800', iconColor: 'text-green-500', bgColor: 'bg-green-50 dark:bg-green-900/20', glowColor: 'shadow-green-500/20', }, user: { icon: lucide_react_1.User, className: 'border-blue-200 dark:border-blue-800', iconColor: 'text-blue-500', bgColor: 'bg-blue-50 dark:bg-blue-900/20', glowColor: 'shadow-blue-500/20', }, wallet: { icon: lucide_react_1.Wallet, className: 'border-purple-200 dark:border-purple-800', iconColor: 'text-purple-500', bgColor: 'bg-purple-50 dark:bg-purple-900/20', glowColor: 'shadow-purple-500/20', }, status: { icon: lucide_react_1.CheckCircle, className: 'border-slate-200 dark:border-slate-800', iconColor: 'text-slate-500', bgColor: 'bg-slate-50 dark:bg-slate-900/20', glowColor: 'shadow-slate-500/20', }, info: { icon: lucide_react_1.AlertCircle, className: 'border-yellow-200 dark:border-yellow-800', iconColor: 'text-yellow-500', bgColor: 'bg-yellow-50 dark:bg-yellow-900/20', glowColor: 'shadow-yellow-500/20', }, transaction: { icon: lucide_react_1.Send, className: 'border-indigo-200 dark:border-indigo-800', iconColor: 'text-indigo-500', bgColor: 'bg-indigo-50 dark:bg-indigo-900/20', glowColor: 'shadow-indigo-500/20', }, invoice: { icon: lucide_react_1.Receipt, className: 'border-emerald-200 dark:border-emerald-800', iconColor: 'text-emerald-500', bgColor: 'bg-emerald-50 dark:bg-emerald-900/20', glowColor: 'shadow-emerald-500/20', }, channel: { icon: lucide_react_1.Zap, className: 'border-cyan-200 dark:border-cyan-800', iconColor: 'text-cyan-500', bgColor: 'bg-cyan-50 dark:bg-cyan-900/20', glowColor: 'shadow-cyan-500/20', }, node: { icon: lucide_react_1.Zap, className: 'border-rose-200 dark:border-rose-800', iconColor: 'text-rose-500', bgColor: 'bg-rose-50 dark:bg-rose-900/20', glowColor: 'shadow-rose-500/20', }, }; const statusConfig = { success: { icon: lucide_react_1.CheckCircle, color: 'text-green-500', bgColor: 'bg-green-50 dark:bg-green-900/20', borderColor: 'border-green-200 dark:border-green-800', }, error: { icon: lucide_react_1.XCircle, color: 'text-red-500', bgColor: 'bg-red-50 dark:bg-red-900/20', borderColor: 'border-red-200 dark:border-red-800', }, warning: { icon: lucide_react_1.AlertCircle, color: 'text-yellow-500', bgColor: 'bg-yellow-50 dark:bg-yellow-900/20', borderColor: 'border-yellow-200 dark:border-yellow-800', }, info: { icon: lucide_react_1.AlertCircle, color: 'text-blue-500', bgColor: 'bg-blue-50 dark:bg-blue-900/20', borderColor: 'border-blue-200 dark:border-blue-800', }, pending: { icon: lucide_react_1.Clock, color: 'text-orange-500', bgColor: 'bg-orange-50 dark:bg-orange-900/20', borderColor: 'border-orange-200 dark:border-orange-800', }, loading: { icon: lucide_react_1.Clock, color: 'text-blue-500', bgColor: 'bg-blue-50 dark:bg-blue-900/20', borderColor: 'border-blue-200 dark:border-blue-800', }, disabled: { icon: lucide_react_1.XCircle, color: 'text-gray-500', bgColor: 'bg-gray-50 dark:bg-gray-900/20', borderColor: 'border-gray-200 dark:border-gray-800', }, }; /** * Enhanced LightningCard component with comprehensive features */ function LightningCard({ variant = 'default', title, description, children, className, showIcon = true, icon, size = 'md', layout = 'default', interactive = false, onClick, onDoubleClick, status, statusMessage, showBorder = true, gradient = false, animation = 'none', hoverEffects = true, glow = false, pulse = false, loading = false, disabled = false, collapsible = false, defaultExpanded = true, expandable = false, showActions = false, actions, favorite = false, onFavorite, bookmarked = false, onBookmark, shareable = false, onShare, copyable = false, onCopy, private: isPrivate = false, showPrivateToggle = false, onPrivateToggle, metadata, header, footer, loadingText = 'Loading...', errorText = 'Error occurred', empty = false, emptyText = 'No data available', emptyIcon, theme = 'auto', colors, ariaLabel, ariaDescription, tabIndex, onFocus, onBlur, onKeyDown, }) { // State management const [isExpanded, setIsExpanded] = (0, react_1.useState)(defaultExpanded); const [isPrivateState, setIsPrivateState] = (0, react_1.useState)(isPrivate); const [isFavorited, setIsFavorited] = (0, react_1.useState)(favorite); const [isBookmarked, setIsBookmarked] = (0, react_1.useState)(bookmarked); const config = variantConfig[variant]; const sizeConfigData = sizeConfig[size]; const statusInfo = status ? statusConfig[status] : null; const IconComponent = config.icon; // Handle private toggle const handlePrivateToggle = () => { const newPrivate = !isPrivateState; setIsPrivateState(newPrivate); onPrivateToggle?.(newPrivate); }; // Handle favorite toggle const handleFavoriteToggle = (e) => { e.stopPropagation(); const newFavorite = !isFavorited; setIsFavorited(newFavorite); onFavorite?.(newFavorite); }; // Handle bookmark toggle const handleBookmarkToggle = (e) => { e.stopPropagation(); const newBookmark = !isBookmarked; setIsBookmarked(newBookmark); onBookmark?.(newBookmark); }; // Handle share const handleShare = (e) => { e.stopPropagation(); onShare?.(); }; // Handle copy const handleCopy = (e) => { e.stopPropagation(); onCopy?.(); }; // Handle expand/collapse const handleToggleExpanded = (e) => { e.stopPropagation(); setIsExpanded(!isExpanded); }; // Get size classes const getSizeClasses = () => { return sizeConfigData.className; }; // Get layout classes const getLayoutClasses = () => { switch (layout) { case 'compact': return 'p-2'; case 'expanded': return 'p-6'; case 'minimal': return 'p-1'; default: return getSizeClasses(); } }; // Get card classes with enhanced styling const getCardClasses = () => { const classes = [ 'relative overflow-hidden transition-all duration-200', showBorder ? 'border' : 'border-0', config.className, config.bgColor, ]; // Status styling if (statusInfo) { classes.push(statusInfo.bgColor, statusInfo.borderColor); } // Gradient background if (gradient) { classes.push('bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800'); } // Interactive effects if (interactive && !disabled) { classes.push('cursor-pointer hover:shadow-lg'); } // Animation effects if (animation === 'hover' || hoverEffects) { classes.push('hover:scale-105 hover:shadow-xl'); } if (animation === 'pulse' || pulse) { classes.push('animate-pulse'); } if (animation === 'glow' || glow) { classes.push(`hover:shadow-lg ${config.glowColor}`); } if (animation === 'bounce') { classes.push('hover:animate-bounce'); } if (animation === 'scale') { classes.push('hover:scale-110 active:scale-95'); } // State classes if (loading) { classes.push('opacity-75 cursor-wait'); } if (disabled) { classes.push('opacity-50 cursor-not-allowed'); } return classes.join(' '); }; // Render status indicator const renderStatus = () => { if (!status || !statusInfo) return null; return ((0, jsx_runtime_1.jsx)("div", { className: "absolute top-3 right-3 z-10", children: (0, jsx_runtime_1.jsxs)("div", { className: (0, formatting_1.cn)('flex items-center space-x-1', statusInfo.color), children: [(0, jsx_runtime_1.jsx)(statusInfo.icon, { className: "w-4 h-4" }), statusMessage && ((0, jsx_runtime_1.jsx)("span", { className: "text-xs font-medium", children: statusMessage }))] }) })); }; // Render action buttons const renderActions = () => { if (!showActions && !actions) return null; return ((0, jsx_runtime_1.jsx)("div", { className: "absolute top-3 left-3 z-10 flex space-x-1", children: actions || ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [onFavorite && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", size: "sm", onClick: handleFavoriteToggle, className: (0, formatting_1.cn)('h-6 w-6 p-0', isFavorited ? 'text-red-500 hover:text-red-600' : 'text-gray-400 hover:text-red-500'), children: (0, jsx_runtime_1.jsx)(lucide_react_1.Heart, { className: (0, formatting_1.cn)('w-3 h-3', isFavorited && 'fill-current') }) })), onBookmark && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", size: "sm", onClick: handleBookmarkToggle, className: (0, formatting_1.cn)('h-6 w-6 p-0', isBookmarked ? 'text-blue-500 hover:text-blue-600' : 'text-gray-400 hover:text-blue-500'), children: (0, jsx_runtime_1.jsx)(lucide_react_1.Bookmark, { className: (0, formatting_1.cn)('w-3 h-3', isBookmarked && 'fill-current') }) })), shareable && onShare && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", size: "sm", onClick: handleShare, className: "h-6 w-6 p-0 text-gray-400 hover:text-gray-600", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Share2, { className: "w-3 h-3" }) })), copyable && onCopy && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", size: "sm", onClick: handleCopy, className: "h-6 w-6 p-0 text-gray-400 hover:text-gray-600", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { className: "w-3 h-3" }) })), showPrivateToggle && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", size: "sm", onClick: handlePrivateToggle, className: (0, formatting_1.cn)('h-6 w-6 p-0', isPrivateState ? 'text-red-500 hover:text-red-600' : 'text-gray-400 hover:text-red-500'), children: isPrivateState ? (0, jsx_runtime_1.jsx)(lucide_react_1.Lock, { className: "w-3 h-3" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Unlock, { className: "w-3 h-3" }) })), collapsible && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", size: "sm", onClick: handleToggleExpanded, className: "h-6 w-6 p-0 text-gray-400 hover:text-gray-600", children: isExpanded ? (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { className: "w-3 h-3" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "w-3 h-3" }) }))] })) })); }; // Render loading state const renderLoading = () => { if (!loading) return null; return ((0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 bg-white/80 dark:bg-slate-900/80 flex items-center justify-center z-20", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium", children: loadingText })] }) })); }; // Render empty state const renderEmpty = () => { if (!empty) return null; return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [emptyIcon || (0, jsx_runtime_1.jsx)(lucide_react_1.AlertCircle, { className: "w-8 h-8 text-gray-400 mb-2" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-gray-500", children: emptyText })] })); }; // Render metadata const renderMetadata = () => { if (!metadata) return null; return ((0, jsx_runtime_1.jsxs)("div", { className: "mt-4 pt-4 border-t border-gray-200 dark:border-gray-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between text-xs text-gray-500", children: [metadata.timestamp && ((0, jsx_runtime_1.jsx)("span", { children: metadata.timestamp.toLocaleDateString() })), metadata.author && ((0, jsx_runtime_1.jsxs)("span", { children: ["by ", metadata.author] }))] }), metadata.tags && metadata.tags.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-1 mt-2", children: metadata.tags.map((tag, index) => ((0, jsx_runtime_1.jsx)(badge_1.Badge, { variant: "secondary", className: "text-xs", children: tag }, index))) }))] })); }; // Render content based on state const renderContent = () => { if (loading) return renderLoading(); if (empty) return renderEmpty(); return children; }; return ((0, jsx_runtime_1.jsxs)(card_1.Card, { className: (0, formatting_1.cn)(getCardClasses(), className), onClick: onClick, onDoubleClick: onDoubleClick, onFocus: onFocus, onBlur: onBlur, onKeyDown: onKeyDown, tabIndex: tabIndex, "aria-label": ariaLabel, "aria-describedby": ariaDescription, role: interactive ? 'button' : undefined, children: [renderStatus(), renderActions(), header || ((0, jsx_runtime_1.jsx)(card_1.CardHeader, { className: getLayoutClasses(), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-3", children: [showIcon && ((0, jsx_runtime_1.jsx)("div", { className: (0, formatting_1.cn)('p-2 rounded-lg bg-slate-100 dark:bg-slate-800', config.iconColor, sizeConfigData.iconSize), children: icon || (0, jsx_runtime_1.jsx)(IconComponent, { className: sizeConfigData.iconSize }) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1", children: [title && ((0, jsx_runtime_1.jsx)(card_1.CardTitle, { className: (0, formatting_1.cn)(sizeConfigData.titleSize, 'font-semibold'), children: title })), description && ((0, jsx_runtime_1.jsx)(card_1.CardDescription, { className: (0, formatting_1.cn)(sizeConfigData.descriptionSize, 'text-slate-600 dark:text-slate-400'), children: description }))] })] }) })), (children || loading || empty) && ((0, jsx_runtime_1.jsxs)(card_1.CardContent, { className: getLayoutClasses(), children: [isExpanded ? renderContent() : null, renderMetadata()] })), footer] })); } function LightningPaymentCard({ amount, description, status, paymentId, timestamp, onCopy, onDownload, className, }) { const formatPrice = (sats) => { if (sats >= 100000) { return `${(sats / 100000).toFixed(3)} BTC`; } return `${sats.toLocaleString()} sats`; }; const getStatusBadge = () => { switch (status) { case 'completed': return (0, jsx_runtime_1.jsx)(badge_1.Badge, { variant: "secondary", className: "bg-green-100 text-green-800", children: "Completed" }); case 'failed': return (0, jsx_runtime_1.jsx)(badge_1.Badge, { variant: "secondary", className: "bg-red-100 text-red-800", children: "Failed" }); case 'expired': return (0, jsx_runtime_1.jsx)(badge_1.Badge, { variant: "secondary", className: "bg-yellow-100 text-yellow-800", children: "Expired" }); default: return (0, jsx_runtime_1.jsx)(badge_1.Badge, { variant: "secondary", className: "bg-orange-100 text-orange-800", children: "Pending" }); } }; return ((0, jsx_runtime_1.jsx)(LightningCard, { variant: "payment", title: "Lightning Payment", description: description, status: status === 'completed' ? 'success' : status === 'failed' ? 'error' : 'pending', className: className, children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-green-600", children: formatPrice(amount) }), getStatusBadge()] }), paymentId && ((0, jsx_runtime_1.jsx)("div", { className: "bg-slate-50 dark:bg-slate-800 p-3 rounded-lg", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Payment ID:" }), (0, jsx_runtime_1.jsx)("code", { className: "text-xs text-slate-800 dark:text-slate-200 bg-slate-100 dark:bg-slate-700 px-2 py-1 rounded", children: paymentId })] }) })), timestamp && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-2 text-sm text-slate-600 dark:text-slate-400", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Clock, { className: "w-4 h-4" }), (0, jsx_runtime_1.jsx)("span", { children: timestamp.toLocaleString() })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex space-x-2", children: [onCopy && ((0, jsx_runtime_1.jsxs)(button_1.Button, { variant: "outline", size: "sm", onClick: onCopy, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { className: "w-4 h-4 mr-2" }), "Copy"] })), onDownload && ((0, jsx_runtime_1.jsxs)(button_1.Button, { variant: "outline", size: "sm", onClick: onDownload, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Download, { className: "w-4 h-4 mr-2" }), "Download"] }))] })] }) })); } function LightningUserCard({ pubkey, alias, connected, lastSeen, onCopy, className, }) { const formatPubkey = (key) => { return `${key.slice(0, 8)}...${key.slice(-8)}`; }; return ((0, jsx_runtime_1.jsx)(LightningCard, { variant: "user", title: alias || 'Lightning User', description: connected ? 'Connected' : 'Disconnected', status: connected ? 'success' : 'error', className: className, children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-slate-50 dark:bg-slate-800 p-3 rounded-lg", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Public Key:" }), (0, jsx_runtime_1.jsx)("code", { className: "text-xs text-slate-800 dark:text-slate-200 bg-slate-100 dark:bg-slate-700 px-2 py-1 rounded", children: formatPubkey(pubkey) })] }) }), lastSeen && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-2 text-sm text-slate-600 dark:text-slate-400", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Clock, { className: "w-4 h-4" }), (0, jsx_runtime_1.jsxs)("span", { children: ["Last seen: ", lastSeen.toLocaleString()] })] })), onCopy && ((0, jsx_runtime_1.jsxs)(button_1.Button, { variant: "outline", size: "sm", onClick: onCopy, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { className: "w-4 h-4 mr-2" }), "Copy Pubkey"] }))] }) })); } function LightningWalletCard({ name, balance, status, url, onConnect, className, }) { const formatBalance = (sats) => { if (sats >= 100000) { return `${(sats / 100000).toFixed(3)} BTC`; } return `${sats.toLocaleString()} sats`; }; return ((0, jsx_runtime_1.jsx)(LightningCard, { variant: "wallet", title: name, description: status === 'connected' ? 'Connected' : 'Disconnected', status: status === 'connected' ? 'success' : status === 'error' ? 'error' : 'warning', className: className, children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [balance !== undefined && ((0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-purple-600", children: formatBalance(balance) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex space-x-2", children: [onConnect && status !== 'connected' && ((0, jsx_runtime_1.jsxs)(button_1.Button, { variant: "outline", size: "sm", onClick: onConnect, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Wallet, { className: "w-4 h-4 mr-2" }), "Connect"] })), url && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "outline", size: "sm", asChild: true, children: (0, jsx_runtime_1.jsxs)("a", { href: url, target: "_blank", rel: "noopener noreferrer", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { className: "w-4 h-4 mr-2" }), "Open"] }) }))] })] }) })); } //# sourceMappingURL=LightningCard.js.map