Ctrl K
ComunidadGuías…

web/src/stores/settings.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import axios from '@/utils/axios'
import { getBrowserTimezone, TIMEZONE_OPTIONS } from '@/utils/timezone'
import { useFontStore } from '@/stores/font'

export const useSettingsStore = defineStore('settings', () => {
  // State
  const settings = ref(null)
  const loading = ref(false)
  const error = ref(null)

  // Computed
  const timezone = computed(() => {
    return settings.value?.timezone || 'America/New_York'
  })

  const weightUnit = computed(() => {
    return settings.value?.weight_unit || 'lbs'
  })

  const distanceUnit = computed(() => {
    return settings.value?.distance_unit || 'miles'
  })

  const dataExportFormat = computed(() => {
    return settings.value?.data_export_format || 'JSON'
  })

  const theme = computed(() => {
    return settings.value?.theme || 'light'
  })

  const fontFamily = computed(() => {
    return settings.value?.font_family || 'system'
  })

  const adminUserEventNotifications = computed(() => {
    return settings.value?.admin_user_event_notifications ?? true
  })

  const leaderboardOptIn = computed(() => {
    return settings.value?.leaderboard_opt_in ?? false
  })

  // Actions
  async function fetchSettings() {
    loading.value = true
    error.value = null

    try {
      const response = await axios.get('/api/users/settings')
      settings.value = response.data

      // Sync font with font store
      const fontStore = useFontStore()
      fontStore.syncFromSettings(response.data.font_family)

      return settings.value
    } catch (err) {
      console.error('Failed to fetch settings:', err)
      error.value = err.response?.data?.error || 'Failed to load settings'
      throw err
    } finally {
      loading.value = false
    }
  }

  async function updateSettings(updates) {
    loading.value = true
    error.value = null

    try {
      const response = await axios.put('/api/users/settings', updates)
      settings.value = response.data
      return settings.value
    } catch (err) {
      console.error('Failed to update settings:', err)
      error.value = err.response?.data?.error || 'Failed to update settings'
      throw err
    } finally {
      loading.value = false
    }
  }

  async function updateTimezone(newTimezone) {
    // Validate timezone
    const isValid = TIMEZONE_OPTIONS.some(opt => opt.value === newTimezone) ||
      newTimezone === getBrowserTimezone()

    if (!isValid) {
      error.value = 'Invalid timezone'
      throw new Error('Invalid timezone')
    }

    return updateSettings({
      ...settings.value,
      timezone: newTimezone
    })
  }

  async function updateWeightUnit(newUnit) {
    if (!['lbs', 'kg'].includes(newUnit)) {
      error.value = 'Invalid weight unit'
      throw new Error('Invalid weight unit')
    }

    return updateSettings({
      ...settings.value,
      weight_unit: newUnit
    })
  }

  async function updateDistanceUnit(newUnit) {
    if (!['miles', 'km'].includes(newUnit)) {
      error.value = 'Invalid distance unit'
      throw new Error('Invalid distance unit')
    }

    return updateSettings({
      ...settings.value,
      distance_unit: newUnit
    })
  }

  async function updateFontFamily(newFont) {
    const validFonts = ['system', 'inter', 'roboto', 'lato', 'firasans', 'lexend', 'opendyslexic', 'atkinson', 'sourceserif', 'jetbrainsmono']
    if (!validFonts.includes(newFont)) {
      error.value = 'Invalid font family'
      throw new Error('Invalid font family')
    }

    // Update font store immediately for instant feedback
    const fontStore = useFontStore()
    fontStore.setFont(newFont)

    return updateSettings({
      ...settings.value,
      font_family: newFont
    })
  }

  async function updateAdminUserEventNotifications(enabled) {
    return updateSettings({
      ...settings.value,
      admin_user_event_notifications: enabled
    })
  }

  async function updateLeaderboardOptIn(enabled) {
    return updateSettings({
      ...settings.value,
      leaderboard_opt_in: enabled
    })
  }

  function detectBrowserTimezone() {
    return getBrowserTimezone()
  }

  // Initialize - fetch settings when store is created (if user is logged in)
  const token = localStorage.getItem('token')
  if (token) {
    fetchSettings().catch(() => {
      // Silently fail on initial load - settings will be fetched when needed
    })
  }

  return {
    // State
    settings,
    loading,
    error,
    // Computed
    timezone,
    weightUnit,
    distanceUnit,
    dataExportFormat,
    theme,
    fontFamily,
    adminUserEventNotifications,
    leaderboardOptIn,
    // Actions
    fetchSettings,
    updateSettings,
    updateTimezone,
    updateWeightUnit,
    updateDistanceUnit,
    updateFontFamily,
    updateAdminUserEventNotifications,
    updateLeaderboardOptIn,
    detectBrowserTimezone
  }
})