2026-03-21 03:01:38 +00:00
|
|
|
<template>
|
|
|
|
|
<div class="space-y-6">
|
|
|
|
|
<!-- App Info Card -->
|
|
|
|
|
<div class="glass-card p-6">
|
|
|
|
|
<h3 class="text-lg font-bold text-white mb-4">{{ t('appDetails.information') }}</h3>
|
|
|
|
|
<div class="space-y-3">
|
|
|
|
|
<div class="flex items-center justify-between py-2 border-b border-white/10">
|
|
|
|
|
<span class="text-white/60 text-sm">{{ t('common.version') }}</span>
|
2026-04-09 11:47:35 +02:00
|
|
|
<div class="text-right">
|
|
|
|
|
<span class="text-white font-medium">v{{ pkg.manifest.version }}</span>
|
|
|
|
|
<span v-if="pkg['available-update']" class="text-orange-300 text-xs ml-2">
|
|
|
|
|
v{{ pkg['available-update'] }} available
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
2026-03-21 03:01:38 +00:00
|
|
|
</div>
|
|
|
|
|
<div v-if="pkg.manifest.author" class="flex items-center justify-between py-2 border-b border-white/10">
|
|
|
|
|
<span class="text-white/60 text-sm">{{ t('common.developer') }}</span>
|
|
|
|
|
<span class="text-white font-medium">{{ pkg.manifest.author }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center justify-between py-2 border-b border-white/10">
|
|
|
|
|
<span class="text-white/60 text-sm">{{ t('common.status') }}</span>
|
|
|
|
|
<span class="text-white font-medium capitalize">{{ pkg.state }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="pkg.manifest.license" class="flex items-center justify-between py-2 border-b border-white/10">
|
|
|
|
|
<span class="text-white/60 text-sm">{{ t('common.license') }}</span>
|
|
|
|
|
<span class="text-white font-medium">{{ pkg.manifest.license }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center justify-between py-2">
|
|
|
|
|
<span class="text-white/60 text-sm">{{ t('common.category') }}</span>
|
|
|
|
|
<span class="text-white font-medium">App</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Fedimint Services Card -->
|
|
|
|
|
<div v-if="packageKey === 'fedimint'" class="glass-card p-6">
|
|
|
|
|
<h3 class="text-lg font-bold text-white mb-4">{{ t('appDetails.services') }}</h3>
|
|
|
|
|
<div class="space-y-3">
|
|
|
|
|
<div class="flex items-center gap-3 py-2 border-b border-white/10">
|
|
|
|
|
<span class="w-2 h-2 rounded-full" :class="pkg.state === 'running' ? 'bg-green-400' : 'bg-yellow-400'"></span>
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
<p class="text-white/80 font-medium text-sm">{{ t('appDetails.guardian') }}</p>
|
|
|
|
|
<p class="text-white/50 text-xs capitalize">{{ pkg.state }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center gap-3 py-2">
|
|
|
|
|
<span class="w-2 h-2 rounded-full" :class="gatewayState === 'running' ? 'bg-green-400' : gatewayState === 'stopped' ? 'bg-yellow-400' : 'bg-red-400'"></span>
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
<p class="text-white/80 font-medium text-sm">{{ t('appDetails.gateway') }}</p>
|
|
|
|
|
<p class="text-white/50 text-xs capitalize">{{ gatewayState }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Access (LAN + Tor) Card -->
|
|
|
|
|
<div v-if="interfaceAddresses" class="glass-card p-6">
|
|
|
|
|
<h3 class="text-lg font-bold text-white mb-4">{{ t('appDetails.access') }}</h3>
|
|
|
|
|
<div class="space-y-3">
|
|
|
|
|
<div v-if="interfaceAddresses['lan-address']" class="flex items-start gap-3">
|
|
|
|
|
<svg class="w-5 h-5 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="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
|
|
|
|
|
</svg>
|
|
|
|
|
<div class="flex-1 min-w-0">
|
|
|
|
|
<p class="text-white/80 font-medium">{{ t('appDetails.lan') }}</p>
|
|
|
|
|
<a
|
|
|
|
|
:href="lanUrl"
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
|
class="text-blue-400 hover:text-blue-300 text-sm break-all"
|
|
|
|
|
>
|
|
|
|
|
{{ interfaceAddresses['lan-address'] }}
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="showTorAddress" class="flex items-start gap-3">
|
|
|
|
|
<svg class="w-5 h-5 text-amber-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="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
|
|
|
|
|
</svg>
|
|
|
|
|
<div class="flex-1 min-w-0">
|
|
|
|
|
<p class="text-white/80 font-medium">{{ t('appDetails.tor') }}</p>
|
|
|
|
|
<span class="text-amber-300/90 text-sm font-mono break-all">{{ torUrl }}</span>
|
|
|
|
|
<p class="text-white/50 text-xs mt-1">{{ t('appDetails.requiresTor') }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Requirements Card (hidden for web-only apps) -->
|
|
|
|
|
<div v-if="!isWebOnly" class="glass-card p-6">
|
|
|
|
|
<h3 class="text-lg font-bold text-white mb-4">{{ t('appDetails.requirements') }}</h3>
|
|
|
|
|
<div class="space-y-3">
|
|
|
|
|
<div class="flex items-start gap-3">
|
|
|
|
|
<svg class="w-5 h-5 text-blue-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 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
|
|
|
|
|
</svg>
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
<p class="text-white/80 font-medium">{{ t('appDetails.ram') }}</p>
|
|
|
|
|
<p class="text-white/60 text-sm">{{ t('appDetails.ramDesc') }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-start gap-3">
|
|
|
|
|
<svg class="w-5 h-5 text-purple-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="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4" />
|
|
|
|
|
</svg>
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
<p class="text-white/80 font-medium">{{ t('appDetails.storage') }}</p>
|
|
|
|
|
<p class="text-white/60 text-sm">{{ t('appDetails.storageDesc') }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Links Card -->
|
|
|
|
|
<div class="glass-card p-6">
|
|
|
|
|
<h3 class="text-lg font-bold text-white mb-4">{{ t('appDetails.links') }}</h3>
|
|
|
|
|
<div class="space-y-2">
|
|
|
|
|
<a
|
|
|
|
|
v-if="pkg.manifest.website"
|
|
|
|
|
:href="pkg.manifest.website"
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
|
class="flex items-center gap-2 text-blue-400 hover:text-blue-300 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
|
|
|
|
|
</svg>
|
|
|
|
|
{{ t('appDetails.website') }}
|
|
|
|
|
</a>
|
|
|
|
|
<a
|
|
|
|
|
href="#"
|
|
|
|
|
class="flex items-center gap-2 text-blue-400 hover:text-blue-300 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
|
|
|
|
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.840 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
|
|
|
|
</svg>
|
|
|
|
|
{{ t('appDetails.sourceCode') }}
|
|
|
|
|
</a>
|
|
|
|
|
<a
|
|
|
|
|
href="#"
|
|
|
|
|
class="flex items-center gap-2 text-blue-400 hover:text-blue-300 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
|
|
|
</svg>
|
|
|
|
|
{{ t('appDetails.documentation') }}
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
|
|
|
|
|
|
const { t } = useI18n()
|
|
|
|
|
|
|
|
|
|
defineProps<{
|
|
|
|
|
pkg: Record<string, any>
|
|
|
|
|
packageKey: string
|
|
|
|
|
isWebOnly: boolean
|
|
|
|
|
gatewayState: string
|
2026-03-22 03:30:21 +00:00
|
|
|
interfaceAddresses: { 'tor-address': string; 'lan-address': string | null } | null
|
2026-03-21 03:01:38 +00:00
|
|
|
lanUrl: string
|
|
|
|
|
torUrl: string
|
|
|
|
|
showTorAddress: boolean
|
|
|
|
|
}>()
|
|
|
|
|
</script>
|