archy/neode-ui/src/views/appDetails/AppContentSection.vue
Dorian 69e25410b0 refactor: split Marketplace, Server, Home, AppDetails views; minor frontend quality fixes
- F29-F32: Split 4 views (Marketplace 1293→505, Server 1132→486, Home 1059→394, AppDetails 1036→386)
- F20: Add aria-current="page" to Dashboard nav links
- F21: Add 150ms search debounce in Marketplace and Apps views
- F22: Reduce backdrop-filter blur to 8px on mobile for GPU performance
- F23: Track and clear WebSocket connect check interval in all paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 03:01:38 +00:00

86 lines
3.6 KiB
Vue

<template>
<div class="lg:col-span-2 space-y-6">
<!-- Screenshots Gallery -->
<div class="glass-card p-6">
<h2 class="text-2xl font-bold text-white mb-4">{{ t('appDetails.screenshots') }}</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div
v-for="i in 4"
:key="i"
class="aspect-video rounded-xl bg-white/5 border border-white/10 flex items-center justify-center hover:bg-white/10 transition-colors cursor-pointer"
>
<svg class="w-16 h-16 text-white/20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
</div>
</div>
<p class="text-white/60 text-sm mt-3 text-center">{{ t('appDetails.screenshotPlaceholder') }}</p>
</div>
<!-- Bitcoin Sync Warning (for dependent apps) -->
<div v-if="needsBitcoinSync && !bitcoinSynced" class="glass-card p-5 border border-orange-500/30">
<div class="flex items-center gap-3 mb-3">
<svg class="w-6 h-6 text-orange-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z" />
</svg>
<div class="flex-1">
<p class="text-orange-300 font-semibold text-sm">Bitcoin is syncing</p>
<p class="text-white/60 text-xs mt-0.5">
Some features may be unavailable until Bitcoin finishes syncing.
Wallet connections and block data require a fully synced node.
</p>
</div>
</div>
<div class="w-full h-2 bg-white/10 rounded-full overflow-hidden">
<div
class="h-full rounded-full bg-orange-400 transition-all duration-500"
:style="{ width: Math.min(bitcoinSyncPercent, 100) + '%' }"
></div>
</div>
<p class="text-xs text-white/40 mt-1.5">
{{ bitcoinSyncPercent.toFixed(1) }}% synced Block {{ bitcoinBlockHeight.toLocaleString() }}
</p>
</div>
<!-- Description -->
<div class="glass-card p-6">
<h2 class="text-2xl font-bold text-white mb-4">{{ t('appDetails.about', { name: pkg.manifest.title }) }}</h2>
<p class="text-white/80 leading-relaxed whitespace-pre-line">
{{ pkg.manifest.description.long }}
</p>
</div>
<!-- Features (if available) -->
<div v-if="features.length > 0" class="glass-card p-6">
<h2 class="text-2xl font-bold text-white mb-4">{{ t('appDetails.features') }}</h2>
<ul class="space-y-3">
<li
v-for="(feature, index) in features"
:key="index"
class="flex items-start gap-3 text-white/80"
>
<svg class="w-6 h-6 text-green-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span>{{ feature }}</span>
</li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
defineProps<{
pkg: Record<string, any>
features: string[]
needsBitcoinSync: boolean
bitcoinSynced: boolean
bitcoinSyncPercent: number
bitcoinBlockHeight: number
}>()
</script>