Compare commits

..

No commits in common. "main" and "groups-specs" have entirely different histories.

6 changed files with 381 additions and 421 deletions

2
.nvmrc
View File

@ -1 +1 @@
24.3.0
24.2.0

View File

@ -3,15 +3,12 @@
import { Entity } from '@/app/lib/definitions';
import { getCsrfToken, getSlug } from '@/app/lib/utils';
export interface Api<T extends Entity> {
getAll(serializable: Serializable<T>, callback: (objets: T[]) => void): void;
get(serializable: Serializable<T>, id: string, callback: (object: T) => void): void;
create(serializable: Serializable<T>, object: T, callback: (object: T) => void): void;
update(serializable: Serializable<T>, object: T, callback: () => void): void;
destroy(serializable: Serializable<T>, object: T, callback: () => void): void;
post(serializable: Serializable<T>, path: string, callback: () => void): void;
}
export interface Serializable<T> {
@ -33,18 +30,6 @@ export class AbstractApi<T extends Entity> implements Api<T> {
});
}
getAllPdf(serializable: Serializable<T>, callback: () => void): void {
fetch(`/api/${getSlug()}/${serializable.apiPath()}`, {
headers: {
'Accept': 'application/pdf',
}
}).then(res => res.blob())
.then(blob => {
var file = window.URL.createObjectURL(blob);
window.location.assign(file);
});
}
get(serializable: Serializable<T>, id: (string | undefined), callback: (object: T) => void): void {
const endpoint = id ? `/api/${getSlug()}/${serializable.apiPath()}/${id}` : `/api/${getSlug()}/${serializable.apiPath()}`;
fetch(endpoint)
@ -100,14 +85,4 @@ export class AbstractApi<T extends Entity> implements Api<T> {
}).then(callback)
.catch((error) => console.error(error));
}
post(serializable: Serializable<T>, path: string, callback: () => void): void {
fetch(`/api/${getSlug()}/${serializable.apiPath()}/${path}`, {
method: 'POST',
headers: {
'X-CSRF-TOKEN': getCsrfToken(),
}
}).then(callback)
.catch((error) => console.error(error));
}
}

View File

@ -5,7 +5,7 @@ import clsx from "clsx";
type ButtonColor = 'primary' | 'blue' | 'green' | 'red' | 'yellow' | 'gray';
export function classNames(type: ButtonColor) {
return (clsx("text-white py-1 px-2 m-2 rounded disabled:opacity-50 disabled:cursor-not-allowed", {
return (clsx("text-white py-1 px-2 mx-1 rounded disabled:opacity-50 disabled:cursor-not-allowed", {
'bg-blue-400 hover:bg-blue-600': type === 'primary' || type === 'blue',
'bg-green-500 hover:bg-green-600': type === 'green',
'bg-red-500 hover:bg-red-600': type === 'red',

View File

@ -10,8 +10,6 @@ import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-d
import { LinkIcon, TrashIcon } from "@heroicons/react/24/outline";
import { useEffect, useRef } from "react";
import { useState } from "react";
import { classNames } from "../components/button";
import { Toast } from "primereact/toast";
function InvitationCard({ invitation, allGuests, onGuestAdded, onDestroy }: {
invitation: Invitation,
@ -118,7 +116,6 @@ export default function InvitationsBoard({ guests, invitations: originalInvitati
guests: Array<Guest>,
invitations: Array<Invitation>
}) {
const toast = useRef<Toast>(null);
const api = new AbstractApi<Invitation>();
const serializer = new InvitationSerializer();
@ -147,20 +144,9 @@ export default function InvitationsBoard({ guests, invitations: originalInvitati
});
}
function handleDownloadQrCodes() {
api.post(serializer, 'email', () => {
toast.current?.show({
severity: 'success',
summary: 'Email scheduled',
detail: 'A document with the QR codes will be sent to the organizer\'s email.'
});
})
}
return (
<div className="flex h-screen">
{/* Left Column: Guests */}
<Toast ref={toast} />
<div className="w-1/4 h-full overflow-auto border-r border-gray-300 p-4">
<h2 className="text-lg font-semibold mb-4">{unassignedGuests.length} guests without invitation</h2>
<div>
@ -178,18 +164,11 @@ export default function InvitationsBoard({ guests, invitations: originalInvitati
<button
onClick={handleCreateInvitation}
className={classNames('primary')}
className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
>
Create New Invitation
</button>
<button
onClick={handleDownloadQrCodes}
className={classNames('primary')}
>
Send QR codes via email
</button>
<div className="grid grid-cols-4 gap-6">

View File

@ -16,8 +16,8 @@
"bcrypt": "^6.0.0",
"clsx": "^2.1.1",
"dompurify": "^3.2.6",
"next": "15.4.5",
"next-auth": "5.0.0-beta.29",
"next": "15.3.3",
"next-auth": "5.0.0-beta.28",
"postcss": "8.5.6",
"primeicons": "^7.0.0",
"primereact": "^10.8.2",
@ -27,12 +27,12 @@
"typescript": "5.8.3",
"use-debounce": "^10.0.1",
"uuid": "11.1.0",
"zod": "^4.0.0"
"zod": "^3.23.8"
},
"devDependencies": {
"@playwright/test": "^1.52.0",
"@types/bcrypt": "^5.0.2",
"@types/node": "24.0.10",
"@types/node": "24.0.3",
"@types/react": "18.3.23",
"@types/react-dom": "18.3.7",
"wait-on": "^8.0.3"
@ -40,5 +40,5 @@
"engines": {
"node": ">=23.0.0"
},
"packageManager": "pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad"
"packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac"
}

740
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff