Redesign tables arrangement layout
Some checks are pending
Build Nginx-based docker image / build-static-assets (push) Waiting to run
Some checks are pending
Build Nginx-based docker image / build-static-assets (push) Waiting to run
This commit is contained in:
parent
043b763ad7
commit
e45625e7fb
@ -6,39 +6,35 @@ import { AbstractApi } from '@/app/api/abstract-api';
|
||||
import { TableSimulation, TableSimulationSerializer } from '@/app/lib/tableSimulation';
|
||||
import Arrangement from '@/app/ui/arrangements/arrangement';
|
||||
import ArrangementsTable from '@/app/ui/arrangements/arrangements-table';
|
||||
import CalculatingSummary from '@/app/ui/arrangements/calculating-summary';
|
||||
import { classNames } from '@/app/ui/components/button';
|
||||
import { Toast } from 'primereact/toast';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
export default function Page() {
|
||||
const toast = useRef<Toast>(null);
|
||||
|
||||
const show = () => {
|
||||
toast.current?.show({
|
||||
severity: 'success',
|
||||
summary: 'Simulation created',
|
||||
detail: 'Table distributions will be calculated shortly, please come back in some minutes'
|
||||
});
|
||||
};
|
||||
|
||||
const [currentArrangement, setCurrentArrangement] = useState<string | null>(null);
|
||||
|
||||
function createSimulation() {
|
||||
const api = new AbstractApi<TableSimulation>();
|
||||
const serializer = new TableSimulationSerializer();
|
||||
api.create(serializer, new TableSimulation(), show);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<div className="flex flex-col w-full items-center justify-between">
|
||||
<Toast ref={toast} />
|
||||
<button onClick={createSimulation} className={classNames('primary')}>Add new</button>
|
||||
<div className="flex flex-row w-full gap-4">
|
||||
<div className="flex-1 border rounded-lg">
|
||||
<ArrangementsTable onArrangementSelected={setCurrentArrangement} />
|
||||
</div>
|
||||
<div className="flex-1 border rounded-lg p-5 shadow-md">
|
||||
<CalculatingSummary />
|
||||
</div>
|
||||
<div className="flex-1 border rounded-lg p-5 shadow-md">
|
||||
<p className="text-lg font-semibold mb-4">Inventory</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ArrangementsTable onArrangementSelected={setCurrentArrangement} />
|
||||
<>
|
||||
{currentArrangement && <Arrangement key={currentArrangement} id={currentArrangement} />}
|
||||
</>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -7,6 +7,8 @@ export interface Entity {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export type TableArrangementStatus = 'in_progress' | 'completed' | 'not_started';
|
||||
|
||||
export type TableArrangement = {
|
||||
id: string;
|
||||
number: number;
|
||||
@ -15,7 +17,7 @@ export type TableArrangement = {
|
||||
discomfort?: number;
|
||||
valid?: boolean;
|
||||
progress: number;
|
||||
status: 'in_progress' | 'completed' | 'not_started';
|
||||
status: TableArrangementStatus;
|
||||
}
|
||||
|
||||
export type User = {
|
||||
|
||||
@ -33,7 +33,7 @@ export class TableSimulation implements Entity {
|
||||
|
||||
export class TableSimulationSerializer implements Serializable<TableSimulation> {
|
||||
fromJson(data: any): TableSimulation {
|
||||
return new TableSimulation(data.id, data.tables.map((table: any) => {
|
||||
return new TableSimulation(data.id, data.tables?.map((table: any) => {
|
||||
return {
|
||||
number: table.number,
|
||||
guests: table.guests.map((guest: any) => new Guest(guest.id, guest.name, guest.color, guest.status, [], guest.group)),
|
||||
|
||||
79
app/ui/arrangements/calculating-summary.tsx
Normal file
79
app/ui/arrangements/calculating-summary.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
/* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/
|
||||
|
||||
'use client'
|
||||
|
||||
import { AbstractApi } from "@/app/api/abstract-api";
|
||||
import { TableArrangementStatus } from "@/app/lib/definitions";
|
||||
import { TableSimulation, TableSimulationSerializer } from "@/app/lib/tableSimulation";
|
||||
import { getSlug } from "@/app/lib/utils";
|
||||
import { Toast } from "primereact/toast";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { ProgressSpinner } from 'primereact/progressspinner';
|
||||
import { classNames } from "../components/button";
|
||||
|
||||
export default function CalculatingSummary() {
|
||||
const [stats, setStats] = useState<{ [key in TableArrangementStatus]: number }>({
|
||||
in_progress: 0,
|
||||
completed: 0,
|
||||
not_started: 0,
|
||||
});
|
||||
|
||||
const [inProgress, setInProgress] = useState<number[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchStats = () => {
|
||||
fetch(`/api/${getSlug()}/tables_arrangements/stats`)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
setStats(data.count);
|
||||
setInProgress(data.in_progress);
|
||||
});
|
||||
};
|
||||
|
||||
fetchStats();
|
||||
const interval = setInterval(fetchStats, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
const toast = useRef<Toast>(null);
|
||||
|
||||
function createSimulation() {
|
||||
const api = new AbstractApi<TableSimulation>();
|
||||
const serializer = new TableSimulationSerializer();
|
||||
api.create(serializer, new TableSimulation(), () => {
|
||||
toast.current?.show({
|
||||
severity: 'success',
|
||||
summary: 'Simulation created',
|
||||
detail: 'Table distributions will be calculated shortly, please come back in some minutes'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Toast ref={toast} />
|
||||
<p className="text-lg font-semibold mb-4">Processing engine</p>
|
||||
<p>{stats.in_progress || 0 } processing</p>
|
||||
|
||||
<div className="my-4">
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
{inProgress.map((progress, index) => (
|
||||
<div key={index} className="relative size-16 flex items-center justify-center">
|
||||
<ProgressSpinner className="size-16" strokeWidth="4" animationDuration={`${Math.random() * 2 + 2}s`} />
|
||||
<span className="absolute text-s">
|
||||
{Math.round(progress * 100)}%
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>+{stats.not_started || 0 } in queue</p>
|
||||
|
||||
<div className="flex justify-center">
|
||||
<button onClick={createSimulation} className={classNames('primary')}>Add new</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user