@@ -512,6 +512,7 @@ export function PairingBanner() {
512512 const [ channels , setChannels ] = useState < PairingChannel [ ] > ( [ ] ) ;
513513 const [ copiedId , setCopiedId ] = useState < string | null > ( null ) ;
514514 const [ revokingId , setRevokingId ] = useState < string | null > ( null ) ;
515+ const [ showUnclaimed , setShowUnclaimed ] = useState ( false ) ;
515516 const toast = useToast ( ) ;
516517 const dialog = useDialog ( ) ;
517518
@@ -565,59 +566,71 @@ export function PairingBanner() {
565566 const claimedChannels = channels . filter ( ( ch ) => ch . claimed ) ;
566567
567568 return (
568- < div className = "mx-6 mt-4 space-y-2" >
569- { /* Unclaimed channels — prominent warning */ }
570- { unclaimedChannels . map ( ( ch ) => (
571- < div key = { ch . pluginId } className = "p-4 rounded-lg border border-warning/40 bg-warning/5" >
572- < div className = "flex items-start gap-3" >
573- < Key className = "w-5 h-5 text-warning mt-0.5 shrink-0" />
574- < div className = "flex-1 min-w-0" >
575- < p className = "text-sm font-semibold text-text-primary dark:text-dark-text-primary" >
576- Claim ownership — { ch . name }
577- </ p >
578- < p className = "text-xs text-text-secondary dark:text-dark-text-secondary mt-0.5" >
579- Send this command on < span className = "capitalize" > { ch . platform } </ span > to become the
580- owner of this channel.
581- </ p >
582- < div className = "mt-2 flex items-center gap-2" >
583- < div className = "flex-1 flex items-center gap-2 px-3 py-2 bg-bg-tertiary dark:bg-dark-bg-tertiary rounded-md border border-border dark:border-dark-border font-mono text-sm" >
584- < span className = "text-text-muted dark:text-dark-text-muted text-xs" >
585- /connect
586- </ span >
587- < span className = "font-bold text-text-primary dark:text-dark-text-primary tracking-widest" >
588- { ch . key }
589- </ span >
590- </ div >
591- < button
592- onClick = { ( ) => handleCopy ( ch . pluginId , `/connect ${ ch . key } ` ) }
593- className = "flex items-center gap-1.5 px-3 py-2 text-xs font-medium border border-border dark:border-dark-border rounded-md hover:bg-bg-tertiary dark:hover:bg-dark-bg-tertiary transition-colors text-text-primary dark:text-dark-text-primary"
569+ < div className = "mx-6 mt-4 space-y-3" >
570+ { /* Unclaimed channels — compact grid layout */ }
571+ { unclaimedChannels . length > 0 && (
572+ < div className = "p-3 rounded-lg border border-warning/30 bg-warning/5" >
573+ < button
574+ onClick = { ( ) => setShowUnclaimed ( ! showUnclaimed ) }
575+ className = "w-full flex items-center justify-between"
576+ >
577+ < div className = "flex items-center gap-2" >
578+ < Key className = "w-4 h-4 text-warning" />
579+ < span className = "text-sm font-medium text-text-primary dark:text-dark-text-primary" >
580+ { unclaimedChannels . length } channel{ unclaimedChannels . length !== 1 ? 's' : '' } need setup
581+ </ span >
582+ </ div >
583+ < span className = "text-xs text-text-muted dark:text-dark-text-muted" >
584+ { showUnclaimed ? 'Hide' : 'Show' } setup instructions
585+ </ span >
586+ </ button >
587+
588+ { showUnclaimed && (
589+ < div className = "mt-3 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2" >
590+ { unclaimedChannels . map ( ( ch ) => (
591+ < div
592+ key = { ch . pluginId }
593+ className = "p-2.5 rounded-md border border-warning/20 bg-bg-primary dark:bg-dark-bg-primary"
594594 >
595- { copiedId === ch . pluginId ? (
596- < >
597- < CheckCircle2 className = "w-3.5 h-3.5 text-success" />
598- Copied!
599- </ >
600- ) : (
601- < >
602- < Copy className = "w-3.5 h-3.5" />
603- Copy
604- </ >
605- ) }
606- </ button >
607- </ div >
608- < p className = "text-[11px] text-text-muted dark:text-dark-text-muted mt-1.5" >
609- Key rotates after each successful claim.
610- </ p >
595+ < div className = "flex items-center gap-2 mb-1.5" >
596+ < span className = "text-xs font-medium text-text-primary dark:text-dark-text-primary" >
597+ { ch . name }
598+ </ span >
599+ < span className = "text-[10px] text-text-muted dark:text-dark-text-muted capitalize" >
600+ { ch . platform }
601+ </ span >
602+ </ div >
603+ < div className = "flex items-center gap-1.5" >
604+ < div className = "flex-1 flex items-center gap-1.5 px-2 py-1 bg-bg-tertiary dark:bg-dark-bg-tertiary rounded font-mono text-xs" >
605+ < span className = "text-text-muted text-[10px]" > /connect</ span >
606+ < span className = "font-bold text-text-primary dark:text-dark-text-primary" >
607+ { ch . key }
608+ </ span >
609+ </ div >
610+ < button
611+ onClick = { ( ) => handleCopy ( ch . pluginId , `/connect ${ ch . key } ` ) }
612+ className = "p-1.5 text-xs border border-border dark:border-dark-border rounded hover:bg-bg-tertiary dark:hover:bg-dark-bg-tertiary transition-colors"
613+ title = "Copy command"
614+ >
615+ { copiedId === ch . pluginId ? (
616+ < CheckCircle2 className = "w-3.5 h-3.5 text-success" />
617+ ) : (
618+ < Copy className = "w-3.5 h-3.5 text-text-muted dark:text-dark-text-muted" />
619+ ) }
620+ </ button >
621+ </ div >
622+ </ div >
623+ ) ) }
611624 </ div >
612- </ div >
625+ ) }
613626 </ div >
614- ) ) }
627+ ) }
615628
616- { /* Claimed channels — compact row with revoke option */ }
629+ { /* Claimed channels — compact row */ }
617630 { claimedChannels . map ( ( ch ) => (
618631 < div
619632 key = { ch . pluginId }
620- className = "p-3 rounded-lg border border-success/30 bg-success/5 flex items-center gap-3"
633+ className = "p-2.5 rounded-lg border border-success/30 bg-success/5 flex items-center gap-3"
621634 >
622635 < ShieldCheck className = "w-4 h-4 text-success shrink-0" />
623636 < div className = "flex-1 min-w-0" >
0 commit comments