Added category input component
This commit is contained in:
@@ -12,11 +12,12 @@ const route = useRoute()
|
||||
const worldId = route.params.id
|
||||
|
||||
const { setCalendarId, setMonths, setDefaultDate, currentConfig, selectedDate, jumpToDate } = useCalendar()
|
||||
const { setEvents } = useCalendarEvents()
|
||||
const { setEvents, setCategories } = useCalendarEvents()
|
||||
const { setCharacters } = useCharacters()
|
||||
|
||||
const { data: calendar, pending: calPending, refresh: calRefresh } = await useLazyFetch(`/api/calendars/query?world_id=${worldId}`)
|
||||
const { data: characters, pending: charPending, refresh: charRefresh } = await useLazyFetch(`/api/characters/query?world_id=${worldId}`)
|
||||
const { data: categories, pending: categoryPending, refresh: categoryRefresh } = await useLazyFetch(`/api/calendars/categories/query`)
|
||||
|
||||
if (!calendar.value) {
|
||||
await calRefresh()
|
||||
@@ -37,6 +38,15 @@ if (!calendar.value) {
|
||||
setEvents(calendar.value?.data?.events)
|
||||
}
|
||||
}
|
||||
|
||||
if (!categories.value) {
|
||||
await categoryRefresh()
|
||||
} else {
|
||||
if (categories.value?.data) {
|
||||
setCategories(categories.value?.data)
|
||||
}
|
||||
}
|
||||
|
||||
if (!characters.value) {
|
||||
await charRefresh()
|
||||
} else {
|
||||
@@ -61,6 +71,13 @@ watch(calPending, (newStatus) => {
|
||||
}
|
||||
}
|
||||
})
|
||||
watch(categoryPending, (newStatus) => {
|
||||
if (!newStatus) {
|
||||
if (categories.value?.data) {
|
||||
setCategories(categories.value?.data)
|
||||
}
|
||||
}
|
||||
})
|
||||
watch(charPending, (newStatus) => {
|
||||
if (!newStatus) {
|
||||
if (characters.value?.data) {
|
||||
@@ -103,7 +120,7 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<div class="h-full">
|
||||
<template v-if="calPending || charPending">
|
||||
<template v-if="calPending || charPending || categoryPending">
|
||||
<div class="h-full grid place-items-center">
|
||||
Loading notamment
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import type { RPGDate } from '~/models/Date';
|
||||
import { PopoverAnchor } from 'radix-vue';
|
||||
import { PhAlarm, PhCircleNotch, PhEye, PhEyeClosed, PhMapPinArea } from '@phosphor-icons/vue'
|
||||
import { PhAlarm, PhCircleNotch, PhEye, PhEyeClosed, PhMapPinArea, PhTag } from '@phosphor-icons/vue'
|
||||
|
||||
const { eventSkeleton, operationInProgress } = storeToRefs(useCalendarEvents())
|
||||
const { resetSkeleton, submitSkeleton, cancelLatestRequest } = useCalendarEvents()
|
||||
@@ -96,7 +96,7 @@ function handleCancel() {
|
||||
@pointer-down-outside="handleClosing"
|
||||
>
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<div class="grid grid-cols-2 gap-y-6">
|
||||
<div class="grid grid-cols-2 gap-y-3">
|
||||
<div class="col-span-2 pl-8">
|
||||
<input
|
||||
id="new-event-title"
|
||||
@@ -140,6 +140,14 @@ function handleCancel() {
|
||||
</div>
|
||||
|
||||
<div class="col-span-2">
|
||||
<div class="flex items-center gap-4">
|
||||
<PhTag size="18" weight="fill" />
|
||||
|
||||
<CalendarInputEventCategories v-model="eventSkeleton.category" placeholder="Ajouter une catégorie principale" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-2 mb-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<PhMapPinArea size="18" weight="fill" />
|
||||
|
||||
@@ -149,7 +157,7 @@ function handleCancel() {
|
||||
type="text"
|
||||
name="new-event-location"
|
||||
placeholder="Ajouter un endroit"
|
||||
class="w-full -my-1 py-1 px-2 text-sm border-b-[1px] bg-transparent focus-visible:outline-none focus-visible:border-blue-600">
|
||||
class="w-full -my-1 py-2 px-2 text-sm border-b-[1px] bg-transparent focus-visible:outline-none focus-visible:border-blue-600">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { PhAlarm, PhCircleNotch, PhEye, PhEyeClosed, PhMapPinArea, PhPencilSimpleLine } from '@phosphor-icons/vue'
|
||||
import { PhAlarm, PhCircleNotch, PhEye, PhEyeClosed, PhMapPinArea, PhPencilSimpleLine, PhTag } from '@phosphor-icons/vue'
|
||||
import { VisuallyHidden } from 'radix-vue'
|
||||
|
||||
const { isEditEventModalOpen } = storeToRefs(useCalendarEvents())
|
||||
@@ -81,7 +81,7 @@ function handleCancel() {
|
||||
</VisuallyHidden>
|
||||
|
||||
<form @submit.prevent="handleAction">
|
||||
<div class="grid grid-cols-2 gap-y-6">
|
||||
<div class="grid grid-cols-2 gap-y-3">
|
||||
<div class="col-span-2">
|
||||
<div class="flex items-center gap-4">
|
||||
<PhPencilSimpleLine size="20" weight="fill" />
|
||||
@@ -130,6 +130,14 @@ function handleCancel() {
|
||||
</div>
|
||||
|
||||
<div class="col-span-2">
|
||||
<div class="flex items-center gap-4">
|
||||
<PhTag size="18" weight="fill" />
|
||||
|
||||
<CalendarInputEventCategories v-model="eventSkeleton.category" placeholder="Ajouter une catégorie principale" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-2 mb-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<PhMapPinArea size="18" weight="fill" />
|
||||
|
||||
@@ -139,7 +147,7 @@ function handleCancel() {
|
||||
type="text"
|
||||
name="new-event-location"
|
||||
placeholder="Ajouter un endroit"
|
||||
class="w-full -my-1 py-1 px-2 text-sm border-b-[1px] bg-transparent focus-visible:outline-none focus-visible:border-blue-600">
|
||||
class="w-full -my-1 py-2 px-2 text-sm border-b-[1px] bg-transparent focus-visible:outline-none focus-visible:border-blue-600">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
72
components/calendar/input/EventCategories.vue
Normal file
72
components/calendar/input/EventCategories.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<script lang="ts" setup>
|
||||
import { PhCaretDown } from '@phosphor-icons/vue';
|
||||
import type { Category } from '~/models/Category';
|
||||
|
||||
const props = defineProps<{
|
||||
placeholder?: string
|
||||
multiple?: boolean
|
||||
}>()
|
||||
|
||||
const model = defineModel<Category[] | Category>()
|
||||
|
||||
const { categories: availableCategories } = useCalendarEvents()
|
||||
|
||||
const isPopoverOpen = ref<boolean>(false)
|
||||
|
||||
function handleCatSelect() {
|
||||
if (!props.multiple) {
|
||||
isPopoverOpen.value = false
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UiPopover v-model:open="isPopoverOpen">
|
||||
<UiPopoverTrigger as-child>
|
||||
<UiButton
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
class="w-fit max-w-full justify-between capitalize"
|
||||
>
|
||||
{{ computedTextValue }}
|
||||
|
||||
<PhCaretDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</UiButton>
|
||||
</UiPopoverTrigger>
|
||||
<UiPopoverContent
|
||||
:align="'start'"
|
||||
class="w-fit p-0"
|
||||
>
|
||||
<UiCommand v-model="model" :multiple>
|
||||
<UiCommandInput placeholder="Rechercher les catégories" />
|
||||
<UiCommandEmpty>Aucune catégorie trouvée.</UiCommandEmpty>
|
||||
<UiCommandList>
|
||||
<UiCommandGroup>
|
||||
<UiCommandItem
|
||||
v-for="category in availableCategories"
|
||||
:key="category.id"
|
||||
:value="category"
|
||||
@select="handleCatSelect"
|
||||
>
|
||||
<span class="capitalize">
|
||||
{{ category.name }}
|
||||
</span>
|
||||
</UiCommandItem>
|
||||
</UiCommandGroup>
|
||||
</UiCommandList>
|
||||
</UiCommand>
|
||||
</UiPopoverContent>
|
||||
</UiPopover>
|
||||
</template>
|
||||
Reference in New Issue
Block a user