diff --git a/src/assets/scss/__animations.scss b/src/assets/scss/__animations.scss index 176d67d..e9b7f74 100644 --- a/src/assets/scss/__animations.scss +++ b/src/assets/scss/__animations.scss @@ -8,3 +8,21 @@ transform: translateY(0); } } + +@keyframes pulse-dot { + 0%, + 100% { + opacity: 1; + box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); + } + 50% { + opacity: 0.8; + box-shadow: 0 0 0 4px rgba(16, 185, 129, 0); + } +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} diff --git a/src/views/Home/components/NetworkTab.vue b/src/views/Home/components/NetworkTab.vue index 6389d35..385b118 100644 --- a/src/views/Home/components/NetworkTab.vue +++ b/src/views/Home/components/NetworkTab.vue @@ -1,16 +1,120 @@ @@ -19,7 +123,20 @@ const networkStatus = ref({ NETWORK STATUS - + + + + Loading network data... + + + + + {{ error }} + Retry Connection + + + + Network {{ networkStatus.network }} @@ -62,6 +179,14 @@ const networkStatus = ref({ Median Time UTC {{ networkStatus.medianTimeUTC }} + + + + + + {{ isConnected ? 'Connected - Live updates' : 'Connecting...' }} + + @@ -118,5 +243,83 @@ const networkStatus = ref({ font-family: var(--font-mono); } } + + // Loading State + .loading-state { + text-align: center; + padding: var(--spacing-4xl); + color: var(--text-secondary); + + .spinner { + width: 40px; + height: 40px; + margin: 0 auto var(--spacing-lg); + border: 4px solid var(--border-light); + border-top-color: var(--primary-color); + border-radius: 50%; + animation: spin 1s linear infinite; + } + + p { + margin: 0; + font-size: var(--font-md); + } + } + + // Error State + .error-state { + text-align: center; + padding: var(--spacing-4xl); + color: var(--error-color); + + p { + margin-bottom: var(--spacing-lg); + font-size: var(--font-md); + } + + .retry-button { + padding: var(--spacing-sm) var(--spacing-lg); + background: var(--primary-color); + color: var(--text-light); + border: none; + border-radius: var(--radius-md); + cursor: pointer; + font-size: var(--font-sm); + transition: var(--transition-all); + + &:hover { + background: var(--primary-hover); + } + } + } + + // Update Indicator + .update-indicator { + display: flex; + align-items: center; + justify-content: center; + gap: var(--spacing-sm); + margin-top: var(--spacing-2xl); + padding-top: var(--spacing-lg); + border-top: 1px solid var(--border-color); + + .update-dot { + width: 8px; + height: 8px; + background: var(--text-muted); + border-radius: 50%; + transition: var(--transition-all); + + &.connected { + background: var(--success-color); + animation: pulse-dot 2s infinite; + } + } + + .update-text { + font-size: var(--font-xs); + color: var(--text-muted); + } + } } diff --git a/vite.config.ts b/vite.config.ts index 8f1179e..8081623 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,11 +1,10 @@ import { fileURLToPath, URL } from 'node:url' - import { defineConfig } from 'vite' + import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import VueDevTools from 'vite-plugin-vue-devtools' -// https://vitejs.dev/config/ export default defineConfig({ server: { port: 3008,
Loading network data...
{{ error }}