+import { Controller, useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { useNavigate } from "@tanstack/react-router";
+import { z } from "zod";
+
+import { createNotification } from "@app/components/notifications";
+import { Button, FormControl, Input, Modal, ModalContent, Spinner } from "@app/components/v2";
+import { useWorkspace } from "@app/context";
+import { useCreateProjectRole, useGetProjectRoleBySlug } from "@app/hooks/api";
+import { TProjectRole } from "@app/hooks/api/roles/types";
+import { slugSchema } from "@app/lib/schemas";
+
+type Props = {
+ isOpen: boolean;
+ onOpenChange: (isOpen: boolean) => void;
+ roleSlug?: string;
+};
+
+const schema = z
+ .object({
+ name: z.string(),
+ description: z.string(),
+ slug: slugSchema({ min: 1 })
+ })
+ .required();
+
+export type FormData = z.infer<typeof schema>;
+
+type ContentProps = {
+ role: TProjectRole;
+ onClose: () => void;
+};
+
+const Content = ({ role, onClose }: ContentProps) => {
+ const {
+ control,
+ handleSubmit,
+ formState: { isSubmitting }
+ } = useForm<FormData>({
+ defaultValues: {
+ name: `${role.name} Duplicate`
+ },
+ resolver: zodResolver(schema)
+ });
+
+ const { currentWorkspace } = useWorkspace();
+
+ const createRole = useCreateProjectRole();
+ const navigate = useNavigate();
+
+ const handleDuplicateRole = async (form: FormData) => {
+ try {
+ const newRole = await createRole.mutateAsync({
+ projectId: role.projectId,
+ permissions: role.permissions,
+ ...form
+ });
+
+ createNotification({
+ type: "success",
+ text: "Role duplicated successfully"
+ });
+
+ navigate({
+ to: `/${currentWorkspace.type}/$projectId/roles/$roleSlug` as const,
+ params: {