- Supprime rounded-lg et hover:scale-105 sur MangaCard - Ajoute overlay gradient + 3 boutons (éditer, sources, rafraîchir) visibles au survol en bas à gauche de la cover - MangaCard émet les événements edit/sources/refresh vers MangaGrid - MangaGrid gère les modales et composables (edit, preferredSources, refresh) - Grille plus dense : cols-3/4/5/7/8 selon breakpoint, gap-2
97 lines
3.0 KiB
Vue
97 lines
3.0 KiB
Vue
<template>
|
|
<div class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-7 xl:grid-cols-8 gap-2 p-4">
|
|
<MangaCard
|
|
v-for="manga in mangas"
|
|
:key="manga.id"
|
|
:manga="manga"
|
|
@edit="openEdit"
|
|
@sources="openSources"
|
|
@refresh="doRefresh" />
|
|
</div>
|
|
|
|
<!-- Modales -->
|
|
<MangaEditModal
|
|
:is-open="isEditModalOpen"
|
|
:manga="selectedManga"
|
|
:is-saving="editIsLoading"
|
|
:error="editError"
|
|
@close="closeEditModal"
|
|
@save="handleSaveEdit" />
|
|
|
|
<MangaPreferredSourcesModal
|
|
:is-open="isSourcesModalOpen"
|
|
:sources="preferredSources"
|
|
:is-loading="sourcesIsLoading"
|
|
:error="sourcesError"
|
|
:is-saving="sourcesIsSaving"
|
|
@close="isSourcesModalOpen = false"
|
|
@save="handleSaveSources" />
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, ref } from 'vue';
|
|
import { useMangaEdit } from '../composables/useMangaEdit';
|
|
import { useMangaPreferredSources } from '../composables/useMangaPreferredSources';
|
|
import { useMangaRefresh } from '../composables/useMangaRefresh';
|
|
import MangaCard from './MangaCard.vue';
|
|
import MangaEditModal from './MangaEditModal.vue';
|
|
import MangaPreferredSourcesModal from './MangaPreferredSourcesModal.vue';
|
|
|
|
defineProps({
|
|
mangas: {
|
|
type: Array,
|
|
required: true
|
|
}
|
|
});
|
|
|
|
const selectedManga = ref(null);
|
|
const isSourcesModalOpen = ref(false);
|
|
|
|
// ── Edit ──────────────────────────────────────────────────
|
|
const { isEditModalOpen, openEditModal, closeEditModal, editManga, isLoading: editIsLoading, error: editError } = useMangaEdit();
|
|
|
|
function openEdit(manga) {
|
|
selectedManga.value = manga;
|
|
openEditModal();
|
|
}
|
|
|
|
async function handleSaveEdit(data) {
|
|
if (!selectedManga.value) return;
|
|
await editManga(selectedManga.value.id, data);
|
|
}
|
|
|
|
// ── Sources préférées ─────────────────────────────────────
|
|
const selectedMangaId = computed(() => selectedManga.value?.id ?? null);
|
|
const {
|
|
sources: preferredSources,
|
|
isLoading: sourcesIsLoading,
|
|
error: sourcesError,
|
|
isSaving: sourcesIsSaving,
|
|
savePreferredSources
|
|
} = useMangaPreferredSources(selectedMangaId);
|
|
|
|
function openSources(manga) {
|
|
selectedManga.value = manga;
|
|
isSourcesModalOpen.value = true;
|
|
}
|
|
|
|
function handleSaveSources(sourceIds) {
|
|
savePreferredSources(sourceIds);
|
|
isSourcesModalOpen.value = false;
|
|
}
|
|
|
|
// ── Refresh ───────────────────────────────────────────────
|
|
const { refreshMetadata } = useMangaRefresh();
|
|
const refreshingId = ref(null);
|
|
|
|
async function doRefresh(manga) {
|
|
if (refreshingId.value) return;
|
|
refreshingId.value = manga.id;
|
|
try {
|
|
await refreshMetadata(manga.id);
|
|
} finally {
|
|
refreshingId.value = null;
|
|
}
|
|
}
|
|
</script>
|