From 7b1d33f09d2fab5641d0abd3669f80b0a3edd1b1 Mon Sep 17 00:00:00 2001 From: Gemini AI Date: Mon, 29 Dec 2025 15:14:41 +0400 Subject: [PATCH] fix: comprehensive google ads export for CSV and HTML --- components/GoogleAdsGenerator.tsx | 238 ++++++++++++++++++++---------- 1 file changed, 160 insertions(+), 78 deletions(-) diff --git a/components/GoogleAdsGenerator.tsx b/components/GoogleAdsGenerator.tsx index c999bb0..284c124 100644 --- a/components/GoogleAdsGenerator.tsx +++ b/components/GoogleAdsGenerator.tsx @@ -307,37 +307,81 @@ export default function GoogleAdsGenerator() { const exportCSV = () => { if (!googleAdsResult && !magicWandResult) return; - let csvContent = "data:text/csv;charset=utf-8,"; + let rows: string[][] = []; if (googleAdsResult) { - // Keywords section - csvContent += "KEYWORDS RESEARCH\n"; - csvContent += "Type,Keyword,CPC\n"; - googleAdsResult.keywords?.primary?.forEach(k => { - csvContent += `Primary,"${k.keyword}","${k.cpc || 'N/A'}"\n`; - }); - googleAdsResult.keywords?.longTail?.forEach(k => { - csvContent += `Long-tail,"${k.keyword}","${k.cpc || 'N/A'}"\n`; - }); - googleAdsResult.keywords?.negative?.forEach(k => { - csvContent += `Negative,"${k.keyword}",""\n`; - }); + // Keywords + rows.push(["KEYWORDS RESEARCH"]); + rows.push(["Type", "Keyword", "CPC"]); + const addKw = (type: string, list?: any[]) => { + if (list) list.forEach(k => rows.push([type, k.keyword, k.cpc || 'N/A'])); + }; + addKw("Primary", googleAdsResult.keywords?.primary); + addKw("Long-tail", googleAdsResult.keywords?.longTail); + addKw("Negative", googleAdsResult.keywords?.negative); + rows.push([]); - // Ad Copies section - csvContent += "\nAD COPIES\n"; - csvContent += "Headlines,Descriptions,CTA\n"; + // Ad Copies + rows.push(["AD COPIES"]); + rows.push(["Headlines", "Descriptions", "CTA"]); googleAdsResult.adCopies?.forEach(ad => { - csvContent += `"${ad.headlines?.join(' | ') || ''}","${ad.descriptions?.join(' | ') || ''}","${ad.callToAction || ''}"\n`; + rows.push([ + ad.headlines?.join(' | ') || '', + ad.descriptions?.join(' | ') || '', + ad.callToAction || '' + ]); }); + rows.push([]); + + // Campaigns + rows.push(["CAMPAIGN STRUCTURE"]); + rows.push(["Name", "Type", "Budget", "Locations", "Schedule"]); + googleAdsResult.campaigns?.forEach(c => { + rows.push([ + c.name, + c.type, + `${c.budget?.daily || 0} ${c.budget?.currency}`, + c.targeting?.locations?.join('; ') || 'All', + c.targeting?.schedule?.join('; ') || 'All' + ]); + }); + rows.push([]); + + // Implementation + rows.push(["IMPLEMENTATION GUIDE"]); + const impl = googleAdsResult.implementation; + if (impl) { + rows.push(["Setup Steps", impl.setupSteps?.join('; ') || '']); + rows.push(["Quality Score Tips", impl.qualityScoreTips?.join('; ') || '']); + rows.push(["Optimization Tips", impl.optimizationTips?.join('; ') || '']); + } + rows.push([]); + + // Predictions + if (googleAdsResult.predictions) { + rows.push(["PERFORMANCE PREDICTIONS"]); + const p = googleAdsResult.predictions; + rows.push(["Metric", "Estimate"]); + rows.push(["Clicks", p.estimatedClicks || "N/A"]); + rows.push(["Impressions", p.estimatedImpressions || "N/A"]); + rows.push(["CTR", p.estimatedCtr || "N/A"]); + rows.push(["Conversions", p.estimatedConversions || "N/A"]); + rows.push([]); + } } if (magicWandResult) { - csvContent += "\nMARKET ANALYSIS\n"; - csvContent += `Growth Rate,"${magicWandResult.marketAnalysis?.growthRate || 'N/A'}"\n`; - csvContent += `Top Competitors,"${magicWandResult.marketAnalysis?.topCompetitors?.join(', ') || 'N/A'}"\n`; - csvContent += `Market Trends,"${magicWandResult.marketAnalysis?.marketTrends?.join(', ') || 'N/A'}"\n`; + rows.push(["MARKET ANALYSIS"]); + const ma = magicWandResult.marketAnalysis; + rows.push(["Growth Rate", ma?.growthRate || 'N/A']); + rows.push(["Top Competitors", ma?.topCompetitors?.join('; ') || 'N/A']); + rows.push(["Market Trends", ma?.marketTrends?.join('; ') || 'N/A']); } + // CSV String Construction with proper escaping + const csvContent = "data:text/csv;charset=utf-8," + + rows.map(row => row.map(cell => `"${(cell || '').replace(/"/g, '""')}"`).join(",")).join("\n"); + const encodedUri = encodeURI(csvContent); const link = document.createElement("a"); link.setAttribute("href", encodedUri); @@ -350,85 +394,123 @@ export default function GoogleAdsGenerator() { const exportHTML = () => { if (!googleAdsResult && !magicWandResult) return; - let htmlContent = ` + let html = ` - Google Ads Report - ${new Date().toLocaleDateString()} + Google Ads Strategy Report
-

📊 Google Ads Report

-

Generated on ${new Date().toLocaleString()}

`; +

Google Ads Strategy Report

+

Generated by PromptArch on ${new Date().toLocaleDateString()}

`; if (googleAdsResult) { // Keywords - if (googleAdsResult.keywords?.primary?.length) { - htmlContent += ` -
-
🎯 Primary Keywords
- ${googleAdsResult.keywords.primary.map(k => `${k.keyword}${k.cpc ? `${k.cpc}` : ''}`).join('')} -
`; - } + html += `

🎯 Keyword Research

`; + const renderKw = (title: string, list?: any[]) => { + if (!list?.length) return ''; + return `

${title}

+ ${list.map(k => `${k.keyword} (${k.cpc || 'N/A'})`).join('')} +
`; + }; + html += renderKw("Primary Keywords", googleAdsResult.keywords?.primary); + html += renderKw("Long-tail Opportunities", googleAdsResult.keywords?.longTail); + html += renderKw("Negative Keywords", googleAdsResult.keywords?.negative); + html += `
`; // Ad Copies if (googleAdsResult.adCopies?.length) { - htmlContent += ` -
-
📝 Ad Variations
- ${googleAdsResult.adCopies.map(ad => ` -
-
${ad.headlines?.[0] || ''}
-

${ad.descriptions?.[0] || ''}

- ${ad.callToAction ? `${ad.callToAction}` : ''} -
`).join('')} -
`; + html += `

✍️ Ad Copy Variations

`; + googleAdsResult.adCopies.forEach((ad, i) => { + html += `
+
Variation ${i + 1}
+ ${ad.headlines.map(h => `
${h}
`).join('')} +
${ad.descriptions.join('
')}
+ ${ad.callToAction ? `
${ad.callToAction}
` : ''} +
`; + }); + html += `
`; } + + // Campaigns + if (googleAdsResult.campaigns?.length) { + html += `

🏗️ Campaign Structure

+
+ ${googleAdsResult.campaigns.map(c => ` +
+

${c.name}

+

${c.type.toUpperCase()} • ${c.budget.daily} ${c.budget.currency}/day

+
+ Locations: ${c.targeting.locations?.join(', ') || 'Global'}
+ Ad Groups: ${c.adGroups.length} +
+
+ `).join('')} +
+
`; + } + + // Implementation & Predictions + html += `

🚀 Implementation & Forecast

+
+
+

Setup Steps

+
    ${googleAdsResult.implementation.setupSteps.map(s => `
  • ${s}
  • `).join('')}
+
+ ${googleAdsResult.predictions ? ` +
+

Monthly Estimations

+
+
${googleAdsResult.predictions.estimatedClicks || '-'}
Clicks
+
${googleAdsResult.predictions.estimatedCtr || '-'}
CTR
+
${googleAdsResult.predictions.estimatedConversions || '-'}
Convs
+
+
` : ''} +
+
`; } if (magicWandResult) { - const ma = magicWandResult.marketAnalysis; - htmlContent += ` -
-
📈 Market Intelligence
-
-
${ma?.growthRate || 'N/A'}
Market Growth
-
- ${ma?.topCompetitors?.length ? `

Top Competitors: ${ma.topCompetitors.join(', ')}

` : ''} - ${ma?.marketTrends?.length ? `

Market Trends: ${ma.marketTrends.join(', ')}

` : ''} -
`; + html += `

🧠 Market Intelligence

+
+
+

Strategy Rationale

+

${magicWandResult.rationale}

+
+
+

Market Data

+

Growth Rate: ${magicWandResult.marketAnalysis?.growthRate || 'N/A'}

+

Top Competitors

+
    ${magicWandResult.marketAnalysis?.topCompetitors?.map(c => `
  • ${c}
  • `).join('') || '
  • None identified
  • '}
+
+
+
`; } - htmlContent += ` - -
- -`; + html += ``; - const blob = new Blob([htmlContent], { type: 'text/html' }); + const blob = new Blob([html], { type: 'text/html' }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.setAttribute("href", url);