Files
BarangaySystem/VueMigration.md
2026-06-06 18:43:00 +08:00

5.1 KiB

Project Structure Analysis: Vue.js Migration from Blade

Overview

The BukidBountyApp has been fully migrated from Blade templates to a Vue 3 SPA (Single Page Application) with Pinia for state management.


1. Application Architecture

Entry Point (resources/js/app.js)

  • Vue 3 app created with createApp()
  • Pinia state manager initialized via createPinia()
  • Auto-imports all Vue components from ./Pages/**/*.vue (excluding Fragments)
  • Main layout structure:
    • TopHeader (fixed header at top)
    • main-content area for page routing
    • BottomNav (fixed bottom navigation bar)
    • BaseModal (global modal component)

Key Components

Layout Components

Component Location Description
TopHeader.vue Pages/Core/Fragments/ Fixed header with back button, title, and settings action
BottomNav.vue Pages/Core/Fragments/ Bottom navigation with Home, Cart, Properties links
BaseModal.vue Components/Core/BaseModal.vue Global modal using Teleport to body

2. Pinia Stores Usage

Current Store: resources/js/stores/network.js

The project currently has one Pinia store for network status management:

import { defineStore } from 'pinia'

export const useNetworkStore = defineStore('network', {
  state: () => ({
    isOnline: navigator.onLine,
    isLoading: false
  }),
  actions: {
    setOnline(status) {
      this.isOnline = status
      if (status) this.isLoading = false
    },
    startLoading() { this.isLoading = true },
    stopLoading() { this.isLoading = false }
  }
})

How to Use Pinia Stores in Components

<script setup>
import { useNetworkStore } from '../stores/network'

// Call the store factory function
const network = useNetworkStore()

// Access reactive state
console.log(network.isOnline)   // true/false
console.log(network.isLoading)  // true/false

// Call actions
network.setOnline(true)
network.startLoading()
network.stopLoading()
</script>

Creating a New Store

// stores/example.js
import { defineStore } from 'pinia'

export const useExampleStore = defineStore('example', {
  state: () => ({
    count: 0,
    items: []
  }),
  getters: {
    doubledCount: (state) => state.count * 2
  },
  actions: {
    increment() { this.count++ },
    addItem(item) { this.items.push(item) }
  }
})

Then use in component:

<script setup>
import { useExampleStore } from '../stores/example'
const store = useExampleStore()
store.increment()
</script>

3. Composables (Vue Composition API)

Key Composables

Composable Location Purpose
useNavigate composables/Core/useNavigate.js SPA navigation between pages
useModal composables/Core/useModal.js Global modal management
useAuth composables/Core/useAuth.js User authentication/role state

Navigation Pattern

<script setup>
import { useNavigate } from '../composables/Core/useNavigate'

const { navigate } = useNavigate()

// Navigate to another page
navigate({ page: 'CartProductMarket' })
navigate({ 
  page: 'ViewStoreMarket', 
  props: { storeId: 123 } 
})

// Reload current page
navigate.reloadPage()
</script>

Global $navigate Helper

The app exposes window.$navigateHelper which can be accessed via:

  • In components: this.$navigate
  • Globally: window.$navigateHelper({ page, props })

4. Page Routing System

How It Works

  1. Initial page is defined in index.html: data-page='{"component":"Home","props":{}}'
  2. Pages are auto-imported from resources/js/Pages/ directory
  3. Component names use dot notation (e.g., Auth.Login, AccountSettings)
  4. URLs use path notation: /, /login, /auth/login

Page File Structure

Pages/
├── Home.vue                    → /
├── Auth/
│   └── Login.vue              → /auth/login
├── AccountSettings.vue        → /account/settings
└── Market/
    ├── ListProductsMarket.vue
    └── ViewStoreMarket.vue

5. Dependencies

{
  "dependencies": {
    "vue": "^3.5.27",
    "pinia": "^3.0.4",
    "axios": "^1.13.2"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^6.0.3",
    "vite": "^7.3.1"
  }
}

6. Summary: How to Access Pinia Stores

From a Vue Component (Composition API)

<script setup>
import { useNetworkStore } from '../stores/network'

const network = useNetworkStore()
// Use: network.isOnline, network.isLoading, network.actions()
</script>

From a Composable or Setup Function

import { useNetworkStore } from '../stores/network'

const network = useNetworkStore()
// Now you can access the store's state and actions
window.$networkStore = useNetworkStore()  // Available if defined globally

Migration Notes

The project has successfully migrated from Blade to Vue with:

  • SPA routing via useNavigate composable
  • Pinia for state management
  • Global modal system
  • Auto-imported page components
  • Browser history navigation (popstate support)