|
|
@@ -0,0 +1,133 @@
|
|
|
+<script lang="ts" setup>
|
|
|
+import type { PropType } from 'vue';
|
|
|
+
|
|
|
+import type { BasicTreeOptionResult } from '#/api/model';
|
|
|
+
|
|
|
+import { onMounted, reactive, ref } from 'vue';
|
|
|
+import { useRoute } from 'vue-router';
|
|
|
+
|
|
|
+import { Loading } from '@vben/common-ui';
|
|
|
+
|
|
|
+import { cn } from '@vben-core/shared/utils';
|
|
|
+
|
|
|
+import { ArticleApi, SiteApi } from '#/api';
|
|
|
+import { useLazyLoad } from '#/components/useLazyLoad';
|
|
|
+import { $t } from '#/locales';
|
|
|
+import { useWebStore } from '#/store';
|
|
|
+
|
|
|
+defineProps({
|
|
|
+ channelInfo: {
|
|
|
+ type: Object as PropType<SiteApi.SiteChannelItem>,
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const emit = defineEmits(['click']);
|
|
|
+
|
|
|
+const webSite = useWebStore();
|
|
|
+
|
|
|
+const route = useRoute();
|
|
|
+
|
|
|
+const listRef = ref<HTMLDivElement | null>(null);
|
|
|
+const { createObserver } = useLazyLoad<HTMLDivElement>();
|
|
|
+
|
|
|
+const handleClick = (item: BasicTreeOptionResult) => {
|
|
|
+ state.typeId = item.value;
|
|
|
+ emit('click', { ...item });
|
|
|
+};
|
|
|
+
|
|
|
+const state = reactive<{
|
|
|
+ channelId: number;
|
|
|
+ listData: BasicTreeOptionResult[];
|
|
|
+ loading: boolean;
|
|
|
+ typeId: boolean | number | string | undefined;
|
|
|
+}>({
|
|
|
+ listData: [],
|
|
|
+ loading: false,
|
|
|
+ channelId: Number(route.query.channelId ?? 0),
|
|
|
+ typeId: '',
|
|
|
+});
|
|
|
+
|
|
|
+const fetch = async () => {
|
|
|
+ try {
|
|
|
+ state.loading = true;
|
|
|
+ state.listData = await ArticleApi.getTypeOptions({
|
|
|
+ siteId: webSite.config?.id ?? 0,
|
|
|
+ channelId: state.channelId,
|
|
|
+ });
|
|
|
+ if (state.listData.length > 0) {
|
|
|
+ state.typeId = state.listData[0]?.value;
|
|
|
+ emit('click', { ...state.listData[0] });
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ state.loading = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ if (listRef.value) {
|
|
|
+ createObserver(listRef.value, () => fetch());
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <Loading :spinning="state.loading" :text="$t('page.common.loading')">
|
|
|
+ <div
|
|
|
+ class="bg-background shadow-primary-200 dark:shadow-heavy max-w-full rounded shadow-md"
|
|
|
+ >
|
|
|
+ <ul class="divide-primary-100 dark:divide-border divide-y" ref="listRef">
|
|
|
+ <li
|
|
|
+ class="bg-primary-400 items-content dark:bg-primary/50 flex gap-4 px-4 py-3 font-bold"
|
|
|
+ >
|
|
|
+ <div class="flex items-center text-white">
|
|
|
+ <svg
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ fill="none"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke="currentColor"
|
|
|
+ class="h-6 w-6"
|
|
|
+ aria-label="Dashboard icon"
|
|
|
+ role="graphics-symbol"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ stroke-linecap="round"
|
|
|
+ stroke-linejoin="round"
|
|
|
+ d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="flex min-h-[2rem] w-full min-w-0 flex-col items-start justify-center gap-0"
|
|
|
+ >
|
|
|
+ <h4 class="text-base text-white">{{ channelInfo.title }}</h4>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ <li
|
|
|
+ class="flex cursor-pointer items-start gap-4 px-4 py-3"
|
|
|
+ v-for="(item, index) in state.listData"
|
|
|
+ :key="index"
|
|
|
+ :class="
|
|
|
+ cn(
|
|
|
+ state.typeId === item.value
|
|
|
+ ? 'bg-primary/30 text-primary-700 dark:text-primary'
|
|
|
+ : 'dark:text-foreground text-slate-700',
|
|
|
+ 'hover:bg-primary/10 hover:text-primary-600',
|
|
|
+ )
|
|
|
+ "
|
|
|
+ @click="handleClick(item)"
|
|
|
+ >
|
|
|
+ <a
|
|
|
+ class="flex min-h-[2rem] w-full min-w-0 flex-col items-start justify-center gap-0"
|
|
|
+ href="#"
|
|
|
+ >
|
|
|
+ <h4 class="text-base">
|
|
|
+ {{ item.label }}
|
|
|
+ </h4>
|
|
|
+ </a>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </Loading>
|
|
|
+</template>
|