Some checks failed
		
		
	
	Check usage of free licenses / build-static-assets (pull_request) Successful in 1m44s
				
			Add copyright notice / copyright_notice (pull_request) Successful in 2m24s
				
			Build Nginx-based docker image / build-static-assets (push) Successful in 8m30s
				
			Playwright Tests / test (pull_request) Failing after 8m55s
				
			
		
			
				
	
	
		
			65 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/
 | |
| 
 | |
| 'use client';
 | |
| 
 | |
| import { AbstractApi } from '@/app/api/abstract-api';
 | |
| import { Guest, GuestSerializer } from '@/app/lib/guest';
 | |
| import { PencilIcon, TrashIcon } from '@heroicons/react/24/outline';
 | |
| import clsx from 'clsx';
 | |
| import TableOfContents from '../components/table-of-contents';
 | |
| 
 | |
| export default function guestsTable({ guests, onUpdate, onEdit }: {
 | |
|   guests: Guest[],
 | |
|   onUpdate: () => void,
 | |
|   onEdit: (guest: Guest) => void
 | |
| }) {
 | |
| 
 | |
|   const api = new AbstractApi<Guest>();
 | |
|   const serializer = new GuestSerializer();
 | |
| 
 | |
|   return (
 | |
|     <TableOfContents
 | |
|       headers={['Name', 'Group', 'Status', 'Actions']}
 | |
|       caption='Guests'
 | |
|       elements={guests}
 | |
|       rowRender={(guest) => (
 | |
|         <tr key={guest.id} className="bg-white border-b odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800">
 | |
|           <td scope="row" className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
 | |
|             {guest.name}
 | |
|           </td>
 | |
|           <td className="px-6 py-4">
 | |
|             {guest.group?.name}
 | |
|           </td>
 | |
|           <td className="px-6 py-4">
 | |
|             <span className="flex items-center text-sm dark:text-white me-3">
 | |
|               <span className={clsx(
 | |
|                 'flex w-2.5 h-2.5 rounded-full me-1.5 flex-shrink-0',
 | |
|                 {
 | |
|                   'bg-gray-400': guest.status === 'considered',
 | |
|                   'bg-blue-400': guest.status === 'invited',
 | |
|                   'bg-green-600': guest.status === 'confirmed',
 | |
|                   'bg-red-400': guest.status === 'declined',
 | |
|                   'bg-yellow-400': guest.status === 'tentative',
 | |
|                 }
 | |
|               )}>
 | |
|               </span>
 | |
|               {guest.status}
 | |
|             </span>
 | |
|           </td>
 | |
|           <td>
 | |
|             <div className="flex flex-row items-center">
 | |
|               <TrashIcon className='size-6 cursor-pointer' onClick={() => {
 | |
|                 if (window.confirm(`Are you sure you want to delete guest "${guest.name}"?`)) {
 | |
|                   api.destroy(serializer, guest, onUpdate)
 | |
|                 }
 | |
|               }}
 | |
|               />
 | |
|               <PencilIcon className='size-6 cursor-pointer' onClick={() => onEdit(guest)} />
 | |
|             </div>
 | |
|           </td>
 | |
|         </tr>
 | |
|       )}
 | |
|     />
 | |
|   );
 | |
| }
 |