No foods found. Try a different search term.
';
+ getDivById('searchResults').innerHTML = 'No foods found. Try a different search term.
';
} else {
- const icons = {
- 'fats': '🥑 🍳 🍟',
- 'proteins': '🫘 🥩 🥚',
- 'carbs (high)': '🍞 🥔 🍠',
- 'leaves': '🥬 🥗 🌿',
- 'fruits': '🍊 🍇 🍎',
- 'carbs (low)': '🥦 🍅 🍓',
- 'dairy': '🧀 🧈 🥛'
- };
-
- searchResults.innerHTML = results.map((food, index) => `
+ getDivById('searchResults').innerHTML = results.map((food, index) => `
-
${icons[food.info.category]} ${food.name}
+
${getIcon(food.info.category)} ${food.name}
${food.info.category} • 100 g
${food.info.calories} cal
@@ -594,42 +481,16 @@ function displaySearchResults(results: FoodItem[]) {
`).join('');
}
- searchResults.classList.add('show');
- currentHighlightIndex = -1;
+ getDivById('searchResults').classList.add('show');
+ appState.currentHighlightIndex = -1;
}
-// Navigate results with keyboard
-function navigateResults(direction: number) {
- const items = searchResults.querySelectorAll('.search-result-item');
- if (items.length === 0) return;
-
- // Remove current highlight
- if (currentHighlightIndex >= 0) {
- items[currentHighlightIndex].classList.remove('highlighted');
- }
-
- // Calculate new index
- currentHighlightIndex += direction;
- if (currentHighlightIndex < 0) currentHighlightIndex = items.length - 1;
- if (currentHighlightIndex >= items.length) currentHighlightIndex = 0;
-
- // Add new highlight
- items[currentHighlightIndex].classList.add('highlighted');
- items[currentHighlightIndex].scrollIntoView({ block: 'nearest' });
-}
-
-// Select food
function selectFood(food: FoodItem) {
selectedFood = food;
- // Clear search and hide results
- searchInput.value = food.name;
- hideSearchResults();
-
- // Focus on quantity input
+ getInputById('foodSearchInput').value = food.name;
+ hideSearchResults();
getInputById('gramAmount').focus();
-
- // Update calories
previewCalories(food);
}
@@ -648,7 +509,7 @@ async function setFoodToEdit(foodId: string) {
// set the selected food name and quantity
const foodData: FoodItem = getFoodItemByName(foodToEdit[0].name);
selectedFood = foodData;
- searchInput.value = foodToEdit[0].name;
+ getInputById('foodSearchInput').value = foodToEdit[0].name;
getInputById('gramAmount').value = foodToEdit[0].grams;
previewCalories(foodData)
@@ -676,25 +537,6 @@ async function setFoodToEdit(foodId: string) {
}
}
-// Hide search results
-function hideSearchResults() {
- searchResults.classList.remove('show');
- currentHighlightIndex = -1;
-}
-
-function toggleCardHandler(e: Event) {
- e.preventDefault();
- e.stopPropagation();
-
- const card = e.currentTarget as HTMLElement;
- card.classList.toggle('expanded');
-
- const cardDetails = card.nextElementSibling as HTMLElement;
- if (cardDetails && cardDetails.classList.contains('card-details')) {
- cardDetails.classList.toggle('expanded');
- }
-}
-
function deleteCardHandler(e: Event) {
e.preventDefault();
e.stopPropagation();
@@ -719,7 +561,7 @@ function editCardHandler(e: Event) {
}
}
-const addDeleteEvents = () => {
+const setupEditAndDeleteEvents = () => {
// Setup toggle show cards events
const cards = getButtonListByClassName('card-header-toggle');
Array.from(cards).forEach((card: HTMLElement) => {
@@ -742,7 +584,6 @@ const addDeleteEvents = () => {
});
}
-// Update current date display
const updateCurrentDate = () => {
const date = new Date(selectedDate);
getDivById('currentDate').textContent = date.toLocaleDateString('en-US', {
@@ -805,7 +646,7 @@ const updateFood = async () => {
const monthlyUpdated = await AppwriteDB.updateMonthlyCaloryForDay(monthlyDocumentId?.documentId, selectedDate, totalCalories);
updateDocumentIdForToday(monthlyUpdated.$id, monthlyUpdated.totalCalories);
}
- delay(1);
+ delay(QUICK_DELAY);
clearEditing();
selectDate(selectedDate);
} catch (error) {
@@ -818,7 +659,7 @@ const updateFood = async () => {
const getDocumentIdForToday = (): DailyTotalCalories | null => {
const today = selectedDate.getDate();
- const todayRecord = calendarMonthlyCalories.filter(x => x.day === today);
+ const todayRecord = appState.calendarMonthlyCalories.filter(x => x.day === today);
if (todayRecord.length > 0) {
return todayRecord[0];
}
@@ -826,7 +667,7 @@ const getDocumentIdForToday = (): DailyTotalCalories | null => {
}
const getDocumentIdForDay = (day: number): number => {
- const todayRecord = calendarMonthlyCalories.filter(x => x.day === day);
+ const todayRecord = appState.calendarMonthlyCalories.filter(x => x.day === day);
return todayRecord.length > 0 ? todayRecord[0].totalCalories : 0;
}
@@ -836,15 +677,15 @@ const updateDocumentIdForToday = (id: string, totalCalories: number): void => {
}
const updateDocumentIdForDay = (id: string, totalCalories: number, day: number): void => {
- const record = calendarMonthlyCalories.filter(x => x.day === day);
+ const record = appState.calendarMonthlyCalories.filter(x => x.day === day);
if (record.length === 0) {
- calendarMonthlyCalories.push({
+ appState.calendarMonthlyCalories.push({
documentId: id,
day: day,
totalCalories: totalCalories
});
- } else {
- calendarMonthlyCalories.forEach((record) => {
+ } else {
+ appState.calendarMonthlyCalories.forEach((record) => {
if (record.day === day) {
record.documentId = id;
record.totalCalories = totalCalories;
@@ -853,7 +694,6 @@ const updateDocumentIdForDay = (id: string, totalCalories: number, day: number):
}
}
-// Add food to the log
const addFood = async () => {
if (!currentUser) {
swal('Hey!', 'Please log in to add food entries.', 'info');
@@ -911,11 +751,8 @@ const addFood = async () => {
updateDocumentIdForToday(monthlyCreated.$id, monthlyCreated.totalCalories);
}
- // Add to HTML table with Appwrite document ID
- addFoodToTable(entry, savedEntry.$id);
-
- // Update totals
- updateTotalCalories([savedEntry]);
+ addFoodToView(entry, savedEntry.$id);
+ updateTotalCalories();
// Update total macros
const proteinDiv: HTMLElement = getDivById('proteinValue');
@@ -938,7 +775,7 @@ const addFood = async () => {
getInputById('foodSearchInput').value = '';
gramAmount.value = '100';
showFoodPreview(false);
- await delay(1);
+ await delay(QUICK_DELAY);
renderCalendar();
} catch (error) {
console.error('Add food error:', error);
@@ -948,7 +785,7 @@ const addFood = async () => {
}
}
-// Load food entries from Appwrite
+// Load food entries from Appwrite for a given date
async function loadFoodEntries(date: Date) {
if (!currentUser) return;
@@ -957,7 +794,6 @@ async function loadFoodEntries(date: Date) {
try {
const entries = await AppwriteDB.getFoodEntries(date);
- // Clear current table
getDivById('foodCardsContainer').innerHTML = '';
// Add each entry to table
@@ -975,8 +811,8 @@ async function loadFoodEntries(date: Date) {
date: entry.date,
alkaline: entry.alkaline,
};
-
- addFoodToTable(foodData, entry.$id);
+
+ addFoodToView(foodData, entry.$id);
});
if (entries.length === 0) {
@@ -989,11 +825,8 @@ async function loadFoodEntries(date: Date) {
`;
}
- // Setup Delete events
- addDeleteEvents();
-
- // Update total calories
- updateTotalCalories(entries);
+ setupEditAndDeleteEvents();
+ updateTotalCalories();
// Update counters
let totalCalories = 0;
@@ -1063,8 +896,6 @@ async function loadFoodEntries(date: Date) {
}
}
-const delay = (seconds: number) => new Promise(resolve => setTimeout(resolve, seconds * 1000));
-
// Handle food deletion
async function handleDeleteFood(documentId: string) {
if (!documentId) return;
@@ -1101,7 +932,7 @@ async function handleDeleteFood(documentId: string) {
const totalCalories = monthlyDocumentId?.totalCalories - existingToDelete;
const monthlyCreated = await AppwriteDB.updateMonthlyCaloryForDay(monthlyDocumentId?.documentId, selectedDate, totalCalories);
updateDocumentIdForToday(monthlyCreated.$id, monthlyCreated.totalCalories);
- await delay(1);
+ await delay(QUICK_DELAY);
}
selectDate(selectedDate);
@@ -1113,8 +944,7 @@ async function handleDeleteFood(documentId: string) {
}
}
-// Add food to table (existing function - update to use document ID)
-function addFoodToTable(foodData: FoodStorage, documentId: string) {
+function addFoodToView(foodData: FoodStorage, documentId: string) {
// New Food card
const container = getDivById('foodCardsContainer');
const card = document.createElement('div');
@@ -1125,6 +955,8 @@ function addFoodToTable(foodData: FoodStorage, documentId: string) {
container.innerHTML = '';
}
+ const foodFromDatabase = getFoodItemByName(foodData.name);
+
card.innerHTML = `
@@ -1167,12 +1002,12 @@ function addFoodToTable(foodData: FoodStorage, documentId: string) {
container?.appendChild(card);
- // Setup Delete events
- addDeleteEvents();
+ setupEditAndDeleteEvents();
}
-// Update total calories
-function updateTotalCalories(entries: Models.DefaultDocument[]) {
+// Update total calories and display it in the counter
+// Also updates alkaline level percentage
+function updateTotalCalories() {
const caloriesDiv = document.querySelectorAll('.calories-display');
let total = 0;
diff --git a/src/state.ts b/src/state.ts
new file mode 100644
index 0000000..4161ba2
--- /dev/null
+++ b/src/state.ts
@@ -0,0 +1,15 @@
+import { DailyTotalCalories, FoodItem } from "./types";
+
+interface AppState {
+ currentHighlightIndex: number;
+ searchTimeout: number | null;
+ searchResults: FoodItem[];
+ calendarMonthlyCalories: DailyTotalCalories[];
+}
+
+export const appState: AppState = {
+ currentHighlightIndex: -1,
+ searchTimeout: null,
+ searchResults: [],
+ calendarMonthlyCalories: []
+};
diff --git a/style.css b/style.css
index 8f5f69d..fd7ba5d 100644
--- a/style.css
+++ b/style.css
@@ -305,7 +305,7 @@ h1 {
.card-actions {
display: flex;
- justify-content: flex-end;
+ justify-content: space-between;
gap: 8px;
padding-top: 16px;
border-top: 1px solid #e0e0e0;