diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2024-03-12 19:18:52 +0000 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2024-03-12 19:18:52 +0000 |
| commit | a4052ffee8bc7c6c8a69eba5120b5c6c2d951b0f (patch) | |
| tree | 970921e587c0972ed4bf8a82a18bbad8dee10458 /components | |
| parent | addf95bc7e1e694cd9ba7797c8b0847bfecaf54c (diff) | |
Add items
Diffstat (limited to 'components')
| -rw-r--r-- | components/base/ItemStack/ItemStackModal.vue | 19 | ||||
| -rw-r--r-- | components/base/ItemStack/ItemStackPicker.vue | 3 | ||||
| -rw-r--r-- | components/editor/EditorSidebar.vue | 16 | ||||
| -rw-r--r-- | components/editor/EditorSidebarItem.vue | 66 | ||||
| -rw-r--r-- | components/editor/task/EditorTaskConfigurationRow.vue | 2 | ||||
| -rw-r--r-- | components/header/PageHeader.vue | 56 |
6 files changed, 157 insertions, 5 deletions
diff --git a/components/base/ItemStack/ItemStackModal.vue b/components/base/ItemStack/ItemStackModal.vue index 7cf4db9..865c054 100644 --- a/components/base/ItemStack/ItemStackModal.vue +++ b/components/base/ItemStack/ItemStackModal.vue @@ -3,12 +3,11 @@ import { computed, ref } from 'vue'; import materials from '@/lib/materials'; const model = defineModel(); - const emit = defineEmits(['confirm']); - const props = defineProps<{ value: any }>(); +const session = useSessionStore(); //TODO unshitify const value = ref<any>(props.value); @@ -42,6 +41,17 @@ const selectedType = ref( const noTypeSelected = computed(() => selectedType.value === ''); const noValue = computed(() => !isQuestItem.value && !isItemStack.value && !isMaterial.value); +const selectedQuestItem = computed({ + get() { + return value.value?.['quest-item']; + }, + set(newValue: string) { + value.value = {} + value.value['quest-item'] = newValue; + } +}) +const knownQuestItems = computed(() => { return session.session.items.map((item) => item.id) }); + const setSelectedType = (type: string) => { if (type === 'questitem') { value.value = {}; @@ -98,6 +108,11 @@ const confirm = () => { <ItemStackForm v-model="value" /> </div> + <div id="quest-item" class="option-group" v-if="selectedType === 'questitem'"> + <label for="quest-item">Quest Item</label> + <multiselect v-model="selectedQuestItem" :options="knownQuestItems" :searchable="true" + placeholder="Enter quest item" /> + </div> <div id="confirm" class="control-group"> <Button :icon="['fas', 'times']" :label="'Cancel'" @click="model = false"></Button> diff --git a/components/base/ItemStack/ItemStackPicker.vue b/components/base/ItemStack/ItemStackPicker.vue index bb0b84d..2dc35d3 100644 --- a/components/base/ItemStack/ItemStackPicker.vue +++ b/components/base/ItemStack/ItemStackPicker.vue @@ -49,7 +49,8 @@ const update = (newValue: any) => { <template> <div class="itemstack" @click="showItemStackModal = true"> <span v-if="empty" class="empty">ItemStack...</span> - <span v-if="isQuestItem" class="item"><font-awesome-icon :icon="['fas', 'tag']" /> Quest Item</span> + <span v-if="isQuestItem" class="item"><font-awesome-icon :icon="['fas', 'tag']" /> Quest Item: {{ + value['quest-item'] }}</span> <span v-if="isItemStack" class="item"><font-awesome-icon :icon="['fas', 'cube']" /> ItemStack: {{ value.type || value.item || value.material }}</span> <span v-if="isMaterial" class="item"><font-awesome-icon :icon="['fas', 'apple-whole']" /> {{ value }}</span> diff --git a/components/editor/EditorSidebar.vue b/components/editor/EditorSidebar.vue index 992dd86..48e187f 100644 --- a/components/editor/EditorSidebar.vue +++ b/components/editor/EditorSidebar.vue @@ -24,7 +24,7 @@ const setSelectedType = (type: 'quests' | 'items') => { </span> <span class="option" @click="setSelectedType('items')" :class="{ selected: currentType === 'items' }"> <span> - <font-awesome-icon :icon="['fas', 'cube']" /> + <font-awesome-icon :icon="['fas', 'cubes']" /> Items </span> </span> @@ -34,6 +34,13 @@ const setSelectedType = (type: 'quests' | 'items') => { <EditorSidebarQuest v-for="quest in session.quests.filter((q) => (!session.categories.some((c) => c.id === q.options.category)))" :key="quest.id" :quest="quest" /> + <p id="count">{{ session.quests.length }} quest{{ session.quests.length === 1 ? '' : 's' }}, {{ + session.categories.length }} + categor{{ session.categories.length === 1 ? 'y' : 'ies' }}</p> + </div> + <div id="items" v-if="currentType === 'items'"> + <EditorSidebarItem v-for="item in session.items" :key="item.id" :item="item" /> + <p id="count">{{ session.items.length }} item{{ session.items.length === 1 ? '' : 's' }}</p> </div> <div id="configuration-container"> <EditorSidebarMainConfiguration /> @@ -99,5 +106,12 @@ const setSelectedType = (type: 'quests' | 'items') => { bottom: 0; width: 100% } + + #count { + margin: 0.5rem 0; + font-size: 0.7rem; + text-align: center; + color: var(--color-text-mute); + } } </style>
\ No newline at end of file diff --git a/components/editor/EditorSidebarItem.vue b/components/editor/EditorSidebarItem.vue new file mode 100644 index 0000000..4696bb1 --- /dev/null +++ b/components/editor/EditorSidebarItem.vue @@ -0,0 +1,66 @@ +<script setup lang="ts"> +import { computed, toRefs } from 'vue'; + +const props = defineProps<{ + item: EditorItem; +}>(); + +const { item } = toRefs(props); + +const route = useRoute(); + +const setSelectedItem = () => { + navigateTo({ path: `/item/${item.value.id}` }) +}; + +const selected = computed(() => { + return route.path.startsWith('/item') && route.params.id === item.value.id; +}); +</script> + +<template> + <div id="item-container" @click.stop="setSelectedItem" :class="{ selected: selected }"> + <span id="item-title"> + <font-awesome-icon class="item-icon" :icon="['fas', 'cube']" /> + <span id="item-name"> + <span id="item-display-id">{{ item.id }}</span> + <code id="item-display-type">{{ item.type }}</code> + </span> + </span> + </div> +</template> + +<style scoped> +#item-container { + cursor: pointer; + padding: 0.3rem 1rem; + transition: background-color 0.3s; + + #item-title { + display: flex; + align-items: center; + margin: 0; + gap: 0.6rem; + font-size: 0.8rem; + + #item-name { + display: flex; + flex-direction: column; + align-items: left; + + #item-display-type { + font-size: 0.6rem; + color: var(--color-text-mute); + } + } + } +} + +.selected { + background-color: var(--color-primary-mute) !important; +} + +#item-container:hover { + background-color: var(--color-hover); +} +</style>
\ No newline at end of file diff --git a/components/editor/task/EditorTaskConfigurationRow.vue b/components/editor/task/EditorTaskConfigurationRow.vue index 666669d..c00896f 100644 --- a/components/editor/task/EditorTaskConfigurationRow.vue +++ b/components/editor/task/EditorTaskConfigurationRow.vue @@ -41,7 +41,7 @@ if (props.initialValue !== currentValue.value) { emit('update', currentValue.value); } -const error = computed(() => currentValue.value === undefined || currentValue.value === null || currentValue.value === '' || (Array.isArray(currentValue.value) && currentValue.value.length === 0)); +const error = computed(() => currentValue.value === undefined || currentValue.value === null || currentValue.value === '' || (Array.isArray(currentValue.value) && currentValue.value.length === 0) || (typeof currentValue.value === 'object' && Object.keys(currentValue.value).length === 0)); const updateValue = (value: any) => { currentValue.value = value; }; diff --git a/components/header/PageHeader.vue b/components/header/PageHeader.vue new file mode 100644 index 0000000..3c616ca --- /dev/null +++ b/components/header/PageHeader.vue @@ -0,0 +1,56 @@ +<template> + <div id="header"> + <slot /> + </div> +</template> + +<style lang="scss"> +#header { + padding: 1rem 1rem 0.5rem 1rem; + background-color: var(--color-background); + border-bottom: 1px solid var(--color-border); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + width: 100%; + height: 55px; + display: flex; + align-items: left; + justify-content: space-between; + gap: 1rem; + position: relative; + z-index: 0; + + #path { + font-size: 1.2rem; + display: flex; + gap: 0.5rem; + align-items: center; + + .icon { + font-size: 0.8rem; + } + + .chevron { + font-size: 0.8rem; + color: var(--color-text-mute); + } + + .title { + font-weight: 700; + } + + code { + font-size: 0.8rem; + color: var(--color-text-mute); + } + } +} + +.none-selected { + display: flex; + align-items: center; + justify-content: center; + padding: 1rem; + font-size: 1.2rem; + color: var(--color-text-mute); +} +</style>
\ No newline at end of file |
