Merge pull request 'Display a tree with the groups of guests (with mocked data)' (#2) from feature/categories-tree into main

Reviewed-on: #2
This commit is contained in:
bustikiller 2024-08-11 15:28:06 +00:00
commit f41c112b25
7 changed files with 167 additions and 1 deletions

View File

@ -1,9 +1,17 @@
import { lusitana } from '@/app/ui/fonts'; import { lusitana } from '@/app/ui/fonts';
import AffinityGroupsTree from '@/app/ui/guests/affinity-groups-tree';
import GuestsTable from '@/app/ui/guests/table'; import GuestsTable from '@/app/ui/guests/table';
import { Tree } from 'primereact/tree';
import React, { useState, useEffect } from 'react';
export default function Page() { export default function Page() {
return ( return (
<div className="w-full"> <div className="w-full">
<h1 className={`${lusitana.className} text-2xl py-4`}>Groups</h1>
<AffinityGroupsTree />
<h1 className={`${lusitana.className} text-2xl py-4`}>Guests</h1> <h1 className={`${lusitana.className} text-2xl py-4`}>Guests</h1>
<div className="flex w-full items-center justify-between"> <div className="flex w-full items-center justify-between">
<GuestsTable /> <GuestsTable />

View File

@ -1,4 +1,8 @@
import '@/app/ui/global.css' import '@/app/ui/global.css'
import 'primereact/resources/themes/lara-light-cyan/theme.css';
import 'primeicons/primeicons.css';
import { inter } from '@/app/ui/fonts'; import { inter } from '@/app/ui/fonts';
export default function RootLayout({ export default function RootLayout({

View File

@ -9,6 +9,8 @@ import Link from 'next/link';
import { usePathname } from 'next/navigation'; import { usePathname } from 'next/navigation';
import clsx from 'clsx'; import clsx from 'clsx';
// Map of links to display in the side navigation.
// Depending on the size of the application, this would be stored in a database.
const links = [ const links = [
{ name: 'Guests', href: '/dashboard/guests', icon: UserGroupIcon }, { name: 'Guests', href: '/dashboard/guests', icon: UserGroupIcon },
{ name: 'Expenses', href: '/dashboard/expenses', icon: BanknotesIcon }, { name: 'Expenses', href: '/dashboard/expenses', icon: BanknotesIcon },

View File

@ -0,0 +1,49 @@
'use client'
import React, { useState, useEffect, Suspense } from 'react';
import { Tree } from 'primereact/tree';
import { PrimeIcons } from 'primereact/api';
import { debug } from 'console';
export default function AffinityGroupsTree() {
const [nodes, setNodes] = useState([]);
const parseNode = (record: any, included: any[]) => {
if (!record.attributes) {
record = included.find((a) => a.id === record.id);
}
const children = (record?.relationships?.children?.data || []).map((child: any) => {
return (parseNode(child, included));
});
return ({
key: record.id,
label: record.attributes.name,
icon: record.attributes.icon,
children: children,
className: "px-4",
})
}
useEffect(() => {
if (nodes.length > 0) {
return;
}
fetch("http://localhost:3001/groups.json")
.then((response) => response.json())
.then((data) => {
setNodes(data.data.map((record: any) => {
return (parseNode(record, data.included));
}))
});
});
return (
<div className="card flex justify-content-center">
<Suspense>
<Tree value={nodes} dragdropScope="affinity-groups" onDragDrop={(e) => setNodes(e.value)} className="w-full md:w-30rem" />
</Suspense>
</div>
)
}

View File

@ -42,7 +42,7 @@ export default function guestsTable() {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<Suspense fallback="<tr><td colspan=3> Loading data</td></tr>"> <Suspense>
{guests.map((guest) => ( {guests.map((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"> <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">
<th scope="row" className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"> <th scope="row" className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">

View File

@ -15,6 +15,8 @@
"next": "15.0.0-canary.56", "next": "15.0.0-canary.56",
"next-auth": "5.0.0-beta.19", "next-auth": "5.0.0-beta.19",
"postcss": "8.4.38", "postcss": "8.4.38",
"primeicons": "^7.0.0",
"primereact": "^10.8.2",
"react": "19.0.0-rc-f38c22b244-20240704", "react": "19.0.0-rc-f38c22b244-20240704",
"react-dom": "19.0.0-rc-f38c22b244-20240704", "react-dom": "19.0.0-rc-f38c22b244-20240704",
"tailwindcss": "3.4.4", "tailwindcss": "3.4.4",

101
pnpm-lock.yaml generated
View File

@ -35,6 +35,12 @@ importers:
postcss: postcss:
specifier: 8.4.38 specifier: 8.4.38
version: 8.4.38 version: 8.4.38
primeicons:
specifier: ^7.0.0
version: 7.0.0
primereact:
specifier: ^10.8.2
version: 10.8.2(@types/react@18.3.3)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
react: react:
specifier: 19.0.0-rc-f38c22b244-20240704 specifier: 19.0.0-rc-f38c22b244-20240704
version: 19.0.0-rc-f38c22b244-20240704 version: 19.0.0-rc-f38c22b244-20240704
@ -87,6 +93,10 @@ packages:
nodemailer: nodemailer:
optional: true optional: true
'@babel/runtime@7.25.0':
resolution: {integrity: sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==}
engines: {node: '>=6.9.0'}
'@emnapi/runtime@1.2.0': '@emnapi/runtime@1.2.0':
resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==}
@ -339,6 +349,9 @@ packages:
'@types/react-dom@18.3.0': '@types/react-dom@18.3.0':
resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==}
'@types/react-transition-group@4.4.11':
resolution: {integrity: sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==}
'@types/react@18.3.3': '@types/react@18.3.3':
resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==}
@ -516,6 +529,9 @@ packages:
dlv@1.1.3: dlv@1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
dom-helpers@5.2.1:
resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
eastasianwidth@0.2.0: eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
@ -648,6 +664,9 @@ packages:
jose@5.4.1: jose@5.4.1:
resolution: {integrity: sha512-U6QajmpV/nhL9SyfAewo000fkiRQ+Yd2H0lBxJJ9apjpOgkOcBQJWOrMo917lxLptdS/n/o/xPzMkXhF46K8hQ==} resolution: {integrity: sha512-U6QajmpV/nhL9SyfAewo000fkiRQ+Yd2H0lBxJJ9apjpOgkOcBQJWOrMo917lxLptdS/n/o/xPzMkXhF46K8hQ==}
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
lilconfig@2.1.0: lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -659,6 +678,10 @@ packages:
lines-and-columns@1.2.4: lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
lru-cache@10.2.2: lru-cache@10.2.2:
resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==}
engines: {node: 14 || >=16.14} engines: {node: 14 || >=16.14}
@ -918,6 +941,23 @@ packages:
pretty-format@3.8.0: pretty-format@3.8.0:
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
primeicons@7.0.0:
resolution: {integrity: sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw==}
primereact@10.8.2:
resolution: {integrity: sha512-bf7vktogGh0PmKT9WLDcJQoQNqqFqcAlP2crUqccnlTu63FNnQV82qEYyaFvE12Qd5qhm3EYmpsHjpf6/+olTQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
queue-microtask@1.2.3: queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@ -926,6 +966,15 @@ packages:
peerDependencies: peerDependencies:
react: 19.0.0-rc-f38c22b244-20240704 react: 19.0.0-rc-f38c22b244-20240704
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
react-transition-group@4.4.5:
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
peerDependencies:
react: '>=16.6.0'
react-dom: '>=16.6.0'
react@19.0.0-rc-f38c22b244-20240704: react@19.0.0-rc-f38c22b244-20240704:
resolution: {integrity: sha512-OP8O6Oc1rdR9IdIKJRKaL1PYd4eGkn6f88VqiygWyyG4P4RmPPix5pp7MatqSt9TnBOcVT+lBMGoVxRgUFeudQ==} resolution: {integrity: sha512-OP8O6Oc1rdR9IdIKJRKaL1PYd4eGkn6f88VqiygWyyG4P4RmPPix5pp7MatqSt9TnBOcVT+lBMGoVxRgUFeudQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -941,6 +990,9 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
regenerator-runtime@0.14.1:
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
resolve@1.22.8: resolve@1.22.8:
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true hasBin: true
@ -1168,6 +1220,10 @@ snapshots:
preact: 10.11.3 preact: 10.11.3
preact-render-to-string: 5.2.3(preact@10.11.3) preact-render-to-string: 5.2.3(preact@10.11.3)
'@babel/runtime@7.25.0':
dependencies:
regenerator-runtime: 0.14.1
'@emnapi/runtime@1.2.0': '@emnapi/runtime@1.2.0':
dependencies: dependencies:
tslib: 2.6.3 tslib: 2.6.3
@ -1374,6 +1430,10 @@ snapshots:
dependencies: dependencies:
'@types/react': 18.3.3 '@types/react': 18.3.3
'@types/react-transition-group@4.4.11':
dependencies:
'@types/react': 18.3.3
'@types/react@18.3.3': '@types/react@18.3.3':
dependencies: dependencies:
'@types/prop-types': 15.7.12 '@types/prop-types': 15.7.12
@ -1542,6 +1602,11 @@ snapshots:
dlv@1.1.3: {} dlv@1.1.3: {}
dom-helpers@5.2.1:
dependencies:
'@babel/runtime': 7.25.0
csstype: 3.1.3
eastasianwidth@0.2.0: {} eastasianwidth@0.2.0: {}
electron-to-chromium@1.4.789: {} electron-to-chromium@1.4.789: {}
@ -1678,12 +1743,18 @@ snapshots:
jose@5.4.1: {} jose@5.4.1: {}
js-tokens@4.0.0: {}
lilconfig@2.1.0: {} lilconfig@2.1.0: {}
lilconfig@3.1.1: {} lilconfig@3.1.1: {}
lines-and-columns@1.2.4: {} lines-and-columns@1.2.4: {}
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
lru-cache@10.2.2: {} lru-cache@10.2.2: {}
make-dir@3.1.0: make-dir@3.1.0:
@ -1892,6 +1963,23 @@ snapshots:
pretty-format@3.8.0: {} pretty-format@3.8.0: {}
primeicons@7.0.0: {}
primereact@10.8.2(@types/react@18.3.3)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704):
dependencies:
'@types/react-transition-group': 4.4.11
react: 19.0.0-rc-f38c22b244-20240704
react-dom: 19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704)
react-transition-group: 4.4.5(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
optionalDependencies:
'@types/react': 18.3.3
prop-types@15.8.1:
dependencies:
loose-envify: 1.4.0
object-assign: 4.1.1
react-is: 16.13.1
queue-microtask@1.2.3: {} queue-microtask@1.2.3: {}
react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704): react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704):
@ -1899,6 +1987,17 @@ snapshots:
react: 19.0.0-rc-f38c22b244-20240704 react: 19.0.0-rc-f38c22b244-20240704
scheduler: 0.25.0-rc-f38c22b244-20240704 scheduler: 0.25.0-rc-f38c22b244-20240704
react-is@16.13.1: {}
react-transition-group@4.4.5(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704):
dependencies:
'@babel/runtime': 7.25.0
dom-helpers: 5.2.1
loose-envify: 1.4.0
prop-types: 15.8.1
react: 19.0.0-rc-f38c22b244-20240704
react-dom: 19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704)
react@19.0.0-rc-f38c22b244-20240704: {} react@19.0.0-rc-f38c22b244-20240704: {}
read-cache@1.0.0: read-cache@1.0.0:
@ -1915,6 +2014,8 @@ snapshots:
dependencies: dependencies:
picomatch: 2.3.1 picomatch: 2.3.1
regenerator-runtime@0.14.1: {}
resolve@1.22.8: resolve@1.22.8:
dependencies: dependencies:
is-core-module: 2.13.1 is-core-module: 2.13.1