78 lines
4.3 KiB
TypeScript
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>
|
|
);
|
|
}
|