@@ -10,45 +10,40 @@ import {
1010} from "@/components/ui/table" ;
1111import { Badge } from "@/components/ui/badge" ;
1212import { Button } from "@/components/ui/button" ;
13- import { Lightbulb } from "lucide-react" ;
13+ import { Lightbulb , ExternalLink } from "lucide-react" ;
1414import { approveIdea , rejectIdea } from "./actions" ;
1515
1616interface ContentIdea {
1717 _id : string ;
1818 _createdAt : string ;
1919 title : string ;
20- status : "new" | "approved" | "rejected" | "published" ;
21- source ?: string ;
22- category ?: string ;
20+ status : "new" | "approved" | "rejected" ;
21+ sourceUrl ?: string ;
22+ summary ?: string ;
23+ topics ?: string [ ] ;
24+ collectedAt ?: string ;
2325}
2426
25- const statusConfig : Record <
26- string ,
27- { label : string ; className : string }
28- > = {
27+ const statusConfig : Record < string , { label : string ; className : string } > = {
2928 new : {
3029 label : "New" ,
31- className : "bg-blue-100 text-blue-800 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-300" ,
30+ className :
31+ "bg-blue-100 text-blue-800 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-300" ,
3232 } ,
3333 approved : {
3434 label : "Approved" ,
35- className : "bg-green-100 text-green-800 hover:bg-green-100 dark:bg-green-900 dark:text-green-300" ,
35+ className :
36+ "bg-green-100 text-green-800 hover:bg-green-100 dark:bg-green-900 dark:text-green-300" ,
3637 } ,
3738 rejected : {
3839 label : "Rejected" ,
39- className : "bg-red-100 text-red-800 hover:bg-red-100 dark:bg-red-900 dark:text-red-300" ,
40- } ,
41- published : {
42- label : "Published" ,
43- className : "bg-purple-100 text-purple-800 hover:bg-purple-100 dark:bg-purple-900 dark:text-purple-300" ,
40+ className :
41+ "bg-red-100 text-red-800 hover:bg-red-100 dark:bg-red-900 dark:text-red-300" ,
4442 } ,
4543} ;
4644
4745function StatusBadge ( { status } : { status : string } ) {
48- const config = statusConfig [ status ] ?? {
49- label : status ,
50- className : "" ,
51- } ;
46+ const config = statusConfig [ status ] ?? { label : status , className : "" } ;
5247 return (
5348 < Badge variant = "outline" className = { config . className } >
5449 { config . label }
@@ -64,15 +59,27 @@ function formatDate(dateString: string) {
6459 } ) ;
6560}
6661
62+ function truncateUrl ( url : string , maxLength = 30 ) {
63+ try {
64+ const parsed = new URL ( url ) ;
65+ const display = parsed . hostname + parsed . pathname ;
66+ return display . length > maxLength
67+ ? display . slice ( 0 , maxLength ) + "\u2026"
68+ : display ;
69+ } catch {
70+ return url . length > maxLength ? url . slice ( 0 , maxLength ) + "\u2026" : url ;
71+ }
72+ }
73+
6774export function ContentIdeasTable ( { ideas } : { ideas : ContentIdea [ ] } ) {
6875 if ( ideas . length === 0 ) {
6976 return (
7077 < div className = "flex flex-col items-center justify-center rounded-lg border border-dashed p-12 text-center" >
7178 < Lightbulb className = "h-12 w-12 text-muted-foreground/50" />
7279 < h3 className = "mt-4 text-lg font-semibold" > No content ideas yet</ h3 >
7380 < p className = "mt-2 text-sm text-muted-foreground" >
74- Content ideas will appear here once they're created in Sanity
75- or generated by the automation pipeline .
81+ Content ideas will appear here once the ideation cron starts
82+ running .
7683 </ p >
7784 </ div >
7885 ) ;
@@ -86,8 +93,8 @@ export function ContentIdeasTable({ ideas }: { ideas: ContentIdea[] }) {
8693 < TableHead > Title</ TableHead >
8794 < TableHead > Status</ TableHead >
8895 < TableHead > Source</ TableHead >
89- < TableHead > Category </ TableHead >
90- < TableHead > Created </ TableHead >
96+ < TableHead > Topics </ TableHead >
97+ < TableHead > Collected </ TableHead >
9198 < TableHead className = "text-right" > Actions</ TableHead >
9299 </ TableRow >
93100 </ TableHeader >
@@ -100,25 +107,60 @@ export function ContentIdeasTable({ ideas }: { ideas: ContentIdea[] }) {
100107 < TableCell >
101108 < StatusBadge status = { idea . status } />
102109 </ TableCell >
103- < TableCell className = "text-muted-foreground" >
104- { idea . source || "\u2014" }
110+ < TableCell >
111+ { idea . sourceUrl ? (
112+ < a
113+ href = { idea . sourceUrl }
114+ target = "_blank"
115+ rel = "noopener noreferrer"
116+ className = "inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
117+ >
118+ { truncateUrl ( idea . sourceUrl ) }
119+ < ExternalLink className = "h-3 w-3" />
120+ </ a >
121+ ) : (
122+ < span className = "text-muted-foreground" > \u2014</ span >
123+ ) }
105124 </ TableCell >
106- < TableCell className = "text-muted-foreground" >
107- { idea . category || "\u2014" }
125+ < TableCell >
126+ { idea . topics && idea . topics . length > 0 ? (
127+ < div className = "flex flex-wrap gap-1" >
128+ { idea . topics . slice ( 0 , 3 ) . map ( ( topic ) => (
129+ < Badge key = { topic } variant = "secondary" className = "text-xs" >
130+ { topic }
131+ </ Badge >
132+ ) ) }
133+ { idea . topics . length > 3 && (
134+ < Badge variant = "secondary" className = "text-xs" >
135+ +{ idea . topics . length - 3 }
136+ </ Badge >
137+ ) }
138+ </ div >
139+ ) : (
140+ < span className = "text-muted-foreground" > \u2014</ span >
141+ ) }
108142 </ TableCell >
109143 < TableCell className = "text-muted-foreground" >
110- { formatDate ( idea . _createdAt ) }
144+ { formatDate ( idea . collectedAt || idea . _createdAt ) }
111145 </ TableCell >
112146 < TableCell className = "text-right" >
113147 { idea . status === "new" && (
114148 < div className = "flex justify-end gap-2" >
115149 < form action = { approveIdea . bind ( null , idea . _id ) } >
116- < Button size = "sm" variant = "outline" className = "text-green-600 hover:text-green-700" >
150+ < Button
151+ size = "sm"
152+ variant = "outline"
153+ className = "text-green-600 hover:text-green-700"
154+ >
117155 Approve
118156 </ Button >
119157 </ form >
120158 < form action = { rejectIdea . bind ( null , idea . _id ) } >
121- < Button size = "sm" variant = "outline" className = "text-red-600 hover:text-red-700" >
159+ < Button
160+ size = "sm"
161+ variant = "outline"
162+ className = "text-red-600 hover:text-red-700"
163+ >
122164 Reject
123165 </ Button >
124166 </ form >
0 commit comments