feat: fix loader interceptor parameter, implement toast error interceptor

This commit is contained in:
2026-02-26 15:52:53 +07:00
parent 1c139eed97
commit 64694d8872
4 changed files with 42 additions and 10 deletions

View File

@@ -1,19 +1,19 @@
<template> <template>
<ion-app> <ion-app>
<ion-router-outlet /> <ion-router-outlet />
<IonLoading <IonLoading :is-open="isLoading" message="Please wait..." spinner="crescent" />
:is-open="isLoading" <ion-toast :is-open="toast.isOpen" :message="toast.message" :color="toast.color" duration="3000"
message="Please wait..." @didDismiss="toast.hide" />
spinner="crescent"
/>
</ion-app> </ion-app>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { IonApp, IonRouterOutlet, IonLoading } from '@ionic/vue'; import { IonApp, IonRouterOutlet, IonLoading, IonToast } from '@ionic/vue';
import { useLoadingStore } from './stores/loading.store'; import { useLoadingStore } from './stores/loading.store';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useToastStore } from '@/stores/toast.store'
const toast = useToastStore();
const loadingStore = useLoadingStore(); const loadingStore = useLoadingStore();
const { isLoading } = storeToRefs(loadingStore); const { isLoading } = storeToRefs(loadingStore);
</script> </script>

View File

@@ -1,6 +1,7 @@
import axios from 'axios' import axios from 'axios'
import { useLoadingStore } from '@/stores/loading.store' import { useLoadingStore } from '@/stores/loading.store'
import router from '@/router' import router from '@/router'
import { useToastStore } from '@/stores/toast.store'
const api = axios.create({ const api = axios.create({
baseURL: import.meta.env.VITE_API_URL, baseURL: import.meta.env.VITE_API_URL,
@@ -10,8 +11,8 @@ const api = axios.create({
// Request Interceptor // Request Interceptor
api.interceptors.request.use((config) => { api.interceptors.request.use((config) => {
console.log('BASE URL:', import.meta.env.VITE_API_URL) console.log('BASE URL:', import.meta.env.VITE_API_URL)
const loader = config.params['loader'] ? JSON.parse(config.params['loader']) : true; const loader = config.params?.loader;
if (loader) { if (loader !== false) {
const loadingStore = useLoadingStore() const loadingStore = useLoadingStore()
loadingStore.start() loadingStore.start()
} }
@@ -33,9 +34,13 @@ api.interceptors.response.use(
return response return response
}, },
(error) => { (error) => {
const toast = useToastStore()
// Extract meaningful message
const message = error.response?.data?.message || error.message || 'Something went wrong'
if (error.response?.status === 401) { if (error.response?.status === 401) {
router.push('/login') router.push('/login')
} }
toast.show(message, 'danger')
const loadingStore = useLoadingStore() const loadingStore = useLoadingStore()
loadingStore.stop() loadingStore.stop()
return Promise.reject(error) return Promise.reject(error)

View File

@@ -2,9 +2,9 @@ import { IPagination } from '@/types/product'
import api from './api' import api from './api'
export const getProducts = (params?: IPagination) => { export const getProducts = (params?: IPagination) => {
return api.get('/products', { params }) return api.get('/products', { params: { ...params, loader: true }, })
} }
export const getProductById = (id: string, params?: IPagination) => { export const getProductById = (id: string, params?: IPagination) => {
return api.get(`/products/${id}`, { params }) return api.get(`/products/${id}`, { params: { ...params, loader: false }, })
} }

27
src/stores/toast.store.ts Normal file
View File

@@ -0,0 +1,27 @@
import { defineStore } from 'pinia'
interface ToastState {
isOpen: boolean
message: string
color: 'success' | 'danger' | 'warning' | 'primary'
}
export const useToastStore = defineStore('toast', {
state: (): ToastState => ({
isOpen: false,
message: '',
color: 'danger'
}),
actions: {
show(message: string, color: ToastState['color'] = 'danger') {
this.message = message
this.color = color
this.isOpen = true
},
hide() {
this.isOpen = false
}
}
})