feat: granular team roles (#3975)

Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: Johannes <johannes@formbricks.com>
This commit is contained in:
Piyush Gupta
2024-11-08 11:33:14 +05:30
committed by GitHub
parent 7b38923b7d
commit 1af1a92fec
391 changed files with 10846 additions and 4654 deletions
@@ -0,0 +1,8 @@
"use server";
import { authenticatedActionClient } from "@/lib/utils/action-client";
import { deleteUser } from "@formbricks/lib/user/service";
export const deleteUserAction = authenticatedActionClient.action(async ({ ctx }) => {
return await deleteUser(ctx.user.id);
});
@@ -0,0 +1,94 @@
"use client";
import { signOut } from "next-auth/react";
import { useTranslations } from "next-intl";
import { Dispatch, SetStateAction, useState } from "react";
import toast from "react-hot-toast";
import { TUser } from "@formbricks/types/user";
import { DeleteDialog } from "@formbricks/ui/components/DeleteDialog";
import { Input } from "@formbricks/ui/components/Input";
import { deleteUserAction } from "./actions";
interface DeleteAccountModalProps {
open: boolean;
setOpen: Dispatch<SetStateAction<boolean>>;
user: TUser;
isFormbricksCloud: boolean;
formbricksLogout: () => void;
}
export const DeleteAccountModal = ({
setOpen,
open,
user,
isFormbricksCloud,
formbricksLogout,
}: DeleteAccountModalProps) => {
const t = useTranslations();
const [deleting, setDeleting] = useState(false);
const [inputValue, setInputValue] = useState("");
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};
const deleteAccount = async () => {
try {
setDeleting(true);
await deleteUserAction();
await formbricksLogout();
// redirect to account deletion survey in Formbricks Cloud
if (isFormbricksCloud) {
await signOut({ redirect: true });
window.location.replace("https://app.formbricks.com/s/clri52y3z8f221225wjdhsoo2");
} else {
await signOut({ callbackUrl: "/auth/login" });
}
} catch (error) {
toast.error("Something went wrong");
} finally {
setDeleting(false);
setOpen(false);
}
};
return (
<DeleteDialog
open={open}
setOpen={setOpen}
deleteWhat={t("common.account")}
onDelete={() => deleteAccount()}
text={t("environments.settings.profile.account_deletion_consequences_warning")}
isDeleting={deleting}
disabled={inputValue !== user.email}>
<div className="py-5">
<ul className="list-disc pb-6 pl-6">
<li>
{t(
"environments.settings.profile.permanent_removal_of_all_of_your_personal_information_and_data"
)}
</li>
<li>{t("environments.settings.profile.org_ownership_transfer")}</li>
<li>{t("environments.settings.profile.org_deletion_warning")}</li>
<li>{t("environments.settings.profile.warning_cannot_undo")}</li>
</ul>
<form>
<label htmlFor="deleteAccountConfirmation">
{t("environments.settings.profile.please_enter_email_to_confirm_account_deletion", {
email: user.email,
})}
:
</label>
<Input
value={inputValue}
onChange={handleInputChange}
placeholder={user.email}
className="mt-5"
type="text"
id="deleteAccountConfirmation"
name="deleteAccountConfirmation"
/>
</form>
</div>
</DeleteDialog>
);
};