Files
archy/.claude/skills/polish-loading/SKILL.md
Dorian 07e46dce56 feat: add YAML frontmatter, bitcoin-conventions skill, path rules, and Gitea CI
- Added YAML frontmatter to all 8 polish-* skills and sweep skill
  so Claude can auto-invoke them
- New bitcoin-conventions skill with PROUX UX methodology, sats display,
  address validation, Tor preferences, Lightning patterns
- Path-specific rules for containers (security hardening) and frontend
  (Vue/glassmorphism conventions)
- Gitea Actions: nightly security review and weekly dependency audit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:35:17 +00:00

2.8 KiB

name, description
name description
polish-loading Add skeleton loaders, loading indicators, timeout warnings, and empty states to all Archipelago async views. Use when user says "polish loading", "add skeletons", "loading states", "empty states", or "blank screen fix".

Skill: Polish Loading States

Add skeleton loaders, loading indicators, timeout warnings, and empty states to all async views. No view should ever show a blank screen.

Skeleton Loader Component

Create or use a SkeletonLoader.vue component with the glassmorphism style:

  • Background: bg-white/5 with shimmer animation
  • Rounded corners matching the card it replaces
  • Animate with CSS @keyframes shimmer (translate gradient left to right)
  • Must use global classes from style.css, not inline Tailwind

Views to Fix

For EACH view in neode-ui/src/views/, verify these states exist:

1. Loading State

  • Show skeleton placeholders immediately on mount
  • Pattern:
    <template>
      <div v-if="isLoading">
        <!-- Skeleton matching the layout -->
      </div>
      <div v-else>
        <!-- Real content -->
      </div>
    </template>
    

2. Empty State

  • When data loads but is empty (zero items)
  • Show helpful message with CTA
  • Pattern:
    <div v-if="!isLoading && items.length === 0" class="glass-card text-center py-12">
      <p class="text-white/60">No apps installed yet</p>
      <router-link to="/marketplace" class="glass-button mt-4">Browse Marketplace</router-link>
    </div>
    

3. Timeout Warning

  • After 15 seconds of loading, show "Taking longer than expected..."
  • After 30 seconds, show troubleshooting options
  • Pattern:
    const loadingTooLong = ref(false)
    let timeout: ReturnType<typeof setTimeout>
    
    onMounted(() => {
      timeout = setTimeout(() => { loadingTooLong.value = true }, 15000)
    })
    
    watch(isLoading, (val) => { if (!val) clearTimeout(timeout) })
    

Priority Views (must have all 3 states)

  1. Apps.vue — app grid skeleton, "No apps installed" empty state
  2. AppDetails.vue — detail card skeleton, loading indicator
  3. Marketplace.vue — app card grid skeleton, "Loading apps..." with timeout
  4. Dashboard.vue — metric card skeletons
  5. Cloud.vue — file list skeleton, "No files" empty state
  6. Settings.vue — settings section skeleton
  7. Server.vue — server info skeleton

Verification

For each view, confirm:

  • isLoading ref exists and is set properly
  • Template has v-if="isLoading" skeleton section
  • Template has empty state for zero-data case
  • Loading timeout warning after 15s
  • Skeleton uses global classes, not inline Tailwind

Deploy After Fixes

Always deploy and verify on live server:

./scripts/deploy-to-target.sh --live

Test by throttling network in browser DevTools to observe loading states.