Merge pull request #5 from RMCampos/copilot/fix-4

Add copy feature for food log entries
This commit is contained in:
2025-09-17 18:49:05 +00:00
committed by GitHub
3 changed files with 86 additions and 1 deletions
+1
View File
@@ -122,4 +122,5 @@ export const foodDatabase: FoodItem[] = [
{ name: 'Chuchu, cozido', info: { calories: 19, protein: 0.4, fat: 0, carbs: 4.9, fiber: 1.0, category: 'low carb', alkaline: true } },
{ name: 'Cogumelo Paris, in natura', info: { calories: 17, protein: 4.9, fat: 0, carbs: 1, fiber: 1.7, category: 'low carb', alkaline: true } },
{ name: 'Milho, verde, enlatado, drenado', info: { calories: 98, protein: 3.2, fat: 2.4, carbs: 17.1, fiber: 4.6, category: 'low carb', alkaline: true } },
{ name: 'Broto de Feijão', info: { calories: 23, protein: 2.8, fat: 0, carbs: 2.8, fiber: 0.7, category: 'low carb', alkaline: true } },
];
+76 -1
View File
@@ -251,6 +251,13 @@ function clearEditing() {
showFoodPreview(false);
getDivById('add-foot-title').innerHTML = 'Add Food Entry';
getButtonById('add-food-btn').innerHTML = 'Add Food';
getButtonById('cancel-food-btn').style.display = 'none';
// Clear edit-specific hidden inputs
getInputById('foodIdToUpdate').value = '';
getInputById('foodTimeToUpdate').value = '';
getInputById('foodCaloriesToUpdate').value = '';
selectedFood = null;
}
@@ -515,6 +522,7 @@ async function setFoodToEdit(foodId: string) {
getDivById('add-foot-title').innerHTML = 'Edit Food Entry';
getButtonById('add-food-btn').innerHTML = 'Save Food';
getButtonById('cancel-food-btn').style.display = 'inline-block';
getInputById('foodIdToUpdate').value = foodId;
getInputById('foodTimeToUpdate').value = foodToEdit[0].time;
getInputById('foodCaloriesToUpdate').value = foodToEdit[0].calories;
@@ -537,6 +545,53 @@ async function setFoodToEdit(foodId: string) {
}
}
async function setFoodToCopy(foodId: string) {
showLoading();
try {
// get food item
const entries = await AppwriteDB.getFoodEntries(selectedDate);
const foodToCopy = entries.filter(entry => entry.$id === foodId);
if (foodToCopy.length === 0) {
swal('Hey!', 'Unable to get food entry from server', 'error');
return;
}
// set the selected food name and quantity (same as original)
const foodData: FoodItem = getFoodItemByName(foodToCopy[0].name);
selectedFood = foodData;
getInputById('foodSearchInput').value = foodToCopy[0].name;
getInputById('gramAmount').value = foodToCopy[0].grams;
previewCalories(foodData)
// Set UI to copy mode (not edit mode)
getDivById('add-foot-title').innerHTML = 'Copy Food Entry';
getButtonById('add-food-btn').innerHTML = 'Add Food';
getButtonById('cancel-food-btn').style.display = 'inline-block';
// Clear edit-specific hidden inputs to ensure we're in add mode
getInputById('foodIdToUpdate').value = '';
getInputById('foodTimeToUpdate').value = '';
getInputById('foodCaloriesToUpdate').value = '';
// Scroll to top
const titleDiv = getDivById('add-foot-title') as HTMLElement;
if (titleDiv) {
titleDiv.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
hideLoading();
} catch (error) {
console.error('Set food to copy error:', error);
swal('Oh no!', 'Failed to load food entry: ' + error.message, 'error');
} finally {
hideLoading();
}
}
function deleteCardHandler(e: Event) {
e.preventDefault();
e.stopPropagation();
@@ -561,6 +616,18 @@ function editCardHandler(e: Event) {
}
}
function copyCardHandler(e: Event) {
e.preventDefault();
e.stopPropagation();
const card = e.currentTarget as HTMLElement;
const foodId = card.getAttribute('data-food-id');
if (foodId) {
setFoodToCopy(foodId);
}
}
const setupEditAndDeleteEvents = () => {
// Setup toggle show cards events
const cards = getButtonListByClassName('card-header-toggle');
@@ -569,6 +636,13 @@ const setupEditAndDeleteEvents = () => {
card.addEventListener('click', toggleCardHandler);
});
// Setup copy card events
const copyCards = getButtonListByClassName('btn-copy');
Array.from(copyCards).forEach((card: HTMLElement) => {
card.removeEventListener('click', copyCardHandler);
card.addEventListener('click', copyCardHandler);
});
// Setup delete card events
const deleteCards = getButtonListByClassName('btn-delete');
Array.from(deleteCards).forEach((card: HTMLElement) => {
@@ -990,8 +1064,9 @@ function addFoodToView(foodData: FoodStorage, documentId: string) {
<div class="food-is-alkaline hidden">${foodData.alkaline ? 'alkaline' : ''}</div>
</div>
<div class="card-actions">
<span class="muted">${getIcon(foodFromDatabase.info.category)} ${foodFromDatabase.info.category}</span>
<span class="muted">${foodFromDatabase.info.category}</span>
<div>
<button class="btn btn-copy" data-food-id="${documentId}">Copy</button>
<button class="btn btn-edit" data-food-id="${documentId}">Edit</button>
<button class="btn btn-delete" data-food-id="${documentId}">Delete</button>
</div>
+9
View File
@@ -338,6 +338,15 @@ h1 {
background: #4834d4;
}
.btn-copy {
background: #2ed573;
color: white;
}
.btn-copy:hover {
background: #1dd1a1;
}
.empty-state {
text-align: center;
padding: 60px 20px;