diff --git a/src/components/PageLogin.vue b/src/components/PageLogin.vue index bb092cd..5d5812a 100644 --- a/src/components/PageLogin.vue +++ b/src/components/PageLogin.vue @@ -18,6 +18,7 @@ - + {{ props.mobileAnnouncement.listTitle }} @@ -330,6 +335,7 @@ interface ToolBarConfig { interface Props { layout: 'side-left' | 'side-right' | 'card' + withAnnouncement?: boolean branding: BrandingConfig illustration: IllustrationConfig announcementBoard: AnnouncementBoardConfig @@ -341,6 +347,7 @@ interface Props { const props = withDefaults(defineProps(), { layout: 'side-left', + withAnnouncement: true, branding: () => ({ title: 'Skyteck Login', organization: 'school', @@ -430,6 +437,7 @@ const mobileAnnouncementSheetVisible = ref(false) const mobileAnnouncementItems = computed(() => props.mobileAnnouncement.items ?? []) const showMobileAnnouncementBanner = computed(() => { + if (!props.withAnnouncement) return false if (props.mobileAnnouncement.show === false) return false return mobileAnnouncementItems.value.length > 0 }) diff --git a/src/stores/loginAnnouncements.ts b/src/composables/useLoginAnnouncements.ts similarity index 83% rename from src/stores/loginAnnouncements.ts rename to src/composables/useLoginAnnouncements.ts index bf246ec..8239cdc 100644 --- a/src/stores/loginAnnouncements.ts +++ b/src/composables/useLoginAnnouncements.ts @@ -1,5 +1,4 @@ -import { defineStore } from 'pinia' -import { computed, ref, watch } from 'vue' +import { computed, ref, toValue, watch, type MaybeRefOrGetter } from 'vue' export interface LoginAnnouncementItem { id: string | number @@ -25,6 +24,10 @@ export interface LoginMobileAnnouncementItem { createdAt?: string } +interface UseLoginAnnouncementsOptions { + enabled: MaybeRefOrGetter +} + const storageKey = 'sk_playground_login_announcements' const defaultItems: LoginAnnouncementItem[] = [ @@ -110,10 +113,11 @@ async function mockFetchMobileAnnouncementsApi(): Promise { - const items = ref(readItems()) +export function useLoginAnnouncements(options: UseLoginAnnouncementsOptions) { + const items = ref([]) const selectedId = ref(null) const mobileAnnouncements = ref([]) + const enabled = computed(() => toValue(options.enabled)) const listItems = computed(() => items.value.map((item) => ({ @@ -132,8 +136,8 @@ export const useLoginAnnouncementsStore = defineStore('loginAnnouncements', () = { label: '國中', value: 'junior' }, { label: '高中', value: 'senior' }, ], - items: listItems.value, - systemAnnouncements: mobileAnnouncements.value, + items: enabled.value ? listItems.value : [], + systemAnnouncements: enabled.value ? mobileAnnouncements.value : [], itemsPerPage: 5, dateHeader: '公告時間', schoolHeader: '公告學校', @@ -142,7 +146,7 @@ export const useLoginAnnouncementsStore = defineStore('loginAnnouncements', () = })) const selectedAnnouncement = computed(() => { - if (selectedId.value === null) return null + if (!enabled.value || selectedId.value === null) return null return items.value.find((item) => item.id === selectedId.value) ?? null }) @@ -151,59 +155,54 @@ export const useLoginAnnouncementsStore = defineStore('loginAnnouncements', () = }) const mobileAnnouncementConfig = computed(() => ({ - items: mobileAnnouncements.value, - show: mobileAnnouncements.value.length > 0, + items: enabled.value ? mobileAnnouncements.value : [], + show: enabled.value && mobileAnnouncements.value.length > 0, viewAllText: '查看全部', listTitle: '系統公告', closeText: '關閉', emptyText: '目前沒有公告', })) - const hydrate = () => { + function hydrate() { + if (!enabled.value) return + items.value = readItems() } - const replaceAll = (nextItems: LoginAnnouncementItem[]) => { - items.value = Array.isArray(nextItems) ? nextItems : [] - } + async function fetchMobileAnnouncements() { + if (!enabled.value) return - const selectById = (id: string | number) => { - selectedId.value = id - } - - const clearSelection = () => { - selectedId.value = null - } - - const fetchMobileAnnouncements = async () => { const result = await mockFetchMobileAnnouncementsApi() mobileAnnouncements.value = Array.isArray(result) ? result : [] } - const fetchMobileAnnouncement = async () => { + async function load() { + hydrate() await fetchMobileAnnouncements() } + function selectById(id: string | number) { + if (!enabled.value) return + + selectedId.value = id + } + watch( items, (val) => { + if (!enabled.value) return + writeItems(val) }, { deep: true } ) return { - items, - listItems, boardConfig, mobileAnnouncementConfig, selectedAnnouncement, selectedAnnouncementDetail, - hydrate, - replaceAll, + load, selectById, - clearSelection, - fetchMobileAnnouncements, - fetchMobileAnnouncement, } -}) +} diff --git a/src/views/Login.vue b/src/views/Login.vue index d5837da..1c4b861 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -8,6 +8,7 @@ :layout="formPositionLayout" :mobile-announcement="mobileAnnouncement" :toolbar="toolbar" + :with-announcement="withAnnouncement" @captcha-change="handleCaptchaChange" @captcha-refresh="handleCaptchaRefresh" @change-locale="handleChangeLocale" @@ -52,18 +53,17 @@