bigblocks
Version:
Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React
15 lines • 15.7 kB
JSON
{
"name": "bap-identity-components-bapencryptionsuite",
"type": "registry:component",
"dependencies": [],
"devDependencies": [],
"registryDependencies": [],
"files": [
{
"path": "components/bap-identity/components/BapEncryptionSuite.tsx",
"type": "registry:component",
"content": "import {\n\tCopyIcon,\n\tFileIcon,\n\tIdCardIcon,\n\tLockClosedIcon,\n\tLockOpen1Icon,\n\tPersonIcon,\n} from \"@radix-ui/react-icons\";\nimport type React from \"react\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { cn } from \"../../../lib/utils.js\";\nimport { ErrorDisplay } from \"../../ui-components/ErrorDisplay.js\";\nimport { LoadingButton } from \"../../ui-components/LoadingButton.js\";\nimport { Badge } from \"../../ui/badge.js\";\nimport { Button } from \"../../ui/button.js\";\nimport { Card, CardContent } from \"../../ui/card.js\";\nimport { Input } from \"../../ui/input.js\";\nimport {\n\tSelect,\n\tSelectContent,\n\tSelectItem,\n\tSelectTrigger,\n\tSelectValue,\n} from \"../../ui/select.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../../ui/tabs.js\";\nimport { Textarea } from \"../../ui/textarea.js\";\nimport { useBapEncryption } from \"../hooks/useBapEncryption.js\";\nimport type {\n\tBapEncryptionSuiteProps,\n\tEncryptionContentType,\n\tEncryptionMode,\n} from \"../types/encryption.js\";\n\nexport function BapEncryptionSuite({\n\tbapInstance: _bapInstance,\n\trecipientBapId,\n\tonEncrypted,\n\tonDecrypted,\n\tonError: onErrorProp,\n\tinitialContent = \"\",\n\tinitialMode = \"encrypt\",\n\tuseType42 = false,\n\tvariant = \"surface\",\n\tsize = \"2\",\n\tclassName,\n}: BapEncryptionSuiteProps) {\n\t// State\n\tconst [currentTab, setCurrentTab] = useState<\"encrypt\" | \"decrypt\">(\n\t\tinitialMode === \"encrypt\" ? \"encrypt\" : \"decrypt\",\n\t);\n\tconst [contentType, setContentType] =\n\t\tuseState<EncryptionContentType>(\"message\");\n\tconst [textToEncrypt, setTextToEncrypt] = useState(initialContent);\n\tconst [textToDecrypt, setTextToDecrypt] = useState(\"\");\n\tconst [selectedFile, setSelectedFile] = useState<File | null>(null);\n\tconst [encryptedContent, setEncryptedContent] = useState<string | null>(null);\n\tconst [decryptedContent, setDecryptedContent] = useState<string | null>(null);\n\n\t// Refs\n\tconst fileInputRef = useRef<HTMLInputElement>(null);\n\n\t// Hooks\n\tconst {\n\t\tencrypt,\n\t\tdecrypt,\n\t\tisLoading,\n\t\terror,\n\t\tgetEncryptionKey,\n\t\treset: resetEncryption,\n\t\tencryptAsync,\n\t\tdecryptAsync,\n\t} = useBapEncryption({\n\t\tuseType42,\n\t});\n\n\t// Error handling\n\tconst handleError = useCallback(\n\t\t(error: Error) => {\n\t\t\tconsole.error(\"Encryption Suite Error:\", error);\n\t\t\tonErrorProp?.(error);\n\t\t},\n\t\t[onErrorProp],\n\t);\n\n\t// Handle encryption\n\tconst handleEncrypt = async () => {\n\t\tif (!textToEncrypt && !selectedFile) {\n\t\t\thandleError(new Error(\"Please provide content to encrypt\"));\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tlet result: Awaited<ReturnType<typeof encryptAsync>>;\n\n\t\t\tif (selectedFile) {\n\t\t\t\tconst fileContent = await selectedFile.text();\n\t\t\t\tresult = await encryptAsync({\n\t\t\t\t\tcontent: fileContent,\n\t\t\t\t\toptions: {\n\t\t\t\t\t\ttype: \"file\",\n\t\t\t\t\t\tmode: recipientBapId ? \"asymmetric\" : \"symmetric\",\n\t\t\t\t\t\trecipientPublicKey: recipientBapId?.getCurrentPublicKey(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tresult = await encryptAsync({\n\t\t\t\t\tcontent: textToEncrypt,\n\t\t\t\t\toptions: {\n\t\t\t\t\t\ttype: \"message\",\n\t\t\t\t\t\tmode: recipientBapId ? \"asymmetric\" : \"symmetric\",\n\t\t\t\t\t\trecipientPublicKey: recipientBapId?.getCurrentPublicKey(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (result.data) {\n\t\t\t\tsetEncryptedContent(result.data.encrypted);\n\t\t\t\tonEncrypted?.(result.data);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error as Error);\n\t\t}\n\t};\n\n\t// Handle decryption\n\tconst handleDecrypt = async () => {\n\t\tif (!textToDecrypt.trim()) {\n\t\t\thandleError(new Error(\"Please provide encrypted content\"));\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await decryptAsync({\n\t\t\t\tencryptedContent: textToDecrypt,\n\t\t\t\toptions: {\n\t\t\t\t\ttype: contentType,\n\t\t\t\t\tmode: \"asymmetric\",\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (result.data) {\n\t\t\t\tsetDecryptedContent(String(result.data.content));\n\t\t\t\tonDecrypted?.(result.data);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error as Error);\n\t\t}\n\t};\n\n\t// Handle file selection\n\tconst handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {\n\t\tconst file = e.target.files?.[0];\n\t\tif (file) {\n\t\t\tsetSelectedFile(file);\n\t\t\tsetContentType(\"file\");\n\t\t}\n\t};\n\n\t// Copy encrypted content\n\tconst copyEncryptedContent = async () => {\n\t\tif (encryptedContent) {\n\t\t\ttry {\n\t\t\t\tawait navigator.clipboard.writeText(encryptedContent);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to copy:\", error);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Copy decrypted content\n\tconst copyDecryptedContent = async () => {\n\t\tif (decryptedContent) {\n\t\t\ttry {\n\t\t\t\tawait navigator.clipboard.writeText(decryptedContent);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to copy:\", error);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Clear all content\n\tconst clearAll = () => {\n\t\tsetTextToEncrypt(\"\");\n\t\tsetTextToDecrypt(\"\");\n\t\tsetSelectedFile(null);\n\t\tsetEncryptedContent(null);\n\t\tsetDecryptedContent(null);\n\t\tresetEncryption();\n\t\tif (fileInputRef.current) {\n\t\t\tfileInputRef.current.value = \"\";\n\t\t}\n\t};\n\n\treturn (\n\t\t<Card\n\t\t\tclassName={cn(\n\t\t\t\tsize === \"1\" ? \"text-sm\" : size === \"3\" ? \"text-base\" : \"text-sm\",\n\t\t\t)}\n\t\t>\n\t\t\t<CardContent className=\"p-6\">\n\t\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t\t{/* Header */}\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<h2 className=\"text-xl font-bold\">\n\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t<LockClosedIcon width=\"20\" height=\"20\" />\n\t\t\t\t\t\t\t\tBAP Encryption Suite\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<p className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\tEncrypt and decrypt content using BAP identity keys\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{/* Current Key Info */}\n\t\t\t\t\t<div className=\"flex justify-between items-center p-3 bg-muted rounded-lg\">\n\t\t\t\t\t\t<span className=\"text-sm font-medium\">Encryption Key</span>\n\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t<Badge variant=\"default\" className=\"text-xs\">\n\t\t\t\t\t\t\t\t<IdCardIcon width=\"12\" height=\"12\" className=\"mr-1\" />\n\t\t\t\t\t\t\t\t{useType42 ? \"Type 42\" : \"Standard\"}\n\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t<span className=\"text-xs font-mono\">\n\t\t\t\t\t\t\t\t{getEncryptionKey()?.publicKey\n\t\t\t\t\t\t\t\t\t? `${getEncryptionKey()?.publicKey.substring(0, 16)}...`\n\t\t\t\t\t\t\t\t\t: \"Not available\"}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{/* Tab navigation */}\n\t\t\t\t\t<Tabs\n\t\t\t\t\t\tvalue={currentTab}\n\t\t\t\t\t\tonValueChange={(v) => setCurrentTab(v as \"encrypt\" | \"decrypt\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TabsList className=\"grid w-full grid-cols-2\">\n\t\t\t\t\t\t\t<TabsTrigger value=\"encrypt\">\n\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t<LockClosedIcon />\n\t\t\t\t\t\t\t\t\tEncrypt\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</TabsTrigger>\n\t\t\t\t\t\t\t<TabsTrigger value=\"decrypt\">\n\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t<LockOpen1Icon />\n\t\t\t\t\t\t\t\t\tDecrypt\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</TabsTrigger>\n\t\t\t\t\t\t</TabsList>\n\n\t\t\t\t\t\t{/* Encrypt Tab */}\n\t\t\t\t\t\t<TabsContent value=\"encrypt\">\n\t\t\t\t\t\t\t<div className=\"flex flex-col gap-3 mt-3\">\n\t\t\t\t\t\t\t\t{/* Content Type Selector */}\n\t\t\t\t\t\t\t\t<div className=\"flex gap-3 items-center\">\n\t\t\t\t\t\t\t\t\t<span className=\"text-sm font-medium\">Content Type:</span>\n\t\t\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\t\t\tvalue={contentType}\n\t\t\t\t\t\t\t\t\t\tonValueChange={(v) =>\n\t\t\t\t\t\t\t\t\t\t\tsetContentType(v as EncryptionContentType)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-32\">\n\t\t\t\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"text\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<PersonIcon width=\"16\" height=\"16\" />\n\t\t\t\t\t\t\t\t\t\t\t\t\tText\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"file\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FileIcon width=\"16\" height=\"16\" />\n\t\t\t\t\t\t\t\t\t\t\t\t\tFile\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t{/* Content Input Area */}\n\t\t\t\t\t\t\t\t{contentType === \"message\" && (\n\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t<PersonIcon />\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\tText Content\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"Enter text to encrypt...\"\n\t\t\t\t\t\t\t\t\t\t\tvalue={textToEncrypt}\n\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => setTextToEncrypt(e.target.value)}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"min-h-24\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{/* File Input */}\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<div className=\"flex flex-col gap-2\">\n\t\t\t\t\t\t\t\t\t\t<label\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-sm font-medium\"\n\t\t\t\t\t\t\t\t\t\t\thtmlFor=\"encrypt-file-input\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<FileIcon />\n\t\t\t\t\t\t\t\t\t\t\t\tFile to Encrypt{\" \"}\n\t\t\t\t\t\t\t\t\t\t\t\t{recipientBapId && \"(for specific recipient)\"}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\tid=\"encrypt-file-input\"\n\t\t\t\t\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\t\t\t\t\tref={fileInputRef}\n\t\t\t\t\t\t\t\t\t\t\tonChange={handleFileSelect}\n\t\t\t\t\t\t\t\t\t\t\taccept=\"*/*\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t{selectedFile && (\n\t\t\t\t\t\t\t\t\t\t<p className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\tSelected: {selectedFile.name} (\n\t\t\t\t\t\t\t\t\t\t\t{(selectedFile.size / 1024).toFixed(1)} KB)\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t{/* Encrypt Button */}\n\t\t\t\t\t\t\t\t<LoadingButton\n\t\t\t\t\t\t\t\t\tonClick={handleEncrypt}\n\t\t\t\t\t\t\t\t\tloading={isLoading}\n\t\t\t\t\t\t\t\t\tdisabled={!textToEncrypt && !selectedFile}\n\t\t\t\t\t\t\t\t\tclassName=\"w-full\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<LockClosedIcon className=\"mr-2\" />\n\t\t\t\t\t\t\t\t\t{isLoading ? \"Encrypting...\" : \"Encrypt Content\"}\n\t\t\t\t\t\t\t\t</LoadingButton>\n\n\t\t\t\t\t\t\t\t{/* Results */}\n\t\t\t\t\t\t\t\t{encryptedContent && (\n\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex justify-between items-center mb-1\">\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-sm font-medium text-green-700\">\n\t\t\t\t\t\t\t\t\t\t\t\tEncrypted Content:\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={copyEncryptedContent}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<CopyIcon className=\"mr-1\" />\n\t\t\t\t\t\t\t\t\t\t\t\tCopy\n\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<pre\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"bg-muted rounded border p-3 text-xs overflow-auto max-h-64\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"pre-wrap\",\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{encryptedContent}\n\t\t\t\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</TabsContent>\n\n\t\t\t\t\t\t{/* Decrypt Tab */}\n\t\t\t\t\t\t<TabsContent value=\"decrypt\">\n\t\t\t\t\t\t\t<div className=\"flex flex-col gap-3 mt-3\">\n\t\t\t\t\t\t\t\t{/* Decrypt Input */}\n\t\t\t\t\t\t\t\t<div className=\"flex gap-3 items-center\">\n\t\t\t\t\t\t\t\t\t<span className=\"text-sm font-medium\">\n\t\t\t\t\t\t\t\t\t\tPaste Encrypted Content:\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t{/* Encrypted Content Input */}\n\t\t\t\t\t\t\t\t{contentType === \"message\" && (\n\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t<LockClosedIcon />\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\tEncrypted Content\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"Paste encrypted content here...\"\n\t\t\t\t\t\t\t\t\t\t\tvalue={textToDecrypt}\n\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => setTextToDecrypt(e.target.value)}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"min-h-24 font-mono text-xs\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{/* Decrypt Button */}\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<LoadingButton\n\t\t\t\t\t\t\t\t\t\tonClick={handleDecrypt}\n\t\t\t\t\t\t\t\t\t\tloading={isLoading}\n\t\t\t\t\t\t\t\t\t\tdisabled={!textToDecrypt.trim()}\n\t\t\t\t\t\t\t\t\t\tclassName=\"w-full\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<LockOpen1Icon className=\"mr-2\" />\n\t\t\t\t\t\t\t\t\t\t{isLoading ? \"Decrypting...\" : \"Decrypt Content\"}\n\t\t\t\t\t\t\t\t\t</LoadingButton>\n\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t{/* Decrypted Results */}\n\t\t\t\t\t\t\t\t{decryptedContent && (\n\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex justify-between items-center mb-1\">\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-sm font-medium text-green-700\">\n\t\t\t\t\t\t\t\t\t\t\t\tDecrypted Content:\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={copyDecryptedContent}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<CopyIcon className=\"mr-1\" />\n\t\t\t\t\t\t\t\t\t\t\t\tCopy\n\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<pre\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"bg-muted rounded border p-3 text-xs overflow-auto max-h-64\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"pre-wrap\",\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{decryptedContent}\n\t\t\t\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</TabsContent>\n\t\t\t\t\t</Tabs>\n\n\t\t\t\t\t{/* Error Display */}\n\t\t\t\t\t{error && <ErrorDisplay error={error.message} />}\n\t\t\t\t</div>\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n",
"target": "<%- config.aliases.components %>/bapencryptionsuite.tsx"
}
]
}