@@ -1302,6 +1302,128 @@ function PRListItem({ pr, onSelect }: PRListItemProps) {
13021302 }
13031303 } ;
13041304
1305+ // Review status indicator with reviewer details
1306+ const ReviewStatusBadge = ( ) => {
1307+ // Don't show review status for merged/closed PRs
1308+ if ( isMerged || isClosed ) return null ;
1309+
1310+ const reviews = pr . latestReviews || [ ] ;
1311+ const approvals = reviews . filter ( ( r ) => r . state === "APPROVED" ) ;
1312+ const changesRequested = reviews . filter (
1313+ ( r ) => r . state === "CHANGES_REQUESTED"
1314+ ) ;
1315+
1316+ // No reviews yet
1317+ if ( reviews . length === 0 && ! pr . reviewDecision ) return null ;
1318+
1319+ const TooltipReviews = ( ) => (
1320+ < div className = "min-w-[150px] max-w-[250px]" >
1321+ < div className = "font-medium text-xs mb-2 pb-1.5 border-b border-border flex items-center gap-2" >
1322+ { pr . reviewDecision === "APPROVED" && (
1323+ < >
1324+ < Check className = "w-3.5 h-3.5 text-green-500" />
1325+ < span > Approved</ span >
1326+ </ >
1327+ ) }
1328+ { pr . reviewDecision === "CHANGES_REQUESTED" && (
1329+ < >
1330+ < XCircle className = "w-3.5 h-3.5 text-red-500" />
1331+ < span > Changes requested</ span >
1332+ </ >
1333+ ) }
1334+ { pr . reviewDecision === "REVIEW_REQUIRED" && (
1335+ < >
1336+ < Clock className = "w-3.5 h-3.5 text-yellow-500" />
1337+ < span > Review required</ span >
1338+ </ >
1339+ ) }
1340+ { ! pr . reviewDecision && reviews . length > 0 && (
1341+ < >
1342+ < MessageSquare className = "w-3.5 h-3.5 text-muted-foreground" />
1343+ < span > Reviewed</ span >
1344+ </ >
1345+ ) }
1346+ </ div >
1347+ { reviews . length > 0 ? (
1348+ < div className = "space-y-1.5" >
1349+ { changesRequested . map ( ( r ) => (
1350+ < div
1351+ key = { r . login }
1352+ className = "flex items-center gap-2 text-[11px]"
1353+ >
1354+ < img
1355+ src = { r . avatarUrl }
1356+ alt = { r . login }
1357+ className = "w-4 h-4 rounded-full"
1358+ />
1359+ < span className = "truncate text-red-400" > { r . login } </ span >
1360+ < XCircle className = "w-3 h-3 text-red-500 shrink-0 ml-auto" />
1361+ </ div >
1362+ ) ) }
1363+ { approvals . map ( ( r ) => (
1364+ < div
1365+ key = { r . login }
1366+ className = "flex items-center gap-2 text-[11px]"
1367+ >
1368+ < img
1369+ src = { r . avatarUrl }
1370+ alt = { r . login }
1371+ className = "w-4 h-4 rounded-full"
1372+ />
1373+ < span className = "truncate text-green-400" > { r . login } </ span >
1374+ < Check className = "w-3 h-3 text-green-500 shrink-0 ml-auto" />
1375+ </ div >
1376+ ) ) }
1377+ </ div >
1378+ ) : (
1379+ < div className = "text-[11px] text-muted-foreground" >
1380+ Waiting for review
1381+ </ div >
1382+ ) }
1383+ </ div >
1384+ ) ;
1385+
1386+ // Display based on review state
1387+ if ( pr . reviewDecision === "APPROVED" || approvals . length > 0 ) {
1388+ return (
1389+ < Tooltip >
1390+ < TooltipTrigger asChild >
1391+ < span className = "shrink-0 inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded border cursor-default bg-green-500/15 text-green-500 border-green-500/30" >
1392+ < Check className = "w-3 h-3" />
1393+ < span className = "hidden sm:inline" >
1394+ { approvals . length > 0 ? `${ approvals . length } ` : "Approved" }
1395+ </ span >
1396+ </ span >
1397+ </ TooltipTrigger >
1398+ < TooltipContent side = "bottom" align = "start" >
1399+ < TooltipReviews />
1400+ </ TooltipContent >
1401+ </ Tooltip >
1402+ ) ;
1403+ }
1404+
1405+ if (
1406+ pr . reviewDecision === "CHANGES_REQUESTED" ||
1407+ changesRequested . length > 0
1408+ ) {
1409+ return (
1410+ < Tooltip >
1411+ < TooltipTrigger asChild >
1412+ < span className = "shrink-0 inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded border cursor-default bg-red-500/15 text-red-500 border-red-500/30" >
1413+ < XCircle className = "w-3 h-3" />
1414+ < span className = "hidden sm:inline" > Changes</ span >
1415+ </ span >
1416+ </ TooltipTrigger >
1417+ < TooltipContent side = "bottom" align = "start" >
1418+ < TooltipReviews />
1419+ </ TooltipContent >
1420+ </ Tooltip >
1421+ ) ;
1422+ }
1423+
1424+ return null ;
1425+ } ;
1426+
13051427 return (
13061428 < button
13071429 onClick = { handleClick }
@@ -1328,6 +1450,7 @@ function PRListItem({ pr, onSelect }: PRListItemProps) {
13281450 { pr . title }
13291451 </ span >
13301452 < CIStatusBadge />
1453+ < ReviewStatusBadge />
13311454 { pr . hasNewChanges && (
13321455 < span className = "px-1.5 py-0.5 text-[10px] font-semibold rounded bg-blue-500/20 text-blue-400 border border-blue-500/30 shrink-0" >
13331456 NEW
0 commit comments