<template> <div class="assets-container"> <div class="asset-categories"> <!-- Asset Categories --> <a class="category" :class="{ selected: selectedCategory === 'tiles' }" @click="() => (selectedCategory = 'tiles')"> <span class="category-name">Tiles</span> </a> <a class="category" :class="{ selected: selectedCategory === 'objects' }" @click="() => (selectedCategory = 'objects')"> <span class="category-name">Objects</span> </a> <a class="category"> <span class="category-name">Loot</span> </a> <a class="category"> <span class="category-name">NPC's</span> </a> </div> <div class="divider categories"></div> <!-- Assets list --> <div class="assets" ref="elementToScroll" @scroll="onScroll"> <TileList v-if="selectedCategory === 'tiles'" /> <ObjectList :name="selectedCategory" v-if="selectedCategory === 'objects'" /> </div> <button class="back-to-top" v-show="hasScrolled" @click="toTop"> <img src="/assets/icons/zoneEditor/chevron.svg" alt="" /> </button> <div class="divider assets-list"></div> <!-- Asset details --> <div class="asset-info"> <TileDetails :tile="selectedTile" v-if="selectedCategory === 'tiles' && assetManagerStore.selectedTile" /> </div> </div> </template> <script setup lang="ts"> import { onMounted, ref } from 'vue' import { useSocketStore } from '@/stores/socket' import TileList from '@/components/utilities/assetManager/partials/TileList.vue' import TileDetails from '@/components/utilities/assetManager/partials/TileDetails.vue' import ObjectList from '@/components/utilities/assetManager/partials/ObjectList.vue' import { useAssetManagerStore } from '@/stores/assetManager' const socket = useSocketStore() const assetManagerStore = useAssetManagerStore() const selectedCategory = ref('tiles') const selectedTile = ref('') const hasScrolled = ref(false) const elementToScroll = ref() const onScroll = (e: Event) => { let scrollTop = (e.target as HTMLBodyElement).scrollTop if (scrollTop > 200) { hasScrolled.value = true } else if (scrollTop <= 200) { hasScrolled.value = false } } function toTop() { elementToScroll.value.scrollTo({ top: 0, left: 0, behavior: 'smooth' }) } </script> <style lang="scss"> @import '@/assets/scss/main'; .container { &.gm-panel { height: 100%; margin: 0 !important; } } .assets-container { display: flex; height: 100%; width: 100%; position: relative; .divider { position: absolute; width: 1px; background-color: $dark-cyan; height: 100%; top: 0; &.categories { left: 15%; //width % of .asset-categories } &.assets-list { left: 50%; //width % of .asset-categories + .assets } } button.back-to-top { position: absolute; left: calc(50% - 60px); bottom: 10px; min-width: unset; width: 50px; height: 50px; border-radius: 8px; background-color: rgba($cyan, 0.5); padding: 0; img { position: absolute; filter: invert(100%); width: 30px; height: 30px; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%) rotateX(180deg); } &:hover { background-color: rgba($cyan, 0.8); } } .asset-categories { width: 15%; display: flex; } .assets { overflow: auto; height: 100%; width: 35%; display: flex; } .asset-info { display: flex; width: 50%; &::after { display: none; } .image-container { text-align: center; img { height: 200px; padding-right: 10px; margin: 20px 0; } } .modal-form { &.asset-manager { margin: 10px; width: calc(100% - 20px); height: 100%; .form-fields { display: flex; gap: 10px; flex-wrap: wrap; .form-field { width: calc(50% - 5px); &.name { width: 100%; } } .submit { width: 100%; } } } } } .asset-details { display: flex; align-items: center; gap: 10px; img { height: 28px; } } .category { &:hover { cursor: pointer; } } .asset-categories, .assets, .asset-info { flex-direction: column; position: relative; .category, .asset, .image-container { position: relative; padding: 10px; &::after { content: ''; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background-color: $dark-cyan; } &.selected { background-color: rgba($cyan, 0.8); } } } } </style>