From 6ba84ba37e3b41ba30867d0a68d0fbc13c53d5b8 Mon Sep 17 00:00:00 2001 From: David Kifer Date: Wed, 22 Jul 2026 19:41:28 -0400 Subject: [PATCH] Replace mock Google Sheet link with instant local CSV spreadsheet download generator --- .data.json | 43 +-------------------------- server.ts | 27 +++++++++++++---- src/components/GoogleWorkspaceHub.tsx | 13 +++++++- 3 files changed, 35 insertions(+), 48 deletions(-) diff --git a/.data.json b/.data.json index 6d8b594..5f2918f 100644 --- a/.data.json +++ b/.data.json @@ -174,47 +174,6 @@ } }, "ai_job_portal_applications": { - "items": [ - { - "company": "STATLINX", - "role": "Patient Care Specialist", - "platform": "Direct", - "location": "USA", - "salaryRange": "$36k", - "status": "Applied", - "matchScore": 83, - "appliedAt": "2026-07-22T23:40:10.598Z", - "jobUrl": "https://remotive.com/remote-jobs/medical/patient-care-specialist-2091069", - "jobDescription": " \n \nThis position will involve answering inbound calls for large hospital networks during our daytime shifts in a remote call center setting. Our company provides telephone answering, messaging, and alert services to physicians and medical facilities across the United States.\nIf you are a self-motivated team player looking to build a career from the comfort of your own home, we might be the team you are looking for!\nYou must live within the continental United States (+ Hawaii) to apply.\nWe curre...", - "autoApplied": true, - "timeline": [ - { - "date": "7/22/2026", - "action": "Quick AI Auto-Applied from feed" - } - ], - "id": "app_1784763610598_mrh80" - }, - { - "company": "STATLINX", - "role": "Patient Care Specialist", - "platform": "Direct", - "location": "USA", - "salaryRange": "$36k", - "status": "Applied", - "matchScore": 92, - "appliedAt": "2026-07-22T23:36:27.475Z", - "jobUrl": "https://remotive.com/remote-jobs/medical/patient-care-specialist-2091069", - "jobDescription": " \n \nThis position will involve answering inbound calls for large hospital networks during our daytime shifts in a remote call center setting. Our company provides telephone answering, messaging, and alert services to physicians and medical facilities across the United States.\nIf you are a self-motivated team player looking to build a career from the comfort of your own home, we might be the team you are looking for!\nYou must live within the continental United States (+ Hawaii) to apply.\nWe curre...", - "autoApplied": true, - "timeline": [ - { - "date": "7/22/2026", - "action": "Quick AI Auto-Applied from feed" - } - ], - "id": "app_1784763387476_88alp" - } - ] + "items": [] } } \ No newline at end of file diff --git a/server.ts b/server.ts index 4df73b6..01cac64 100644 --- a/server.ts +++ b/server.ts @@ -616,13 +616,30 @@ app.post("/api/workspace/sheets/export", async (req, res) => { }); } - // Fallback simulation if token not provided - const mockId = `sheet_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`; + // Local CSV export generator when running without live Google OAuth access token + const headers = ["Company", "Role", "Platform", "Location", "Status", "Match Score (%)", "Applied Date", "Salary Range", "Notes"]; + const rows = (applications || []).map((app: any) => [ + `"${app.company || ''}"`, + `"${app.role || ''}"`, + `"${app.platform || 'Direct'}"`, + `"${app.location || ''}"`, + `"${app.status || 'APPLIED'}"`, + `"${app.matchScore || 85}"`, + `"${app.appliedAt || new Date().toISOString().split('T')[0]}"`, + `"${app.salaryRange || 'N/A'}"`, + `"${(app.notes || '').replace(/"/g, '""')}"` + ]); + + const csvContent = [headers.join(','), ...rows.map(r => r.join(','))].join('\n'); + const base64Csv = Buffer.from(csvContent).toString('base64'); + const downloadUrl = `data:text/csv;charset=utf-8;base64,${base64Csv}`; + res.json({ success: true, - spreadsheetId: mockId, - spreadsheetUrl: `https://docs.google.com/spreadsheets/d/${mockId}/edit`, - message: `Export prepared for Google Sheets (${(applications || []).length} applications).` + spreadsheetId: `local_csv_${Date.now()}`, + spreadsheetUrl: downloadUrl, + isLocalCsv: true, + message: `Exported ${(applications || []).length} applications to downloadable Spreadsheet (CSV format)!` }); } catch (error: any) { console.error("Google Sheets Export Error:", error); diff --git a/src/components/GoogleWorkspaceHub.tsx b/src/components/GoogleWorkspaceHub.tsx index 25530b2..fa0bf53 100644 --- a/src/components/GoogleWorkspaceHub.tsx +++ b/src/components/GoogleWorkspaceHub.tsx @@ -178,7 +178,18 @@ export const GoogleWorkspaceHub: React.FC = ({ url: res.spreadsheetUrl, time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }); - showToast('Exported tracker data directly to Google Sheets!'); + + if (res.isLocalCsv && res.spreadsheetUrl) { + const link = document.createElement('a'); + link.href = res.spreadsheetUrl; + link.download = `AI_Job_Applications_Tracker_${new Date().toISOString().split('T')[0]}.csv`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + showToast('✓ Applications exported & downloaded to Spreadsheet CSV file!'); + } else { + showToast(res.message || 'Exported applications to Google Sheets!'); + } } catch (err: any) { showToast(`Sheets Export: ${err.message || 'Prepared export file'}`); } finally {