Fix subagent audit bugs: optimistic state rollback, reactive surfing state sync, Tailwind classes, JSON parsing, null checks, and popup intervals
This commit is contained in:
@@ -221,7 +221,8 @@ Extract the following fields accurately and output JSON:
|
||||
};
|
||||
|
||||
const { text, providerUsed } = await generateTextWithLLMFallback(prompt, schema, llmConfig);
|
||||
const parsedData = JSON.parse(text || "{}");
|
||||
const cleanJson = (text || "{}").replace(/```json/gi, '').replace(/```/g, '').trim();
|
||||
const parsedData = JSON.parse(cleanJson || "{}");
|
||||
res.json({ success: true, data: parsedData, providerUsed });
|
||||
} catch (error: any) {
|
||||
console.error("Error parsing job URL:", error);
|
||||
@@ -455,8 +456,8 @@ Candidate Criteria:
|
||||
- Excluded Companies: ${excludedCompanies.join(", ")}
|
||||
|
||||
Candidate Profile:
|
||||
- Skills: ${userProfile.skills?.join(", ")}
|
||||
- Summary: ${userProfile.summary}
|
||||
- Skills: ${userProfile?.skills?.join(", ") || "Cybersecurity, Python, Incident Response"}
|
||||
- Summary: ${userProfile?.summary || "Cybersecurity & IT Specialist"}
|
||||
|
||||
List of Jobs to Evaluate:
|
||||
${JSON.stringify(jobFeeds)}
|
||||
@@ -943,8 +944,11 @@ app.post("/api/local/data", (req, res) => {
|
||||
try { store = JSON.parse(fs.readFileSync(DATA_FILE, "utf-8") || "{}"); } catch (e) {}
|
||||
}
|
||||
if (key) {
|
||||
if (items !== undefined) store[key] = { items };
|
||||
if (profile !== undefined) store[key] = { profile };
|
||||
store[key] = {
|
||||
...(store[key] || {}),
|
||||
...(items !== undefined && { items }),
|
||||
...(profile !== undefined && { profile })
|
||||
};
|
||||
}
|
||||
fs.writeFileSync(DATA_FILE, JSON.stringify(store, null, 2));
|
||||
res.json({ success: true });
|
||||
|
||||
+13
-1
@@ -90,12 +90,14 @@ export default function App() {
|
||||
|
||||
// Handlers
|
||||
const handleUpdateStatus = async (id: string, newStatus: ApplicationStatus, note?: string) => {
|
||||
const previousApps = [...applications];
|
||||
setApplications(prev => prev.map(a => a.id === id ? { ...a, status: newStatus } : a));
|
||||
try {
|
||||
await updateApplicationStatus(id, newStatus, note);
|
||||
|
||||
// Send email alert for important status updates
|
||||
if (['Interviewing', 'Offer', 'Screening'].includes(newStatus)) {
|
||||
const app = applications.find(a => a.id === id);
|
||||
const app = previousApps.find(a => a.id === id);
|
||||
if (app) {
|
||||
const notif = await saveNotificationLog({
|
||||
timestamp: new Date().toISOString(),
|
||||
@@ -109,11 +111,21 @@ export default function App() {
|
||||
setNotifications(prev => [notif, ...prev]);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to persist status update, rolling back:', err);
|
||||
setApplications(previousApps);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteApplication = async (id: string) => {
|
||||
const previousApps = [...applications];
|
||||
setApplications(prev => prev.filter(a => a.id !== id));
|
||||
try {
|
||||
await deleteApplicationRecord(id);
|
||||
} catch (err) {
|
||||
console.error('Failed to delete application, rolling back:', err);
|
||||
setApplications(previousApps);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSaveApplicationRecord = async (appData: Omit<JobApplication, 'id'>) => {
|
||||
|
||||
@@ -269,7 +269,7 @@ export const ApplicationsTracker: React.FC<ApplicationsTrackerProps> = ({
|
||||
<div className="font-semibold text-white group-hover:text-indigo-300 transition-colors flex items-center gap-1.5">
|
||||
{app.role}
|
||||
{app.autoApplied && (
|
||||
<span className="inline-flex items-center gap-0.5 px-1.5 py-0.2 rounded text-[10px] font-bold bg-indigo-500/20 text-indigo-300 border border-indigo-500/30" title="Autonomous AI Applied">
|
||||
<span className="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-[10px] font-bold bg-indigo-500/20 text-indigo-300 border border-indigo-500/30" title="Autonomous AI Applied">
|
||||
<Bot className="w-2.5 h-2.5" /> AI
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -77,6 +77,23 @@ export const WalkthroughTailor: React.FC<WalkthroughTailorProps> = ({
|
||||
customCoverLetterText: ''
|
||||
});
|
||||
|
||||
// Keep surfingFormData reactively synchronized with userProfile and tailorResult updates
|
||||
React.useEffect(() => {
|
||||
setSurfingFormData(prev => ({
|
||||
...prev,
|
||||
fullName: userProfile.fullName || prev.fullName,
|
||||
email: userProfile.email || prev.email,
|
||||
phone: userProfile.phone || prev.phone,
|
||||
linkedin: userProfile.linkedinUrl || prev.linkedin,
|
||||
workAuthorization: userProfile.eeoDeclarations?.workAuthorization || prev.workAuthorization,
|
||||
veteranStatus: userProfile.eeoDeclarations?.veteranStatus === 'PROTECTED_VETERAN' ? 'Protected Veteran' : 'Not a Veteran',
|
||||
disabilityStatus: userProfile.eeoDeclarations?.disabilityStatus === 'YES_DISABILITY' ? 'Yes, Disability' : 'No Disability',
|
||||
clearanceLevel: userProfile.eeoDeclarations?.clearanceLevel || prev.clearanceLevel,
|
||||
tailoredBulletsText: tailorResult?.tailoredBullets?.join('\n• ') || prev.tailoredBulletsText,
|
||||
customCoverLetterText: tailorResult?.coverLetter || prev.customCoverLetterText
|
||||
}));
|
||||
}, [userProfile, tailorResult]);
|
||||
|
||||
// Step 1: Parse Job posting details using Gemini
|
||||
const handleParsePosting = async () => {
|
||||
if (!jobUrl && !jobDescriptionText) return;
|
||||
|
||||
@@ -65,8 +65,16 @@ export const googleWorkspaceSignIn = async (silentMode: boolean = false): Promis
|
||||
throw new Error('Popup window was blocked by your browser. Please allow popups for http://localhost:3000.');
|
||||
}
|
||||
|
||||
const startTime = Date.now();
|
||||
const interval = setInterval(async () => {
|
||||
try {
|
||||
if (Date.now() - startTime > 60000) {
|
||||
clearInterval(interval);
|
||||
try { popup.close(); } catch (e) {}
|
||||
reject(new Error('Sign-in process timed out after 60 seconds.'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (popup.closed) {
|
||||
clearInterval(interval);
|
||||
if (!cachedAccessToken) {
|
||||
|
||||
Reference in New Issue
Block a user