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,306 @@
<template>
<Transition name="modal-fade">
<div v-if="isOpen" class="auth-modal-overlay" @click.self="closeModal">
<div class="auth-modal-container">
<div class="auth-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">
{{ mode === 'login' ? 'Welcome Back' : 'Join IndeedHub' }}
</h2>
<p class="text-white/60">
{{ mode === 'login' ? 'Sign in to continue' : 'Create an account to get started' }}
</p>
</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>
<!-- Cognito Auth Form -->
<form @submit.prevent="handleSubmit" class="space-y-4">
<!-- Legal Name (Register only) -->
<div v-if="mode === 'register'" class="form-group">
<label class="block text-white/80 text-sm font-medium mb-2">Full Name</label>
<input
v-model="formData.legalName"
type="text"
required
class="auth-input"
placeholder="John Doe"
/>
</div>
<!-- Email -->
<div class="form-group">
<label class="block text-white/80 text-sm font-medium mb-2">Email</label>
<input
v-model="formData.email"
type="email"
required
class="auth-input"
placeholder="you@example.com"
/>
</div>
<!-- Password -->
<div class="form-group">
<label class="block text-white/80 text-sm font-medium mb-2">Password</label>
<input
v-model="formData.password"
type="password"
required
class="auth-input"
:placeholder="mode === 'login' ? 'Enter your password' : 'Create a password'"
/>
</div>
<!-- Forgot Password Link (Login only) -->
<div v-if="mode === 'login'" class="text-right">
<a href="#" @click.prevent="mode = 'forgot'" class="text-sm text-white/60 hover:text-white transition-colors">
Forgot password?
</a>
</div>
<!-- Submit Button -->
<button
type="submit"
:disabled="isLoading"
class="hero-play-button w-full flex items-center justify-center"
>
<span v-if="!isLoading">{{ mode === 'login' ? 'Sign In' : 'Create Account' }}</span>
<span v-else>Loading...</span>
</button>
</form>
<!-- Divider -->
<div class="relative my-6">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-white/10"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-4 bg-transparent text-white/40">or</span>
</div>
</div>
<!-- Nostr Login Button -->
<button
@click="handleNostrLogin"
:disabled="isLoading"
class="hero-info-button w-full flex items-center justify-center gap-2"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z"/>
</svg>
Sign in with Nostr
</button>
<!-- Toggle Mode -->
<div class="mt-6 text-center text-sm text-white/60">
{{ mode === 'login' ? "Don't have an account?" : "Already have an account?" }}
<button
@click="toggleMode"
class="ml-1 text-white hover:text-white/80 font-medium transition-colors"
>
{{ mode === 'login' ? 'Sign up' : 'Sign in' }}
</button>
</div>
</div>
</div>
</div>
</Transition>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useAuth } from '../composables/useAuth'
interface Props {
isOpen: boolean
defaultMode?: 'login' | 'register'
}
interface Emits {
(e: 'close'): void
(e: 'success'): void
}
const props = withDefaults(defineProps<Props>(), {
defaultMode: 'login',
})
const emit = defineEmits<Emits>()
const { login, loginWithNostr, register, isLoading: authLoading } = useAuth()
const mode = ref<'login' | 'register' | 'forgot'>(props.defaultMode)
const formData = ref({
email: '',
password: '',
legalName: '',
})
const errorMessage = ref<string | null>(null)
const isLoading = computed(() => authLoading.value)
function closeModal() {
emit('close')
// Reset form
formData.value = { email: '', password: '', legalName: '' }
errorMessage.value = null
}
function toggleMode() {
mode.value = mode.value === 'login' ? 'register' : 'login'
errorMessage.value = null
}
async function handleSubmit() {
errorMessage.value = null
try {
if (mode.value === 'login') {
await login(formData.value.email, formData.value.password)
} else if (mode.value === 'register') {
await register(formData.value.email, formData.value.password, formData.value.legalName)
}
emit('success')
closeModal()
} catch (error: any) {
errorMessage.value = error.message || 'Authentication failed. Please try again.'
}
}
async function handleNostrLogin() {
errorMessage.value = null
try {
// Check for Nostr extension (NIP-07)
if (!window.nostr) {
errorMessage.value = 'Nostr extension not found. Please install a Nostr browser extension like Alby or nos2x.'
return
}
// Get public key from extension
const pubkey = await window.nostr.getPublicKey()
// Create authentication event
const authEvent = {
kind: 27235, // NIP-98 HTTP Auth
created_at: Math.floor(Date.now() / 1000),
tags: [
['u', window.location.origin],
['method', 'POST'],
],
content: '',
}
// Sign event with extension
const signedEvent = await window.nostr.signEvent(authEvent)
// Create session with backend
await loginWithNostr(pubkey, signedEvent.sig, signedEvent)
emit('success')
closeModal()
} catch (error: any) {
console.error('Nostr login failed:', error)
errorMessage.value = error.message || 'Nostr authentication failed. Please try again.'
}
}
// Declare window.nostr for TypeScript
declare global {
interface Window {
nostr?: {
getPublicKey: () => Promise<string>
signEvent: (event: any) => Promise<any>
}
}
}
</script>
<style scoped>
.auth-modal-overlay {
position: fixed;
inset: 0;
z-index: 9998;
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;
}
.auth-modal-container {
width: 100%;
max-width: 480px;
max-height: 90vh;
overflow-y: auto;
}
.auth-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;
}
.auth-input {
width: 100%;
padding: 12px 16px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
color: white;
font-size: 14px;
transition: all 0.3s ease;
}
.auth-input:focus {
outline: none;
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.2);
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.05);
}
.auth-input::placeholder {
color: rgba(255, 255, 255, 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 .auth-modal-content {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.modal-fade-enter-from .auth-modal-content {
transform: scale(0.95);
opacity: 0;
}
</style>