# Pinia Stores

Monetarie NPC Backoffice uses Pinia for state management. This document provides comprehensive documentation for all available stores.

## Overview

The application includes five Pinia stores:

| Store | File | Purpose |
|-------|------|---------|
| `useAuthStore` | `src/stores/auth.ts` | Authentication state |
| `useDashboardStore` | `src/stores/dashboard.ts` | Dashboard data |
| `useNotificationsStore` | `src/stores/notifications.ts` | Notification management |
| `useSerenaStore` | `src/stores/serena.ts` | AI assistant state |
| `useSidebarStore` | `src/stores/sidebar.ts` | Sidebar collapse state |

## Auth Store

Manages user authentication and session persistence.

### State

```typescript
interface User {
  id: number
  name: string
  email: string
  role: string
  avatar?: string
}

const user = ref<User | null>(null)
const isAuthenticated = computed(() => user.value !== null)
```

### Actions

#### `login(email: string, password: string): boolean`

Authenticates user with provided credentials.

```typescript
const authStore = useAuthStore()

if (authStore.login('admin@monetarie_npc.com.br', 'admin123')) {
  console.log('Login successful')
  router.push('/')
} else {
  console.log('Invalid credentials')
}
```

#### `logout()`

Clears user session and localStorage.

```typescript
authStore.logout()
router.push('/login')
```

#### `updateAvatar(avatar: string)`

Updates the user's avatar URL.

```typescript
authStore.updateAvatar('https://example.com/avatar.jpg')
```

### Persistence

The store automatically initializes from localStorage:

```typescript
function init() {
  const savedUser = localStorage.getItem('user')
  if (savedUser) {
    user.value = JSON.parse(savedUser)
  }
}
```

### Usage Example

```vue
<script setup lang="ts">
import { useAuthStore } from '@/stores/auth'

const authStore = useAuthStore()

// Check authentication
if (authStore.isAuthenticated) {
  console.log(`Welcome, ${authStore.user?.name}`)
}
</script>

<template>
  <div v-if="authStore.isAuthenticated">
    <span>{{ authStore.user?.name }}</span>
    <v-btn @click="authStore.logout()">Logout</v-btn>
  </div>
</template>
```

---

## Dashboard Store

Manages dashboard data including health status, SISBAJUD orders, and RSS feed.

### State

```typescript
interface HealthStatus {
  id: string
  name: string
  status: 'online' | 'offline'
  lastCheck: string
}

interface SisbajudOrder {
  id: string
  type: 'Bloqueio' | 'Desbloqueio' | 'Transferencia'
  account: string
  value: number
  status: 'Pendente' | 'Executado' | 'Rejeitado'
  date: string
}

interface RssFeedItem {
  id: number
  title: string
  source: string
  date: string
  url: string
}

const healthStatus = ref<HealthStatus[]>([...mockHealthStatus])
const sisbajudOrders = ref<SisbajudOrder[]>([...mockSisbajudOrders])
const rssFeed = ref<RssFeedItem[]>([...mockRssFeed])
```

### Actions

#### `refreshHealth()`

Updates the health status timestamps.

```typescript
const dashboardStore = useDashboardStore()
dashboardStore.refreshHealth()
```

### Usage Example

```vue
<script setup lang="ts">
import { useDashboardStore } from '@/stores/dashboard'

const dashboardStore = useDashboardStore()

// Access health status
const onlineSystems = computed(() =>
  dashboardStore.healthStatus.filter(s => s.status === 'online')
)

// Access orders
const pendingOrders = computed(() =>
  dashboardStore.sisbajudOrders.filter(o => o.status === 'Pendente')
)
</script>

<template>
  <div>
    <p>Online systems: {{ onlineSystems.length }}</p>
    <p>Pending orders: {{ pendingOrders.length }}</p>
  </div>
</template>
```

---

## Notifications Store

Manages application notifications with read/unread state.

### State

```typescript
interface PendingNotification {
  id: number
  title: string
  entity: string
  priority: 'high' | 'medium' | 'low'
  read: boolean
}

const notifications = ref<PendingNotification[]>([...mockPendingNotifications])
const unreadCount = computed(() => notifications.value.filter(n => !n.read).length)
const pendingNotifications = computed(() => notifications.value.filter(n => !n.read))
```

### Actions

#### `markAsRead(id: number)`

Marks a specific notification as read.

```typescript
const notificationsStore = useNotificationsStore()
notificationsStore.markAsRead(123)
```

#### `markAllAsRead()`

Marks all notifications as read.

```typescript
notificationsStore.markAllAsRead()
```

### Usage Example

```vue
<script setup lang="ts">
import { useNotificationsStore } from '@/stores/notifications'

const notificationsStore = useNotificationsStore()
</script>

<template>
  <v-badge :content="notificationsStore.unreadCount" color="error">
    <v-icon>mdi-bell</v-icon>
  </v-badge>

  <v-list>
    <v-list-item
      v-for="notif in notificationsStore.pendingNotifications"
      :key="notif.id"
      @click="notificationsStore.markAsRead(notif.id)"
    >
      <v-list-item-title>{{ notif.title }}</v-list-item-title>
    </v-list-item>
  </v-list>
</template>
```

---

## Serena Store

Manages the AI assistant chat state and message history.

### State

```typescript
interface ChatMessage {
  id: number
  role: 'user' | 'assistant'
  content: string
  timestamp: string
}

const isOpen = ref(false)
const isTyping = ref(false)
const messages = ref<ChatMessage[]>([])
```

### Actions

#### `open()`

Opens the chat window.

```typescript
const serenaStore = useSerenaStore()
serenaStore.open()
```

#### `close()`

Closes the chat window.

```typescript
serenaStore.close()
```

#### `toggle()`

Toggles the chat window visibility.

```typescript
serenaStore.toggle()
```

#### `sendMessage(content: string, fallbackMessage: string): Promise<void>`

Sends a message and receives a response.

```typescript
await serenaStore.sendMessage('Como fazer um PIX?', 'Desculpe, nao entendi.')
```

#### `clearHistory()`

Clears all chat messages.

```typescript
serenaStore.clearHistory()
```

### Persistence

Messages are automatically saved to localStorage:

```typescript
function saveMessages() {
  localStorage.setItem('serenaMessages', JSON.stringify(messages.value))
}
```

### Usage Example

```vue
<script setup lang="ts">
import { useSerenaStore } from '@/stores/serena'
import { useI18n } from 'vue-i18n'

const { t } = useI18n()
const serenaStore = useSerenaStore()

const messageInput = ref('')

async function sendMessage() {
  if (!messageInput.value.trim()) return

  await serenaStore.sendMessage(
    messageInput.value,
    t('serena.fallback')
  )

  messageInput.value = ''
}
</script>

<template>
  <div v-if="serenaStore.isOpen">
    <div v-for="msg in serenaStore.messages" :key="msg.id">
      {{ msg.content }}
    </div>

    <div v-if="serenaStore.isTyping">
      Serena is typing...
    </div>

    <v-text-field
      v-model="messageInput"
      @keyup.enter="sendMessage"
    />
  </div>
</template>
```

---

## Sidebar Store

Manages the collapse state of left and right sidebars.

### State

```typescript
const leftCollapsed = ref(localStorage.getItem('leftSidebarCollapsed') === 'true')
const rightCollapsed = ref(localStorage.getItem('rightSidebarCollapsed') === 'true')
```

### Actions

#### `toggleLeft()`

Toggles the left sidebar collapse state.

```typescript
const sidebarStore = useSidebarStore()
sidebarStore.toggleLeft()
```

#### `toggleRight()`

Toggles the right sidebar collapse state.

```typescript
sidebarStore.toggleRight()
```

#### `setLeft(collapsed: boolean)`

Sets the left sidebar collapse state.

```typescript
sidebarStore.setLeft(true) // Collapse
sidebarStore.setLeft(false) // Expand
```

#### `setRight(collapsed: boolean)`

Sets the right sidebar collapse state.

```typescript
sidebarStore.setRight(true) // Collapse
sidebarStore.setRight(false) // Expand
```

### Persistence

State is automatically persisted to localStorage.

### Usage Example

```vue
<script setup lang="ts">
import { useSidebarStore } from '@/stores/sidebar'

const sidebarStore = useSidebarStore()
</script>

<template>
  <v-navigation-drawer
    :rail="sidebarStore.leftCollapsed"
    permanent
  >
    <!-- Navigation content -->

    <template #append>
      <v-btn @click="sidebarStore.toggleLeft">
        <v-icon>
          {{ sidebarStore.leftCollapsed ? 'mdi-chevron-right' : 'mdi-chevron-left' }}
        </v-icon>
      </v-btn>
    </template>
  </v-navigation-drawer>
</template>
```

---

## Store Initialization

All stores are automatically created when first accessed. For stores that need initialization (auth, serena), the `init()` function is called in the store setup:

```typescript
export const useAuthStore = defineStore('auth', () => {
  // ... state and actions

  function init() {
    const savedUser = localStorage.getItem('user')
    if (savedUser) {
      user.value = JSON.parse(savedUser)
    }
  }

  init() // Called on store creation

  return { /* ... */ }
})
```

## Type Exports

For TypeScript support, export interfaces from stores or create dedicated type files:

```typescript
// src/types/stores.ts
export interface User {
  id: number
  name: string
  email: string
  role: string
  avatar?: string
}

export interface HealthStatus {
  id: string
  name: string
  status: 'online' | 'offline'
  lastCheck: string
}

// ... more types
```

## Testing Stores

Example of testing a Pinia store:

```typescript
import { setActivePinia, createPinia } from 'pinia'
import { useAuthStore } from '@/stores/auth'

describe('Auth Store', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    localStorage.clear()
  })

  it('should login with valid credentials', () => {
    const authStore = useAuthStore()

    const result = authStore.login('admin@monetarie_npc.com.br', 'admin123')

    expect(result).toBe(true)
    expect(authStore.isAuthenticated).toBe(true)
  })

  it('should reject invalid credentials', () => {
    const authStore = useAuthStore()

    const result = authStore.login('wrong@email.com', 'wrongpass')

    expect(result).toBe(false)
    expect(authStore.isAuthenticated).toBe(false)
  })
})
```

## Related Documentation

- [Authentication](/guide/authentication) - Auth flow details
- [Dashboard](/guide/dashboard) - Dashboard features
- [Serena Chat](/components/serena-chat) - AI assistant component
- [Sidebars](/guide/sidebars) - Navigation components
