Enhance deployment script and update package dependencies

- Added detailed labels to the deployment script for IndeedHub, including title, version, description, license, icon, and repository URL.
- Updated package dependencies in package.json and package-lock.json, including upgrading 'nostr-tools' to version 2.23.0 and adding 'axios' and '@tanstack/vue-query'.
- Improved README with a modern description of the platform and updated project structure details.

This commit enhances the clarity of the deployment process and ensures the project is using the latest dependencies for better performance and features.
This commit is contained in:
Dorian
2026-02-12 10:30:47 +00:00
parent dacfa7a822
commit c970f5b29f
43 changed files with 6906 additions and 603 deletions

View File

@@ -0,0 +1,251 @@
<template>
<Transition name="modal-fade">
<div v-if="isOpen" class="modal-overlay" @click.self="closeModal">
<div class="modal-container">
<div class="modal-content">
<!-- Close Button -->
<button @click="closeModal" class="absolute top-4 right-4 text-white/60 hover:text-white transition-colors">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<!-- Header -->
<div class="text-center mb-8">
<h2 class="text-3xl font-bold text-white mb-2">Choose Your Plan</h2>
<p class="text-white/60">Unlimited streaming. Cancel anytime.</p>
</div>
<!-- Period Toggle -->
<div class="flex justify-center mb-8">
<div class="inline-flex rounded-xl bg-white/5 p-1">
<button
@click="period = 'monthly'"
:class="[
'px-6 py-2 rounded-lg font-medium transition-all',
period === 'monthly'
? 'bg-white text-black'
: 'text-white/60 hover:text-white'
]"
>
Monthly
</button>
<button
@click="period = 'annual'"
:class="[
'px-6 py-2 rounded-lg font-medium transition-all flex items-center gap-2',
period === 'annual'
? 'bg-white text-black'
: 'text-white/60 hover:text-white'
]"
>
Annual
<span class="text-xs bg-orange-500 text-white px-2 py-0.5 rounded-full">Save 17%</span>
</button>
</div>
</div>
<!-- Error Message -->
<div v-if="errorMessage" class="mb-4 p-3 rounded-lg bg-red-500/20 border border-red-500/30 text-red-400 text-sm">
{{ errorMessage }}
</div>
<!-- Subscription Tiers -->
<div class="grid md:grid-cols-3 gap-4 mb-6">
<div
v-for="tier in tiers"
:key="tier.tier"
:class="[
'tier-card',
selectedTier === tier.tier && 'selected'
]"
@click="selectedTier = tier.tier"
>
<h3 class="text-xl font-bold text-white mb-2">{{ tier.name }}</h3>
<div class="mb-4">
<span class="text-3xl font-bold text-white">
${{ period === 'monthly' ? tier.monthlyPrice : tier.annualPrice }}
</span>
<span class="text-white/60 text-sm">
/{{ period === 'monthly' ? 'month' : 'year' }}
</span>
</div>
<ul class="space-y-2 text-sm text-white/80">
<li v-for="feature in tier.features" :key="feature" class="flex items-start gap-2">
<svg class="w-5 h-5 text-green-400 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
</svg>
{{ feature }}
</li>
</ul>
</div>
</div>
<!-- Subscribe Button -->
<button
@click="handleSubscribe"
:disabled="isLoading || !selectedTier"
class="hero-play-button w-full flex items-center justify-center"
>
<span v-if="!isLoading">Subscribe to {{ selectedTierName }}</span>
<span v-else>Processing...</span>
</button>
<p class="text-center text-xs text-white/40 mt-4">
By subscribing, you agree to our Terms of Service and Privacy Policy.
</p>
</div>
</div>
</div>
</Transition>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { subscriptionService } from '../services/subscription.service'
interface Props {
isOpen: boolean
}
interface Emits {
(e: 'close'): void
(e: 'success'): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
const period = ref<'monthly' | 'annual'>('monthly')
const selectedTier = ref<string>('film-buff')
const tiers = ref<any[]>([])
const isLoading = ref(false)
const errorMessage = ref<string | null>(null)
const selectedTierName = computed(() => {
const tier = tiers.value.find((t) => t.tier === selectedTier.value)
return tier?.name || ''
})
onMounted(async () => {
tiers.value = await subscriptionService.getSubscriptionTiers()
})
function closeModal() {
emit('close')
errorMessage.value = null
}
async function handleSubscribe() {
if (!selectedTier.value) return
isLoading.value = true
errorMessage.value = null
try {
// Check if we're in development mode
const useMockData = import.meta.env.VITE_USE_MOCK_DATA === 'true' || import.meta.env.DEV
if (useMockData) {
// Mock subscription for development
console.log('🔧 Development mode: Mock subscription successful')
console.log(`📝 Subscribed to: ${selectedTierName.value} (${period.value})`)
await new Promise(resolve => setTimeout(resolve, 500))
emit('success')
closeModal()
return
}
// Real API call
await subscriptionService.subscribe({
tier: selectedTier.value as any,
period: period.value,
})
emit('success')
closeModal()
} catch (error: any) {
errorMessage.value = error.message || 'Subscription failed. Please try again.'
} finally {
isLoading.value = false
}
}
</script>
<style scoped>
.modal-overlay {
position: fixed;
inset: 0;
z-index: 9999;
background: rgba(0, 0, 0, 0.85);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
}
.modal-container {
width: 100%;
max-width: 1024px;
max-height: 90vh;
overflow-y: auto;
}
.modal-content {
position: relative;
background: rgba(0, 0, 0, 0.65);
backdrop-filter: blur(40px);
-webkit-backdrop-filter: blur(40px);
border-radius: 24px;
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.5),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
padding: 32px;
}
.tier-card {
background: rgba(255, 255, 255, 0.05);
border: 2px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 24px;
cursor: pointer;
transition: all 0.3s ease;
}
.tier-card:hover {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.15);
transform: translateY(-2px);
}
.tier-card.selected {
background: rgba(247, 147, 26, 0.1);
border-color: #F7931A;
box-shadow: 0 0 20px rgba(247, 147, 26, 0.3);
}
/* Modal Transitions */
.modal-fade-enter-active,
.modal-fade-leave-active {
transition: opacity 0.3s ease;
}
.modal-fade-enter-from,
.modal-fade-leave-to {
opacity: 0;
}
.modal-fade-enter-active .modal-content {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.modal-fade-enter-from .modal-content {
transform: scale(0.95);
opacity: 0;
}
</style>