Skip to content

Stores Documentation ​

Overview ​

This section documents all Pinia stores used in the Collage Brand Portal. Stores are located in app/stores/ and use Pinia for state management.

Store Structure ​

stores/
├── auth.ts          # Authentication store
├── appData.ts       # Application data store
├── search.ts        # Search store
├── download.ts      # Download store
├── analytics.ts     # Analytics store
└── index.ts         # Store exports

Store Documentation ​

Core Stores ​

  1. Auth Store - Authentication state management with HTTP-only cookie support
  2. App Data Store - Application data management with caching support
  3. Search Store - Search state management

Feature Stores ​

  1. Download Store - Download state management with progress tracking
  2. Analytics Store - Analytics and insights tracking state

Store Modules ​

Auth Store (auth.ts) ​

Centralized authentication state management with HTTP-only cookie support.

State:

typescript
{
  user: User | null           // Current user data
  accessToken: string | null  // JWT access token
  loading: boolean           // Loading state
  isAuthenticated: boolean   // Computed authentication status
}

Actions:

  • login(email, password, workspaceId) - User login
  • logout() - User logout
  • getUser() - Fetch current user data
  • loginWithToken(token, url) - Token-based login
  • storeSession(token, userData) - Store session in cookies
  • clearSession() - Clear session

Getters:

  • isAuthenticated - Computed authentication status
  • currentWorkspace - Current workspace data

Documentation: Auth Store

File Path: app/stores/auth.ts

App Data Store (appData.ts) ​

Application data management with caching support.

State:

typescript
{
  bannerData: Banner[]           // Banner carousel data
  tileData: Tile[]               // Dashboard tiles
  dashboardData: DashboardData   // Dashboard metrics
  folders: Folder[]              // Folder list
  leftMenuOpen: boolean          // Sidebar state
  logo: string                   // Brand logo
  brand: Brand | null            // Brand data
  subscriptionFeatures: object   // Subscription features
}

Actions:

  • fetchDashboardData(options?) - Fetch dashboard data (cached)
  • fetchBannerData(options?) - Fetch banners (cached)
  • fetchTileData(options?) - Fetch tiles (cached)
  • fetchFolders(subfolderList, options?) - Fetch folders (cached)
  • fetchBrandData() - Fetch brand data
  • setLeftMenuOpen(value) - Toggle sidebar

Caching:

  • Default TTL: 15 minutes
  • Cache can be bypassed with force: true
  • Custom TTL can be set with ttlMs option

Documentation: App Data Store

File Path: app/stores/appData.ts

Search Store (search.ts) ​

Search state management with Typesense integration.

State:

typescript
{
  query: string              // Search query
  filters: SearchFilters     // Active filters
  results: SearchResult[]    // Search results
  loading: boolean          // Loading state
  pagination: Pagination     // Pagination data
}

Actions:

  • setQuery(query) - Set search query
  • setFilters(filters) - Set search filters
  • search(query, filters) - Perform search
  • clearSearch() - Clear search state
  • loadMore() - Load more results

Documentation: Search Store

File Path: app/stores/search.ts

Download Store (download.ts) ​

Download state management with progress tracking and multiple download methods.

State:

typescript
{
  pinned: boolean,                    // Download panel pinned state
  expanded: boolean,                  // Download panel expanded state
  count: number,                      // Number of active downloads
  files: Record<string, DownloadItem> // Active download items
}

Actions:

  • downloadFile(payload) - Download single file with progress
  • downloadMultipleFiles(payload) - Download multiple files as ZIP
  • downloadImageAsset(payload) - Download image asset with proper MIME type
  • setDownloadingItem(id, item) - Update download item state

Features:

  • Progress tracking
  • Cancellation support
  • Stream-based downloads for large files
  • Email notification for very large downloads

Documentation: Download Store

File Path: app/stores/download.ts

Analytics Store (analytics.ts) ​

Analytics and insights tracking state.

State:

typescript
{
  InsightsTransaction: Record<string, any>,      // Transaction insights
  InsightsTransactionShare: Record<string, any>, // Share transaction insights
  userAgentAndLocation: Record<string, any>      // User agent and location
}

Actions:

  • setUserAgentAndLocation(payload) - Set user agent and location data

Getters:

  • getInsightsTransaction - Get transaction insights
  • getInsightsTransactionShare - Get share transaction insights
  • getUserAgentAndLocation - Get user agent and location

Documentation: Analytics Store

File Path: app/stores/analytics.ts

Store Patterns ​

Basic Store Structure ​

typescript
import { defineStore } from 'pinia'
import type { MyStoreState } from '~/types'

export const useMyStore = defineStore('myStore', () => {
  // State
  const data = ref<MyData[]>([])
  const loading = ref(false)
  const error = ref(null)

  // Getters
  const hasData = computed(() => data.value.length > 0)

  // Actions
  const fetchData = async () => {
    loading.value = true
    try {
      const result = await api.getData()
      data.value = result
    } catch (e) {
      error.value = e
    } finally {
      loading.value = false
    }
  }

  return {
    // State
    data,
    loading,
    error,
    // Getters
    hasData,
    // Actions
    fetchData
  }
})

Store with Caching ​

typescript
export const useMyStore = defineStore('myStore', () => {
  const data = ref(null)
  const lastFetched = ref<number | null>(null)
  const CACHE_TTL_MS = 15 * 60 * 1000 // 15 minutes

  const isCacheValid = () => {
    if (!lastFetched.value) return false
    return Date.now() - lastFetched.value < CACHE_TTL_MS
  }

  const fetchData = async (options: { force?: boolean } = {}) => {
    const { force = false } = options

    if (!force && data.value && isCacheValid()) {
      return data.value
    }

    const result = await api.getData()
    data.value = result
    lastFetched.value = Date.now()
    return result
  }

  return { data, fetchData }
})

Best Practices ​

  1. Single Responsibility: Each store should manage a specific domain
  2. Type Safety: Use TypeScript types from ~/types
  3. Actions for Async: Use actions for all async operations
  4. Getters for Computed: Use getters for computed values
  5. Error Handling: Implement consistent error handling
  6. Loading States: Provide loading state management
  7. Caching: Implement caching for frequently accessed data
  8. Persistence: Use persistence plugin for important state
  9. Naming: Use descriptive store and action names
  10. Documentation: Document state, getters, and actions