@@ -348,168 +348,184 @@ export default function RoadmapPage({
348348 leaveTo = "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
349349 >
350350 < div className = "relative" >
351+ { /* Desktop Close Button */ }
351352 < button
352353 type = "button"
353- className = "absolute -top-4 -right-4 z-10 rounded-full bg-white dark:bg-gray-700 p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 shadow-lg border border-gray-200 dark:border-gray-600"
354+ className = "hidden sm:block absolute -top-4 -right-4 z-30 rounded-full bg-white dark:bg-gray-700 p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 shadow-lg border border-gray-200 dark:border-gray-600"
354355 onClick = { closeItemModal }
355356 >
356357 < XIcon className = "h-5 w-5" aria-hidden = "true" />
357358 </ button >
358- < Dialog . Panel className = "w-full max-w-5xl sm:min-w-[880px] transform overflow-hidden rounded-t-2xl sm:rounded-2xl bg-white dark:bg-gray-900 p-8 text-left align-middle shadow-xl transition-all min-h-[50vh] sm:min-h-0" >
359- < div className = "grid grid-cols-1 lg:grid-cols-3 gap-8 relative" >
360- { /* Column Divider */ }
361- < div className = "hidden lg:block absolute left-2/3 top-0 bottom-0 w-px bg-gray-200 dark:bg-gray-700 transform -translate-x-1/2 z-10" > </ div >
362-
363- { /* Left side - Content */ }
364- < div className = "lg:col-span-2 space-y-6" >
365- < h3 className = "text-xl font-semibold leading-6 text-gray-900 dark:text-white" >
366- { selectedItem ?. title }
367- </ h3 >
368- { selectedItem ?. description && (
369- < div >
370- < div className = "prose prose-sm dark:prose-invert max-w-none text-gray-600 dark:text-gray-300" >
371- < ReactMarkdown
372- rehypePlugins = { [
373- rehypeRaw ,
374- [
375- rehypeSanitize ,
376- {
377- ...defaultSchema ,
378- attributes : {
379- ...defaultSchema . attributes ,
380- a : [
381- ...( defaultSchema . attributes ?. a ||
382- [ ] ) ,
383- [ "target" ] ,
384- [ "rel" ] ,
385- ] ,
386- code : [
387- ...( defaultSchema . attributes ?. code ||
388- [ ] ) ,
389- [ "className" ] ,
390- ] ,
391- span : [
392- ...( defaultSchema . attributes ?. span ||
393- [ ] ) ,
394- [ "className" ] ,
395- ] ,
396- } ,
359+
360+ < Dialog . Panel className = "w-full h-full sm:h-auto sm:max-w-5xl sm:min-w-[880px] transform overflow-hidden rounded-none sm:rounded-2xl bg-white dark:bg-gray-900 text-left align-middle shadow-xl transition-all flex flex-col sm:block" >
361+
362+ { /* Mobile Header with Close Button */ }
363+ < div className = "flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 sm:hidden" >
364+ < h3 className = "text-lg font-semibold text-gray-900 dark:text-white truncate" >
365+ { selectedItem ?. title }
366+ </ h3 >
367+ < button
368+ type = "button"
369+ className = "rounded-full p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500"
370+ onClick = { closeItemModal }
371+ >
372+ < XIcon className = "h-6 w-6" aria-hidden = "true" />
373+ </ button >
374+ </ div >
375+
376+ < div className = "grid grid-cols-1 lg:grid-cols-3 gap-8 relative p-4 sm:p-8 overflow-y-auto flex-1 sm:h-auto" >
377+ { /* Column Divider */ }
378+ < div className = "hidden lg:block absolute left-2/3 top-0 bottom-0 w-px bg-gray-200 dark:bg-gray-800 transform -translate-x-1/2 z-10" > </ div >
379+
380+ { /* Left side - Content */ }
381+ < div className = "lg:col-span-2 space-y-6" >
382+ < h3 className = "hidden sm:block text-xl font-semibold leading-6 text-gray-900 dark:text-white" >
383+ { selectedItem ?. title }
384+ </ h3 >
385+ { selectedItem ?. description && (
386+ < div >
387+ < div className = "prose prose-sm dark:prose-invert max-w-none text-gray-600 dark:text-gray-300" >
388+ < ReactMarkdown
389+ rehypePlugins = { [
390+ rehypeRaw ,
391+ [
392+ rehypeSanitize ,
393+ {
394+ ...defaultSchema ,
395+ attributes : {
396+ ...defaultSchema . attributes ,
397+ a : [
398+ ...( defaultSchema . attributes ?. a || [ ] ) ,
399+ [ "target" ] ,
400+ [ "rel" ] ,
401+ ] ,
402+ code : [
403+ ...( defaultSchema . attributes ?. code ||
404+ [ ] ) ,
405+ [ "className" ] ,
406+ ] ,
407+ span : [
408+ ...( defaultSchema . attributes ?. span ||
409+ [ ] ) ,
410+ [ "className" ] ,
411+ ] ,
397412 } ,
398- ] ,
399- ] }
400- remarkPlugins = { [ remarkGfm ] }
401- >
402- { selectedItem . description }
403- </ ReactMarkdown >
404- </ div >
413+ } ,
414+ ] ,
415+ ] }
416+ remarkPlugins = { [ remarkGfm ] }
417+ >
418+ { selectedItem . description }
419+ </ ReactMarkdown >
405420 </ div >
406- ) }
421+ </ div >
422+ ) }
423+ </ div >
424+
425+ { /* Right side - Metadata */ }
426+ < div className = "lg:col-span-1 space-y-6" >
427+ { /* Votes */ }
428+ < div className = "flex items-center justify-between" >
429+ < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" >
430+ Votes
431+ </ span >
432+ < button
433+ onClick = { ( ) =>
434+ selectedItem && handleVote ( selectedItem . id )
435+ }
436+ disabled = {
437+ ! selectedItem || votingItems . has ( selectedItem . id )
438+ }
439+ className = { `flex items-center text-sm px-3 py-1.5 rounded-lg border transition-colors ${
440+ selectedItem && votes [ selectedItem . id ] ?. voted
441+ ? "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 border-blue-300 dark:border-blue-700"
442+ : "text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-600 border-gray-200 dark:border-gray-600 hover:border-gray-300 dark:hover:border-gray-500"
443+ } ${
444+ ! selectedItem || votingItems . has ( selectedItem . id )
445+ ? "opacity-50 cursor-not-allowed"
446+ : "cursor-pointer"
447+ } `}
448+ >
449+ < svg
450+ className = "mr-1 h-4 w-4"
451+ fill = "currentColor"
452+ viewBox = "0 0 20 20"
453+ >
454+ < path
455+ fillRule = "evenodd"
456+ d = "M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z"
457+ clipRule = "evenodd"
458+ />
459+ </ svg >
460+ < span >
461+ { selectedItem
462+ ? votes [ selectedItem . id ] ?. count ??
463+ ( selectedItem . vote_count || 0 )
464+ : 0 }
465+ </ span >
466+ </ button >
407467 </ div >
408468
409- { /* Right side - Metadata */ }
410- < div className = "lg:col-span-1 space-y-6" >
411- { /* Votes */ }
469+ { /* Status (Column) */ }
470+ { selectedItem ?. column_id && (
412471 < div className = "flex items-center justify-between" >
413472 < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" >
414- Votes
473+ Status
474+ </ span >
475+ < span className = "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200" >
476+ { columns . find (
477+ ( col ) => col . id === selectedItem . column_id
478+ ) ?. name || "Unknown" }
415479 </ span >
416- < button
417- onClick = { ( ) =>
418- selectedItem && handleVote ( selectedItem . id )
419- }
420- disabled = {
421- ! selectedItem || votingItems . has ( selectedItem . id )
422- }
423- className = { `flex items-center text-sm px-3 py-1.5 rounded-lg border transition-colors ${
424- selectedItem && votes [ selectedItem . id ] ?. voted
425- ? "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 border-blue-300 dark:border-blue-700"
426- : "text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-600 border-gray-200 dark:border-gray-600 hover:border-gray-300 dark:hover:border-gray-500"
427- } ${
428- ! selectedItem || votingItems . has ( selectedItem . id )
429- ? "opacity-50 cursor-not-allowed"
430- : "cursor-pointer"
431- } `}
432- >
433- < svg
434- className = "mr-1 h-4 w-4"
435- fill = "currentColor"
436- viewBox = "0 0 20 20"
437- >
438- < path
439- fillRule = "evenodd"
440- d = "M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z"
441- clipRule = "evenodd"
442- />
443- </ svg >
444- < span >
445- { selectedItem
446- ? votes [ selectedItem . id ] ?. count ??
447- ( selectedItem . vote_count || 0 )
448- : 0 }
449- </ span >
450- </ button >
451480 </ div >
481+ ) }
452482
453- { /* Status (Column) */ }
454- { selectedItem ?. column_id && (
455- < div className = "flex items-center justify-between" >
456- < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" >
457- Status
458- </ span >
459- < span className = "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200" >
460- { columns . find (
461- ( col ) => col . id === selectedItem . column_id
462- ) ?. name || "Unknown" }
463- </ span >
464- </ div >
465- ) }
466-
467- { /* Category */ }
468- { selectedItem ?. roadmap_categories && (
469- < div className = "flex items-center justify-between" >
470- < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" >
471- Category
472- </ span >
473- < span
474- className = { `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${ getCategoryColorClasses (
475- selectedItem . roadmap_categories . color || "blue"
476- ) } `}
477- >
478- { selectedItem . roadmap_categories . name }
479- </ span >
480- </ div >
481- ) }
482-
483- { /* Board */ }
483+ { /* Category */ }
484+ { selectedItem ?. roadmap_categories && (
484485 < div className = "flex items-center justify-between" >
485486 < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" >
486- Board
487+ Category
487488 </ span >
488- < span className = "text-sm text-gray-900 dark:text-gray-100 font-medium" >
489- { board . title }
489+ < span
490+ className = { `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${ getCategoryColorClasses (
491+ selectedItem . roadmap_categories . color || "blue"
492+ ) } `}
493+ >
494+ { selectedItem . roadmap_categories . name }
490495 </ span >
491496 </ div >
492-
493- { /* Created Date */ }
494- { selectedItem ?. created_at && (
495- < div className = "flex items-center justify-between" >
496- < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" >
497- Created
498- </ span >
499- < span className = "text-sm text-gray-900 dark:text-gray-100" >
500- { new Date (
501- selectedItem . created_at
502- ) . toLocaleDateString ( "en-US" , {
503- year : "numeric" ,
504- month : "long" ,
505- day : "numeric" ,
506- } ) }
507- </ span >
508- </ div >
509- ) }
497+ ) }
498+
499+ { /* Board */ }
500+ < div className = "flex items-center justify-between" >
501+ < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" >
502+ Board
503+ </ span >
504+ < span className = "text-sm text-gray-900 dark:text-gray-100 font-medium" >
505+ { board . title }
506+ </ span >
510507 </ div >
508+
509+ { /* Created Date */ }
510+ { selectedItem ?. created_at && (
511+ < div className = "flex items-center justify-between" >
512+ < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" >
513+ Created
514+ </ span >
515+ < span className = "text-sm text-gray-900 dark:text-gray-100" >
516+ { new Date (
517+ selectedItem . created_at
518+ ) . toLocaleDateString ( "en-US" , {
519+ year : "numeric" ,
520+ month : "long" ,
521+ day : "numeric" ,
522+ } ) }
523+ </ span >
524+ </ div >
525+ ) }
511526 </ div >
512- </ Dialog . Panel >
527+ </ div >
528+ </ Dialog . Panel >
513529 </ div >
514530 </ Transition . Child >
515531 </ div >
0 commit comments