diff --git a/assets/vue/app/domain/manga/domain/entities/manga.js b/assets/vue/app/domain/manga/domain/entities/manga.js
index 78b1e3d..98d0c9b 100644
--- a/assets/vue/app/domain/manga/domain/entities/manga.js
+++ b/assets/vue/app/domain/manga/domain/entities/manga.js
@@ -4,6 +4,7 @@ export class Manga {
slug,
title,
description = null,
+ author = null,
authors = [],
imageUrl = null,
thumbnailUrl = null,
@@ -20,7 +21,7 @@ export class Manga {
this.slug = slug;
this.title = title;
this.description = description;
- this.authors = authors;
+ this.authors = authors.length ? authors : (author ? [author] : []);
this.imageUrl = imageUrl;
this.thumbnailUrl = thumbnailUrl;
this.publicationYear = publicationYear;
diff --git a/assets/vue/app/domain/manga/presentation/components/HomeDisplaySettingsModal.vue b/assets/vue/app/domain/manga/presentation/components/HomeDisplaySettingsModal.vue
new file mode 100644
index 0000000..0103d2c
--- /dev/null
+++ b/assets/vue/app/domain/manga/presentation/components/HomeDisplaySettingsModal.vue
@@ -0,0 +1,161 @@
+
+ {{ manga.title }}
- {{ manga.publicationYear }}
+ {{ manga.title }}
+ {{ manga.publicationYear }}
+ {{ manga.authors[0] }}
{{ manga.status }}
-
+
{{ manga.description }}
@@ -100,6 +109,10 @@ const props = defineProps({ mangas: { type: Array, required: true + }, + options: { + type: Object, + default: () => ({ showCover: true, showStatus: true, showDescription: true, showAuthor: false, showYear: false }) } }); diff --git a/assets/vue/app/domain/manga/presentation/components/MangaTable.vue b/assets/vue/app/domain/manga/presentation/components/MangaTable.vue index bb204c5..62ddf0a 100644 --- a/assets/vue/app/domain/manga/presentation/components/MangaTable.vue +++ b/assets/vue/app/domain/manga/presentation/components/MangaTable.vue @@ -4,10 +4,13 @@| + | Titre | -Source préférée | -Chapitres | +Auteur | +Année | +Statut | +Source préférée | +Chapitres | Actions | + | + + + | + {{ manga.publicationYear || '—' }} + | + + ++ + {{ manga.status }} + + — + | + -+ |
|
- + |
@@ -139,9 +163,19 @@ const props = defineProps({
mangas: {
type: Array,
required: true
+ },
+ options: {
+ type: Object,
+ default: () => ({ showMonitoring: true, showPreferredSource: true, showChapters: true, showStatus: false, showAuthor: false, showYear: false })
}
});
+function statusClass(status) {
+ if (status === 'ongoing') return 'text-blue-600 bg-blue-50 dark:bg-blue-900/20';
+ if (status === 'completed') return 'text-green-600 bg-green-50 dark:bg-green-900/20';
+ return 'text-gray-500 bg-gray-100 dark:bg-gray-700';
+}
+
function progressPercent(manga) {
if (!manga.chaptersTotal) return 0;
return Math.round((manga.chaptersScraped / manga.chaptersTotal) * 100);
diff --git a/assets/vue/app/domain/manga/presentation/pages/HomePage.vue b/assets/vue/app/domain/manga/presentation/pages/HomePage.vue
index b27c481..0b2eca6 100644
--- a/assets/vue/app/domain/manga/presentation/pages/HomePage.vue
+++ b/assets/vue/app/domain/manga/presentation/pages/HomePage.vue
@@ -3,12 +3,13 @@
@@ -44,6 +51,7 @@ import { useUserPreferencesStore } from '../../../../domain/setting/application/
import Pagination from '../../../../shared/components/ui/Pagination.vue';
import Toolbar from '../../../../shared/components/ui/Toolbar.vue';
import { useMangaStore } from '../../application/store/mangaStore';
+import HomeDisplaySettingsModal from '../components/HomeDisplaySettingsModal.vue';
import MangaGrid from '../components/MangaGrid.vue';
import MangaOverview from '../components/MangaOverview.vue';
import MangaTable from '../components/MangaTable.vue';
@@ -61,6 +69,7 @@ import MangaTable from '../components/MangaTable.vue';
const viewMode = ref(prefs.defaultView);
const currentPage = ref(1);
+ const isDisplaySettingsOpen = ref(false);
onMounted(() => {
mangaStore.loadCollection();
@@ -71,7 +80,12 @@ import MangaTable from '../components/MangaTable.vue';
};
const sortedCollection = computed(() => {
- const items = [...(collection.value?.items || [])];
+ let items = [...(collection.value?.items || [])];
+ if (prefs.filterBy === 'completed') {
+ items = items.filter(m => m.status?.toLowerCase() === 'completed');
+ } else if (prefs.filterBy === 'ongoing') {
+ items = items.filter(m => m.status?.toLowerCase() === 'ongoing');
+ }
if (prefs.sortBy === 'title') {
items.sort((a, b) => a.title.localeCompare(b.title));
} else if (prefs.sortBy === 'addedAt') {
@@ -91,7 +105,7 @@ import MangaTable from '../components/MangaTable.vue';
currentPage.value = 1;
});
- const toolbarConfig = {
+ const toolbarConfig = computed(() => ({
leftSection: [
{
icon: ArrowPathIcon,
@@ -103,15 +117,15 @@ import MangaTable from '../components/MangaTable.vue';
{ icon: MagnifyingGlassIcon, label: 'Search', type: 'button', onClick: () => {} }
],
rightSection: [
- { icon: Cog6ToothIcon, type: 'button', onClick: () => {} },
+ { icon: Cog6ToothIcon, label: 'Options', type: 'button', onClick: () => { isDisplaySettingsOpen.value = true; } },
{
icon: EyeIcon,
type: 'dropdown',
label: 'View',
items: [
- { label: 'Overview', onClick: () => { viewMode.value = 'list'; prefs.setDefaultView('list'); } },
- { label: 'Grid', onClick: () => { viewMode.value = 'grid'; prefs.setDefaultView('grid'); } },
- { label: 'Table', onClick: () => { viewMode.value = 'table'; prefs.setDefaultView('table'); } }
+ { label: 'Overview', isSelected: prefs.defaultView === 'list', onClick: () => { viewMode.value = 'list'; prefs.setDefaultView('list'); } },
+ { label: 'Grid', isSelected: prefs.defaultView === 'grid', onClick: () => { viewMode.value = 'grid'; prefs.setDefaultView('grid'); } },
+ { label: 'Table', isSelected: prefs.defaultView === 'table', onClick: () => { viewMode.value = 'table'; prefs.setDefaultView('table'); } }
]
},
{
@@ -119,9 +133,9 @@ import MangaTable from '../components/MangaTable.vue';
type: 'dropdown',
label: 'Sort',
items: [
- { label: 'Title', onClick: () => prefs.setSortBy('title') },
- { label: "Date d'ajout", onClick: () => prefs.setSortBy('addedAt') },
- { label: 'Progression', onClick: () => prefs.setSortBy('progress') }
+ { label: 'Title', isSelected: prefs.sortBy === 'title', onClick: () => prefs.setSortBy('title') },
+ { label: "Date d'ajout", isSelected: prefs.sortBy === 'addedAt', onClick: () => prefs.setSortBy('addedAt') },
+ { label: 'Progression', isSelected: prefs.sortBy === 'progress', onClick: () => prefs.setSortBy('progress') }
]
},
{
@@ -129,11 +143,11 @@ import MangaTable from '../components/MangaTable.vue';
type: 'dropdown',
label: 'Filter',
items: [
- { label: 'All', onClick: () => {} },
- { label: 'Completed', onClick: () => {} },
- { label: 'In Progress', onClick: () => {} }
+ { label: 'All', isSelected: prefs.filterBy === 'all', onClick: () => prefs.setFilterBy('all') },
+ { label: 'Completed', isSelected: prefs.filterBy === 'completed', onClick: () => prefs.setFilterBy('completed') },
+ { label: 'In Progress', isSelected: prefs.filterBy === 'ongoing', onClick: () => prefs.setFilterBy('ongoing') }
]
}
]
- };
+ }));
diff --git a/assets/vue/app/domain/setting/application/store/userPreferencesStore.js b/assets/vue/app/domain/setting/application/store/userPreferencesStore.js
index a185066..9a60879 100644
--- a/assets/vue/app/domain/setting/application/store/userPreferencesStore.js
+++ b/assets/vue/app/domain/setting/application/store/userPreferencesStore.js
@@ -8,6 +8,12 @@ const defaultState = {
defaultView: 'grid',
itemsPerPage: 20,
sortBy: 'title',
+ filterBy: 'all',
+ displayOptions: {
+ grid: { showTitle: true, showYear: true, showAuthor: false },
+ overview: { showCover: true, showStatus: true, showDescription: true, showAuthor: false, showYear: false },
+ table: { showMonitoring: true, showPreferredSource: true, showChapters: true, showStatus: false, showAuthor: false, showYear: false }
+ },
readingDirection: 'ltr',
readingMode: 'scroll',
autoFullscreen: false,
@@ -88,6 +94,16 @@ export const useUserPreferencesStore = defineStore('userPreferences', {
this.persist();
},
+ setFilterBy(filter) {
+ this.filterBy = filter;
+ this.persist();
+ },
+
+ setDisplayOption(view, key, value) {
+ this.displayOptions[view][key] = value;
+ this.persist();
+ },
+
setReadingDirection(direction) {
this.readingDirection = direction;
this.persist();
@@ -127,6 +143,8 @@ export const useUserPreferencesStore = defineStore('userPreferences', {
defaultView: this.defaultView,
itemsPerPage: this.itemsPerPage,
sortBy: this.sortBy,
+ filterBy: this.filterBy,
+ displayOptions: this.displayOptions,
readingDirection: this.readingDirection,
readingMode: this.readingMode,
autoFullscreen: this.autoFullscreen,
diff --git a/assets/vue/app/shared/components/ui/ToggleRow.vue b/assets/vue/app/shared/components/ui/ToggleRow.vue
new file mode 100644
index 0000000..5828666
--- /dev/null
+++ b/assets/vue/app/shared/components/ui/ToggleRow.vue
@@ -0,0 +1,37 @@
+
+
-
+ {{ label }}
+
+
+
+
+
diff --git a/assets/vue/app/shared/components/ui/Toolbar.vue b/assets/vue/app/shared/components/ui/Toolbar.vue
index 35a58d8..ebeedf9 100644
--- a/assets/vue/app/shared/components/ui/Toolbar.vue
+++ b/assets/vue/app/shared/components/ui/Toolbar.vue
@@ -8,7 +8,7 @@
|
|---|