220 lines
5.1 KiB
Markdown
220 lines
5.1 KiB
Markdown
# 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:
|
|
|
|
```javascript
|
|
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
|
|
|
|
```vue
|
|
<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
|
|
|
|
```javascript
|
|
// 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:
|
|
```vue
|
|
<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
|
|
|
|
```vue
|
|
<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
|
|
|
|
```json
|
|
{
|
|
"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)
|
|
```vue
|
|
<script setup>
|
|
import { useNetworkStore } from '../stores/network'
|
|
|
|
const network = useNetworkStore()
|
|
// Use: network.isOnline, network.isLoading, network.actions()
|
|
</script>
|
|
```
|
|
|
|
### From a Composable or Setup Function
|
|
```javascript
|
|
import { useNetworkStore } from '../stores/network'
|
|
|
|
const network = useNetworkStore()
|
|
// Now you can access the store's state and actions
|
|
```
|
|
|
|
### Global Access (Not Recommended)
|
|
```javascript
|
|
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) |