@@ -9,6 +9,9 @@ import useAppWallet from "@/hooks/useAppWallet";
99import { deserializeAddress } from "@meshsdk/core" ;
1010import { getBalanceFromUtxos } from "@/utils/getBalance" ;
1111import { useWalletsStore } from "@/lib/zustand/wallets" ;
12+ import ImgDragAndDrop from "@/components/common/ImgDragAndDrop" ;
13+ import IPFSImage from "@/components/common/ipfs-image" ;
14+ import Image from "next/image" ;
1215
1316import {
1417 DropdownMenu ,
@@ -52,6 +55,18 @@ export default function CardInfo({ appWallet }: { appWallet: Wallet }) {
5255 < CardUI
5356 title = { appWallet . name }
5457 description = { appWallet . description }
58+ profileImage = {
59+ appWallet . profileImageIpfsUrl ? (
60+ < div className = "relative aspect-square w-12 sm:w-14 rounded-lg overflow-hidden border border-border/50 shadow-sm" >
61+ < IPFSImage
62+ src = { appWallet . profileImageIpfsUrl }
63+ alt = "Wallet Profile"
64+ fill
65+ className = "object-cover object-center"
66+ />
67+ </ div >
68+ ) : undefined
69+ }
5570 headerDom = {
5671 < div className = "flex items-center gap-2" >
5772 { isLegacyWallet && (
@@ -101,6 +116,9 @@ function EditInfo({
101116 appWallet . description ?? "" ,
102117 ) ;
103118 const [ isArchived , setIsArchived ] = useState < boolean > ( appWallet . isArchived ) ;
119+ const [ profileImageIpfsUrl , setProfileImageIpfsUrl ] = useState < string | null > (
120+ appWallet . profileImageIpfsUrl ?? null ,
121+ ) ;
104122 const [ loading , setLoading ] = useState < boolean > ( false ) ;
105123 const ctx = api . useUtils ( ) ;
106124 const { toast } = useToast ( ) ;
@@ -133,6 +151,7 @@ function EditInfo({
133151 name,
134152 description,
135153 isArchived,
154+ profileImageIpfsUrl : profileImageIpfsUrl || null ,
136155 } ) ;
137156 }
138157 return (
@@ -158,6 +177,17 @@ function EditInfo({
158177 onChange = { ( e ) => setDescription ( e . target . value ) }
159178 />
160179 </ div >
180+ < div className = "grid gap-2 sm:gap-3" >
181+ < Label htmlFor = "profileImage" > Profile Image</ Label >
182+ < ImgDragAndDrop
183+ onImageUpload = { ( url ) => setProfileImageIpfsUrl ( url ) }
184+ initialUrl = { profileImageIpfsUrl }
185+ />
186+ < p className = "text-xs text-muted-foreground" >
187+ < strong > Note:</ strong > Images will be stored on public IPFS (InterPlanetary File System).
188+ Once uploaded, the image will be publicly accessible and cannot be removed from IPFS.
189+ </ p >
190+ </ div >
161191 < div className = "grid gap-2 sm:gap-3" >
162192 < Label htmlFor = "type" className = "text-sm" >
163193 Archive Status
@@ -190,7 +220,10 @@ function EditInfo({
190220 onClick = { ( ) => editWallet ( ) }
191221 disabled = {
192222 loading ||
193- ( appWallet . name === name && appWallet . description === description && appWallet . isArchived === isArchived )
223+ ( appWallet . name === name &&
224+ appWallet . description === description &&
225+ appWallet . isArchived === isArchived &&
226+ appWallet . profileImageIpfsUrl === profileImageIpfsUrl )
194227 }
195228 className = "flex-1 sm:flex-initial"
196229 >
@@ -396,31 +429,40 @@ function ShowInfo({ appWallet }: { appWallet: Wallet }) {
396429 const requiredCount = getRequiredCount ( ) ;
397430
398431 return (
399- < div className = "space-y-4" >
400- { /* Desktop: Grid layout for addresses and balance */ }
401- < div className = "grid grid-cols-1 md:grid-cols-2 gap-4" >
402- { /* Left Column */ }
403- < div className = "space-y-4" >
404- { /* Signing Threshold - Above Address */ }
405- < div className = "flex items-center gap-3 p-3 bg-muted/30 rounded-lg border border-border/30" >
406- < div className = "flex-1 min-w-0" >
407- < div className = "text-xs font-medium text-muted-foreground mb-0.5" > Signing Threshold</ div >
408- < div className = "text-sm font-medium" > { getSignersText ( ) } </ div >
409- </ div >
432+ < div className = "space-y-6" >
433+ { /* Top Section: Key Info */ }
434+ < div className = "grid grid-cols-1 sm:grid-cols-2 gap-4 w-full" >
435+ { /* Signing Threshold */ }
436+ < div className = "flex items-center gap-3 p-4 bg-muted/40 rounded-lg border border-border/40" >
410437 < div className = "flex items-center gap-1.5 flex-shrink-0" >
411438 { Array . from ( { length : signersCount } ) . map ( ( _ , index ) => (
412439 < User
413440 key = { index }
414- className = { `h-5 w-5 sm:h-6 sm:w-6 ${
441+ className = { `h-4 w-4 sm:h-5 sm:w-5 ${
415442 index < requiredCount
416443 ? "text-foreground opacity-100"
417444 : "text-muted-foreground opacity-30"
418445 } `}
419446 />
420447 ) ) }
421448 </ div >
449+ < div className = "flex-1 min-w-0" >
450+ < div className = "text-xs font-medium text-muted-foreground mb-0.5" > Signing Threshold</ div >
451+ < div className = "text-sm font-semibold" > { getSignersText ( ) } </ div >
452+ </ div >
422453 </ div >
423454
455+ { /* Balance */ }
456+ < div className = "flex flex-col justify-center p-4 bg-muted/40 rounded-lg border border-border/40" >
457+ < div className = "text-xs font-medium text-muted-foreground mb-1" > Balance</ div >
458+ < div className = "text-2xl sm:text-3xl font-bold" > { balance } ₳</ div >
459+ </ div >
460+ </ div >
461+
462+ { /* Addresses Section */ }
463+ < div className = "space-y-3 pt-2 border-t border-border/30" >
464+ < div className = "text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-2" > Wallet Details</ div >
465+ < div className = "grid grid-cols-1 sm:grid-cols-2 gap-3" >
424466 { /* Address */ }
425467 < RowLabelInfo
426468 label = "Address"
@@ -468,15 +510,6 @@ function ShowInfo({ appWallet }: { appWallet: Wallet }) {
468510 />
469511 ) : null }
470512 </ div >
471-
472- { /* Right Column */ }
473- < div className = "space-y-4" >
474- { /* Balance - Larger Display */ }
475- < div className = "flex flex-col gap-2" >
476- < div className = "text-sm font-medium text-muted-foreground" > Balance</ div >
477- < div className = "text-2xl sm:text-3xl font-semibold" > { balance } ₳</ div >
478- </ div >
479- </ div >
480513 </ div >
481514
482515 { /* Native Script - Collapsible Pro Feature */ }
0 commit comments