diff --git a/src/public/scripts/geolocation.js b/src/public/scripts/geolocation.js index 7fce450..94c9c66 100644 --- a/src/public/scripts/geolocation.js +++ b/src/public/scripts/geolocation.js @@ -5,38 +5,47 @@ function getLocation() { } function update(data) { - document.getElementById("loading").style = "display: none"; - document.getElementById("currencyExchange").style = "display: flex"; - - document.getElementById("yourFlag").src = `/static/svgs/flags/${data.data.country}.svg` - document.getElementById("yourFlag").alt = data.data.country; - document.getElementById("flagTag").innerHTML = `(${data.data.country})`; - - document.getElementById("exchangeFlag").src = `/static/svgs/flags/USD.svg`; - document.getElementById("exchangeFlag").alt = "USD"; - document.getElementById("exFlagTag").innerHTML = "(USD)"; + if (data.data.message != "error") { + document.getElementById("loading").style = "display: none"; + document.getElementById("currencyExchange").style = "display: flex"; - document.getElementById("dropdown-country-button").value = data.data.toCurrencyRates["USD"]; - - updateExchange(document.getElementById("dropdown-country-button").value); - - const dropdown = document.getElementById("dropdown"); - let countries = Object.keys(data.data.toCurrencyRates); - - countries.forEach(item => { - if (dropdown.querySelector(`button[value="${data.data.toCurrencyRates[item]}"]`)) { - return; - } - - const listItem = document.createElement("li"); - listItem.innerHTML = ``; - - dropdown.appendChild(listItem); - }); + document.getElementById("yourFlag").src = `/static/svgs/flags/${data.data.country}.svg` + document.getElementById("yourFlag").alt = data.data.country; + document.getElementById("flagTag").innerHTML = `(${data.data.country})`; + + document.getElementById("exchangeFlag").src = `/static/svgs/flags/USD.svg`; + document.getElementById("exchangeFlag").alt = "USD"; + document.getElementById("exFlagTag").innerHTML = "(USD)"; + + document.getElementById("dropdown-country-button").value = data.data.toCurrencyRates["USD"]; + + updateExchange(document.getElementById("dropdown-country-button").value); + + const dropdown = document.getElementById("dropdown"); + let countries = Object.keys(data.data.toCurrencyRates); + + countries.forEach(item => { + if (dropdown.querySelector(`button[value="${data.data.toCurrencyRates[item]}"]`)) { + return; + } + + const listItem = document.createElement("li"); + listItem.innerHTML = ``; + + dropdown.appendChild(listItem); + }); + } else { + document.getElementById("loading").style = "display: none"; + document.getElementById("exFrom").style = "display: none"; + document.getElementById("dropdown-country-button").style = "display: none"; + document.getElementById("currencyExchange").style = "display: flex"; + document.getElementById("exchange").innerHTML = "Country not supported"; + document.getElementById("exchange").className = "block rounded-lg text-center p-2.5 w-50 z-20 text-sm border bg-gray-700 border-gray-600 placeholder-gray-400 text-white focus:border-blue-500"; + } } function switchButton(clickedButton) { @@ -60,10 +69,16 @@ async function getLatestExchange(position) { let lon = position.coords.longitude; const res = await fetch(`/exRates/${lat}/${lon}`); const data = await res.json(); - + update(data); } function error(err) { - console.error("Geolocation error: ", err); + const data = { + data: { + message: "error" + } + } + + update(data); } \ No newline at end of file diff --git a/src/router/user.js b/src/router/user.js index 41c91ff..420eb55 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -101,18 +101,17 @@ module.exports = (middleware, users, plans, assets) => { try { const userPlansFromDB = await plans.find({ userId: new ObjectId(req.session.userId) }).toArray(); - // Use a for...of loop for proper async/await behavior in series for updates for (const plan of userPlansFromDB) { - const percentage = await calculatePlanProgress(plan, assets, req.session.userId); - await updatePlanProgressInDB(plan._id, percentage, plans); // Pass the 'plans' collection + const percentage = await calculatePlanProgress(plan, assets, req.session.user._id); + await updatePlanProgressInDB(plan._id, percentage, plans); } - // Re-fetch plans to get updated progress for rendering - const updatedUserPlans = await plans.find({ userId: new ObjectId(req.session.userId) }).toArray(); + const updatedUserPlans = await plans.find({ userId: new ObjectId(req.session.user._id) }).toArray(); + res.render('plans', { user: req.session.user, - plans: updatedUserPlans, // Send the most up-to-date plans + plans: updatedUserPlans, geoData: req.session.geoData }); } catch (err) { @@ -141,16 +140,9 @@ module.exports = (middleware, users, plans, assets) => { return res.status(status.NotFound).redirect('/plans'); } - // The plan.progress should be up-to-date from the database as it was updated in the /plans route - // or when assets/plans are modified. If an immediate recalculation for this specific view is absolutely needed, - // (e.g., if assets were modified without an immediate plan progress update elsewhere), - // you could do it here: - // const currentProgress = await calculatePlanProgress(plan, assets, req.session.user._id); - // plan.progress = currentProgress; // This would only update the 'plan' object for this render, not in DB - res.render('planDetail', { user: req.session.user, - plan: plan, // This plan object will have the progress from the database + plan: plan, geoData: req.session.geoData, assets: userAssets, suggestions: await suggestions.generateSuggestions(), @@ -217,9 +209,10 @@ module.exports = (middleware, users, plans, assets) => { } }); - router.get('/pun', async (req, res) => { - const pun = await suggestions.generatePun(); - return res.status(status.Ok).json({ pun }); + router.post('/fact', async (req, res) => { + const factInput = req.body.fact; + const fact = await suggestions.generateFact(factInput); + return res.status(status.Ok).json({ fact }); }); router.get('/more', (req, res) => { @@ -659,11 +652,19 @@ module.exports = (middleware, users, plans, assets) => { country = data.results[0].formatted_address; let results = await getRates(country); - req.session.geoData = { - country: results.abbreviation, - toCurrencyRates: results.exRates, - geoData: req.session.geoData + + if (!results.exRates) { + req.session.geoData = { + message: "error" + } + } else { + req.session.geoData = { + country: results.abbreviation, + toCurrencyRates: results.exRates, + geoData: req.session.geoData + } } + } return res.status(status.Ok).send({ data: req.session.geoData }); diff --git a/src/util/suggestions.js b/src/util/suggestions.js index 2961014..2bfb957 100644 --- a/src/util/suggestions.js +++ b/src/util/suggestions.js @@ -2,10 +2,10 @@ const { GoogleGenAI } = require("@google/genai"); const ai = new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY }); -async function generatePun() { +async function generateFact(factInput) { const response = await ai.models.generateContent({ model: "gemini-2.0-flash", - contents: "Return a funny pun about investments, answer the pun only, no additional text.", + contents: `Generate a concise investment fact about "${factInput}". If "${factInput}" is not directly investment-related, provide a general, useful investment fact instead. Deliver only the fact itself, with no extra text or explanation.`, }); return response.text; } @@ -19,6 +19,6 @@ async function generateSuggestions() { } module.exports = { - generatePun, + generateFact, generateSuggestions }; diff --git a/src/views/partials/footer.ejs b/src/views/partials/footer.ejs index 2c04272..f6d1596 100644 --- a/src/views/partials/footer.ejs +++ b/src/views/partials/footer.ejs @@ -1,7 +1,14 @@ -