@@ -66,14 +66,22 @@ const DEMO_WORKERS = [
6666 } ,
6767] ;
6868
69- const JOBS = [
70- { id : 1 , title : "Bridal Lehenga Embroidery" , budget : "Rs. 2000-4000" , skill : "Embroidery" , postedAgo : "2h" , urgent : true } ,
71- { id : 2 , title : "10 Suit Alterations (Corporate)" , budget : "Rs. 1500" , skill : "Alterations" , postedAgo : "5h" , urgent : false } ,
72- { id : 3 , title : "Pattern Making - SS25 Collection" , budget : "Rs. 5000-8000" , skill : "Pattern Making" , postedAgo : "1d" , urgent : false } ,
73- { id : 4 , title : "Leather Jacket Repair and Restoration" , budget : "Rs. 800-1200" , skill : "Leather Work" , postedAgo : "3h" , urgent : true } ,
74- { id : 5 , title : "Children's School Uniform x 30 pcs" , budget : "Rs. 600-800" , skill : "Children's Wear" , postedAgo : "2d" , urgent : false } ,
69+ const FALLBACK_JOBS = [
70+ { id : "f1" , title : "Bridal Lehenga Embroidery" , budget : "Rs. 2000-4000" , skill : "Embroidery" , posted_at : new Date ( Date . now ( ) - 2 * 3600000 ) . toISOString ( ) , urgent : true } ,
71+ { id : "f2" , title : "10 Suit Alterations (Corporate)" , budget : "Rs. 1500" , skill : "Alterations" , posted_at : new Date ( Date . now ( ) - 5 * 3600000 ) . toISOString ( ) , urgent : false } ,
72+ { id : "f3" , title : "Leather Jacket Repair and Restoration" , budget : "Rs. 800-1200" , skill : "Leather Work" , posted_at : new Date ( Date . now ( ) - 3 * 3600000 ) . toISOString ( ) , urgent : true } ,
7573] ;
7674
75+ function postedAgo ( isoString ) {
76+ const diff = Date . now ( ) - new Date ( isoString ) . getTime ( ) ;
77+ const mins = Math . floor ( diff / 60000 ) ;
78+ if ( mins < 2 ) return "just now" ;
79+ if ( mins < 60 ) return `${ mins } m` ;
80+ const hrs = Math . floor ( mins / 60 ) ;
81+ if ( hrs < 24 ) return `${ hrs } h` ;
82+ return `${ Math . floor ( hrs / 24 ) } d` ;
83+ }
84+
7785const inputStyle = {
7886 width : "100%" ,
7987 padding : "10px 12px" ,
@@ -402,7 +410,7 @@ function JobCard({ job, copy, skillLabel }) {
402410 < div style = { { display : "flex" , alignItems : "center" , gap : 10 , flexWrap : "wrap" } } >
403411 < span style = { { fontSize : 11 , padding : "5px 10px" , borderRadius : 999 , background : palette . soft , color : palette . primary , fontWeight : 700 } } > { skillLabel ( job . skill ) } </ span >
404412 < span style = { { fontSize : 13 , color : palette . text , fontWeight : 700 , marginLeft : "auto" } } > { job . budget } </ span >
405- < span style = { { fontSize : 12 , color : palette . muted } } > { job . postedAgo } </ span >
413+ < span style = { { fontSize : 12 , color : palette . muted } } > { job . posted_at ? postedAgo ( job . posted_at ) : ( job . postedAgo || "" ) } </ span >
406414 </ div >
407415 </ article >
408416 ) ;
@@ -479,11 +487,18 @@ export default function WorkersBoardPage() {
479487 const [ selectedWorker , setSelectedWorker ] = useState ( null ) ;
480488 const [ activeTab , setActiveTab ] = useState ( "tailors" ) ;
481489 const [ postForm , setPostForm ] = useState ( { title : "" , skill : "Alterations" , budget : "" , description : "" } ) ;
482- const [ postedJobs , setPostedJobs ] = useState ( JOBS ) ;
490+ const [ postedJobs , setPostedJobs ] = useState ( [ ] ) ;
483491 const [ jobPosted , setJobPosted ] = useState ( false ) ;
484492
485493 const skillLabel = ( skill ) => copy . skillLabels [ skill ] || skill ;
486494
495+ // Fetch jobs from API
496+ useEffect ( ( ) => {
497+ screeningApi . listJobs ( )
498+ . then ( ( jobs ) => setPostedJobs ( jobs && jobs . length > 0 ? jobs : FALLBACK_JOBS ) )
499+ . catch ( ( ) => setPostedJobs ( FALLBACK_JOBS ) ) ;
500+ } , [ ] ) ;
501+
487502 // Fetch real workers from API
488503 useEffect ( ( ) => {
489504 screeningApi . listWorkers ( )
@@ -526,10 +541,14 @@ export default function WorkersBoardPage() {
526541
527542 const handlePostJob = ( ) => {
528543 if ( ! postForm . title || ! postForm . description ) return ;
529- setPostedJobs ( ( prev ) => [ { id : Date . now ( ) , title : postForm . title , budget : postForm . budget || copy . openBudget , skill : postForm . skill , postedAgo : copy . justNow , urgent : false } , ...prev ] ) ;
544+ const optimistic = { id : `opt_${ Date . now ( ) } ` , title : postForm . title , budget : postForm . budget || copy . openBudget , skill : postForm . skill , posted_at : new Date ( ) . toISOString ( ) , urgent : false } ;
545+ setPostedJobs ( ( prev ) => [ optimistic , ...prev ] ) ;
530546 setJobPosted ( true ) ;
531547 setPostForm ( { title : "" , skill : "Alterations" , budget : "" , description : "" } ) ;
532548 setTimeout ( ( ) => setJobPosted ( false ) , 3000 ) ;
549+ screeningApi . createJob ( { title : optimistic . title , budget : optimistic . budget , skill : optimistic . skill , description : postForm . description } )
550+ . then ( ( created ) => setPostedJobs ( ( prev ) => prev . map ( ( j ) => j . id === optimistic . id ? created : j ) ) )
551+ . catch ( ( ) => { } ) ;
533552 } ;
534553
535554 const totalKarma = Object . values ( karmaMap ) ;
0 commit comments