All checks were successful
		
		
	
	Playwright Tests / test (pull_request) Has been skipped
				
			Check usage of free licenses / build-static-assets (pull_request) Successful in 1m12s
				
			Add copyright notice / copyright_notice (pull_request) Successful in 1m32s
				
			Build Nginx-based docker image / build-static-assets (push) Successful in 6m2s
				
			
		
			
				
	
	
		
			107 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/
 | |
| 
 | |
| import { Guest } from "@/app/lib/guest";
 | |
| import { Table as TableType } from "@/app/lib/tableSimulation";
 | |
| import { RectangleGroupIcon, UserGroupIcon } from "@heroicons/react/24/outline";
 | |
| import { v4 as uuidv4 } from 'uuid';
 | |
| import { Tooltip } from "primereact/tooltip";
 | |
| import clsx from "clsx";
 | |
| 
 | |
| 
 | |
| function Dish({ guest, rotation }: { guest: Guest, rotation?: number }) {
 | |
|   rotation = rotation || 0
 | |
|   return (
 | |
|     <div className={`m-3 w-24 h-24 rounded-full content-center text-center cursor-default`} style={{
 | |
|       rotate: `${360 - rotation}deg`,
 | |
|       backgroundColor: guest.color,
 | |
|     }}>
 | |
|       {guest.name}
 | |
|     </div>
 | |
|   )
 | |
| }
 | |
| 
 | |
| function GuestRow({ guests }: { guests: Guest[] }) {
 | |
|   return (
 | |
|     <div className="justify-around flex flex-row">
 | |
|       {guests.map((guest) => <Dish key={guest.id} guest={guest} />)}
 | |
|     </div>
 | |
|   )
 | |
| }
 | |
| 
 | |
| function RectangularTable({ table }: { table: TableType }) {
 | |
|   const guests = table.guests;
 | |
|   const halfwayThrough = Math.floor(guests.length / 2)
 | |
|   const arrayFirstHalf = guests.slice(0, halfwayThrough);
 | |
|   const arraySecondHalf = guests.slice(halfwayThrough, guests.length);
 | |
| 
 | |
|   return (
 | |
|     <div className="m-12 h-64 bg-cyan-800 flex flex-col justify-between">
 | |
|       <GuestRow guests={arrayFirstHalf} />
 | |
|       <GuestRow guests={arraySecondHalf} />
 | |
|     </div>
 | |
|   )
 | |
| }
 | |
| 
 | |
| function RoundedTable({ table }: { table: TableType }) {
 | |
|   const guests = table.guests;
 | |
|   const size = 500
 | |
|   const rotation = 360 / guests.length
 | |
| 
 | |
|   const className = (penalty: number) => {
 | |
|     return clsx("px-2 tooltip-cohesion", {
 | |
|       "hidden": penalty === 0,
 | |
|       "text-orange-300": penalty <= 5,
 | |
|       "text-orange-500": penalty > 5 && penalty <= 10,
 | |
|       "text-orange-700": penalty > 10,
 | |
|     })
 | |
|   }
 | |
| 
 | |
| 
 | |
|   return (
 | |
|     <div className={`m-12 rounded-full bg-cyan-800 relative z-0 grid flex items-center justify-items-center`} style={{ width: `${size}px`, height: `${size}px` }}>
 | |
| 
 | |
|       {
 | |
|         guests.map((guest, index) => {
 | |
|           return (
 | |
|             <div key={guest.id} className={`border-dashed grid justify-items-center absolute inset-0`} style={{
 | |
|               rotate: `${index * rotation}deg`,
 | |
|               height: `${size}px`,
 | |
|               width: `${size}px`,
 | |
|             }}>
 | |
|               <Dish guest={guest} rotation={index * rotation} />
 | |
|             </div>
 | |
|           )
 | |
|         })
 | |
|       }
 | |
| 
 | |
|       <div className="bg-zinc-200 w-48 h-12 p-3 flex flex-row rounded z-10">
 | |
|         <div className="px-2 text-slate-800">{`Table #${table.number}`}</div>
 | |
| 
 | |
| 
 | |
|         <Tooltip target=".tooltip-cohesion" />
 | |
|         <Tooltip target=".tooltip-size" />
 | |
| 
 | |
|         <RectangleGroupIcon
 | |
|           className={className(table.discomfort.breakdown.cohesionPenalty)}
 | |
|           data-pr-tooltip={`Cohesion penalty: ${Math.round(table.discomfort.breakdown.cohesionPenalty)}`}
 | |
|           data-pr-position="top"
 | |
|         />
 | |
| 
 | |
|         <UserGroupIcon
 | |
|           className={className(table.discomfort.breakdown.tableSizePenalty)}
 | |
|           data-pr-tooltip={`Table size penalty: ${Math.round(table.discomfort.breakdown.tableSizePenalty)}`}
 | |
|           data-pr-position="top"
 | |
|         />
 | |
|       </div>
 | |
|     </div>
 | |
|   )
 | |
| }
 | |
| 
 | |
| export function Table({ table, style }: { table: TableType, style: "rectangular" | "rounded" }) {
 | |
|   return (
 | |
|     <>
 | |
|       {style === "rectangular" && <RectangularTable table={table} />}
 | |
|       {style === "rounded" && <RoundedTable table={table} />}
 | |
|     </>
 | |
|   )
 | |
| } |