YEs
This commit is contained in:
@@ -71,6 +71,11 @@
|
||||
let showMemberModal = $state(false);
|
||||
let selectedMember = $state<Member | null>(null);
|
||||
let selectedMemberRole = $state("");
|
||||
let isTransferring = $state(false);
|
||||
|
||||
const currentUserRole = $derived(
|
||||
members.find((m) => m.user_id === userId)?.role ?? "viewer",
|
||||
);
|
||||
|
||||
async function sendInvite() {
|
||||
if (!inviteEmail.trim()) return;
|
||||
@@ -181,6 +186,65 @@
|
||||
members = members.filter((m) => m.id !== selectedMember!.id);
|
||||
showMemberModal = false;
|
||||
}
|
||||
|
||||
async function transferOwnership() {
|
||||
if (!selectedMember) return;
|
||||
const rp = selectedMember.profiles;
|
||||
const prof = Array.isArray(rp) ? rp[0] : rp;
|
||||
const targetName = prof?.full_name || prof?.email || "this member";
|
||||
|
||||
if (!confirm(m.settings_transfer_confirm({ name: targetName }))) return;
|
||||
|
||||
isTransferring = true;
|
||||
|
||||
// Demote current owner to admin
|
||||
const currentOwner = members.find((m) => m.user_id === userId);
|
||||
if (!currentOwner) {
|
||||
isTransferring = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const { error: demoteError } = await supabase
|
||||
.from("org_members")
|
||||
.update({ role: "admin" })
|
||||
.eq("id", currentOwner.id);
|
||||
|
||||
if (demoteError) {
|
||||
toasts.error(m.toast_error_transfer_ownership());
|
||||
isTransferring = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Promote target to owner
|
||||
const { error: promoteError } = await supabase
|
||||
.from("org_members")
|
||||
.update({ role: "owner" })
|
||||
.eq("id", selectedMember.id);
|
||||
|
||||
if (promoteError) {
|
||||
// Rollback: re-promote current user
|
||||
await supabase
|
||||
.from("org_members")
|
||||
.update({ role: "owner" })
|
||||
.eq("id", currentOwner.id);
|
||||
toasts.error(m.toast_error_transfer_ownership());
|
||||
isTransferring = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Update local state
|
||||
members = members.map((mb) => {
|
||||
if (mb.id === currentOwner.id) return { ...mb, role: "admin" };
|
||||
if (mb.id === selectedMember!.id) return { ...mb, role: "owner" };
|
||||
return mb;
|
||||
});
|
||||
|
||||
isTransferring = false;
|
||||
showMemberModal = false;
|
||||
toasts.success(
|
||||
m.toast_success_transfer_ownership({ name: targetName }),
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="space-y-4 max-w-2xl">
|
||||
@@ -411,13 +475,27 @@
|
||||
{ value: "admin", label: m.role_admin() },
|
||||
]}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="text-[11px] text-error hover:underline self-start"
|
||||
onclick={removeMember}
|
||||
>
|
||||
{m.settings_members_remove()}
|
||||
</button>
|
||||
<div class="flex items-center justify-between">
|
||||
<button
|
||||
type="button"
|
||||
class="text-[11px] text-error hover:underline"
|
||||
onclick={removeMember}
|
||||
>
|
||||
{m.settings_members_remove()}
|
||||
</button>
|
||||
{#if currentUserRole === "owner"}
|
||||
<button
|
||||
type="button"
|
||||
class="text-[11px] text-warning hover:underline"
|
||||
onclick={transferOwnership}
|
||||
disabled={isTransferring}
|
||||
>
|
||||
{isTransferring
|
||||
? "..."
|
||||
: m.settings_transfer_ownership()}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center justify-end gap-3 pt-2 border-t border-light/5"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user