/** * Abandoned Recovery Email Campaign Form Page * * Create and edit email recovery campaigns * * @package Yatra * @since 3.0.0 */ import React, { useState, useEffect } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Card, CardContent, CardHeader, CardTitle, CardDescription, } from "../components/ui/card"; import { Button } from "../components/ui/button"; import { Label } from "../components/ui/label"; import { Input } from "../components/ui/input"; import { Select } from "../components/ui/select"; import { PageHeader } from "../components/common/PageHeader"; import { useToast } from "../components/ui/toast"; import { __ } from "../lib/i18n"; import { apiService } from "../lib/api-client"; import { ArrowLeft, Save, Loader2 } from "lucide-react"; interface EmailCampaignFormData { name: string; subject: string; email_body: string; delay_hours: number; status: string; discount_code: string; discount_amount: number; discount_type: string; } const AbandonedRecoveryEmailForm: React.FC = () => { const { showToast } = useToast(); const queryClient = useQueryClient(); const urlParams = new URLSearchParams(window.location.search); const campaignId = urlParams.get("id"); const isEdit = !!campaignId; const [formData, setFormData] = useState({ name: "", subject: "", email_body: "", delay_hours: 1, status: "active", discount_code: "", discount_amount: 0, discount_type: "percentage", }); // Fetch existing campaign if editing const { data: campaignData, isLoading } = useQuery({ queryKey: ["abandoned-recovery-campaign", campaignId], queryFn: async () => { if (!campaignId) return null; const data = await apiService.getAbandonedBookingCampaign(campaignId!); return data; }, enabled: isEdit, }); // Populate form with existing data useEffect(() => { if (campaignData?.data) { setFormData(campaignData.data); } }, [campaignData]); // Create/Update mutation const saveMutation = useMutation({ mutationFn: async (data: EmailCampaignFormData) => { return isEdit ? await apiService.updateAbandonedBookingCampaign(campaignId!, data) : await apiService.createAbandonedBookingCampaign(data); }, onSuccess: () => { showToast( isEdit ? __("Email campaign updated successfully") : __("Email campaign created successfully"), "success", ); queryClient.invalidateQueries({ queryKey: ["abandoned-recovery-campaigns"], }); // Navigate back to main page window.location.href = window.location.href.split("&action=")[0]; }, onError: (error: any) => { showToast(error?.message || __("Failed to save email campaign"), "error"); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); saveMutation.mutate(formData); }; const handleCancel = () => { window.location.href = window.location.href.split("&action=")[0]; }; const handleChange = (field: keyof EmailCampaignFormData, value: any) => { setFormData((prev) => ({ ...prev, [field]: value })); }; if (isLoading) { return (
); } return (
{/* Basic Information */} {__("Campaign Information")} {__("Basic campaign details")}
handleChange("name", e.target.value)} placeholder={__("e.g., First Reminder Email")} required />

{__( "Internal name for this campaign (not visible to customers)", )}

handleChange("delay_hours", parseInt(e.target.value)) } min="1" max="168" required />

{__( "How many hours after abandonment to send this email (1-168 hours)", )}

{/* Email Content */} {__("Email Content")} {__("Customize the email message")}
handleChange("subject", e.target.value)} placeholder={__("Complete your booking and save 10%")} required />

{__( "Available variables: {customer_name}, {trip_name}, {booking_amount}", )}