develop-updateui #1
@@ -19,26 +19,26 @@
|
|||||||
* ||| / //
|
* ||| / //
|
||||||
* ||| /
|
* ||| /
|
||||||
*/
|
*/
|
||||||
|
import { tinyassert } from "@hiogawa/utils";
|
||||||
import {
|
import {
|
||||||
reactive,
|
getCurrentInstance,
|
||||||
watch,
|
inject,
|
||||||
ref,
|
isReadonly,
|
||||||
toRefs,
|
isRef,
|
||||||
// isRef,
|
// isRef,
|
||||||
onMounted,
|
onMounted,
|
||||||
onUnmounted,
|
|
||||||
getCurrentInstance,
|
|
||||||
isReadonly,
|
|
||||||
onServerPrefetch,
|
onServerPrefetch,
|
||||||
isRef,
|
onUnmounted,
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
toRefs,
|
||||||
useSSRContext,
|
useSSRContext,
|
||||||
type FunctionPlugin,
|
watch,
|
||||||
inject
|
type FunctionPlugin
|
||||||
} from 'vue'
|
} from 'vue';
|
||||||
import webPreset from './lib/web-preset'
|
import SWRVCache from './cache';
|
||||||
import SWRVCache from './cache'
|
import webPreset from './lib/web-preset';
|
||||||
import type { IConfig, IKey, IResponse, fetcherFn, revalidateOptions } from './types'
|
import type { IConfig, IKey, IResponse, fetcherFn, revalidateOptions } from './types';
|
||||||
import { tinyassert } from "@hiogawa/utils";
|
|
||||||
|
|
||||||
type StateRef<Data, Error> = {
|
type StateRef<Data, Error> = {
|
||||||
data: Data, error: Error, isValidating: boolean, isLoading: boolean, revalidate: Function, key: any
|
data: Data, error: Error, isValidating: boolean, isLoading: boolean, revalidate: Function, key: any
|
||||||
@@ -183,7 +183,7 @@ function useSWRV<Data = any, Error = any>(...args: any[]): IResponse<Data, Error
|
|||||||
// #region ssr
|
// #region ssr
|
||||||
const isSsrHydration = Boolean(
|
const isSsrHydration = Boolean(
|
||||||
!IS_SERVER &&
|
!IS_SERVER &&
|
||||||
window !== undefined && (window as any).__SSR_STATE__.swrv)
|
window !== undefined && (window as any).window.swrv)
|
||||||
// #endregion
|
// #endregion
|
||||||
if (args.length >= 1) {
|
if (args.length >= 1) {
|
||||||
key = args[0]
|
key = args[0]
|
||||||
@@ -211,7 +211,7 @@ function useSWRV<Data = any, Error = any>(...args: any[]): IResponse<Data, Error
|
|||||||
if (isSsrHydration) {
|
if (isSsrHydration) {
|
||||||
// component was ssrHydrated, so make the ssr reactive as the initial data
|
// component was ssrHydrated, so make the ssr reactive as the initial data
|
||||||
|
|
||||||
const swrvState = (window as any).__SSR_STATE__.swrv || []
|
const swrvState = (window as any).window.swrv || []
|
||||||
const swrvKey = nanoHex(vm.$.type.__name ?? vm.$.type.name)
|
const swrvKey = nanoHex(vm.$.type.__name ?? vm.$.type.name)
|
||||||
if (swrvKey !== undefined && swrvKey !== null) {
|
if (swrvKey !== undefined && swrvKey !== null) {
|
||||||
const nodeState = swrvState[swrvKey] || []
|
const nodeState = swrvState[swrvKey] || []
|
||||||
@@ -466,5 +466,5 @@ export const vueSWR = (swrvConfig: Partial<IConfig> = defaultConfig): FunctionPl
|
|||||||
// app.provide('swrv', useSWRV)
|
// app.provide('swrv', useSWRV)
|
||||||
app.provide('swrv-config', swrvConfig)
|
app.provide('swrv-config', swrvConfig)
|
||||||
}
|
}
|
||||||
export { mutate }
|
export { mutate };
|
||||||
export default useSWRV
|
export default useSWRV
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, computed } from 'vue';
|
|
||||||
import { useAuthStore } from '@/stores/auth';
|
|
||||||
import { client, type ModelPlan } from '@/api/client';
|
import { client, type ModelPlan } from '@/api/client';
|
||||||
import PageHeader from '@/components/dashboard/PageHeader.vue';
|
import PageHeader from '@/components/dashboard/PageHeader.vue';
|
||||||
import Card from 'primevue/card';
|
import useSWRV from '@/lib/swr';
|
||||||
|
import { useAuthStore } from '@/stores/auth';
|
||||||
import Button from 'primevue/button';
|
import Button from 'primevue/button';
|
||||||
import Skeleton from 'primevue/skeleton';
|
|
||||||
import DataTable from 'primevue/datatable';
|
|
||||||
import Column from 'primevue/column';
|
import Column from 'primevue/column';
|
||||||
import Tag from 'primevue/tag';
|
import DataTable from 'primevue/datatable';
|
||||||
import ProgressBar from 'primevue/progressbar';
|
|
||||||
import Dialog from 'primevue/dialog';
|
import Dialog from 'primevue/dialog';
|
||||||
|
import ProgressBar from 'primevue/progressbar';
|
||||||
|
import Skeleton from 'primevue/skeleton';
|
||||||
|
import Tag from 'primevue/tag';
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
const auth = useAuthStore();
|
const auth = useAuthStore();
|
||||||
const plans = ref<ModelPlan[]>([]);
|
const plans = ref<ModelPlan[]>([]);
|
||||||
const loading = ref(true);
|
|
||||||
const error = ref<string | null>(null);
|
const error = ref<string | null>(null);
|
||||||
const subscribing = ref<string | null>(null);
|
const subscribing = ref<string | null>(null);
|
||||||
const showManageDialog = ref(false);
|
const showManageDialog = ref(false);
|
||||||
@@ -48,27 +47,27 @@ const currentPlan = computed(() => {
|
|||||||
if (!Array.isArray(plans.value)) return undefined;
|
if (!Array.isArray(plans.value)) return undefined;
|
||||||
return plans.value.find(p => p.id === currentPlanId.value);
|
return plans.value.find(p => p.id === currentPlanId.value);
|
||||||
});
|
});
|
||||||
|
const { isLoading } = useSWRV("plans", client.plans.plansList)
|
||||||
const fetchPlans = async () => {
|
// const fetchPlans = async () => {
|
||||||
loading.value = true;
|
// loading.value = true;
|
||||||
error.value = null;
|
// error.value = null;
|
||||||
try {
|
// try {
|
||||||
const response = await client.plans.plansList();
|
// const response = await client.plans.plansList();
|
||||||
if (response.data && Array.isArray(response.data)) {
|
// if (response.data && Array.isArray(response.data)) {
|
||||||
plans.value = response.data;
|
// plans.value = response.data;
|
||||||
} else if (response.data && Array.isArray((response.data as any).data)) {
|
// } else if (response.data && Array.isArray((response.data as any).data)) {
|
||||||
// Handle paginated or wrapped response
|
// // Handle paginated or wrapped response
|
||||||
plans.value = (response.data as any).data;
|
// plans.value = (response.data as any).data;
|
||||||
} else {
|
// } else {
|
||||||
plans.value = [];
|
// plans.value = [];
|
||||||
}
|
// }
|
||||||
} catch (err: any) {
|
// } catch (err: any) {
|
||||||
console.error(err);
|
// console.error(err);
|
||||||
error.value = err.message || 'Failed to load plans';
|
// error.value = err.message || 'Failed to load plans';
|
||||||
} finally {
|
// } finally {
|
||||||
loading.value = false;
|
// loading.value = false;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
const subscribe = async (plan: ModelPlan) => {
|
const subscribe = async (plan: ModelPlan) => {
|
||||||
if (!plan.id) return;
|
if (!plan.id) return;
|
||||||
@@ -145,10 +144,6 @@ const getStatusSeverity = (status: string) => {
|
|||||||
return 'info';
|
return 'info';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
fetchPlans();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -165,7 +160,7 @@ onMounted(() => {
|
|||||||
<div class="content max-w-7xl mx-auto space-y-12 pb-12">
|
<div class="content max-w-7xl mx-auto space-y-12 pb-12">
|
||||||
|
|
||||||
<!-- Hero Section: Current Plan & Usage -->
|
<!-- Hero Section: Current Plan & Usage -->
|
||||||
<div v-if="!loading" class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
<div v-if="!isLoading" class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
<!-- Current Plan Card -->
|
<!-- Current Plan Card -->
|
||||||
<div class="lg:col-span-2 relative overflow-hidden rounded-2xl bg-gradient-to-br from-gray-900 to-gray-800 text-white p-8 shadow-xl">
|
<div class="lg:col-span-2 relative overflow-hidden rounded-2xl bg-gradient-to-br from-gray-900 to-gray-800 text-white p-8 shadow-xl">
|
||||||
<!-- Background decorations -->
|
<!-- Background decorations -->
|
||||||
@@ -222,7 +217,7 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Loading State -->
|
<!-- Loading State -->
|
||||||
<div v-if="loading" class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
<div v-if="isLoading" class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||||
<div v-for="i in 3" :key="i" class="h-full">
|
<div v-for="i in 3" :key="i" class="h-full">
|
||||||
<Skeleton height="300px" borderRadius="16px"></Skeleton>
|
<Skeleton height="300px" borderRadius="16px"></Skeleton>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user