TalentSync

Home Projects TalentSync Frontend Application Dashboard Pages Cold Mail Generator

Cold Mail Generator

Purpose and Scope

The Cold Mail Generator is an AI-powered feature that enables users to create personalized cold emails for networking and job applications. This page documents the frontend implementation of the cold mail generation interface, including resume selection mechanisms, form handling, email generation workflows, and the edit/enhancement capabilities.

For backend cold mail generation service details including LLM integration and company research, see 3.3. For the shared resume selection pattern used across features, compare with the Hiring Assistant implementation at 4.5.5.


Component Architecture

The Cold Mail Generator page is structured as a multi-panel interface with distinct responsibilities for input collection, resume management, and output display.

Component Hierarchy

Architecture Diagram

Sources: frontend/app/dashboard/cold-mail/page.tsx1-806 frontend/components/cold-mail/ResumeSelection.tsx1-697


State Management

The page maintains extensive state to handle the three-mode resume selection system, form data, generated content, and editing workflows.

State Variables

State Variable Type Purpose
isPageLoading boolean Controls initial page load animation
isGenerating boolean Tracks email generation API call
isEditing boolean Tracks email editing API call
generatedEmail `object null`
resumeFile `File null`
resumeText string Preview text for uploaded file
isPreloaded boolean Indicates resume was pre-populated from analysis
editMode boolean Controls visibility of edit UI
editInstructions string User instructions for editing email
customDraft string User's pasted draft in custom draft mode
customDraftEdited string Enhanced version of custom draft
userResumes UserResume[] List of user's saved resumes
selectedResumeId string ID of selected existing resume
isLoadingResumes boolean Loading state for resume fetch
showResumeDropdown boolean Controls resume dropdown visibility
resumeSelectionMode `"existing" "upload"
formData object Email generation form fields

Form Data Structure

interface FormData {
  recipient_name: string;
  recipient_designation: string;
  company_name: string;
  sender_name: string;
  sender_role_or_goal: string;
  key_points_to_include: string;
  additional_info_for_llm: string;
  company_url: string;
}

Sources: frontend/app/dashboard/cold-mail/page.tsx34-73


Resume Selection System

The Cold Mail Generator implements a three-mode resume selection system, allowing users to choose between existing resumes, upload new files, or provide custom drafts for enhancement.

Resume Selection Mode Toggle

The mode toggle is implemented as a segmented control using three buttons that switch the resumeSelectionMode state. Each mode renders different UI components and validation logic.

Architecture Diagram

Sources: frontend/app/dashboard/cold-mail/page.tsx52-59 frontend/components/cold-mail/ResumeSelection.tsx107-138

Existing Resume Mode

In existing resume mode, the component fetches user's saved resumes via GET /api/cold-mail and displays them in a dropdown. Selecting a resume auto-populates form fields with candidate name and predicted field if available.

Dropdown Implementation:

Upload Mode

Upload mode provides a drag-and-drop style file input accepting PDF, DOC, DOCX, TXT, and MD files. The file is stored in resumeFile state and a preview is generated.

File Preview Logic:

Custom Draft Mode

Custom draft mode allows users to paste an existing email draft and provide enhancement instructions. This mode optionally accepts a resume (either selected or uploaded) to enhance the draft with resume-relevant information.

UI Components:

  1. Resume picker (optional) - same dropdown as existing mode frontend/components/cold-mail/ResumeSelection.tsx391-526
  2. File upload (optional) - same as upload mode frontend/components/cold-mail/ResumeSelection.tsx536-616
  3. Draft textarea - for pasting email draft frontend/components/cold-mail/ResumeSelection.tsx642-647
  4. Edit instructions textarea - for enhancement guidance frontend/components/cold-mail/ResumeSelection.tsx652-658
  5. "Edit My Draft" button - triggers handleCustomDraftEdit() frontend/components/cold-mail/ResumeSelection.tsx660-678

Sources: frontend/components/cold-mail/ResumeSelection.tsx54-80 frontend/components/cold-mail/ResumeSelection.tsx385-692


Email Generation Flow

The email generation process involves validation, form data collection, API communication, and state updates.

Generation Sequence

Architecture Diagram

Sources: frontend/app/dashboard/cold-mail/page.tsx192-348

Validation Logic

The generateColdMail function implements mode-specific validation:

Existing Resume Mode Validation:

if (!selectedResumeId) {
  toast({ 
    title: "Resume Required",
    description: "Please select a resume from your saved resumes.",
    variant: "destructive" 
  });
  return;
}

frontend/app/dashboard/cold-mail/page.tsx193-201

Upload Mode Validation:

Custom Draft Mode Validation:

Common Validation:

if (!formData.recipient_name || !formData.company_name || !formData.sender_name) {
  toast({
    title: "Required Fields Missing",
    description: "Please fill in recipient name, company name, and your name.",
    variant: "destructive"
  });
  return;
}

frontend/app/dashboard/cold-mail/page.tsx242-254

FormData Construction

The function builds a FormData object with multipart/form-data encoding for file uploads:

Resume Data Appending:

Form Fields Appending: All form data fields are appended individually frontend/app/dashboard/cold-mail/page.tsx281-302

Endpoint Selection:

Sources: frontend/app/dashboard/cold-mail/page.tsx192-348


Email Editing Feature

The editing feature allows users to modify generated emails or enhance custom drafts with AI-powered refinement based on natural language instructions.

Edit Workflow Diagram

Architecture Diagram

Sources: frontend/app/dashboard/cold-mail/page.tsx382-491

Edit Function Implementation

The editColdMail function handles editing of already-generated emails:

  1. Pre-checks: Verifies generatedEmail exists and editInstructions is non-empty frontend/app/dashboard/cold-mail/page.tsx383-399
  2. Resume handling: Uses existing selection mode and resume state frontend/app/dashboard/cold-mail/page.tsx407-419
  3. FormData construction: Includes original email subject/body and edit instructions frontend/app/dashboard/cold-mail/page.tsx422-453
  4. API call: POST to /api/cold-mail/edit with edit-specific fields frontend/app/dashboard/cold-mail/page.tsx455-458
  5. State updates: Updates generated email with new content, clears edit instructions, exits edit mode frontend/app/dashboard/cold-mail/page.tsx462-470

Custom Draft Enhancement

The handleCustomDraftEdit function enhances user-provided drafts:

Key Differences from Standard Edit:

Sources: frontend/app/dashboard/cold-mail/page.tsx493-586


Pre-population Mechanism

The Cold Mail Generator supports automatic pre-population of form fields and resume data when navigating from the Resume Analysis page.

Pre-population Flow

Architecture Diagram

Sources: frontend/app/dashboard/cold-mail/page.tsx112-162

Pre-population Data Mapping

The useEffect hook checks localStorage on mount and maps analysis data to form fields:

Analysis Data Field Form Field Mapping Logic
name sender_name Direct copy if not already set
skills (array) key_points_to_include Joined with ", " separator
predicted_field sender_role_or_goal Direct copy if not already set

File Data Handling:

Cleanup: Data is removed from localStorage after 100ms delay to ensure processing completes frontend/app/dashboard/cold-mail/page.tsx146-149

Sources: frontend/app/dashboard/cold-mail/page.tsx119-159


API Integration

The Cold Mail Generator integrates with three backend endpoints for resume fetching, email generation, and email editing.

API Endpoints

Architecture Diagram

Fetch Resumes Endpoint

Request:

const response = await fetch("/api/cold-mail", {
  method: "GET",
});

frontend/app/dashboard/cold-mail/page.tsx78-80

Response Type:

interface FetchResumesResponse {
  success: boolean;
  data?: {
    resumes: UserResume[];
  };
}

interface UserResume {
  id: string;
  customName: string;
  uploadDate: string;
  candidateName?: string;
  predictedField?: string;
}

frontend/app/dashboard/cold-mail/page.tsx26-32

Usage: Called in fetchUserResumes() during component mount and updates userResumes state frontend/app/dashboard/cold-mail/page.tsx75-93

Generate Email Endpoint

Request:

const formDataToSend = new FormData();
// Add resume data based on mode
// Add all form fields
// Optional: company_url

const response = await fetch("/api/cold-mail", {
  method: "POST",
  body: formDataToSend,
});

frontend/app/dashboard/cold-mail/page.tsx310-313

Response Type:

interface ColdMailResponse {
  success: boolean;
  message: string;
  subject: string;
  body: string;
  requestId?: string;
  responseId?: string;
}

frontend/app/dashboard/cold-mail/page.tsx17-24

FormData Fields:

  • resumeId (existing mode) or file (upload mode) or both conditionally (custom draft)
  • recipient_name, recipient_designation, company_name (required)
  • sender_name, sender_role_or_goal, key_points_to_include (required)
  • additional_info_for_llm (optional)
  • company_url (optional)
  • custom_draft (custom draft mode only)
  • edit_instructions (custom draft mode only)

Edit Email Endpoint

Request:

const formDataToSend = new FormData();
// Add resume data
// Add all form fields
// Add edit-specific fields:
formDataToSend.append("generated_email_subject", generatedEmail.subject);
formDataToSend.append("generated_email_body", generatedEmail.body);
formDataToSend.append("edit_inscription", editInstructions);
formDataToSend.append("cold_mail_request_id", generatedEmail.requestId);

const response = await fetch("/api/cold-mail/edit", {
  method: "POST",
  body: formDataToSend,
});

frontend/app/dashboard/cold-mail/page.tsx404-458

Response Structure: Same as ColdMailResponse but wrapped in data object:

interface EditResponse {
  success: boolean;
  message?: string;
  data: {
    subject: string;
    body: string;
    requestId?: string;
    responseId?: string;
  };
}

frontend/app/dashboard/cold-mail/page.tsx460-468

Sources: frontend/app/dashboard/cold-mail/page.tsx75-93 frontend/app/dashboard/cold-mail/page.tsx192-348 frontend/app/dashboard/cold-mail/page.tsx382-491


User Feedback System

The page implements comprehensive user feedback through toast notifications and loading states.

Toast Notifications

The component uses the useToast hook to display feedback for various user actions:

Success Notifications:

Error Notifications:

Loading States

The page implements multiple loading indicators:

PageLoader Component:

LoadingOverlay Component:

Inline Loaders:

Button Disabled States:

Sources: frontend/app/dashboard/cold-mail/page.tsx10 frontend/app/dashboard/cold-mail/page.tsx350-364


Utility Functions

The page implements several utility functions for user interactions with generated content.

Copy to Clipboard

The copyToClipboard function uses the Clipboard API to copy email content:

const copyToClipboard = async (text: string) => {
  try {
    await navigator.clipboard.writeText(text);
    toast({
      title: "Copied!",
      description: "Email content copied to clipboard.",
    });
  } catch (error) {
    toast({
      title: "Copy Failed",
      description: "Could not copy to clipboard.",
      variant: "destructive",
    });
  }
};

frontend/app/dashboard/cold-mail/page.tsx350-364

This function is passed to GeneratedEmailPanel for copy buttons on subject and body sections.

Download as Text

The downloadAsText function creates a downloadable text file containing the generated email:

const downloadAsText = () => {
  if (!generatedEmail) return;

  const content = `Subject: ${generatedEmail.subject}\n\n${generatedEmail.body}`;
  const blob = new Blob([content], { type: "text/plain" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "cold-email.txt";
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
};

frontend/app/dashboard/cold-mail/page.tsx366-379

Process:

  1. Combines subject and body with formatting
  2. Creates a Blob with text/plain MIME type
  3. Generates object URL for the blob
  4. Creates temporary anchor element and triggers click
  5. Cleans up DOM and revokes object URL

Sources: frontend/app/dashboard/cold-mail/page.tsx350-379


Responsive Design

The page implements mobile-first responsive design with breakpoint-specific adaptations.

Layout Adaptations

Container Padding:

px-4 sm:px-6 lg:px-8 py-4 sm:py-8
  • Mobile: 16px horizontal, 16px vertical
  • Tablet (sm): 24px horizontal, 32px vertical
  • Desktop (lg): 32px horizontal, 32px vertical

Grid Layout:

grid grid-cols-1 xl:grid-cols-2 gap-6 lg:gap-8

Header Typography:

text-3xl sm:text-4xl md:text-5xl

Back Button Text:

<span className="hidden sm:inline">Back to Dashboard</span>
<span className="sm:hidden">Back</span>

Shows abbreviated text on mobile frontend/app/dashboard/cold-mail/page.tsx610-611

Component-Level Responsiveness

Resume Dropdown:

File Upload Label:

Generate Button:

Sources: frontend/app/dashboard/cold-mail/page.tsx595-637 frontend/components/cold-mail/ResumeSelection.tsx104-363