mirror of
https://github.com/C9Glax/tranga-website.git
synced 2025-10-15 09:50:48 +02:00
recursive navigation
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<TrangaPage v-bind="$props">
|
<TrangaPage v-bind="$props" :back="backUrl ? { href: backUrl, icon: 'i-lucide-arrow-left', text: 'Back' } : undefined">
|
||||||
<template #left>
|
<template #left>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<MangaCover v-if="manga" :manga="manga" class="self-center" />
|
<MangaCover v-if="manga" :manga="manga" class="self-center" />
|
||||||
@@ -10,9 +10,11 @@
|
|||||||
</p>
|
</p>
|
||||||
<USkeleton v-else class="text-xl h-20 w-full" />
|
<USkeleton v-else class="text-xl h-20 w-full" />
|
||||||
<div v-if="manga" class="flex flex-row gap-1 flex-wrap">
|
<div v-if="manga" class="flex flex-row gap-1 flex-wrap">
|
||||||
<UBadge v-for="author in manga.authors" :key="author.key" variant="outline" color="neutral">{{ author.name }}</UBadge>
|
<UBadge v-for="author in manga.authors" :key="author.key" variant="outline" color="neutral"
|
||||||
|
><NuxtLink :to="`/manga/author/${author.key}?return=${path}`">{{ author.name }}</NuxtLink></UBadge
|
||||||
|
>
|
||||||
<UBadge v-for="tag in manga.tags" :key="tag" variant="outline" color="primary"
|
<UBadge v-for="tag in manga.tags" :key="tag" variant="outline" color="primary"
|
||||||
><NuxtLink :to="`/manga/tag/${tag}`">{{ tag }}</NuxtLink></UBadge
|
><NuxtLink :to="`/manga/tag/${tag}?return=${path}`">{{ tag }}</NuxtLink></UBadge
|
||||||
>
|
>
|
||||||
<NuxtLink v-for="link in manga.links" :key="link.key" :to="link.url" external no-prefetch>
|
<NuxtLink v-for="link in manga.links" :key="link.key" :to="link.url" external no-prefetch>
|
||||||
<UBadge variant="outline" color="secondary">{{ link.provider }}</UBadge>
|
<UBadge variant="outline" color="secondary">{{ link.provider }}</UBadge>
|
||||||
@@ -34,9 +36,11 @@
|
|||||||
import type { components } from '#open-fetch-schemas/api';
|
import type { components } from '#open-fetch-schemas/api';
|
||||||
import TrangaPage, { type PageProps } from '~/components/TrangaPage.vue';
|
import TrangaPage, { type PageProps } from '~/components/TrangaPage.vue';
|
||||||
type Manga = components['schemas']['Manga'];
|
type Manga = components['schemas']['Manga'];
|
||||||
|
const path = useRoute().fullPath;
|
||||||
|
|
||||||
export interface MangaDetailPageProps extends PageProps {
|
export interface MangaDetailPageProps extends PageProps {
|
||||||
manga?: Manga;
|
manga?: Manga;
|
||||||
|
backUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineProps<MangaDetailPageProps>();
|
defineProps<MangaDetailPageProps>();
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<MangaDetailPage :manga="manga">
|
<MangaDetailPage :manga="manga" :back-url="backUrl">
|
||||||
<div class="grid gap-3 max-sm:grid-flow-row-dense min-sm:grid-cols-[70%_auto]">
|
<div class="grid gap-3 max-sm:grid-flow-row-dense min-sm:grid-cols-[70%_auto]">
|
||||||
<ChaptersList :manga-id="mangaId" />
|
<ChaptersList :manga-id="mangaId" />
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
@@ -67,9 +67,11 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import MangaDetailPage from '~/components/MangaDetailPage.vue';
|
import MangaDetailPage from '~/components/MangaDetailPage.vue';
|
||||||
|
const { $api } = useNuxtApp();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const mangaId = route.params.mangaId as string;
|
const mangaId = route.params.mangaId as string;
|
||||||
const { $api } = useNuxtApp();
|
const backUrl = route.query.return as string | undefined;
|
||||||
|
|
||||||
const flashDownloading = route.query.download;
|
const flashDownloading = route.query.download;
|
||||||
|
|
||||||
const { data: manga } = await useApi('/v2/Manga/{MangaId}', {
|
const { data: manga } = await useApi('/v2/Manga/{MangaId}', {
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const targetId = route.params.targetId as string;
|
const targetId = route.params.targetId as string;
|
||||||
const mangaId = route.params.mangaId as string;
|
const mangaId = route.params.mangaId as string;
|
||||||
|
const path = route.fullPath;
|
||||||
const { $api } = useNuxtApp();
|
const { $api } = useNuxtApp();
|
||||||
|
|
||||||
const reverse = ref(false);
|
const reverse = ref(false);
|
||||||
@@ -34,7 +35,7 @@ const merge = async () => {
|
|||||||
const from = reverse.value ? mangaId : targetId;
|
const from = reverse.value ? mangaId : targetId;
|
||||||
const to = reverse.value == false ? targetId : mangaId;
|
const to = reverse.value == false ? targetId : mangaId;
|
||||||
await $api('/v2/Manga/{MangaIdFrom}/MergeInto/{MangaIdInto}', { method: 'POST', path: { MangaIdFrom: from, MangaIdInto: to } });
|
await $api('/v2/Manga/{MangaIdFrom}/MergeInto/{MangaIdInto}', { method: 'POST', path: { MangaIdFrom: from, MangaIdInto: to } });
|
||||||
navigateTo(`/manga/${to}`);
|
navigateTo(`/manga/${to}?return=${path}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
useHead({ title: 'Confirm merge' });
|
useHead({ title: 'Confirm merge' });
|
||||||
|
@@ -1,13 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<MangaDetailPage :manga="manga" :back="{ text: 'Back', href: `/manga/${mangaId}`, icon: 'i-lucide-arrow-left' }" title="Merge with">
|
<MangaDetailPage
|
||||||
|
:manga="manga"
|
||||||
|
:back="{ text: 'Back', href: backUrl ?? `/manga/${mangaId}`, icon: 'i-lucide-arrow-left' }"
|
||||||
|
title="Merge with">
|
||||||
<USkeleton v-if="!mangas" class="w-full h-[350px]" />
|
<USkeleton v-if="!mangas" class="w-full h-[350px]" />
|
||||||
<MangaCardList :manga="mangas" @click="(m) => navigateTo(`/manga/${mangaId}/merge/${m.key}`)" />
|
<MangaCardList :manga="mangas" @click="(m) => navigateTo(`/manga/${mangaId}/merge/${m.key}?return=${path}`)" />
|
||||||
</MangaDetailPage>
|
</MangaDetailPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const mangaId = route.params.mangaId as string;
|
const mangaId = route.params.mangaId as string;
|
||||||
|
const backUrl = route.query.return as string | undefined;
|
||||||
|
const path = route.fullPath;
|
||||||
|
|
||||||
const { data: manga } = await useApi('/v2/Manga/{MangaId}', { path: { MangaId: mangaId }, key: FetchKeys.Manga.Id(mangaId) });
|
const { data: manga } = await useApi('/v2/Manga/{MangaId}', { path: { MangaId: mangaId }, key: FetchKeys.Manga.Id(mangaId) });
|
||||||
const { data: mangas } = await useApi('/v2/Manga', { key: FetchKeys.Manga.All });
|
const { data: mangas } = await useApi('/v2/Manga', { key: FetchKeys.Manga.All });
|
||||||
|
23
website/app/pages/manga/author/[authorId].vue
Normal file
23
website/app/pages/manga/author/[authorId].vue
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<TrangaPage :back="backUrl ? { href: backUrl, icon: 'i-lucide-arrow-left', text: 'Back' } : undefined">
|
||||||
|
<template #title>
|
||||||
|
<h1 class="text-2xl">
|
||||||
|
Manga with Author <UBadge variant="outline" color="neutral" class="font-semibold text-xl ml-1">{{ author?.name }}</UBadge>
|
||||||
|
</h1>
|
||||||
|
</template>
|
||||||
|
<LoadingPage :loading="status === 'pending'">
|
||||||
|
<MangaCardList :manga="manga" @click="(m) => navigateTo(`/manga/${m.key}?return=${route.fullPath}`)" />
|
||||||
|
</LoadingPage>
|
||||||
|
</TrangaPage>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const route = useRoute();
|
||||||
|
const authorId = route.params.authorId as string;
|
||||||
|
const backUrl = route.query.return as string | undefined;
|
||||||
|
|
||||||
|
const { data: author } = await useApi('/v2/Author/{AuthorId}', { path: { AuthorId: authorId } });
|
||||||
|
const { data: manga, status } = await useApi('/v2/Manga/WithAuthorId/{AuthorId}', { path: { AuthorId: authorId }, lazy: true });
|
||||||
|
|
||||||
|
useHead({ title: 'Author Search' });
|
||||||
|
</script>
|
@@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<TrangaPage>
|
<TrangaPage :back="backUrl ? { href: backUrl, icon: 'i-lucide-arrow-left', text: 'Back' } : undefined">
|
||||||
<template #title>
|
<template #title>
|
||||||
<h1 class="text-2xl">
|
<h1 class="text-2xl">
|
||||||
Manga with Tag <UBadge variant="outline" class="text-primary font-semibold text-xl">{{ tag }}</UBadge>
|
Manga with Tag <UBadge variant="outline" color="primary" class="font-semibold text-xl ml-1">{{ tag }}</UBadge>
|
||||||
</h1>
|
</h1>
|
||||||
</template>
|
</template>
|
||||||
<LoadingPage :loading="status === 'pending'">
|
<LoadingPage :loading="status === 'pending'">
|
||||||
<MangaCardList :manga="manga" />
|
<MangaCardList :manga="manga" @click="(m) => navigateTo(`/manga/${m.key}?return=${route.fullPath}`)" />
|
||||||
</LoadingPage>
|
</LoadingPage>
|
||||||
</TrangaPage>
|
</TrangaPage>
|
||||||
</template>
|
</template>
|
||||||
@@ -14,7 +14,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const tag = route.params.tag as string;
|
const tag = route.params.tag as string;
|
||||||
|
const backUrl = route.query.return as string | undefined;
|
||||||
const { data: manga, status } = await useApi('/v2/Manga/WithTag/{Tag}', { path: { Tag: tag }, lazy: true });
|
const { data: manga, status } = await useApi('/v2/Manga/WithTag/{Tag}', { path: { Tag: tag }, lazy: true });
|
||||||
|
|
||||||
useHead({ title: 'Tranga' });
|
useHead({ title: 'Tag search' });
|
||||||
</script>
|
</script>
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
:expanded="i === expanded"
|
:expanded="i === expanded"
|
||||||
@click="expanded = expanded === i ? -1 : i">
|
@click="expanded = expanded === i ? -1 : i">
|
||||||
<template #actions="manga">
|
<template #actions="manga">
|
||||||
<UButton :to="`/manga/${manga.key}?download=true`">Download</UButton>
|
<UButton :to="`/manga/${manga.key}?download=true&return=${path}`">Download</UButton>
|
||||||
</template>
|
</template>
|
||||||
</MangaCard>
|
</MangaCard>
|
||||||
</div>
|
</div>
|
||||||
@@ -56,6 +56,8 @@ import type { StepperItem } from '@nuxt/ui';
|
|||||||
type MangaConnector = components['schemas']['MangaConnector'];
|
type MangaConnector = components['schemas']['MangaConnector'];
|
||||||
type MinimalManga = components['schemas']['MinimalManga'];
|
type MinimalManga = components['schemas']['MinimalManga'];
|
||||||
|
|
||||||
|
const path = useRoute().fullPath;
|
||||||
|
|
||||||
const { data: connectors } = await useApi('/v2/MangaConnector', { key: FetchKeys.MangaConnector.All });
|
const { data: connectors } = await useApi('/v2/MangaConnector', { key: FetchKeys.MangaConnector.All });
|
||||||
|
|
||||||
const query = ref<string>();
|
const query = ref<string>();
|
||||||
|
Reference in New Issue
Block a user