mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-11 10:00:08 +08:00
no data found pages
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1.25rem;
|
||||
min-block-size: calc(var(--vh, 1vh) * 100);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.misc-footer-img {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1.25rem;
|
||||
min-block-size: calc(var(--vh, 1vh) * 100);
|
||||
overflow: hidden;
|
||||
|
||||
.misc-footer-img {
|
||||
position: absolute;
|
||||
|
||||
70
src/components/NoDataFound.vue
Normal file
70
src/components/NoDataFound.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<script setup lang="ts">
|
||||
import misc404 from '@images/pages/404.png'
|
||||
import miscMaskDark from '@images/pages/misc-mask-dark.png'
|
||||
import miscMaskLight from '@images/pages/misc-mask-light.png'
|
||||
import tree from '@images/pages/tree.png'
|
||||
import { useTheme } from 'vuetify'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const authThemeMask = computed(() => {
|
||||
return vuetifyTheme.global.name.value === 'light' ? miscMaskLight : miscMaskDark
|
||||
})
|
||||
|
||||
interface Props {
|
||||
errorCode?: string
|
||||
errorTitle?: string
|
||||
errorDescription?: string
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="misc-wrapper">
|
||||
<ErrorHeader
|
||||
:error-code="props.errorCode"
|
||||
:error-title="props.errorTitle"
|
||||
:error-description="props.errorDescription"
|
||||
/>
|
||||
|
||||
<!-- 👉 Image -->
|
||||
<div class="misc-avatar w-100 text-center">
|
||||
<VImg
|
||||
:src="misc404"
|
||||
:max-width="800"
|
||||
class="mx-auto"
|
||||
/>
|
||||
<slot name="button" />
|
||||
</div>
|
||||
|
||||
<!-- 👉 Footer -->
|
||||
<VImg
|
||||
:src="tree"
|
||||
class="misc-footer-tree d-none d-md-block"
|
||||
/>
|
||||
|
||||
<VImg
|
||||
:src="authThemeMask"
|
||||
class="misc-footer-img d-none d-md-block"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@use '@core/scss/pages/misc.scss';
|
||||
|
||||
.misc-wrapper .misc-footer-tree {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
inline-size: 15.625rem;
|
||||
inset-block-end: 3.5rem;
|
||||
inset-inline-start: 0.375rem;
|
||||
}
|
||||
|
||||
.misc-wrapper .misc-footer-img {
|
||||
position: absolute;
|
||||
inline-size: 100%;
|
||||
inset-block-end: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,68 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import misc404 from '@images/pages/404.png'
|
||||
import miscMaskDark from '@images/pages/misc-mask-dark.png'
|
||||
import miscMaskLight from '@images/pages/misc-mask-light.png'
|
||||
import tree from '@images/pages/tree.png'
|
||||
import { useTheme } from 'vuetify'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const authThemeMask = computed(() => {
|
||||
return vuetifyTheme.global.name.value === 'light' ? miscMaskLight : miscMaskDark
|
||||
})
|
||||
import NoDataFound from '@/components/NoDataFound.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="misc-wrapper">
|
||||
<ErrorHeader
|
||||
error-code="404"
|
||||
error-title="页面不存在 ⚠️"
|
||||
error-description="您想要访问的页面不存在,请检查地址是否正确."
|
||||
/>
|
||||
|
||||
<!-- 👉 Image -->
|
||||
<div class="misc-avatar w-100 text-center">
|
||||
<VImg
|
||||
:src="misc404"
|
||||
alt="Coming Soon"
|
||||
:max-width="800"
|
||||
class="mx-auto"
|
||||
/>
|
||||
<NoDataFound
|
||||
errorCode="404"
|
||||
errorTitle="页面不存在 ⚠️"
|
||||
errorDescription="您想要访问的页面不存在,请检查地址是否正确。"
|
||||
>
|
||||
<template #button>
|
||||
<VBtn
|
||||
to="/"
|
||||
class="mt-10"
|
||||
>
|
||||
返回
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Footer -->
|
||||
<VImg
|
||||
:src="tree"
|
||||
class="misc-footer-tree d-none d-md-block"
|
||||
/>
|
||||
|
||||
<VImg
|
||||
:src="authThemeMask"
|
||||
class="misc-footer-img d-none d-md-block"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</NoDataFound>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@use "@core/scss/pages/misc.scss";
|
||||
|
||||
.misc-wrapper .misc-footer-tree {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
inline-size: 15.625rem;
|
||||
inset-block-end: 3.5rem;
|
||||
inset-inline-start: 0.375rem;
|
||||
}
|
||||
|
||||
.misc-wrapper .misc-footer-img {
|
||||
position: absolute;
|
||||
inline-size: 100%;
|
||||
inset-block-end: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,7 +23,7 @@ const page = ref(1);
|
||||
// 是否加载中
|
||||
const loading = ref(false);
|
||||
// 是否加载完成
|
||||
const finished = ref(false);
|
||||
const isRefreshed = ref(false);
|
||||
|
||||
// 数据列表
|
||||
const dataList = ref<MediaInfo[]>([]);
|
||||
@@ -62,7 +62,7 @@ const fetchData = async ({ done }) => {
|
||||
params: getParams(),
|
||||
});
|
||||
// 标计为已请求完成
|
||||
finished.value = true;
|
||||
isRefreshed.value = true;
|
||||
if (currData.value.length === 0) {
|
||||
// 如果没有数据,跳出
|
||||
done("ok");
|
||||
@@ -80,7 +80,7 @@ const fetchData = async ({ done }) => {
|
||||
params: getParams(),
|
||||
});
|
||||
// 标计为已请求完成
|
||||
finished.value = true;
|
||||
isRefreshed.value = true;
|
||||
if (currData.value.length === 0) {
|
||||
// 如果没有数据,跳出
|
||||
done("ok");
|
||||
@@ -107,7 +107,7 @@ const fetchData = async ({ done }) => {
|
||||
<template>
|
||||
<VProgressCircular
|
||||
class="centered"
|
||||
v-if="!finished"
|
||||
v-if="!isRefreshed"
|
||||
indeterminate
|
||||
color="primary"
|
||||
></VProgressCircular>
|
||||
@@ -118,9 +118,16 @@ const fetchData = async ({ done }) => {
|
||||
class="overflow-hidden"
|
||||
>
|
||||
<template #loading />
|
||||
<div class="grid gap-4 grid-media-card mx-3">
|
||||
<div class="grid gap-4 grid-media-card mx-3" v-if="dataList.length > 0">
|
||||
<MediaCard v-for="data in dataList" :key="data.tmdb_id" :media="data"> </MediaCard>
|
||||
</div>
|
||||
<NoDataFound
|
||||
v-if="dataList.length === 0 && isRefreshed"
|
||||
error-code="500"
|
||||
error-title="出错啦!"
|
||||
error-description="无法获取到媒体信息,请检查网络连接。"
|
||||
>
|
||||
</NoDataFound>
|
||||
</VInfiniteScroll>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,40 +1,64 @@
|
||||
<script lang="ts" setup>
|
||||
import api from "@/api";
|
||||
import type { DownloadingInfo } from "@/api/types";
|
||||
import DownloadingCard from "@/components/cards/DownloadingCard.vue";
|
||||
import PullRefresh from "pull-refresh-vue3";
|
||||
import api from '@/api'
|
||||
import type { DownloadingInfo } from '@/api/types'
|
||||
import NoDataFound from '@/components/NoDataFound.vue'
|
||||
import DownloadingCard from '@/components/cards/DownloadingCard.vue'
|
||||
import PullRefresh from 'pull-refresh-vue3'
|
||||
|
||||
// 数据列表
|
||||
const dataList = ref<DownloadingInfo[]>([]);
|
||||
const dataList = ref<DownloadingInfo[]>([])
|
||||
|
||||
// 获取订阅列表数据
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
dataList.value = await api.get("download");
|
||||
dataList.value = await api.get('download')
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error(error)
|
||||
}
|
||||
};
|
||||
|
||||
// 加载时获取数据
|
||||
onMounted(fetchData);
|
||||
}
|
||||
|
||||
// 刷新状态
|
||||
const loading = ref(false);
|
||||
const loading = ref(false)
|
||||
|
||||
// 是否刷新过
|
||||
const isRefreshed = ref(false)
|
||||
|
||||
// 下拉刷新
|
||||
const onRefresh = () => {
|
||||
loading.value = true;
|
||||
fetchData();
|
||||
loading.value = false;
|
||||
};
|
||||
loading.value = true
|
||||
fetchData()
|
||||
loading.value = false
|
||||
isRefreshed.value = true
|
||||
}
|
||||
|
||||
// 加载时获取数据
|
||||
onBeforeMount(() => {
|
||||
fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PullRefresh v-model="loading" @refresh="onRefresh">
|
||||
<div class="grid gap-3 grid-downloading-card">
|
||||
<DownloadingCard v-for="data in dataList" :key="data.hash" :info="data" />
|
||||
<PullRefresh
|
||||
v-model="loading"
|
||||
@refresh="onRefresh"
|
||||
>
|
||||
<div
|
||||
class="grid gap-3 grid-downloading-card"
|
||||
v-if="dataList.length > 0"
|
||||
>
|
||||
<DownloadingCard
|
||||
v-for="data in dataList"
|
||||
:key="data.hash"
|
||||
:info="data"
|
||||
/>
|
||||
</div>
|
||||
<NoDataFound
|
||||
v-if="dataList.length === 0 && isRefreshed"
|
||||
error-code="404"
|
||||
error-title="没有任务"
|
||||
error-description="正在下载的任务将会显示在这里。"
|
||||
>
|
||||
</NoDataFound>
|
||||
</PullRefresh>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,28 +1,46 @@
|
||||
<script lang="ts" setup>
|
||||
import api from "@/api";
|
||||
import { Site } from "@/api/types";
|
||||
import SiteCard from "@/components/cards/SiteCard.vue";
|
||||
import api from '@/api';
|
||||
import { Site } from '@/api/types';
|
||||
import SiteCard from '@/components/cards/SiteCard.vue';
|
||||
|
||||
// 数据列表
|
||||
const dataList = ref<Site[]>([]);
|
||||
const dataList = ref<Site[]>([])
|
||||
|
||||
// 是否刷新过
|
||||
const isRefreshed = ref(false)
|
||||
|
||||
// 获取订阅列表数据
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
dataList.value = await api.get("site");
|
||||
dataList.value = await api.get('site')
|
||||
isRefreshed.value = true
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error(error)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 加载时获取数据
|
||||
onMounted(fetchData);
|
||||
onBeforeMount(fetchData)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid gap-3 grid-site-card">
|
||||
<SiteCard v-for="data in dataList" :key="data.id" :site="data" />
|
||||
<div
|
||||
class="grid gap-3 grid-site-card"
|
||||
v-if="dataList.length > 0"
|
||||
>
|
||||
<SiteCard
|
||||
v-for="data in dataList"
|
||||
:key="data.id"
|
||||
:site="data"
|
||||
/>
|
||||
</div>
|
||||
<NoDataFound
|
||||
v-if="dataList.length === 0 && isRefreshed"
|
||||
error-code="404"
|
||||
error-title="没有站点"
|
||||
error-description="已添加并支持的站点将会在这里显示。"
|
||||
>
|
||||
</NoDataFound>
|
||||
</template>
|
||||
|
||||
<style type="scss">
|
||||
|
||||
@@ -9,6 +9,9 @@ const props = defineProps({
|
||||
type: String,
|
||||
});
|
||||
|
||||
// 是否刷新过
|
||||
const isRefreshed = ref(false)
|
||||
|
||||
// 数据列表
|
||||
const dataList = ref<Subscribe[]>([]);
|
||||
|
||||
@@ -16,13 +19,14 @@ const dataList = ref<Subscribe[]>([]);
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
dataList.value = await api.get("subscribe");
|
||||
isRefreshed.value = true
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
// 加载时获取数据
|
||||
onMounted(fetchData);
|
||||
onBeforeMount(fetchData);
|
||||
|
||||
// 刷新状态
|
||||
const loading = ref(false);
|
||||
@@ -42,9 +46,17 @@ const filteredDataList = computed(() => {
|
||||
|
||||
<template>
|
||||
<PullRefresh v-model="loading" @refresh="onRefresh">
|
||||
<div class="grid gap-3 grid-subscribe-card">
|
||||
<div class="grid gap-3 grid-subscribe-card"
|
||||
v-if="filteredDataList.length > 0">
|
||||
<SubscribeCard v-for="data in filteredDataList" :key="data.id" :media="data" />
|
||||
</div>
|
||||
<NoDataFound
|
||||
v-if="filteredDataList.length === 0 && isRefreshed"
|
||||
error-code="404"
|
||||
error-title="没有订阅"
|
||||
error-description="请通过搜索添加电影、电视剧订阅。"
|
||||
>
|
||||
</NoDataFound>
|
||||
</PullRefresh>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user