FinMK / frontend /src /context /SettingsContext.jsx
Kumar
Refactor: Exclude PDF and CSV files from Git to fix HF push error
24e6f5b
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import api from '../api/axios';
const SettingsContext = createContext();
export const useSettings = () => useContext(SettingsContext);
export const SettingsProvider = ({ children }) => {
// --- State Initialization ---
// Load from local storage or set defaults
const [currency, setCurrency] = useState(localStorage.getItem('app_currency') || 'INR');
const [theme, setTheme] = useState(localStorage.getItem('app_theme') || 'cosmic');
const [privacyMode, setPrivacyMode] = useState(localStorage.getItem('app_privacy') === 'true');
// Pro Features (Realistic)
const [savingsGoal, setSavingsGoal] = useState(parseInt(localStorage.getItem('app_savings_goal')) || 20); // % Target
const [notifications, setNotifications] = useState(JSON.parse(localStorage.getItem('app_notifications')) || {
email: true,
push: false,
budget_alerts: true,
monthly_reports: true
});
// --- Currency Logic ---
const getSymbol = (curr) => {
switch (curr) {
case 'INR': return '₹';
case 'USD': return '$';
case 'EUR': return '€';
case 'GBP': return '£';
default: return '$';
}
};
const [currencySymbol, setCurrencySymbol] = useState(getSymbol(currency));
useEffect(() => {
setCurrencySymbol(getSymbol(currency));
localStorage.setItem('app_currency', currency);
}, [currency]);
// --- Theme Logic ---
const themes = {
cosmic: { primary: '#6366f1', secondary: '#ec4899', name: 'Cosmic Indigo' },
emerald: { primary: '#10b981', secondary: '#34d399', name: 'Emerald Forest' },
rose: { primary: '#f43f5e', secondary: '#fb7185', name: 'Rose Gold' },
amber: { primary: '#f59e0b', secondary: '#fbbf24', name: 'Amber Sunset' },
azure: { primary: '#0ea5e9', secondary: '#38bdf8', name: 'Azure Sky' }
};
useEffect(() => {
const root = document.documentElement;
const selectedTheme = themes[theme] || themes.cosmic;
// Update CSS Variables
root.style.setProperty('--primary-color', selectedTheme.primary);
root.style.setProperty('--secondary-color', selectedTheme.secondary);
localStorage.setItem('app_theme', theme);
}, [theme]);
// --- Privacy & Notifications Persistence ---
useEffect(() => {
localStorage.setItem('app_privacy', privacyMode);
}, [privacyMode]);
useEffect(() => {
localStorage.setItem('app_savings_goal', savingsGoal);
}, [savingsGoal]);
useEffect(() => {
localStorage.setItem('app_notifications', JSON.stringify(notifications));
}, [notifications]);
// --- Actions ---
const updateNotification = (key) => {
setNotifications(prev => ({ ...prev, [key]: !prev[key] }));
};
// --- Background Reporting States ---
const [generatingPDF, setGeneratingPDF] = useState(false);
const [sendingEmail, setSendingEmail] = useState(false);
const handleDownloadReport = useCallback(async (format, type, provider) => {
if (generatingPDF) return;
setGeneratingPDF(true);
try {
const payload = provider && provider !== 'Auto Mode' ? { provider } : {};
const initRes = await api.post(`finance/generate-report/?type=${type}`, payload);
const { task_id } = initRes.data;
let pollCount = 0;
const pollInterval = setInterval(async () => {
try {
pollCount++;
const statusRes = await api.get(`finance/generate-report/?task_id=${task_id}`);
if (statusRes.data.status === 'completed') {
clearInterval(pollInterval);
const fileRes = await api.get(`finance/generate-report/?task_id=${task_id}&download=true`, {
responseType: 'blob'
});
const url = window.URL.createObjectURL(new Blob([fileRes.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `Pro_Financial_Report_${new Date().toISOString().split('T')[0]}.pdf`);
document.body.appendChild(link);
link.click();
link.remove();
setGeneratingPDF(false);
alert("PDF Report Generated Successfully!");
} else if (statusRes.data.status === 'failed') {
clearInterval(pollInterval);
setGeneratingPDF(false);
alert(`Generation Failed: ${statusRes.data.error || 'Unknown error'}`);
} else {
if (pollCount > 60) {
clearInterval(pollInterval);
setGeneratingPDF(false);
alert("Report generation is taking longer than expected. It will continue in the background.");
}
}
} catch (pollErr) {
console.error("Polling error:", pollErr);
}
}, 5000);
} catch (err) {
alert(`Report Initiation Failed: ${err.message}`);
setGeneratingPDF(false);
}
}, [generatingPDF]);
const handleSendEmailReport = useCallback(async (recipient, provider) => {
if (!recipient) {
alert("Please enter an email address.");
return false;
}
setSendingEmail(true);
try {
const payload = { email: recipient };
if (provider && provider !== 'Auto Mode') {
payload.provider = provider;
}
const initRes = await api.post('finance/send-email-report/', payload);
const { task_id } = initRes.data;
(async () => {
let pollCount = 0;
const pollInterval = setInterval(async () => {
try {
pollCount++;
const statusRes = await api.get(`finance/generate-report/?task_id=${task_id}`);
if (statusRes.data.status === 'completed') {
clearInterval(pollInterval);
setSendingEmail(false);
alert("Email Report Sent Successfully!");
} else if (statusRes.data.status === 'failed') {
clearInterval(pollInterval);
setSendingEmail(false);
alert(`Email Failed: ${statusRes.data.error || 'Unknown error'}`);
} else {
if (pollCount > 120) {
clearInterval(pollInterval);
setSendingEmail(false);
alert("Email report is taking longer than expected. It will continue in the background.");
}
}
} catch (pollErr) {
console.error("Polling error:", pollErr);
}
}, 5000);
})();
return true;
} catch (err) {
alert(`Email Initiation Failed: ${err.message}`);
setSendingEmail(false);
return false;
}
}, []);
const value = {
currency, setCurrency, currencySymbol,
theme, setTheme, themes,
privacyMode, setPrivacyMode,
savingsGoal, setSavingsGoal,
notifications, updateNotification,
generatingPDF, sendingEmail,
handleDownloadReport, handleSendEmailReport
};
return (
<SettingsContext.Provider value={value}>
{children}
</SettingsContext.Provider>
);
};