@@ -61,6 +61,34 @@ function resolvePrReviewConfigPath(projectCwd: string, configPath: string): stri
6161 return joinPath ( projectCwd , configPath ) ;
6262}
6363
64+ function formatReviewDecision ( decision : string | null | undefined ) : string {
65+ if ( ! decision ) return "No decision" ;
66+ return decision . toLowerCase ( ) . replaceAll ( "_" , " " ) ;
67+ }
68+
69+ function reviewDecisionTone ( decision : string | null | undefined ) : string {
70+ switch ( decision ) {
71+ case "APPROVED" :
72+ return "text-emerald-600 dark:text-emerald-400" ;
73+ case "CHANGES_REQUESTED" :
74+ case "REVIEW_REQUIRED" :
75+ return "text-amber-600 dark:text-amber-400" ;
76+ default :
77+ return "text-muted-foreground" ;
78+ }
79+ }
80+
81+ function formatReviewTimestamp ( value : string ) : string {
82+ const date = new Date ( value ) ;
83+ if ( Number . isNaN ( date . getTime ( ) ) ) return value ;
84+ return new Intl . DateTimeFormat ( undefined , {
85+ month : "short" ,
86+ day : "numeric" ,
87+ hour : "numeric" ,
88+ minute : "2-digit" ,
89+ } ) . format ( date ) ;
90+ }
91+
6492export function PrReviewShell ( {
6593 project,
6694 projects,
@@ -360,6 +388,8 @@ export function PrReviewShell({
360388 const blockingWorkflowStepsComputed = ( dashboardQuery . data ?. workflowSteps ?? [ ] ) . filter (
361389 ( step ) => step . status === "blocked" || step . status === "failed" ,
362390 ) ;
391+ const recentReviews = dashboardQuery . data ?. pullRequest . recentReviews ?? [ ] ;
392+ const displayedRecentReviews = recentReviews . slice ( 0 , 3 ) ;
363393
364394 // Inspector props helper
365395 const inspectorProps = {
@@ -531,7 +561,58 @@ export function PrReviewShell({
531561 ) }
532562 >
533563 < div className = "overflow-hidden" >
534- < div className = "px-4 py-3 space-y-3" >
564+ < div className = "space-y-3 px-4 py-3" >
565+ < div className = "flex flex-wrap items-start gap-x-4 gap-y-2 rounded-xl border border-border/60 bg-muted/30 px-3 py-2.5 text-xs" >
566+ < div className = "space-y-0.5" >
567+ < div className = "text-[11px] uppercase tracking-wide text-muted-foreground" >
568+ Review decision
569+ </ div >
570+ < div
571+ className = { cn (
572+ "font-medium capitalize" ,
573+ reviewDecisionTone ( dashboardQuery . data ?. pullRequest . reviewDecision ) ,
574+ ) }
575+ >
576+ { formatReviewDecision ( dashboardQuery . data ?. pullRequest . reviewDecision ) }
577+ </ div >
578+ </ div >
579+ </ div >
580+ < div className = "space-y-1.5" >
581+ < div className = "text-[11px] uppercase tracking-wide text-muted-foreground" >
582+ Recent maintainer reviews
583+ </ div >
584+ { displayedRecentReviews . length > 0 ? (
585+ < div className = "space-y-1.5" >
586+ { displayedRecentReviews . map ( ( review ) => (
587+ < div
588+ className = "rounded-md border border-border/60 bg-muted/30 px-2.5 py-2 text-xs"
589+ key = { `${ review . authorLogin } :${ review . submittedAt } ` }
590+ >
591+ < div className = "flex items-center justify-between gap-2" >
592+ < div className = "min-w-0" >
593+ < span className = "font-medium text-foreground" >
594+ { review . authorLogin }
595+ </ span >
596+ < span className = "ml-2 capitalize text-muted-foreground" >
597+ { review . state . toLowerCase ( ) . replaceAll ( "_" , " " ) }
598+ </ span >
599+ </ div >
600+ < span className = "shrink-0 text-muted-foreground" >
601+ { formatReviewTimestamp ( review . submittedAt ) }
602+ </ span >
603+ </ div >
604+ { review . body . trim ( ) . length > 0 ? (
605+ < p className = "mt-1 line-clamp-2 whitespace-pre-wrap text-muted-foreground" >
606+ { review . body }
607+ </ p >
608+ ) : null }
609+ </ div >
610+ ) ) }
611+ </ div >
612+ ) : (
613+ < div className = "text-xs text-muted-foreground" > No maintainer reviews yet.</ div >
614+ ) }
615+ </ div >
535616 < PrMentionComposer
536617 cwd = { project . cwd }
537618 participants = { dashboardQuery . data ?. pullRequest . participants ?? [ ] }
@@ -540,7 +621,6 @@ export function PrReviewShell({
540621 value = { reviewBody }
541622 onChange = { ( value ) => {
542623 setReviewBody ( value ) ;
543- // Auto-expand when user starts typing
544624 if ( value . trim ( ) . length > 0 && ! actionRailExpanded ) {
545625 setActionRailExpanded ( true ) ;
546626 }
0 commit comments