@@ -188,8 +188,15 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
188188 if ( ! mounted ) return null ;
189189
190190 return createPortal (
191- < div className = "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" >
192- < div className = "bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-6xl w-full max-h-[90vh] overflow-hidden flex flex-col" >
191+ < div
192+ className = "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"
193+ onClick = { onClose }
194+ >
195+ < div
196+ className = "bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-6xl w-full max-h-[90vh] overflow-hidden flex flex-col"
197+ onClick = { ( e ) => e . stopPropagation ( ) }
198+ >
199+
193200 { /* Header */ }
194201 < div className = "p-6 border-b theme-border flex items-center justify-between" >
195202 < h2 className = "text-2xl font-semibold theme-text-primary" >
@@ -204,9 +211,9 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
204211
205212 { /* Filters */ }
206213 < div className = "p-4 border-b theme-border" >
207- < div className = "flex items-center space-x -4" >
214+ < div className = "flex flex-wrap items-center gap -4" >
208215 < div className = "flex items-center space-x-2" >
209- < label className = "text-sm font-medium theme-text-primary" >
216+ < label className = "text-sm font-medium theme-text-primary whitespace-nowrap " >
210217 { t ( 'admin.status' ) || 'Status:' }
211218 </ label >
212219 < select
@@ -215,7 +222,7 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
215222 setFilterStatus ( e . target . value as TicketStatus | 'all' ) ;
216223 setPage ( 1 ) ;
217224 } }
218- className = "px-3 py-2 theme-bg-primary theme-border rounded-lg theme-text-primary text-sm"
225+ className = "px-3 py-2 theme-bg-primary theme-border rounded-lg theme-text-primary text-sm min-w-[120px] "
219226 >
220227 { statusOptions . map ( ( option ) => (
221228 < option key = { option . value } value = { option . value } >
@@ -225,7 +232,7 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
225232 </ select >
226233 </ div >
227234 < div className = "flex items-center space-x-2" >
228- < label className = "text-sm font-medium theme-text-primary" >
235+ < label className = "text-sm font-medium theme-text-primary whitespace-nowrap " >
229236 { t ( 'admin.category' ) || 'Category:' }
230237 </ label >
231238 < select
@@ -234,7 +241,7 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
234241 setFilterCategory ( e . target . value as TicketCategory | 'all' ) ;
235242 setPage ( 1 ) ;
236243 } }
237- className = "px-3 py-2 theme-bg-primary theme-border rounded-lg theme-text-primary text-sm"
244+ className = "px-3 py-2 theme-bg-primary theme-border rounded-lg theme-text-primary text-sm min-w-[140px] "
238245 >
239246 { categoryOptions . map ( ( option ) => (
240247 < option key = { option . value } value = { option . value } >
@@ -250,7 +257,7 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
250257 < div className = "p-4 border-b theme-border bg-gray-50 dark:bg-gray-800/50" >
251258 < div className = "flex flex-col md:flex-row items-center justify-between gap-4" >
252259 { /* Search Box */ }
253- < div className = "relative w-full md:w-1/3 " >
260+ < div className = "relative w-full md:flex-1 md:max-w-md " >
254261 < input
255262 type = "text"
256263 placeholder = { t ( 'admin.searchTickets' ) || 'Search tickets...' }
@@ -266,32 +273,22 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
266273 { /* Create Ticket Button (Right Aligned) */ }
267274 < button
268275 onClick = { ( ) => {
269- // Logic to open create ticket modal?
270- // The user asked to put the create ticket button here.
271- // Assuming there is a way to trigger creation or they just want the button visual/placeholder for now if functional isn't described.
272- // Actually this is the ADMIN modal. Admins usually don't create tickets for themselves here, but maybe they want to create on behalf?
273- // Or maybe this is a misunderstanding and they want to be able to create one?
274- // I will add the button and make it trigger valid logic or a toast if not implemented.
275- // Wait, this is `TicketsModal` which seems to be the ADMIN view.
276- // User said: "put the create ticket button on bottom right on the body before the ticket list"
277- // I will add it here.
278276 toast . success ( 'Create Ticket clicked (Feature to be implemented)' ) ;
279277 } }
280278 className = "w-full md:w-auto px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg text-sm font-medium transition-colors flex items-center justify-center gap-2"
281279 >
282280 < svg className = "w-4 h-4" fill = "none" stroke = "currentColor" viewBox = "0 0 24 24" >
283281 < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M12 4v16m8-8H4" />
284282 </ svg >
285- < span className = "md:inline hidden" > { t ( 'tickets.createTicket' ) || 'Create Ticket' } </ span >
286- < span className = "inline md:hidden" > { t ( 'common.create' ) || 'Create' } </ span >
283+ < span > { t ( 'tickets.createTicket' ) || 'Create Ticket' } </ span >
287284 </ button >
288285 </ div >
289286 </ div >
290287
291288 { /* Content */ }
292- < div className = "flex-1 overflow-hidden flex" >
289+ < div className = "flex-1 overflow-hidden flex flex-col md:flex-row " >
293290 { /* Tickets List */ }
294- < div className = { `${ selectedTicket ? 'w-1/2' : 'w-full' } border-r theme-border overflow-y-auto ` } >
291+ < div className = { `w-full md:border-r theme-border overflow-y-auto flex-1 ${ selectedTicket ? 'hidden md:block md: w-1/2' : 'block' } ` } >
295292 { loading ? (
296293 < div className = "flex items-center justify-center h-64" >
297294 < LoadingSpinner />
@@ -325,21 +322,21 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
325322 < div className = "flex-1" >
326323 < div className = "flex items-center space-x-2 mb-1" >
327324 < span className = "text-lg" > { categoryConfig . icon } </ span >
328- < span className = "font-semibold theme-text-primary" > { ticket . subject } </ span >
325+ < span className = "font-semibold theme-text-primary line-clamp-1 " > { ticket . subject } </ span >
329326 </ div >
330- < div className = "flex items-center space-x -2 mb-1" >
331- < span className = { `px-2 py-0.5 rounded text-xs font-medium ${ statusConfig . bgColor } ${ statusConfig . color } ` } >
327+ < div className = "flex flex-wrap items-center gap -2 mb-1" >
328+ < span className = { `px-2 py-0.5 rounded text-[10px] font-medium ${ statusConfig . bgColor } ${ statusConfig . color } ` } >
332329 { t ( statusConfig . label ) }
333330 </ span >
334- < span className = { `px-2 py-0.5 rounded text-xs font-medium ${ priorityConfig . bgColor } ${ priorityConfig . color } ` } >
331+ < span className = { `px-2 py-0.5 rounded text-[10px] font-medium ${ priorityConfig . bgColor } ${ priorityConfig . color } ` } >
335332 { t ( priorityConfig . label ) }
336333 </ span >
337334 </ div >
338- < p className = "text-sm theme-text-muted" >
335+ < p className = "text-xs theme-text-muted" >
339336 { t ( 'admin.user' ) || 'User' } : { ticket . username || 'Unknown' }
340337 </ p >
341338 </ div >
342- < span className = "text-xs theme-text-muted whitespace-nowrap" >
339+ < span className = "text-[10px] theme-text-muted whitespace-nowrap ml-2 " >
343340 { formatTicketDate ( ticket . created_at ) }
344341 </ span >
345342 </ div >
@@ -352,20 +349,31 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
352349
353350 { /* Ticket Details */ }
354351 { selectedTicket && (
355- < div className = "w-1/2 overflow-y-auto p-6" >
352+ < div className = "w-full md:w-1/2 overflow-y-auto p-4 md:p-6 flex-1" >
353+ { /* Back Button for Mobile */ }
354+ < button
355+ onClick = { ( ) => setSelectedTicket ( null ) }
356+ className = "md:hidden flex items-center gap-2 text-sm theme-text-muted mb-4 px-2 py-1 rounded hover:theme-bg-tertiary transition-colors"
357+ >
358+ < svg className = "w-4 h-4" fill = "none" stroke = "currentColor" viewBox = "0 0 24 24" >
359+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M15 19l-7-7 7-7" />
360+ </ svg >
361+ { t ( 'common.back' ) || 'Back' }
362+ </ button >
363+
356364 < div className = "space-y-4" >
357365 < div >
358- < h3 className = "text-lg font-semibold theme-text-primary mb-4" >
366+ < h3 className = "text-lg font-semibold theme-text-primary mb-2 md:mb- 4" >
359367 { t ( 'admin.ticketDetails' ) || 'Ticket Details' }
360368 </ h3 >
361369 </ div >
362370
363371 < div className = "space-y-3" >
364372 < div >
365- < label className = "text-sm font-medium theme-text-muted" >
373+ < label className = "text-xs font-medium theme-text-muted" >
366374 { t ( 'admin.subject' ) || 'Subject' }
367375 </ label >
368- < p className = "theme-text-primary font-semibold" > { selectedTicket . subject } </ p >
376+ < p className = "theme-text-primary font-semibold text-sm md:text-base " > { selectedTicket . subject } </ p >
369377 </ div >
370378
371379 < div >
@@ -434,11 +442,12 @@ const TicketsModal: React.FC<TicketsModalProps> = ({ onClose }) => {
434442 . map ( ( msg ) => (
435443 < div
436444 key = { msg . id }
437- className = { `p-4 rounded-lg border ${ msg . is_admin
438- ? 'bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 ml-8'
439- : 'theme-bg-tertiary theme-border mr-8'
445+ className = { `p-3 md:p- 4 rounded-lg border text-sm ${ msg . is_admin
446+ ? 'bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 ml-4 md:ml- 8'
447+ : 'theme-bg-tertiary theme-border mr-4 md:mr- 8'
440448 } `}
441449 >
450+
442451 < div className = "flex items-center justify-between mb-2" >
443452 < div className = "flex items-center space-x-2" >
444453 < span className = "text-sm font-semibold theme-text-primary" >
0 commit comments