---
globs: src/stores/**/*.js
---

# State Management với Pinia

## Store Structure
Sử dụng Composition API style cho Pinia stores:

```javascript
// stores/userStore.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { userService } from '@/services/userService'

export const useUserStore = defineStore('user', () => {
  // State
  const user = ref(null)
  const users = ref([])
  const loading = ref(false)
  const error = ref(null)

  // Getters
  const isAuthenticated = computed(() => !!user.value)
  const userRole = computed(() => user.value?.role || null)
  const isAdmin = computed(() => userRole.value === 'admin')

  // Actions
  const login = async (credentials) => {
    try {
      loading.value = true
      error.value = null
      
      const response = await userService.login(credentials)
      user.value = response.data
      
      // Store in localStorage
      localStorage.setItem('user', JSON.stringify(user.value))
      
      return response.data
    } catch (err) {
      error.value = err.message
      throw err
    } finally {
      loading.value = false
    }
  }

  const logout = () => {
    user.value = null
    localStorage.removeItem('user')
    // Redirect to login
  }

  const fetchUsers = async (params = {}) => {
    try {
      loading.value = true
      const response = await userService.getUsers(params)
      users.value = response.data
      return response.data
    } catch (err) {
      error.value = err.message
      throw err
    } finally {
      loading.value = false
    }
  }

  const updateUser = async (id, userData) => {
    try {
      loading.value = true
      const response = await userService.updateUser(id, userData)
      
      // Update local state
      const index = users.value.findIndex(u => u.id === id)
      if (index !== -1) {
        users.value[index] = response.data
      }
      
      return response.data
    } catch (err) {
      error.value = err.message
      throw err
    } finally {
      loading.value = false
    }
  }

  // Initialize from localStorage
  const initializeFromStorage = () => {
    const storedUser = localStorage.getItem('user')
    if (storedUser) {
      try {
        user.value = JSON.parse(storedUser)
      } catch (err) {
        console.error('Error parsing stored user:', err)
        localStorage.removeItem('user')
      }
    }
  }

  return {
    // State
    user,
    users,
    loading,
    error,
    
    // Getters
    isAuthenticated,
    userRole,
    isAdmin,
    
    // Actions
    login,
    logout,
    fetchUsers,
    updateUser,
    initializeFromStorage
  }
})
```

## Store Usage trong Components
```vue
<script setup>
import { useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'

const userStore = useUserStore()

// Destructure reactive state
const { user, users, loading, error, isAuthenticated } = storeToRefs(userStore)

// Destructure actions
const { login, logout, fetchUsers } = userStore

// Use in component
const handleLogin = async (credentials) => {
  try {
    await login(credentials)
    // Handle success
  } catch (err) {
    // Handle error
  }
}
</script>
```

## Multiple Stores Pattern
```javascript
// stores/index.js
export { useUserStore } from './userStore'
export { useOrderStore } from './orderStore'
export { useAppStore } from './appStore'

// stores/appStore.js - Global app state
export const useAppStore = defineStore('app', () => {
  const theme = ref('light')
  const sidebarCollapsed = ref(false)
  const notifications = ref([])

  const toggleSidebar = () => {
    sidebarCollapsed.value = !sidebarCollapsed.value
  }

  const addNotification = (notification) => {
    notifications.value.push({
      id: Date.now(),
      ...notification,
      timestamp: new Date()
    })
  }

  const removeNotification = (id) => {
    const index = notifications.value.findIndex(n => n.id === id)
    if (index !== -1) {
      notifications.value.splice(index, 1)
    }
  }

  return {
    theme,
    sidebarCollapsed,
    notifications,
    toggleSidebar,
    addNotification,
    removeNotification
  }
})
```

## Store Persistence
```javascript
// stores/userStore.js
export const useUserStore = defineStore('user', () => {
  const user = ref(null)

  // Load from localStorage on store creation
  const loadFromStorage = () => {
    const stored = localStorage.getItem('user')
    if (stored) {
      user.value = JSON.parse(stored)
    }
  }

  // Save to localStorage when user changes
  watch(user, (newUser) => {
    if (newUser) {
      localStorage.setItem('user', JSON.stringify(newUser))
    } else {
      localStorage.removeItem('user')
    }
  }, { deep: true })

  // Initialize
  loadFromStorage()

  return { user, loadFromStorage }
})
```

## Store Testing
```javascript
// stores/__tests__/userStore.test.js
import { setActivePinia, createPinia } from 'pinia'
import { useUserStore } from '../userStore'

describe('User Store', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
  })

  it('should login user', async () => {
    const store = useUserStore()
    
    const credentials = { username: 'test', password: 'test' }
    await store.login(credentials)
    
    expect(store.isAuthenticated).toBe(true)
    expect(store.user).toBeDefined()
  })

  it('should logout user', () => {
    const store = useUserStore()
    store.user = { id: 1, name: 'Test' }
    
    store.logout()
    
    expect(store.isAuthenticated).toBe(false)
    expect(store.user).toBeNull()
  })
})
```

## Store Composition
```javascript
// stores/composables/useUserActions.js
export const useUserActions = () => {
  const userStore = useUserStore()
  const appStore = useAppStore()

  const loginWithNotification = async (credentials) => {
    try {
      await userStore.login(credentials)
      appStore.addNotification({
        type: 'success',
        message: 'Đăng nhập thành công'
      })
    } catch (error) {
      appStore.addNotification({
        type: 'error',
        message: 'Đăng nhập thất bại'
      })
      throw error
    }
  }

  return {
    loginWithNotification
  }
}
```