@@ -7,6 +7,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
77import { Button } from "@/components/ui/button" ;
88import { Badge } from "@/components/ui/badge" ;
99import { Tabs , TabsContent , TabsList , TabsTrigger } from "@/components/ui/tabs" ;
10+ import { Avatar , AvatarImage , AvatarFallback } from "@/components/ui/avatar" ;
1011import {
1112 Table ,
1213 TableBody ,
@@ -23,7 +24,6 @@ import {
2324 Zap ,
2425 ExternalLink ,
2526 RefreshCw ,
26- Star ,
2727 LucideIcon ,
2828} from "lucide-react" ;
2929import { useActionItemsStore } from "@/stores" ;
@@ -38,16 +38,34 @@ interface ActionItem {
3838 url ?: string ;
3939 repo : string ;
4040 type : string ;
41- author ?: string ;
41+ author : {
42+ login : string ;
43+ avatarUrl : string ;
44+ } ;
45+ labels : Array < { name : string ; color ?: string } > ;
4246 priority : "urgent" | "high" | "medium" | "low" ;
4347 daysOld ?: number ;
48+ updatedAt : string ;
4449 comments ?: number ;
4550 stars ?: number ;
4651}
4752
4853const VALID_TABS = [ "assigned" , "mentions" , "stale" ] as const ;
4954type ValidTab = ( typeof VALID_TABS ) [ number ] ;
5055
56+ function formatTimeAgo ( dateString : string ) : string {
57+ const now = new Date ( ) ;
58+ const past = new Date ( dateString ) ;
59+ const diffInSeconds = Math . floor ( ( now . getTime ( ) - past . getTime ( ) ) / 1000 ) ;
60+
61+ if ( diffInSeconds < 60 ) return "just now" ;
62+ if ( diffInSeconds < 3600 ) return `${ Math . floor ( diffInSeconds / 60 ) } m ago` ;
63+ if ( diffInSeconds < 86400 ) return `${ Math . floor ( diffInSeconds / 3600 ) } h ago` ;
64+ if ( diffInSeconds < 604800 ) return `${ Math . floor ( diffInSeconds / 86400 ) } d ago` ;
65+ if ( diffInSeconds < 2592000 ) return `${ Math . floor ( diffInSeconds / 604800 ) } w ago` ;
66+ return `${ Math . floor ( diffInSeconds / 2592000 ) } mo ago` ;
67+ }
68+
5169function ActionRequiredContent ( ) {
5270 const {
5371 assignedItems,
@@ -144,12 +162,13 @@ function ActionRequiredContent() {
144162 < Table >
145163 < TableHeader >
146164 < TableRow >
147- < TableHead className = "w-[35%]" > Title / Repository</ TableHead >
148- < TableHead className = "w-[12%]" > Priority</ TableHead >
149- < TableHead className = "w-[12%]" > Activity</ TableHead >
150- < TableHead className = "w-[13%]" > Repo Popularity</ TableHead >
151- < TableHead className = "w-[13%]" > Type</ TableHead >
152- < TableHead className = "w-[15%]" > Actions</ TableHead >
165+ < TableHead className = "w-[30%]" > Title / Repository</ TableHead >
166+ < TableHead className = "w-[10%]" > Author</ TableHead >
167+ < TableHead className = "w-[18%]" > Labels</ TableHead >
168+ < TableHead className = "w-[10%]" > Priority</ TableHead >
169+ < TableHead className = "w-[8%]" > Activity</ TableHead >
170+ < TableHead className = "w-[10%]" > Updated</ TableHead >
171+ < TableHead className = "w-[14%]" > Actions</ TableHead >
153172 </ TableRow >
154173 </ TableHeader >
155174 < TableBody >
@@ -162,16 +181,22 @@ function ActionRequiredContent() {
162181 </ div >
163182 </ TableCell >
164183 < TableCell >
165- < div className = "w-16 h-6 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
184+ < div className = "w-8 h-8 bg-gray-300 dark:bg-gray-600 rounded-full animate-pulse" />
166185 </ TableCell >
167186 < TableCell >
168- < div className = "w-12 h-4 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
187+ < div className = "flex gap-1" >
188+ < div className = "w-16 h-6 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
189+ < div className = "w-16 h-6 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
190+ </ div >
191+ </ TableCell >
192+ < TableCell >
193+ < div className = "w-16 h-6 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
169194 </ TableCell >
170195 < TableCell >
171196 < div className = "w-12 h-4 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
172197 </ TableCell >
173198 < TableCell >
174- < div className = "w-16 h-6 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
199+ < div className = "w-16 h-4 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
175200 </ TableCell >
176201 < TableCell >
177202 < div className = "w-8 h-8 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
@@ -221,12 +246,13 @@ function ActionRequiredContent() {
221246 < Table >
222247 < TableHeader >
223248 < TableRow >
224- < TableHead className = "w-[35%]" > Title / Repository</ TableHead >
225- < TableHead className = "w-[12%]" > Priority</ TableHead >
226- < TableHead className = "w-[12%]" > Activity</ TableHead >
227- < TableHead className = "w-[13%]" > Repo Popularity</ TableHead >
228- < TableHead className = "w-[13%]" > Type</ TableHead >
229- < TableHead className = "w-[15%]" > Actions</ TableHead >
249+ < TableHead className = "w-[30%]" > Title / Repository</ TableHead >
250+ < TableHead className = "w-[10%]" > Author</ TableHead >
251+ < TableHead className = "w-[18%]" > Labels</ TableHead >
252+ < TableHead className = "w-[10%]" > Priority</ TableHead >
253+ < TableHead className = "w-[8%]" > Activity</ TableHead >
254+ < TableHead className = "w-[10%]" > Updated</ TableHead >
255+ < TableHead className = "w-[14%]" > Actions</ TableHead >
230256 </ TableRow >
231257 </ TableHeader >
232258 < TableBody >
@@ -253,11 +279,47 @@ function ActionRequiredContent() {
253279 </ div >
254280 < p className = "text-sm text-gray-500 dark:text-gray-400 truncate" >
255281 { item . repo }
256- { item . author && ` • ${ item . author } ` }
257282 </ p >
258283 </ div >
259284 </ div >
260285 </ TableCell >
286+ < TableCell >
287+ < div className = "flex items-center gap-2" >
288+ < Avatar className = "w-8 h-8" >
289+ < AvatarImage src = { item . author . avatarUrl } alt = { item . author . login } />
290+ < AvatarFallback >
291+ { item . author . login . substring ( 0 , 2 ) . toUpperCase ( ) }
292+ </ AvatarFallback >
293+ </ Avatar >
294+ </ div >
295+ </ TableCell >
296+ < TableCell >
297+ < div className = "flex flex-wrap gap-1" >
298+ { item . labels . slice ( 0 , 3 ) . map ( ( label , idx ) => (
299+ < Badge
300+ key = { idx }
301+ variant = "outline"
302+ className = "text-xs"
303+ style = {
304+ label . color
305+ ? {
306+ borderColor : `#${ label . color } ` ,
307+ backgroundColor : `#${ label . color } 20` ,
308+ color : `#${ label . color } ` ,
309+ }
310+ : undefined
311+ }
312+ >
313+ { label . name }
314+ </ Badge >
315+ ) ) }
316+ { item . labels . length > 3 && (
317+ < Badge variant = "outline" className = "text-xs" >
318+ +{ item . labels . length - 3 }
319+ </ Badge >
320+ ) }
321+ </ div >
322+ </ TableCell >
261323 < TableCell >
262324 < Badge
263325 variant = {
@@ -281,16 +343,10 @@ function ActionRequiredContent() {
281343 </ div >
282344 </ TableCell >
283345 < TableCell >
284- < div className = "flex items-center gap-1 text-gray-600 dark:text-gray-300" >
285- < Star className = "w-4 h-4 text-yellow-500" />
286- < span > { item . stars || 0 } </ span >
346+ < div className = "text-sm text-gray-500 dark:text-gray-400" >
347+ { formatTimeAgo ( item . updatedAt ) }
287348 </ div >
288349 </ TableCell >
289- < TableCell >
290- < Badge variant = "outline" className = "capitalize" >
291- { item . type === "pullRequest" ? "PR" : "Issue" }
292- </ Badge >
293- </ TableCell >
294350 < TableCell >
295351 < AddToKanbanButton item = { item as StoreActionItem } />
296352 </ TableCell >
0 commit comments