Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions frontend/src/components/MealList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={component.base_calories}
onChange={(e) => updateComponentNutrition(idx, 'base_calories', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
<div>
Expand All @@ -880,7 +880,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={component.base_protein_g}
onChange={(e) => updateComponentNutrition(idx, 'base_protein_g', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
<div>
Expand All @@ -891,7 +891,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={component.base_carbs_g}
onChange={(e) => updateComponentNutrition(idx, 'base_carbs_g', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
<div>
Expand All @@ -902,7 +902,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={component.base_fat_g}
onChange={(e) => updateComponentNutrition(idx, 'base_fat_g', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
<div>
Expand All @@ -913,7 +913,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={component.base_fiber_g}
onChange={(e) => updateComponentNutrition(idx, 'base_fiber_g', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
</div>
Expand Down Expand Up @@ -1027,7 +1027,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={simpleMacros.base_calories}
onChange={(e) => updateSimpleMacro('base_calories', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
<div>
Expand All @@ -1038,7 +1038,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={simpleMacros.base_protein_g}
onChange={(e) => updateSimpleMacro('base_protein_g', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
<div>
Expand All @@ -1049,7 +1049,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={simpleMacros.base_carbs_g}
onChange={(e) => updateSimpleMacro('base_carbs_g', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
<div>
Expand All @@ -1060,7 +1060,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={simpleMacros.base_fat_g}
onChange={(e) => updateSimpleMacro('base_fat_g', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
<div>
Expand All @@ -1071,7 +1071,7 @@ export default function MealList({ refreshTrigger, onMealDeleted, onMealUpdated,
min="0"
value={simpleMacros.base_fiber_g}
onChange={(e) => updateSimpleMacro('base_fiber_g', e.target.value)}
className="w-full px-1 sm:px-2 py-1 border text-xs sm:text-sm text-white"
className={`w-full px-1 sm:px-2 py-1 border ${colors.inputBorder} ${colors.inputBg} text-xs sm:text-sm text-white`}
/>
</div>
</div>
Expand Down
84 changes: 84 additions & 0 deletions frontend/src/components/__tests__/MealList.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Tests for MealList component - edit mode input contrast (issue #3)
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import MealList from '../MealList';

// All vi.mock calls MUST use inline factory functions (no external const references),
// so shared fixtures go through vi.hoisted.
const { mockMeal, createBuilder } = vi.hoisted(() => {
const mockMeal = {
id: 'meal-1',
user_id: 'test-user-id',
meal_name: 'Grilled Chicken',
meal_type: 'lunch',
consumed_at: '2024-01-15T12:00:00.000Z',
total_calories: 200,
total_protein_g: 30,
total_carbs_g: 5,
total_fat_g: 8,
total_fiber_g: 2,
portion_size: null,
portion_unit: null,
is_compound: false,
notes: '',
};

const createBuilder = (result) => {
const builder = {};
['select', 'eq', 'gte', 'lte', 'order', 'limit', 'delete', 'insert', 'update'].forEach((fn) => {
builder[fn] = () => builder;
});
builder.single = () => Promise.resolve(result);
builder.then = (resolve, reject) => Promise.resolve(result).then(resolve, reject);
return builder;
};

return { mockMeal, createBuilder };
});

vi.mock('../../supabaseClient', () => ({
supabase: {
auth: {
getUser: vi.fn().mockResolvedValue({ data: { user: { id: 'test-user-id' } } }),
},
from: vi.fn((table) => {
if (table === 'meals') {
return createBuilder({ data: [mockMeal], error: null });
}
if (table === 'meal_components') {
return createBuilder({ data: [], error: null });
}
return createBuilder({ data: [], error: null });
}),
storage: {
from: vi.fn(() => ({
remove: vi.fn().mockResolvedValue({ data: null, error: null }),
})),
},
},
}));

describe('MealList - edit mode input contrast', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('gives every macro number input a dark background in manual edit mode', async () => {
render(<MealList />);

const editButton = await screen.findByRole('button', { name: 'Edit' });
fireEvent.click(editButton);

const editManuallyButton = await screen.findByText('Edit Manually');
fireEvent.click(editManuallyButton);

const numberInputs = screen.getAllByRole('spinbutton');
expect(numberInputs).toHaveLength(5);
numberInputs.forEach((input) => {
expect(input).toHaveClass('bg-black');
expect(input).toHaveClass('border-[#1a1a1a]');
});
});
});
1 change: 1 addition & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
body {
@apply bg-black text-white antialiased;
font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
color-scheme: dark;
}

h1, h2, h3, h4, h5, h6 {
Expand Down
Loading