import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { api } from "@/utils/api"; import { Copy, Loader2 } from "lucide-react"; import { useRouter } from "next/router"; import { useState } from "react"; import { toast } from "sonner"; export type Services = { appName: string; serverId?: string | null; name: string; type: | "mariadb" | "application" | "postgres" | "mysql" | "mongo" | "redis" | "compose"; description?: string | null; id: string; createdAt: string; status?: "idle" | "running" | "done" | "error"; }; interface DuplicateProjectProps { projectId: string; services: Services[]; selectedServiceIds: string[]; } export const DuplicateProject = ({ projectId, services, selectedServiceIds, }: DuplicateProjectProps) => { const [open, setOpen] = useState(false); const [name, setName] = useState(""); const [description, setDescription] = useState(""); const [duplicateType, setDuplicateType] = useState("new-project"); // "new-project" or "same-project" const utils = api.useUtils(); const router = useRouter(); const selectedServices = services.filter((service) => selectedServiceIds.includes(service.id), ); const { mutateAsync: duplicateProject, isLoading } = api.project.duplicate.useMutation({ onSuccess: async (newProject) => { await utils.project.all.invalidate(); toast.success( duplicateType === "new-project" ? "Project duplicated successfully" : "Services duplicated successfully", ); setOpen(false); if (duplicateType === "new-project") { router.push(`/dashboard/project/${newProject.projectId}`); } }, onError: (error) => { toast.error(error.message); }, }); const handleDuplicate = async () => { if (duplicateType === "new-project" && !name) { toast.error("Project name is required"); return; } await duplicateProject({ sourceProjectId: projectId, name, description, includeServices: true, selectedServices: selectedServices.map((service) => ({ id: service.id, type: service.type, })), duplicateInSameProject: duplicateType === "same-project", }); }; return ( { setOpen(isOpen); if (!isOpen) { // Reset form when closing setName(""); setDescription(""); setDuplicateType("new-project"); } }} > Duplicate Services Choose where to duplicate the selected services
{duplicateType === "new-project" && ( <>
setName(e.target.value)} placeholder="New project name" />
setDescription(e.target.value)} placeholder="Project description (optional)" />
)}
{selectedServices.map((service) => (
{service.name} ({service.type})
))}
); };