UNPKG

bigblocks

Version:

Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React

53 lines (52 loc) 5.74 kB
"use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { CheckIcon, CopyIcon, DotsHorizontalIcon, ExternalLinkIcon, InfoCircledIcon, Pencil1Icon, RocketIcon, } from "@radix-ui/react-icons"; import React from "react"; import { BitcoinAvatar } from "../ui-components/BitcoinAvatar.js"; import { Badge } from "../ui/badge.js"; import { Button } from "../ui/button.js"; import { Card } from "../ui/card.js"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "../ui/dropdown-menu.js"; /** * ProfileViewer displays a complete view of a BAP profile * * Features: * - Profile avatar, name, and description * - Bitcoin address with copy functionality * - Published/unpublished status * - Edit and publish actions * - Responsive layout */ export function ProfileViewer({ profile, showAddress = true, showPublishStatus = true, showActions = true, onEdit, onPublish, className = "", variant = "surface", size = "3", }) { const [copied, setCopied] = React.useState(false); const handleCopyAddress = async () => { try { await navigator.clipboard.writeText(profile.address); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (error) { console.error("Failed to copy address:", error); } }; const getDisplayName = () => { // Priority order for name fields return (profile.name || profile.alternateName || profile.givenName || profile.familyName || profile.legalName || "Unnamed Profile"); }; const getInitials = (name) => { if (!name) return "?"; return name .split(" ") .map((word) => word[0]) .join("") .toUpperCase() .slice(0, 2); }; return (_jsx(Card, { className: `p-6 max-w-2xl ${className}`, children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex items-start gap-4", children: [_jsx(BitcoinAvatar, { size: "lg", src: profile.image, alt: getDisplayName(), fallback: getInitials(getDisplayName()) }), _jsxs("div", { className: "flex flex-col gap-1 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("h2", { className: "text-xl font-bold", children: getDisplayName() }), showPublishStatus && (_jsx(Badge, { variant: profile.isPublished ? "default" : "secondary", className: `text-xs ${profile.isPublished ? "text-green-700" : "text-orange-700"}`, children: profile.isPublished ? "Published" : "Unpublished" }))] }), profile.description && (_jsx("p", { className: "text-sm text-muted-foreground", children: profile.description }))] }), showActions && (onEdit || onPublish) && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "sm", className: "rounded-full", children: _jsx(DotsHorizontalIcon, { className: "h-4 w-4" }) }) }), _jsxs(DropdownMenuContent, { children: [onEdit && (_jsxs(DropdownMenuItem, { onClick: onEdit, children: [_jsx(Pencil1Icon, { className: "h-4 w-4 mr-2" }), "Edit Profile"] })), onPublish && !profile.isPublished && (_jsxs(DropdownMenuItem, { onClick: onPublish, children: [_jsx(RocketIcon, { className: "h-4 w-4 mr-2" }), "Publish to Blockchain"] }))] })] }))] }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "w-24 text-sm text-muted-foreground", children: "Profile ID" }), _jsx("div", { className: "flex-1", children: _jsx("p", { className: "text-sm text-muted-foreground", children: profile.id }) })] }), showAddress && (_jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "w-24 text-sm text-muted-foreground", children: "Address" }), _jsxs("div", { className: "flex-1 flex items-center gap-2", children: [_jsxs("p", { className: "text-sm font-mono", children: [profile.address.slice(0, 8), "...", profile.address.slice(-6)] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: handleCopyAddress, children: copied ? (_jsx(CheckIcon, { className: "h-3 w-3" })) : (_jsx(CopyIcon, { className: "h-3 w-3" })) }), _jsx(Button, { variant: "ghost", size: "sm", asChild: true, children: _jsx("a", { href: `https://whatsonchain.com/address/${profile.address}`, target: "_blank", rel: "noopener noreferrer", children: _jsx(ExternalLinkIcon, { className: "h-3 w-3" }) }) })] })] })), profile.isPublished && (_jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "w-24 text-sm text-muted-foreground", children: "Status" }), _jsxs("div", { className: "flex-1 flex items-center gap-2", children: [_jsx("div", { className: "w-2 h-2 rounded-full bg-green-500" }), _jsx("p", { className: "text-sm text-green-700", children: "Published to blockchain" })] })] }))] }), !profile.isPublished && (_jsx(Card, { className: "p-3 bg-orange-50 border border-orange-200", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(InfoCircledIcon, { className: "h-4 w-4 text-orange-600" }), _jsx("p", { className: "text-sm text-orange-700", children: "This profile is not yet published to the blockchain." })] }) })), showActions && (onEdit || (onPublish && !profile.isPublished)) && (_jsx("div", { className: "border-t pt-4 mt-2", children: _jsxs("div", { className: "flex gap-2 justify-end", children: [onEdit && (_jsx(Button, { variant: "outline", size: "sm", onClick: onEdit, children: "Edit" })), onPublish && !profile.isPublished && (_jsx(Button, { variant: "default", size: "sm", onClick: onPublish, children: "Publish" }))] }) }))] }) })); }