
This commit includes several improvements and new features: - Updated the WebSocket connection logic in `websocket.py` to include connection status messages and periodic pings for maintaining the connection. - Introduced new skeleton components (`Skeleton.vue`, `SkeletonDashboard.vue`, `SkeletonList.vue`) for improved loading states in the UI, enhancing user experience during data fetching. - Refactored the Vite configuration to support advanced code splitting and caching strategies, optimizing the build process. - Enhanced ESLint configuration for better compatibility with project structure. These changes aim to improve real-time communication, user interface responsiveness, and overall application performance.
124 lines
5.6 KiB
Vue
124 lines
5.6 KiB
Vue
<template>
|
|
<div :class="['space-y-6', className]">
|
|
<!-- Header Section -->
|
|
<div class="flex items-center justify-between">
|
|
<div class="space-y-2">
|
|
<Skeleton variant="text" size="xl" width="300px" />
|
|
<Skeleton variant="text" size="md" width="200px" />
|
|
</div>
|
|
<Skeleton variant="avatar" size="lg" />
|
|
</div>
|
|
|
|
<!-- Stats Cards Row -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
<div v-for="i in 4" :key="i"
|
|
class="p-6 rounded-xl bg-white dark:bg-stone-900 border border-stone-200 dark:border-stone-800">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<Skeleton variant="circular" size="md" />
|
|
<Skeleton variant="text" size="sm" width="60px" />
|
|
</div>
|
|
<Skeleton variant="text" size="xl" width="80px" />
|
|
<Skeleton variant="text" size="sm" width="120px" className="mt-2" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Content Grid -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
<!-- Left Column - Priority Items -->
|
|
<div class="lg:col-span-2 space-y-6">
|
|
<!-- Priority Section -->
|
|
<div class="bg-white dark:bg-stone-900 rounded-xl border border-stone-200 dark:border-stone-800 p-6">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<Skeleton variant="text" size="lg" width="150px" />
|
|
<Skeleton variant="button" size="sm" />
|
|
</div>
|
|
|
|
<div class="space-y-3">
|
|
<div v-for="i in 3" :key="i"
|
|
class="flex items-center gap-4 p-3 rounded-lg bg-stone-50 dark:bg-stone-800">
|
|
<Skeleton variant="circular" size="sm" />
|
|
<div class="flex-1 space-y-1">
|
|
<Skeleton variant="text" size="md" :width="priorityWidths[i - 1]" />
|
|
<Skeleton variant="text" size="sm" width="100px" />
|
|
</div>
|
|
<Skeleton variant="button" size="sm" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Activity Feed -->
|
|
<div class="bg-white dark:bg-stone-900 rounded-xl border border-stone-200 dark:border-stone-800 p-6">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<Skeleton variant="text" size="lg" width="120px" />
|
|
<Skeleton variant="text" size="sm" width="80px" />
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div v-for="i in 4" :key="i" class="flex gap-3">
|
|
<Skeleton variant="avatar" size="sm" />
|
|
<div class="flex-1 space-y-1">
|
|
<Skeleton variant="text" size="sm" :width="activityWidths[i - 1]" />
|
|
<Skeleton variant="text" size="sm" width="60px" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right Column - Sidebar Widgets -->
|
|
<div class="space-y-6">
|
|
<!-- Quick Stats Widget -->
|
|
<div class="bg-white dark:bg-stone-900 rounded-xl border border-stone-200 dark:border-stone-800 p-6">
|
|
<Skeleton variant="text" size="lg" width="120px" className="mb-4" />
|
|
|
|
<div class="space-y-3">
|
|
<div v-for="i in 3" :key="i" class="flex justify-between items-center">
|
|
<Skeleton variant="text" size="sm" width="80px" />
|
|
<Skeleton variant="text" size="sm" width="40px" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Widget -->
|
|
<div class="bg-white dark:bg-stone-900 rounded-xl border border-stone-200 dark:border-stone-800 p-6">
|
|
<Skeleton variant="text" size="lg" width="100px" className="mb-4" />
|
|
|
|
<div class="space-y-4">
|
|
<div v-for="i in 2" :key="i" class="space-y-2">
|
|
<div class="flex justify-between">
|
|
<Skeleton variant="text" size="sm" width="70px" />
|
|
<Skeleton variant="text" size="sm" width="30px" />
|
|
</div>
|
|
<Skeleton variant="rectangular" height="8px" className="rounded-full" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions Widget -->
|
|
<div class="bg-white dark:bg-stone-900 rounded-xl border border-stone-200 dark:border-stone-800 p-6">
|
|
<Skeleton variant="text" size="lg" width="110px" className="mb-4" />
|
|
|
|
<div class="space-y-3">
|
|
<Skeleton variant="button" size="md" className="w-full" v-for="i in 3" :key="i" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import Skeleton from './Skeleton.vue';
|
|
|
|
export interface SkeletonDashboardProps {
|
|
className?: string;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<SkeletonDashboardProps>(), {
|
|
className: ''
|
|
});
|
|
|
|
// Varied widths for realistic appearance
|
|
const priorityWidths = ['70%', '85%', '60%'];
|
|
const activityWidths = ['80%', '65%', '90%', '75%'];
|
|
</script> |