Skip to content

Root Index Page ​

File Information ​

  • Path: app/pages/index.vue
  • Route: /
  • Purpose: Landing page for brand URL entry
  • Layout: login-layout (custom)
  • Middleware: None

Overview ​

The Root Index page is the landing page when users visit the root URL. It allows users to enter their brand URL to navigate to their brand's portal. This page provides a simple interface for brand URL entry and validation.

Key Features ​

  1. Brand URL Input

    • Text input for brand URL
    • Real-time validation
    • Placeholder and example display
    • Error handling
  2. Domain Verification

    • Validates brand URL via API
    • Verifies domain exists
    • Handles invalid domains
  3. Navigation

    • Redirects to brand portal on success
    • Preserves brand URL in navigation
    • Error handling
  4. Branding

    • Collage logo display
    • "Powered by Collage" footer
    • Consistent branding

Components Used ​

  • v-text-field - Vuetify text input component
  • v-btn - Vuetify button component
  • v-progress-circular - Loading spinner
  • v-skeleton-loader - Skeleton loader
  • AsyncIcon - Async icon component

Composables Used ​

  • useAppDataApi() - App data API (app/composables/api/useAppDataApi.ts)
  • useSnackbar() - Snackbar notifications
  • useHelpers() - Helper functions

Data Properties ​

Reactive Data ​

typescript
{
  brandName: string,              // Brand URL input
  loading: boolean,               // Form submission loading state
  contentLoading: boolean,        // Initial content loading state
  canGo: boolean                 // Navigation enabled flag
}

Computed Properties ​

brandNameError ​

Determines if brand name input has error.

typescript
computed(() => !brandName.value.trim())

Returns: boolean - True if brand name is empty

Methods ​

submitHandler() ​

Handles brand URL form submission.

typescript
async function submitHandler() {
  if (!brandName.value.trim()) {
    return
  }
  
  loading.value = true
  canGo.value = false
  
  try {
    const response = await appDataApi.verifyDomain(brandName.value.trim())
    await navigateTo(`/${brandName.value.trim()}`)
  } catch (error: any) {
    console.error("Domain verification failed:", error)
    // Still navigate even on error (domain validation happens on brand page)
    await navigateTo(`/${brandName.value.trim()}`)
  } finally {
    loading.value = false
    canGo.value = true
  }
}

Flow:

  1. Validates brand name is not empty
  2. Sets loading state
  3. Calls domain verification API
  4. Navigates to brand portal
  5. Handles errors (still navigates)
  6. Resets loading state

Note: Even on API error, navigation proceeds (domain validation happens on brand page).

User Interactions ​

  1. Form Input

    • Enter brand URL
    • Real-time validation
    • Example URL display
  2. Form Submission

    • Click "Go to {brandName}" or "Enter your brand url" button
    • Form validates before submission
    • Loading state during API call
  3. Navigation

    • Automatic redirect to brand portal
    • Brand URL preserved in navigation

Styling ​

  • Uses scoped styles from @/assets/scss/login.scss
  • Form layout styles
  • Input field styles
  • Button styles with loading states
  • Skeleton loader styles
  • Branding footer styles

Lifecycle Hooks ​

onMounted ​

Initializes content loading state.

typescript
onMounted(() => {
  nextTick(() => (contentLoading.value = false))
})

Purpose: Hides skeleton loader after component mounts.

API Endpoints ​

Verify Domain ​

  • Endpoint: POST /verify-domain (via appDataApi.verifyDomain())
  • Request Body:
    typescript
    {
      url: string  // Brand URL
    }
  • Response: Domain verification result

User Flow ​

  1. User visits root URL (/)
  2. Page displays brand URL input form
  3. User enters brand URL
  4. User clicks submit button
  5. System verifies domain (optional, for UX)
  6. System navigates to brand portal (/{brandName})
  7. Brand portal page handles further validation

Notes for Development ​

  • Page is public (no authentication required)
  • Domain verification is optional (for better UX)
  • Navigation proceeds even if verification fails
  • Brand URL trimmed before navigation
  • Button text changes based on input state
  • Example URL shown when input is empty
  • Full URL preview shown when input has value
  • "Powered by Collage" footer always visible
  • Uses login layout for consistent branding