"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { toast } from "sonner"; import { SetupHeader, FieldLabel, TextInput, PrimaryButton, type SetupProps } from "./setup-shared"; const HOSTING_OPTIONS = [ { value: "", label: "Select hosting provider" }, { value: "vercel", label: "Vercel" }, { value: "aws", label: "AWS (EC2 / ECS / Elastic Beanstalk)" }, { value: "heroku", label: "Heroku" }, { value: "digitalocean", label: "DigitalOcean (Droplet / App Platform)" }, { value: "gcp", label: "Google Cloud Platform" }, { value: "azure", label: "Microsoft Azure" }, { value: "railway", label: "Railway" }, { value: "render", label: "Render" }, { value: "netlify", label: "Netlify" }, { value: "self-hosted", label: "Self-hosted / VPS" }, { value: "other", label: "Other" }, ]; export function MigrateSetup({ workspace, onClose, onBack }: SetupProps) { const router = useRouter(); const [name, setName] = useState(""); const [repoUrl, setRepoUrl] = useState(""); const [liveUrl, setLiveUrl] = useState(""); const [hosting, setHosting] = useState(""); const [pat, setPat] = useState(""); const [loading, setLoading] = useState(false); const isValidRepo = repoUrl.trim().startsWith("http"); const isValidLive = liveUrl.trim().startsWith("http"); const canCreate = name.trim().length > 0 && (isValidRepo || isValidLive); const handleCreate = async () => { if (!canCreate) return; setLoading(true); try { const res = await fetch("/api/projects/create", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ projectName: name.trim(), projectType: "web-app", slug: name.toLowerCase().replace(/[^a-z0-9]+/g, "-"), product: { name: name.trim() }, creationMode: "migration", sourceData: { repoUrl: repoUrl.trim() || undefined, liveUrl: liveUrl.trim() || undefined, hosting: hosting || undefined, pat: pat.trim() || undefined, }, }), }); if (!res.ok) { const err = await res.json(); toast.error(err.error || "Failed to create project"); return; } const data = await res.json(); onClose(); router.push(`/${workspace}/project/${data.projectId}/overview`); } catch { toast.error("Something went wrong"); } finally { setLoading(false); } }; return (
Product name Repository URL{" "} (recommended) Live URL{" "} (optional)
Hosting provider
PAT{" "}(private repos) setPat(e.target.value)} placeholder="ghp_…" style={{ width: "100%", padding: "11px 14px", marginBottom: 16, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.9rem", fontFamily: "Outfit, sans-serif", color: "#1a1a1a", outline: "none", boxSizing: "border-box", }} onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")} onBlur={e => (e.currentTarget.style.borderColor = "#e0dcd4")} />
Non-destructive. Atlas builds a full audit and migration plan. Your existing product stays live throughout the entire migration process.
Start migration plan →
); }