95 lines
2.6 KiB
TypeScript
95 lines
2.6 KiB
TypeScript
// app/(app)/users/components/AssignGroupForm.tsx
|
|
'use client';
|
|
|
|
import { useState, useTransition } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import Dropdown from '@/components/ui/Dropdown';
|
|
import type { SimpleGroup, UserWithAvatar } from './types';
|
|
|
|
type Props = {
|
|
user: UserWithAvatar;
|
|
defaultGroupId: string | null;
|
|
allGroups: SimpleGroup[];
|
|
};
|
|
|
|
export default function AssignGroupForm({
|
|
user,
|
|
defaultGroupId,
|
|
allGroups,
|
|
}: Props) {
|
|
const router = useRouter();
|
|
const [pending, startTransition] = useTransition();
|
|
const [groupId, setGroupId] = useState<string>(defaultGroupId ?? 'none');
|
|
|
|
async function updateGroup(nextGroupId: string) {
|
|
setGroupId(nextGroupId);
|
|
|
|
startTransition(async () => {
|
|
try {
|
|
const res = await fetch('/api/users/assign-group', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
userId: user.nwkennung,
|
|
groupId: nextGroupId,
|
|
}),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
console.error(
|
|
'Fehler beim Zuordnen der Gruppe',
|
|
await res.text(),
|
|
);
|
|
}
|
|
|
|
router.refresh();
|
|
} catch (err) {
|
|
console.error('Fehler beim Zuordnen der Gruppe', err);
|
|
}
|
|
});
|
|
}
|
|
|
|
const currentLabel =
|
|
groupId === 'none'
|
|
? 'Ohne Gruppe'
|
|
: allGroups.find((g) => g.id === groupId)?.name ?? 'Gruppe wählen';
|
|
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
<Dropdown
|
|
triggerVariant="button"
|
|
label={currentLabel}
|
|
ariaLabel="Gruppe auswählen"
|
|
align="left"
|
|
disabled={pending}
|
|
triggerClassName="inline-flex items-center rounded-md bg-white px-2 py-1 text-xs font-normal text-gray-900 shadow-sm inset-ring-1 inset-ring-gray-300 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed dark:bg-gray-900 dark:text-gray-100 dark:inset-ring-gray-700"
|
|
sections={[
|
|
{
|
|
id: 'groups',
|
|
items: [
|
|
{
|
|
id: 'none',
|
|
label: 'Ohne Gruppe',
|
|
disabled: pending && groupId === 'none',
|
|
onClick: () => updateGroup('none'),
|
|
},
|
|
...allGroups.map((g) => ({
|
|
id: g.id,
|
|
label: g.name,
|
|
disabled: pending && groupId === g.id,
|
|
onClick: () => updateGroup(g.id),
|
|
})),
|
|
],
|
|
},
|
|
]}
|
|
/>
|
|
|
|
{pending && (
|
|
<span className="text-xs text-gray-500 dark:text-gray-400">
|
|
Speichere …
|
|
</span>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|