123 lines
4.1 KiB
TypeScript
123 lines
4.1 KiB
TypeScript
/* Copyright (C) 2024 Manuel Bustillo*/
|
|
|
|
'use client';
|
|
|
|
import { AbstractApi } from '@/app/api/abstract-api';
|
|
import { Group, GroupSerializer } from '@/app/lib/group';
|
|
import { classNames } from '@/app/ui/components/button';
|
|
import { ColorPicker } from 'primereact/colorpicker';
|
|
import { Dialog } from 'primereact/dialog';
|
|
import { Dropdown } from 'primereact/dropdown';
|
|
import { FloatLabel } from 'primereact/floatlabel';
|
|
import { InputText } from 'primereact/inputtext';
|
|
import { useEffect, useState } from 'react';
|
|
import AffinitySlider from './form/affinitySlider';
|
|
import { Affinities } from '@/app/lib/affinities';
|
|
import { getSlug } from '@/app/lib/utils';
|
|
|
|
export default function GroupFormDialog({ groups, onCreate, onHide, group, visible }: {
|
|
groups: Group[],
|
|
onCreate?: () => void,
|
|
onHide: () => void,
|
|
group?: Group,
|
|
visible: boolean,
|
|
}) {
|
|
|
|
const [name, setName] = useState(group?.name || '');
|
|
const [icon, setIcon] = useState(group?.icon || '');
|
|
const [color, setColor] = useState<string>(group?.color || '');
|
|
const [parentId, setParentId] = useState(group?.parentId || '');
|
|
const [affinities, setAffinities] = useState<Affinities>({});
|
|
|
|
useEffect(() => {
|
|
if (group?.id === undefined) {
|
|
setAffinities({});
|
|
} else {
|
|
fetch(`/api/${getSlug()}/groups/${group?.id}/affinities`)
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
setAffinities(data);
|
|
});
|
|
}
|
|
}, []);
|
|
|
|
const api = new AbstractApi<Group>();
|
|
const serializer = new GroupSerializer();
|
|
|
|
function resetForm() {
|
|
setName('');
|
|
setIcon('');
|
|
setColor('');
|
|
setParentId('');
|
|
}
|
|
|
|
function submitGroup() {
|
|
if (!(name)) {
|
|
return
|
|
}
|
|
|
|
if (group?.id !== undefined) {
|
|
group.name = name;
|
|
group.icon = icon;
|
|
group.color = color;
|
|
group.parentId = parentId;
|
|
|
|
api.update(serializer, group, () => {
|
|
resetForm();
|
|
onCreate && onCreate();
|
|
});
|
|
} else {
|
|
|
|
api.create(serializer, new Group(undefined, name, undefined, icon, undefined, parentId, color), () => {
|
|
resetForm();
|
|
onCreate && onCreate();
|
|
});
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
|
|
<Dialog header="Add group" visible={visible} style={{ width: '60vw' }} onHide={onHide}>
|
|
<div className="card flex justify-evenly py-5">
|
|
<FloatLabel>
|
|
<InputText id="name" className='rounded-sm' value={name} onChange={(e) => setName(e.target.value)} />
|
|
<label htmlFor="name">Name</label>
|
|
</FloatLabel>
|
|
<FloatLabel>
|
|
<InputText id="icon" className='rounded-sm' value={icon} onChange={(e) => setIcon(e.target.value)} />
|
|
<label htmlFor="icon">Icon</label>
|
|
</FloatLabel>
|
|
<FloatLabel>
|
|
<ColorPicker value={color} format='hex' onChange={(e) => setColor(`#${e.value}`)} />
|
|
<label htmlFor="color" />
|
|
</FloatLabel>
|
|
<FloatLabel>
|
|
<Dropdown id="parentId" className='rounded-sm min-w-32' value={parentId} onChange={(e) => setParentId(e.target.value)} options={
|
|
groups.map((group) => {
|
|
return { label: group.name, value: group.id };
|
|
})
|
|
} />
|
|
<label htmlFor="parentId">Parent</label>
|
|
</FloatLabel>
|
|
|
|
<button className={classNames('primary')} onClick={submitGroup} disabled={!(name.length > 0)}>
|
|
{group?.id !== undefined ? 'Update' : 'Create'}
|
|
</button>
|
|
</div>
|
|
|
|
<div className="card justify-evenly py-5 bg-gray-200 flex flex-col">
|
|
<span className="text-center p-4">Describe the affinity with the rest of the groups</span>
|
|
|
|
{
|
|
groups.map((group) =>
|
|
<div key={group.id} className="flex flex-row hover:bg-gray-300 px-3 py-2 items-center">
|
|
<span className="w-1/3 text-right px-4">{group.name}</span>
|
|
<AffinitySlider value={group.id && affinities[group.id] || 2} onChange={(value) => setAffinities({...affinities, [group.id || "default"]:value})} />
|
|
</div>)
|
|
}
|
|
</div>
|
|
</Dialog>
|
|
</>
|
|
);
|
|
} |