Separated multi and single category component

I also disabled secondary categories because they shouldn't be used right now, it adds too much complexity
This commit is contained in:
Alexis
2024-06-11 21:38:47 +02:00
parent 23365d6324
commit fe8ab76aaf
4 changed files with 126 additions and 28 deletions

View File

@@ -142,10 +142,18 @@ function handleCancel() {
<div class="flex items-center gap-4">
<PhTag size="18" weight="fill" />
<CalendarInputEventCategories v-model="eventSkeleton.category" placeholder="Ajouter une catégorie principale" />
<CalendarInputEventCategory v-model="eventSkeleton.category" placeholder="Ajouter une catégorie principale" />
</div>
</div>
<!-- <div class="col-span-2">
<div class="flex items-center gap-4">
<PhTag size="18" weight="fill" />
<CalendarInputEventCategories v-model="eventSkeleton.secondaryCategories" placeholder="Ajouter des catégories secondaires" />
</div>
</div> -->
<div class="col-span-2 mb-2">
<div class="flex items-center gap-4">
<PhMapPinArea size="18" weight="fill" />

View File

@@ -133,10 +133,22 @@ function handleCancel() {
<div class="flex items-center gap-4">
<PhTag size="18" weight="fill" />
<CalendarInputEventCategories v-model="eventSkeleton.category" placeholder="Ajouter une catégorie principale" />
<div class="w-1/2">
<CalendarInputEventCategory v-model="eventSkeleton.category" placeholder="Ajouter une catégorie principale" />
</div>
</div>
</div>
<!-- <div class="col-span-2">
<div class="flex items-center gap-4">
<PhTag size="18" weight="fill" />
<div class="w-1/2">
<CalendarInputEventCategories v-model="eventSkeleton.secondaryCategories" placeholder="Ajouter des catégories secondaires" />
</div>
</div>
</div> -->
<div class="col-span-2 mb-2">
<div class="flex items-center gap-4">
<PhMapPinArea size="18" weight="fill" />

View File

@@ -1,38 +1,26 @@
<script lang="ts" setup>
import { PhCaretDown } from '@phosphor-icons/vue';
import { cn } from '@/lib/utils'
import type { Category } from '~/models/Category';
import { PhCaretDown, PhCheck } from '@phosphor-icons/vue';
const isPopoverOpen = ref<boolean>(false)
const props = defineProps<{
placeholder?: string
multiple?: boolean
}>()
const computedTextValue = computed(() => {
if (model.value) {
if ("name" in model.value) {
return model.value.name
} else {
return model.value[0].name
}
} else {
return props.placeholder
}
})
const model = defineModel<Category[]>({ default: [] })
const modelBuffer = ref<Category[]>([])
const model = defineModel<Category[] | Category>()
watch(modelBuffer.value, () => {
model.value = [ ...modelBuffer.value ]
})
const { categories: availableCategories } = useCalendarEvents()
const searchTerm = ref<string>('')
function handleCatSelect() {
if (!props.multiple) {
isPopoverOpen.value = false
}
}
const filteredCategories = computed(() =>
searchTerm.value === ''
? availableCategories
@@ -48,9 +36,20 @@ const filteredCategories = computed(() =>
<UiButton
variant="outline"
role="combobox"
class="w-fit max-w-full justify-between"
class="relative w-full max-w-full h-fit justify-between"
>
{{ computedTextValue }}
<template v-if="!model.length">
{{ props.placeholder }}
</template>
<template v-else>
<ul class="flex flex-wrap gap-1">
<li v-for="category in model" :key="`selected-cat-${category.id}`">
<UiBadge class="lowercase" variant="secondary">
{{ category.name }}
</UiBadge>
</li>
</ul>
</template>
<PhCaretDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
</UiButton>
@@ -61,7 +60,7 @@ const filteredCategories = computed(() =>
:collision-padding="50"
class="w-fit h-[33vh] p-0"
>
<UiCommand v-model="model" v-model:searchTerm="searchTerm" :multiple>
<UiCommand v-model="modelBuffer" v-model:searchTerm="searchTerm" :multiple="true">
<UiCommandInput placeholder="Rechercher les catégories" />
<UiCommandEmpty>Aucune catégorie trouvée.</UiCommandEmpty>
<UiCommandList>
@@ -70,10 +69,16 @@ const filteredCategories = computed(() =>
v-for="category in filteredCategories"
:key="category.id"
:value="category"
class="cursor-pointer"
@select="handleCatSelect"
class="cursor-pointer flex justify-between items-center"
:class="cn({
})"
>
{{ category.name }}
<span>
{{ category.name }}
</span>
<PhCheck v-if="model.find(cat => cat.id === category.id)" />
</UiCommandItem>
</UiCommandGroup>
</UiCommandList>

View File

@@ -0,0 +1,73 @@
<script lang="ts" setup>
import { PhCaretDown } from '@phosphor-icons/vue';
import type { Category } from '~/models/Category';
const isPopoverOpen = ref<boolean>(false)
const props = defineProps<{
placeholder?: string
}>()
const model = defineModel<Category>()
const { categories: availableCategories } = useCalendarEvents()
const searchTerm = ref<string>('')
function handleCatSelect() {
isPopoverOpen.value = false
}
const filteredCategories = computed(() =>
searchTerm.value === ''
? availableCategories
: availableCategories.filter((category) => {
return category.name.toLowerCase().includes(searchTerm.value.toLowerCase())
})
)
</script>
<template>
<UiPopover v-model:open="isPopoverOpen">
<UiPopoverTrigger as-child>
<UiButton
variant="outline"
role="combobox"
class="w-full max-w-full justify-between"
>
<template v-if="!model">
{{ props.placeholder }}
</template>
<template v-else>
{{ model.name }}
</template>
<PhCaretDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
</UiButton>
</UiPopoverTrigger>
<UiPopoverContent
align="start"
side="bottom"
:collision-padding="50"
class="w-fit h-[33vh] p-0"
>
<UiCommand v-model="model" v-model:searchTerm="searchTerm">
<UiCommandInput placeholder="Rechercher les catégories" />
<UiCommandEmpty>Aucune catégorie trouvée.</UiCommandEmpty>
<UiCommandList>
<UiCommandGroup>
<UiCommandItem
v-for="category in filteredCategories"
:key="category.id"
:value="category"
class="cursor-pointer"
@select="handleCatSelect"
>
{{ category.name }}
</UiCommandItem>
</UiCommandGroup>
</UiCommandList>
</UiCommand>
</UiPopoverContent>
</UiPopover>
</template>