feat: integrate TagBadge and TagPicker in inventory (#28 #29)
Some checks failed
Deploy to Coolify / Code Quality (pull_request) Has been cancelled
Deploy to Coolify / Run Tests (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Development (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Production (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Test (pull_request) Has been cancelled
Pull Request Checks / Validate PR (pull_request) Has been cancelled

Issue #28 - Tag assignment in AddItemForm:
- Replace custom tag selection with TagPicker component
- Simplified code (removed manual tag state management)
- Cleaner UI with reusable component

Issue #29 - Display tags in InventoryList:
- Replace UBadge with TagBadge in InventoryCard
- Automatic contrast color for readability
- Consistent tag display across app

Closes #28, #29
This commit is contained in:
Pantry Lead Agent
2026-02-24 00:05:44 +00:00
parent 6b1c34ceff
commit 080d2424c8
2 changed files with 8 additions and 81 deletions

View File

@@ -68,37 +68,7 @@
<!-- Tags --> <!-- Tags -->
<UFormGroup label="Tags" hint="Optional"> <UFormGroup label="Tags" hint="Optional">
<div class="space-y-2"> <TagsTagPicker v-model="selectedTags" />
<!-- Selected Tags -->
<div v-if="selectedTags.length > 0" class="flex flex-wrap gap-1 mb-2">
<UBadge
v-for="tag in selectedTags"
:key="tag.id"
:style="{ backgroundColor: tag.color }"
class="text-white cursor-pointer"
@click="removeTag(tag.id)"
>
{{ tag.icon }} {{ tag.name }}
</UBadge>
</div>
<!-- Tag Selection by Category -->
<div v-for="category in tagCategories" :key="category.name" class="space-y-1">
<p class="text-xs font-medium text-gray-500 uppercase">{{ category.name }}</p>
<div class="flex flex-wrap gap-1">
<UButton
v-for="tag in category.tags"
:key="tag.id"
size="xs"
:color="isTagSelected(tag.id) ? 'primary' : 'gray'"
:variant="isTagSelected(tag.id) ? 'solid' : 'outline'"
@click="toggleTag(tag)"
>
{{ tag.icon }} {{ tag.name }}
</UButton>
</div>
</div>
</div>
</UFormGroup> </UFormGroup>
<!-- Submit --> <!-- Submit -->
@@ -129,7 +99,6 @@
<script setup lang="ts"> <script setup lang="ts">
const { addInventoryItem, addItemTags } = useInventory() const { addInventoryItem, addItemTags } = useInventory()
const { getUnits } = useUnits() const { getUnits } = useUnits()
const { getTags } = useTags()
const props = defineProps<{ const props = defineProps<{
initialData?: { initialData?: {
@@ -158,18 +127,12 @@ const form = reactive({
const submitting = ref(false) const submitting = ref(false)
const selectedTags = ref<any[]>([]) const selectedTags = ref<any[]>([])
// Load units and tags // Load units
const units = ref<any[]>([]) const units = ref<any[]>([])
const tags = ref<any[]>([])
onMounted(async () => { onMounted(async () => {
const [unitsResult, tagsResult] = await Promise.all([ const unitsResult = await getUnits()
getUnits(),
getTags()
])
units.value = unitsResult.data || [] units.value = unitsResult.data || []
tags.value = tagsResult.data || []
// Set default unit (Piece) // Set default unit (Piece)
const defaultUnit = units.value.find(u => u.abbreviation === 'pc') const defaultUnit = units.value.find(u => u.abbreviation === 'pc')
@@ -231,39 +194,6 @@ const unitOptions = computed(() => {
]) ])
}) })
// Tag categories for display
const tagCategories = computed(() => {
const categories: Record<string, any[]> = {}
for (const tag of tags.value) {
const cat = tag.category
if (!categories[cat]) categories[cat] = []
categories[cat].push(tag)
}
return Object.entries(categories).map(([name, tags]) => ({
name,
tags
}))
})
// Tag selection helpers
const isTagSelected = (tagId: string) => {
return selectedTags.value.some(t => t.id === tagId)
}
const toggleTag = (tag: any) => {
if (isTagSelected(tag.id)) {
removeTag(tag.id)
} else {
selectedTags.value.push(tag)
}
}
const removeTag = (tagId: string) => {
selectedTags.value = selectedTags.value.filter(t => t.id !== tagId)
}
// Validation // Validation
const isValid = computed(() => { const isValid = computed(() => {
return form.name.trim().length > 0 && form.quantity > 0 && form.unit_id return form.name.trim().length > 0 && form.quantity > 0 && form.unit_id

View File

@@ -50,15 +50,12 @@
<!-- Tags --> <!-- Tags -->
<div v-if="item.tags && item.tags.length > 0" class="flex flex-wrap gap-1"> <div v-if="item.tags && item.tags.length > 0" class="flex flex-wrap gap-1">
<UBadge <TagsTagBadge
v-for="tagItem in item.tags.slice(0, 3)" v-for="tagItem in item.tags.slice(0, 3)"
:key="tagItem.tag.id" :key="tagItem.tag.id"
:style="{ backgroundColor: tagItem.tag.color }" :tag="tagItem.tag"
size="xs" size="sm"
class="text-white" />
>
{{ tagItem.tag.icon }} {{ tagItem.tag.name }}
</UBadge>
<UBadge v-if="item.tags.length > 3" size="xs" color="gray"> <UBadge v-if="item.tags.length > 3" size="xs" color="gray">
+{{ item.tags.length - 3 }} +{{ item.tags.length - 3 }}
</UBadge> </UBadge>