Merge pull request #27 from JoaquinPar/feature/ai-challenge2
Feature/ai challenge2
This commit is contained in:
3 files changed
+44
-30
No files matched your search
+10
-17
@@ -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) => {
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -1,7 +1,14 @@
|
||||
<div data-dial-init class="fixed end-6 bottom-20 group">
|
||||
<button type="button" id="punButton" class="flex items-center justify-center text-white bg-blue-700 rounded-full w-14 h-14 hover:bg-blue-800 dark:bg-blue-600 dark:hover:bg-blue-700 focus:ring-4 focus:ring-blue-300 focus:outline-none dark:focus:ring-blue-800">
|
||||
<div class="fixed end-6 bottom-20 group">
|
||||
<div id="factMenu" class="absolute right-0 bottom-full mb-2 hidden">
|
||||
<div id="factContainer" class="bg-white p-4 rounded-lg shadow-md dark:bg-gray-700 w-64">
|
||||
<p class="mb-2 text-sm text-gray-700 dark:text-gray-300">Insert the kind of short fact you would like to know more about:</p>
|
||||
<input type="text" id="factInput" placeholder="Enter your topic here" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-600 dark:border-gray-500 dark:text-white dark:placeholder-gray-400">
|
||||
<button type="button" id="factSubmitButton" class="mt-3 w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-700">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" id="factButton" class="flex items-center justify-center text-white bg-blue-700 rounded-full w-14 h-14 hover:bg-blue-800 dark:bg-blue-600 dark:hover:bg-blue-700 focus:ring-4 focus:ring-blue-300 focus:outline-none dark:focus:ring-blue-800">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path></svg>
|
||||
<span class="sr-only">Get a Pun</span>
|
||||
<span class="sr-only">Get a Fact</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -13,19 +20,33 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/flowbite@3.1.2/dist/flowbite.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<script>
|
||||
const punButton = document.getElementById("punButton");
|
||||
punButton.addEventListener("click", () => {
|
||||
fetch("/pun")
|
||||
const factButton = document.getElementById("factButton");
|
||||
const factMenu = document.getElementById("factMenu");
|
||||
const factInput = document.getElementById("factInput");
|
||||
const factSubmitButton = document.getElementById("factSubmitButton");
|
||||
|
||||
factButton.addEventListener("click", () => {
|
||||
factMenu.classList.toggle("hidden");
|
||||
});
|
||||
factSubmitButton.addEventListener("click", () => {
|
||||
fetch("/fact", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
fact: factInput.value,
|
||||
}),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
Swal.fire('Here is a pun!', data.pun, 'success');
|
||||
Swal.fire('Here is a fact!', data.fact, 'success');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error fetching pun:", error);
|
||||
Swal.fire('Error fetching pun', 'Please try again later', 'error');
|
||||
console.error("Error fetching fact:", error);
|
||||
Swal.fire('Error fetching fact', 'Please try again later', 'error');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in new issue
Block a user