NUXT PRACTICAL 5: STATE MANAGEMENT DEEP DIVE WITH PINIA
=================================================================

================================================

AIM:
Use Pinia to manage a shared list of tasks.
The user can add tasks, mark tasks as completed and delete tasks.

PROJECT STRUCTURE:
nuxt-pinia/
|
|-- nuxt.config.ts
|-- app.vue
|-- pages/
|   |-- index.vue
|-- stores/
    |-- task.js

STEP 1: Create Nuxt project
---------------------------
npx nuxi@latest init nuxt-pinia
cd nuxt-pinia
npm install

STEP 2: Install Pinia
---------------------
npm install pinia @pinia/nuxt

STEP 3: nuxt.config.ts
----------------------
export default defineNuxtConfig({
  modules: ['@pinia/nuxt']
})

STEP 4: app.vue
---------------
<template>
  <NuxtPage />
</template>

STEP 5: stores/task.js
----------------------
import { defineStore } from 'pinia'

export const useTaskStore = defineStore('task', {
  // State stores the data
  state: () => ({
    tasks: []
  }),

  // Getters return calculated data
  getters: {
    completedTasks: (state) => {
      return state.tasks.filter(task => task.completed)
    },

    remainingTasks: (state) => {
      return state.tasks.filter(task => !task.completed)
    }
  },

  // Actions change the state
  actions: {
    addTask(title) {
      if (!title.trim()) return

      this.tasks.push({
        id: Date.now(),
        title: title,
        completed: false
      })
    },

    toggleTask(id) {
      const task = this.tasks.find(task => task.id === id)

      if (task) {
        task.completed = !task.completed
      }
    },

    deleteTask(id) {
      this.tasks = this.tasks.filter(task => task.id !== id)
    }
  }
})

STEP 6: pages/index.vue
-----------------------
<script setup>
import { ref } from 'vue'
import { useTaskStore } from '~/stores/task'

const taskStore = useTaskStore()
const newTask = ref('')
</script>

<template>
  <div>
    <h1>Pinia Task Manager</h1>

    <form @submit.prevent="taskStore.addTask(newTask); newTask = ''">
      <input v-model="newTask" placeholder="Enter a task" />
      <button type="submit">Add Task</button>
    </form>

    <h2>All Tasks</h2>

    <p v-if="taskStore.tasks.length === 0">No tasks added.</p>

    <ul>
      <li v-for="task in taskStore.tasks" :key="task.id">
        <span :style="{ textDecoration: task.completed ? 'line-through' : 'none' }">
          {{ task.title }}
        </span>

        <button @click="taskStore.toggleTask(task.id)">
          {{ task.completed ? 'Undo' : 'Complete' }}
        </button>

        <button @click="taskStore.deleteTask(task.id)">Delete</button>
      </li>
    </ul>

    <h3>Completed: {{ taskStore.completedTasks.length }}</h3>
    <h3>Remaining: {{ taskStore.remainingTasks.length }}</h3>
  </div>
</template>

RUN:
npm run dev

Open:
http://localhost:3000

CONCEPT:
- State: stores the tasks array.
- Getters: calculate completed and remaining tasks.
- Actions: add, toggle and delete tasks.
- useTaskStore(): accesses the Pinia store in a page.
- Components using the same store share the same state.


================================================
