Skip to content

Collage Layout ​

File Information ​

  • Path: app/layouts/collage-layout.vue
  • Purpose: Main application layout with header, sidebar, and content area
  • Used For: Authenticated pages (dashboard, search, folders, collages, etc.)

Overview ​

The collage-layout is the primary layout for authenticated pages in the Brand Portal. It provides a consistent structure with a header, sidebar navigation, and main content area. This layout is used for all main application pages that require navigation and user interaction.

Structure ​

vue
<template>
  <v-app>
    <div class="main">
      <!-- Top Header -->
      <Header />
      <!-- Main Content Area -->
      <div class="collage-main">
        <!-- Left Sidebar Navigation -->
        <SideBar />
        <!-- Page Content -->
        <NuxtPage />
      </div>
    </div>
    <!-- Global Snackbar Notifications -->
    <Snackbar />
  </v-app>
</template>

Components ​

Header Component ​

  • Path: app/components/global/Header.vue
  • Purpose: Top navigation bar with search, user menu, and notifications
  • Features:
    • Search bar integration
    • User authentication state
    • Workspace switching
    • Notifications display
    • User profile menu
    • Responsive design
  • Path: app/components/global/SideBar.vue
  • Purpose: Left navigation sidebar
  • Features:
    • Navigation links (Home, Collages, Folders, Shared URLs)
    • Browse menu (Images, Documents, Audios, Videos, Trending, Recent Uploaded)
    • Collapsible design (mini mode)
    • Active route highlighting
    • SSR-safe implementation
    • Responsive (temporary drawer on mobile)

Snackbar Component ​

  • Path: app/components/global/Snackbar.vue
  • Purpose: Global notification snackbar
  • Features:
    • Success messages
    • Error messages
    • Warning messages
    • Info messages
    • Auto-dismiss functionality
    • Queue management

Features ​

Brand Integration ​

The layout loads brand details and applies them:

typescript
onMounted(async () => {
  try {
    if (!appDataStore.brand) {
      await appDataStore.fetchBrandDetails(route.params.brand_name as string)
      await nextTick()
      brand.value = appDataStore.brand || {}
    } else {
      brand.value = appDataStore.brand || {}
    }
    logo.value = appDataStore.logo || "/Collage-labinc-dark12c.svg"
  } catch (error) {
    console.error("Failed to load brand details:", error)
  }
})

SEO Configuration ​

The layout sets up SEO metadata:

typescript
useHead({
  title: () => `${brand.value?.brand_name || brandName.value} Brand Portal by Collage Inc`,
  link: computed(() => [
    {
      rel: "icon",
      type: "image/svg+xml",
      href: faviconUrl.value,
    },
  ]),
})

useSeoMeta({
  ogImage: logo.value || "/Collage-labinc-dark12c.svg",
  ogImageWidth: "1200",
  ogImageHeight: "630",
  ogImageAlt: `${brand.value?.brand_name || brandName.value} Logo`,
  ogTitle: `${brand.value?.brand_name || brandName.value} Brand Portal by Collage Inc`,
})

Dynamic Favicon ​

The layout watches for favicon changes and updates the DOM:

typescript
if (import.meta.client) {
  watch(faviconUrl, (newFavicon) => {
    if (newFavicon) {
      let link = document.querySelector('link[rel="icon"]') as HTMLLinkElement
      if (!link) {
        link = document.createElement('link')
        link.rel = 'icon'
        link.type = 'image/svg+xml'
        document.head.appendChild(link)
      }
      link.href = newFavicon
    }
  }, { immediate: true })
}

Usage ​

In Page Component ​

vue
<script setup lang="ts">
definePageMeta({
  layout: 'collage-layout'
})
</script>

<template>
  <div>
    <!-- Page content -->
  </div>
</template>

Default Behavior ​

If a page doesn't specify a layout, default.vue is used. To use collage-layout, explicitly specify it:

typescript
definePageMeta({
  layout: 'collage-layout'
})

Styling ​

Uses global SCSS classes:

  • .main - Main container
  • .collage-main - Main content area with sidebar
  • See Styling - Layout for detailed styles

Dependencies ​

  • useAppDataStore() - App data store for brand information
  • useRoute() - Route for brand name parameter
  • Global components: Header, SideBar, Snackbar

Pages Using This Layout ​

  • Dashboard ([brand_name]/index.vue)
  • Search ([brand_name]/search.vue)
  • Folders ([brand_name]/folders.vue, [brand_name]/folders/[id].vue)
  • Collages ([brand_name]/collage.vue, [brand_name]/collage/[id].vue)
  • Sharing ([brand_name]/sharing.vue)
  • Profile ([brand_name]/profile.vue)
  • Asset Details ([brand_name]/files/[id].vue)