"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { Button } from "@/components/ui/button"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Switch } from "@/components/ui/switch"; import { Textarea } from "@/components/ui/textarea"; // Use DeploymentFormInputSchema for the form, which excludes PLATFORM_API_KEY import { DeploymentFormInputSchema, type DeploymentFormInput } from "@/lib/schemas"; import { createNewDeployment } from "@/lib/actions/deployment"; import { useToast } from "@/hooks/use-toast"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; import { AlertCircle, Loader2, Rocket, Github, Coins, ExternalLink } from "lucide-react"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import Link from "next/link"; const defaultAnitaV4RepoUrl = "https://github.com/DavidCyrilTech/Anita-V4"; const DEPLOYMENT_COST = 10; // Defined here for display purposes interface EnvVarField { name: keyof Omit; // Base on DeploymentFormInput label: string; description: string; type: "text" | "boolean" | "textarea" | "password"; // password type just for semantic input, not secure storage here placeholder?: string; required?: boolean; } const envVarFields: EnvVarField[] = [ { name: "SESSION_ID", label: "Session ID", description: "Your WhatsApp session ID. This is mandatory.", type: "textarea", placeholder: "Enter your full session ID here", required: true }, { name: "PLATFORM_APP_NAME", label: "App Name (Optional)", description: "Custom name for your app on the platform. If blank, one will be generated.", type: "text", placeholder: "my-anita-bot" }, { name: "BOT_NAME", label: "Bot Name", description: "The name of your bot.", type: "text", placeholder: "𝐐𝐔𝐄𝐄𝐍_𝐀𝐍𝐈𝐓𝐀-𝐕𝟒" }, { name: "OWNER_NUMBER", label: "Owner Numbers", description: "Comma-separated list of owner WhatsApp numbers (e.g., 234...).", type: "text", placeholder: "2347043759577,2348123456789" }, { name: "OWNER_NAME", label: "Owner Name", description: "The name of the bot owner.", type: "text", placeholder: "David Cyril" }, { name: "PACK_NAME", label: "Sticker Pack Name", description: "Default name for sticker packs.", type: "text", placeholder: "𝐐𝐔𝐄𝐄𝐍_𝐀𝐍𝐈𝐓𝐀-𝐕𝟒 Pack" }, { name: "AUTHOR", label: "Sticker Author Name", description: "Default author for sticker packs.", type: "text", placeholder: "𝐃𝐀𝐕𝐈𝐃 𝐂𝐘𝐑𝐈𝐋" }, { name: "CHANNEL_NAME", label: "Channel Name", description: "Name of your WhatsApp channel.", type: "text", placeholder: "𝐃𝐀𝐕𝐈𝐃 𝐂𝐘𝐑𝐈𝐋 Updates" }, { name: "CHANNEL_JID", label: "Channel JID", description: "JID of your WhatsApp channel.", type: "text", placeholder: "120363315231436175@newsletter" }, { name: "AUTO_TYPING", label: "Auto Typing", description: "Enable automatic typing indicator.", type: "boolean" }, { name: "AUTO_RECORD", label: "Auto Recording", description: "Enable automatic recording indicator.", type: "boolean" }, { name: "AUTO_VIEW_STATUS", label: "Auto View Status", description: "Automatically view contacts' statuses.", type: "boolean" }, { name: "AUTO_STATUS_REACT", label: "Auto React to Status", description: "Automatically react to statuses.", type: "boolean" }, { name: "LEVELUP", label: "Level Up System", description: "Enable the leveling system for users.", type: "boolean" }, { name: "ANTIVIEWONCE", label: "Anti View Once", description: "Save view-once messages.", type: "boolean" }, { name: "PUBLIC", label: "Public Mode", description: "Allow anyone to use the bot commands.", type: "boolean" }, { name: "ANTIDELETE", label: "Anti Delete Messages", description: "Prevent users from deleting messages for the bot.", type: "boolean" }, { name: "ANTI_TAG", label: "Anti Tag All", description: "Prevent tagging everyone in a group.", type: "boolean" }, { name: "ANTI_TEMU", label: "Anti Temu Links", description: "Block Temu links.", type: "boolean" }, { name: "UNAVAILABLE", label: "Bot Unavailable Mode", description: "Set bot to unavailable status.", type: "boolean" }, { name: "AVAILABLE", label: "Bot Available Mode", description: "Set bot to available status (overrides unavailable).", type: "boolean" }, { name: "AUTO_READ_MESSAGES", label: "Auto Read Messages", description: "Mark messages as read automatically.", type: "boolean" }, { name: "CHATBOT", label: "Enable Chatbot", description: "Enable AI chatbot functionality.", type: "boolean" }, { name: "AUTO_REACT", label: "Auto React to Messages", description: "Automatically react to incoming messages.", type: "boolean" }, { name: "WELCOME", label: "Welcome Messages", description: "Send welcome messages to new group members.", type: "boolean" }, { name: "AUTO_LIKE_EMOJI", label: "Auto Like Emoji", description: "Emoji used for auto-liking.", type: "text", placeholder: "💚" }, { name: "SUDO_USERS", label: "Sudo Users", description: "Comma-separated list of sudo user WhatsApp numbers.", type: "text", placeholder: "2349066528353" }, { name: "PREFIX", label: "Command Prefix", description: "The prefix for bot commands.", type: "text", placeholder: "." }, ]; export function DeploymentForm() { const { toast } = useToast(); const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const form = useForm({ // Use DeploymentFormInput for the form resolver: zodResolver(DeploymentFormInputSchema), // Use the schema for form input defaultValues: { SESSION_ID: "", PLATFORM_APP_NAME: "", OWNER_NUMBER: "2347043759577,2348123456789", BOT_NAME: "𝐐𝐔𝐄𝐄𝐍_𝐀𝐍𝐈𝐓𝐀-𝐕𝟒", OWNER_NAME: "David Cyril", PACK_NAME: "𝐐𝐔𝐄𝐄𝐍_𝐀𝐍𝐈𝐓𝐀-𝐕𝟒", AUTHOR: "𝐃𝐀𝐕𝐈𝐃 𝐂𝐘𝐑𝐈𝐋", CHANNEL_NAME: "𝐃𝐀𝐕𝐈𝐃 𝐂𝐘𝐑𝐈𝐋", CHANNEL_JID: "120363315231436175@newsletter", AUTO_TYPING: false, AUTO_RECORD: false, AUTO_VIEW_STATUS: true, AUTO_STATUS_REACT: false, AUTO_LIKE_EMOJI: "💚", LEVELUP: false, ANTIVIEWONCE: false, SUDO_USERS: "2349066528353,2348129988915", PUBLIC: true, ANTIDELETE: false, ANTI_TAG: false, ANTI_TEMU: false, UNAVAILABLE: true, AVAILABLE: false, AUTO_READ_MESSAGES: false, CHATBOT: false, AUTO_REACT: false, WELCOME: false, PREFIX: ".", }, }); async function onSubmit(values: DeploymentFormInput) { // values are of type DeploymentFormInput setIsLoading(true); try { const result = await createNewDeployment(values); // Pass DeploymentFormInput directly if (result.success && result.deployment) { toast({ title: "Deployment Initiated", description: result.message, }); router.push(`/dashboard/deployments/${result.deployment.id}`); } else { toast({ title: "Deployment Failed", description: result.message || "An unknown error occurred.", variant: "destructive", }); } } catch (error) { toast({ title: "Error", description: "An unexpected error occurred. Please try again.", variant: "destructive", }); } finally { setIsLoading(false); } } const groupFields = (fields: EnvVarField[]) => { const groups: Record = { "Core Configuration": [], "Bot Identity & Ownership": [], "Sticker Settings": [], "Channel Integration": [], "Automation Features": [], "Moderation & Utility": [], "Miscellaneous": [], }; fields.forEach(field => { if (["SESSION_ID", "PLATFORM_APP_NAME"].includes(field.name)) groups["Core Configuration"].push(field); else if (["BOT_NAME", "OWNER_NUMBER", "OWNER_NAME", "SUDO_USERS", "PUBLIC", "PREFIX"].includes(field.name)) groups["Bot Identity & Ownership"].push(field); else if (["PACK_NAME", "AUTHOR"].includes(field.name)) groups["Sticker Settings"].push(field); else if (["CHANNEL_NAME", "CHANNEL_JID"].includes(field.name)) groups["Channel Integration"].push(field); else if (field.type === "boolean" && field.name.startsWith("AUTO_")) groups["Automation Features"].push(field); else if (field.type === "boolean" && ["ANTIVIEWONCE", "ANTIDELETE", "ANTI_TAG", "ANTI_TEMU", "LEVELUP", "WELCOME", "UNAVAILABLE", "AVAILABLE", "CHATBOT"].includes(field.name)) groups["Moderation & Utility"].push(field); else groups["Miscellaneous"].push(field); }); return groups; }; const groupedFields = groupFields(envVarFields); return ( Configure Your Anita-V4 Deployment Fill in the details below to deploy your Anita-V4 bot. The deployment platform API key is pre-configured on the server.
GitHub Repository

{defaultAnitaV4RepoUrl}

This deployment will use the official Anita-V4 repository.
Important Ensure your Session ID is correct. An incorrect Session ID will lead to deployment failure. Need help getting your Session ID? Deployment Cost Deploying a new bot costs {DEPLOYMENT_COST} coins. Admins deploy for free. {Object.entries(groupedFields).map(([groupName, fields]) => ( fields.length > 0 && ( {groupName}
{fields.map((envField) => ( (
{envField.label} {envField.required && *} {envField.description} {envField.name === "SESSION_ID" && ( )}
{envField.type === "boolean" ? ( ) : envField.type === "textarea" ? (