76 lines
3.3 KiB
Vue
76 lines
3.3 KiB
Vue
<template>
|
|
<BaseModal v-model="isModalOpen" @close="closeModal" :movable="true" :resizable="true" :showBackdrop="false" :showBorder="true">
|
|
<template #header-icon>
|
|
<i class="fas fa-images text-blue-500"></i>
|
|
</template>
|
|
<template #header-title>Sprites</template>
|
|
|
|
<div class="p-6">
|
|
<!-- Sprites List -->
|
|
<div v-if="sprites.length === 0" class="text-center text-gray-400 py-8">
|
|
<i class="fas fa-image text-4xl mb-4 opacity-30"></i>
|
|
<p>No sprites uploaded yet</p>
|
|
<button @click="showUploadSection" class="mt-4 flex items-center gap-2 bg-blue-500 border border-blue-500 text-white rounded px-4 py-2 text-sm transition-colors mx-auto hover:bg-blue-600 hover:border-blue-600"><i class="fas fa-upload"></i> Upload sprites</button>
|
|
</div>
|
|
|
|
<div v-else>
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h3 class="text-lg font-medium text-gray-200 flex items-center gap-2"><i class="fas fa-images text-blue-500"></i> Uploaded Sprites</h3>
|
|
<span class="text-sm text-gray-400">{{ sprites.length }} sprites</span>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-3 gap-4 max-h-96 overflow-y-auto p-2">
|
|
<div v-for="(sprite, index) in sprites" :key="sprite.id" @click="handleSpriteClick(sprite.id)" class="border border-gray-600 rounded bg-gray-700 p-3 text-center transition-all cursor-pointer hover:border-blue-500 hover:-translate-y-0.5 hover:shadow-md">
|
|
<img :src="sprite.img.src" :alt="sprite.name" class="max-w-full max-h-20 mx-auto mb-2 bg-black bg-opacity-20 rounded" />
|
|
<div class="text-xs text-gray-400 truncate">{{ index + 1 }}. {{ truncateName(sprite.name) }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-end gap-3 mt-6">
|
|
<button @click="showUploadSection" class="flex items-center gap-2 bg-gray-700 text-gray-200 border border-gray-600 rounded px-4 py-2 text-sm transition-colors hover:border-blue-500"><i class="fas fa-upload"></i> Upload more</button>
|
|
<button @click="confirmClearAll" class="flex items-center gap-2 bg-red-600 border border-red-600 text-white rounded px-4 py-2 text-sm transition-colors hover:bg-red-700 hover:border-red-700"><i class="fas fa-trash-alt"></i> Clear all</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</BaseModal>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
import { useSpritesheetStore } from '../composables/useSpritesheetStore';
|
|
import BaseModal from './BaseModal.vue';
|
|
|
|
const store = useSpritesheetStore();
|
|
const sprites = computed(() => store.sprites.value);
|
|
const isModalOpen = computed({
|
|
get: () => store.isSpritesModalOpen.value,
|
|
set: value => {
|
|
store.isSpritesModalOpen.value = value;
|
|
},
|
|
});
|
|
|
|
const closeModal = () => {
|
|
store.isSpritesModalOpen.value = false;
|
|
};
|
|
|
|
const handleSpriteClick = (spriteId: string) => {
|
|
store.highlightSprite(spriteId);
|
|
};
|
|
|
|
const showUploadSection = () => {
|
|
// Close sprites modal and focus on upload section
|
|
closeModal();
|
|
};
|
|
|
|
const confirmClearAll = () => {
|
|
if (confirm('Are you sure you want to clear all sprites?')) {
|
|
store.clearAllSprites();
|
|
store.showNotification('All sprites cleared');
|
|
}
|
|
};
|
|
|
|
const truncateName = (name: string) => {
|
|
return name.length > 15 ? `${name.substring(0, 15)}...` : name;
|
|
};
|
|
</script>
|