Skip to content

Commit

Permalink
Added filtering by ingredients and allergens.
Browse files Browse the repository at this point in the history
  • Loading branch information
That-Thing committed Nov 8, 2024
1 parent 89dcb41 commit 34be636
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
10 changes: 10 additions & 0 deletions src/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,13 @@ a.text-light:hover {
color: var(--color-text);
border-color: var(--color-secondary-hover);
}

.exclude-tag {
max-width: 10em; /* Adjust width as needed */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
cursor: pointer;
}
55 changes: 53 additions & 2 deletions src/views/HomeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ const searchQuery = ref(''); // Search query
const selectedLabels = ref([]); // Selected labels for filtering
const showFilters = ref(false); // Toggle state for filters
// Custom tag filter state
const excludeTags = ref([]); // List of tags to exclude
const tagInput = ref(''); // Input field for new tag
// Fetch locations from the API
axios.get(`${API_URL}/locations`)
.then(response => {
Expand Down Expand Up @@ -121,7 +125,21 @@ const uniqueLabels = computed(() => {
return [...new Set(menuItems.value.flatMap(item => item.labels || []))];
});
// Filter items based on selected time, search query, and labels
// Add new tag to excludeTags when pressing Enter
const addTag = () => {
const tag = tagInput.value.trim();
if (tag && !excludeTags.value.includes(tag)) {
excludeTags.value.push(tag);
}
tagInput.value = ''; // Clear input after adding the tag
};
// Remove a tag from excludeTags
const removeTag = (tag) => {
excludeTags.value = excludeTags.value.filter(t => t !== tag);
};
// Filter menu items based on selectedTime, searchQuery, selectedLabels, and excludeTags
const filteredMenuItems = computed(() => {
return menuItems.value
.filter(item => item.time === selectedTime.value)
Expand All @@ -132,10 +150,23 @@ const filteredMenuItems = computed(() => {
.filter(item =>
// Check if item.labels contains all selected labels
selectedLabels.value.length === 0 || selectedLabels.value.every(label => (item.labels || []).includes(label))
)
.filter(item =>
// Exclude items that have any of the tags in excludeTags in either ingredients or allergens, case-insensitively and ignoring trailing asterisks
excludeTags.value.length === 0 || !excludeTags.value.some(tag => {
const lowercaseTag = tag.toLowerCase();
// Normalize ingredients and allergens by removing trailing asterisk and converting to lowercase
const ingredients = (item.ingredients || []).map(i => i.toLowerCase().replace(/\*$/, ''));
const allergens = (item.allergens || []).map(a => a.toLowerCase().replace(/\*$/, ''));
return ingredients.includes(lowercaseTag) || allergens.includes(lowercaseTag);
})
);
});
const paginationPages = computed(() => {
const pages = [];
const range = 2;
Expand Down Expand Up @@ -196,7 +227,6 @@ const toggleLabel = (label) => {
{{ showFilters ? 'Hide Filters' : 'Filters' }}
</button>
</div>

<!-- Filters -->
<div v-if="showFilters" class="mt-3">
<h6>Filter by Labels</h6>
Expand All @@ -211,6 +241,27 @@ const toggleLabel = (label) => {
{{ label }}
</label>
</div>
<!-- Exclude Tag Filter -->
<h6 class="mt-3">Exclude Ingredients/Allergens</h6>
<div class="d-flex gap-2 mb-3">
<input
type="text"
class="form-control"
placeholder="Type a tag and press Enter"
v-model="tagInput"
@keyup.enter="addTag"
/>
</div>
<div class="d-flex flex-wrap gap-2">
<span
v-for="tag in excludeTags"
:key="tag"
class="badge bg-danger exclude-tag"
@click="removeTag(tag)"
>
{{ tag }} <font-awesome-icon :icon="faTimes" />
</span>
</div>
</div>
</div>
</div>
Expand Down

0 comments on commit 34be636

Please sign in to comment.