Implement backend API and database services in Docker setup
- Added a new `api` service for the NestJS backend, including health checks and dependencies on PostgreSQL, Redis, and MinIO. - Introduced PostgreSQL and Redis services with health checks and configurations for data persistence. - Added MinIO for S3-compatible object storage and a one-shot service to initialize required buckets. - Updated the Nginx configuration to proxy requests to the new backend API and MinIO storage. - Enhanced the Dockerfile to support the new API environment variables and configurations. - Updated the `package.json` and `package-lock.json` to include new dependencies for QR code generation and other utilities. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -220,16 +220,32 @@
|
||||
</svg>
|
||||
<span>My Library</span>
|
||||
</button>
|
||||
|
||||
<!-- Content Source Toggle -->
|
||||
<button @click="handleSourceToggle" class="profile-menu-item flex items-center gap-3 px-4 py-2.5 w-full text-left">
|
||||
<!-- Backstage (filmmaker only) -->
|
||||
<button v-if="isFilmmakerUser" @click="navigateTo('/backstage')" class="profile-menu-item flex items-center gap-3 px-4 py-2.5 w-full text-left">
|
||||
<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="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 4V20M17 4V20M3 8H7M17 8H21M3 12H21M3 16H7M17 16H21M4 20H20C20.5523 20 21 19.5523 21 19V5C21 4.44772 20.5523 4 20 4H4C3.44772 4 3 4.44772 3 5V19C3 19.5523 3.44772 20 4 20Z" />
|
||||
</svg>
|
||||
<span class="flex-1">{{ contentSourceStore.activeSource === 'indeehub' ? 'IndeeHub Films' : 'TopDoc Films' }}</span>
|
||||
<span class="text-[10px] text-white/40 uppercase tracking-wider">Switch</span>
|
||||
<span>Backstage</span>
|
||||
</button>
|
||||
|
||||
<!-- Content Source Selector -->
|
||||
<div class="px-4 py-2">
|
||||
<p class="text-[10px] text-white/40 uppercase tracking-wider mb-2">Content Source</p>
|
||||
<div class="flex flex-col gap-1">
|
||||
<button
|
||||
v-for="source in contentSourceStore.availableSources"
|
||||
:key="source.id"
|
||||
@click="handleSourceSelect(source.id)"
|
||||
class="profile-menu-item flex items-center gap-3 px-3 py-2 w-full text-left rounded-lg transition-all"
|
||||
:class="contentSourceStore.activeSource === source.id ? 'bg-white/10 text-white' : 'text-white/60 hover:text-white'"
|
||||
>
|
||||
<span class="w-2 h-2 rounded-full" :class="contentSourceStore.activeSource === source.id ? 'bg-[#F7931A]' : 'bg-white/20'"></span>
|
||||
<span class="flex-1 text-sm">{{ source.label }}</span>
|
||||
<span v-if="contentSourceStore.activeSource === source.id" class="text-[10px] text-[#F7931A] uppercase tracking-wider">Active</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-white/10 my-1"></div>
|
||||
<button @click="handleLogout" class="profile-menu-item flex items-center gap-3 px-4 py-2.5 text-red-400 w-full text-left">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
@@ -311,7 +327,7 @@ const emit = defineEmits<Emits>()
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { user, isAuthenticated, loginWithNostr: appLoginWithNostr, logout: appLogout } = useAuth()
|
||||
const { user, isAuthenticated, isFilmmaker: isFilmmakerComputed, loginWithNostr: appLoginWithNostr, logout: appLogout } = useAuth()
|
||||
const {
|
||||
isLoggedIn: nostrLoggedIn,
|
||||
activePubkey: nostrActivePubkey,
|
||||
@@ -332,13 +348,16 @@ const {
|
||||
|
||||
const contentSourceStore = useContentSourceStore()
|
||||
const contentStore = useContentStore()
|
||||
const isFilmmakerUser = isFilmmakerComputed
|
||||
|
||||
/** Toggle between IndeeHub and TopDocFilms catalogs, then reload content */
|
||||
function handleSourceToggle() {
|
||||
contentSourceStore.toggle()
|
||||
/** Switch content source and reload */
|
||||
function handleSourceSelect(sourceId: string) {
|
||||
contentSourceStore.setSource(sourceId as any)
|
||||
contentStore.fetchContent()
|
||||
}
|
||||
|
||||
// Source toggle is now handled by handleSourceSelect above
|
||||
|
||||
const dropdownOpen = ref(false)
|
||||
const personaMenuOpen = ref(false)
|
||||
const algosMenuOpen = ref(false)
|
||||
@@ -352,6 +371,10 @@ const searchWrapperRef = ref<HTMLElement | null>(null)
|
||||
|
||||
/** All films from the active content source for searching */
|
||||
const allContent = computed<Content[]>(() => {
|
||||
// When using API source, search from the content store's loaded data
|
||||
if (contentSourceStore.activeSource === 'indeehub-api') {
|
||||
return Object.values(contentStore.contentRows).flat()
|
||||
}
|
||||
return contentSourceStore.activeSource === 'topdocfilms'
|
||||
? topDocFilms
|
||||
: indeeHubFilms
|
||||
|
||||
Reference in New Issue
Block a user