@@ -92,9 +92,18 @@ function GalleryDetail() {
9292 } ,
9393 } )
9494 if ( ! res . ok ) throw new Error ( "Failed to load photos" )
95- const data = await res . json ( ) as { data : { id : string ; filename : string ; url : string } [ ] ; count : number }
95+ const data = await res . json ( ) as {
96+ data : {
97+ id : string ;
98+ filename : string ;
99+ url : string ;
100+ file_size : number ;
101+ uploaded_at : string ;
102+ } [ ] ;
103+ count : number
104+ }
96105 // Convert relative URLs to absolute URLs
97- data . data = data . data . map ( ( photo : { id : string ; filename : string ; url : string } ) => ( {
106+ data . data = data . data . map ( ( photo ) => ( {
98107 ...photo ,
99108 url : photo . url . startsWith ( "http" ) ? photo . url : `${ OpenAPI . BASE } ${ photo . url } ` ,
100109 } ) )
@@ -204,6 +213,32 @@ function GalleryDetail() {
204213 setSelected ( ( prev : Record < string , boolean > ) => ( { ...prev , [ id ] : ! prev [ id ] } ) )
205214 }
206215
216+ // Format file size for display
217+ const formatFileSize = ( bytes : number ) : string => {
218+ if ( bytes === 0 ) return "0 Bytes"
219+ const k = 1024
220+ const sizes = [ "Bytes" , "KB" , "MB" , "GB" ]
221+ const i = Math . floor ( Math . log ( bytes ) / Math . log ( k ) )
222+ return Math . round ( ( bytes / Math . pow ( k , i ) ) * 100 ) / 100 + " " + sizes [ i ]
223+ }
224+
225+ // Format date for display
226+ const formatDate = ( dateString : string | undefined ) : string => {
227+ if ( ! dateString ) return "Unknown"
228+ try {
229+ const date = new Date ( dateString )
230+ return date . toLocaleDateString ( "en-US" , {
231+ year : "numeric" ,
232+ month : "long" ,
233+ day : "numeric" ,
234+ hour : "2-digit" ,
235+ minute : "2-digit" ,
236+ } )
237+ } catch {
238+ return "Unknown"
239+ }
240+ }
241+
207242 const onDownloadAll = ( ) => {
208243 if ( ! hasPhotos ) {
209244 showErrorToast ( "There are no photos in this gallery to download" )
@@ -445,14 +480,28 @@ function GalleryDetail() {
445480 ›
446481 </ Button >
447482 </ Box >
448- < Box > { /* TODO: Add file size and date added */ }
449- < Text fontWeight = "bold" > Filename: { photos [ currentPhotoIndex ] . filename } </ Text >
450- < Text >
451- Size: unknown (file size is not tracked in the database)
452- </ Text >
453- < Text >
454- Date added: { gallery . date ?? "Unknown" }
455- </ Text >
483+ < Box >
484+ < Stack gap = { 2 } >
485+ < Text fontWeight = "bold" > Filename: { photos [ currentPhotoIndex ] . filename } </ Text >
486+ < Text >
487+ Size: { photos [ currentPhotoIndex ] . file_size
488+ ? formatFileSize ( photos [ currentPhotoIndex ] . file_size )
489+ : "Unknown" }
490+ </ Text >
491+ < Text >
492+ Date uploaded: { formatDate ( photos [ currentPhotoIndex ] . uploaded_at ) }
493+ </ Text >
494+ < Flex alignItems = "center" gap = { 2 } mt = { 2 } >
495+ < Checkbox
496+ checked = { ! ! selected [ photos [ currentPhotoIndex ] . id ] }
497+ onCheckedChange = { ( ) => {
498+ onSelectToggle ( photos [ currentPhotoIndex ] . id )
499+ } }
500+ >
501+ Select this photo
502+ </ Checkbox >
503+ </ Flex >
504+ </ Stack >
456505 </ Box >
457506 </ Stack >
458507 ) }
@@ -478,7 +527,7 @@ function GalleryDetail() {
478527 } }
479528 gap = { 4 }
480529 >
481- { photos . map ( ( p : { id : string ; filename : string ; url : string } , index : number ) => (
530+ { photos . map ( ( p : { id : string ; filename : string ; url : string ; file_size ?: number ; uploaded_at ?: string } , index : number ) => (
482531 < Box
483532 key = { p . id }
484533 position = "relative"
@@ -489,18 +538,38 @@ function GalleryDetail() {
489538 alignItems = "center"
490539 justifyContent = "center"
491540 overflow = "hidden"
492- onClick = { ( ) => openLightboxAt ( index ) }
541+ onClick = { ( e : React . MouseEvent < HTMLDivElement > ) => {
542+ // Don't open dialog if clicking on checkbox
543+ const target = e . target as HTMLElement
544+ if ( target . closest ( '[role="checkbox"]' ) || target . closest ( 'input[type="checkbox"]' ) ) {
545+ return
546+ }
547+ openLightboxAt ( index )
548+ } }
493549 cursor = "pointer"
494550 >
495551 < img
496552 src = { p . url }
497553 alt = { p . filename }
498554 style = { { width : "100%" , height : "100%" , objectFit : "cover" } }
499555 />
500- < Box position = "absolute" top = "8px" left = "8px" bg = "whiteAlpha.800" borderRadius = "md" p = { 1 } >
556+ < Box
557+ position = "absolute"
558+ top = "8px"
559+ left = "8px"
560+ bg = "whiteAlpha.800"
561+ borderRadius = "md"
562+ p = { 1 }
563+ onClick = { ( e : React . MouseEvent < HTMLDivElement > ) => {
564+ // Stop propagation so clicking checkbox doesn't open dialog
565+ e . stopPropagation ( )
566+ } }
567+ >
501568 < Checkbox
502569 checked = { ! ! selected [ p . id ] }
503- onCheckedChange = { ( ) => onSelectToggle ( p . id ) }
570+ onCheckedChange = { ( ) => {
571+ onSelectToggle ( p . id )
572+ } }
504573 >
505574 Select
506575 </ Checkbox >
0 commit comments