lightning-auth-and-payment
Version:
Lightning Network authentication and payment processing library for modern web applications
355 lines • 22.3 kB
JavaScript
;
'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