fiddy/apps/web/features/groups/components/group-settings-members-card.tsx

78 lines
4.3 KiB
TypeScript

"use client";
import type { GroupSettingsViewModelState } from "@/features/groups/components/use-group-settings-view-model";
type GroupSettingsMembersCardProps = {
vm: GroupSettingsViewModelState;
};
export default function GroupSettingsMembersCard({ vm }: GroupSettingsMembersCardProps) {
return (
<div className="panel panel-accent p-4 space-y-3">
<div className="card-header">
<div className="card-title">Members</div>
<div className="text-xs text-soft">{vm.memberCount} total</div>
</div>
<div className="space-y-2">
{vm.members.map(member => {
const isSelf = member.userId === vm.currentUserId;
const privilegeLabel = member.role === "GROUP_OWNER"
? "Owner - Full control"
: member.role === "GROUP_ADMIN"
? "Admin - Manage members"
: "Member - Entries only";
return (
<div
key={member.userId}
className={`flex flex-wrap items-center justify-between gap-3 rounded-lg border border-accent-weak px-3 py-2 text-sm ${isSelf ? "bg-accent-soft" : "bg-panel"}`}
>
<div>
<div className={`font-medium ${isSelf ? "text-[color:var(--color-text)]" : ""}`}>
{member.displayName || member.email}
{isSelf ? <span className="ml-2 rounded-full border border-accent-weak px-2 py-0.5 text-[10px] text-soft">You</span> : null}
</div>
<div className="text-xs text-soft">{member.email}</div>
<div className="mt-1 text-[11px] text-soft">{privilegeLabel}</div>
</div>
<div className="flex flex-wrap items-center gap-2">
{vm.isAdmin ? (
<select
className="input-base px-2 py-1 text-xs"
value={member.role}
onChange={event => vm.handleRoleChange(member.userId, event.target.value as "MEMBER" | "GROUP_ADMIN" | "GROUP_OWNER")}
disabled={member.role === "GROUP_OWNER"}
>
<option value="MEMBER">Member</option>
<option value="GROUP_ADMIN">Admin</option>
{vm.isOwner ? <option value="GROUP_OWNER">Owner</option> : null}
</select>
) : (
<span className="text-xs text-soft">{member.role}</span>
)}
{vm.isAdmin && member.role !== "GROUP_OWNER" ? (
<button
type="button"
className="rounded-lg border border-red-400/60 bg-red-500/10 px-2 py-1 text-xs text-red-200"
onClick={() => vm.setConfirmKick({ userId: member.userId, name: member.displayName || member.email })}
>
Remove
</button>
) : null}
{vm.isOwner && member.role !== "GROUP_OWNER" ? (
<button
type="button"
className="rounded-lg btn-accent px-2 py-1 text-xs"
onClick={() => vm.setConfirmTransfer({ userId: member.userId, name: member.displayName || member.email })}
>
Make owner
</button>
) : null}
</div>
</div>
);
})}
</div>
</div>
);
}