diff --git a/src/components/dashboard/PropertyStatusWidget.vue b/src/components/dashboard/PropertyStatusWidget.vue new file mode 100644 index 0000000..b59403a --- /dev/null +++ b/src/components/dashboard/PropertyStatusWidget.vue @@ -0,0 +1,117 @@ + + + diff --git a/src/components/dashboard/QuickActionsWidget.vue b/src/components/dashboard/QuickActionsWidget.vue new file mode 100644 index 0000000..5eae393 --- /dev/null +++ b/src/components/dashboard/QuickActionsWidget.vue @@ -0,0 +1,82 @@ + + + diff --git a/src/components/dashboard/RecentSalesWidget.vue b/src/components/dashboard/RecentSalesWidget.vue index b966922..fd4a688 100644 --- a/src/components/dashboard/RecentSalesWidget.vue +++ b/src/components/dashboard/RecentSalesWidget.vue @@ -1,40 +1,143 @@ diff --git a/src/components/dashboard/RevenueStreamWidget.vue b/src/components/dashboard/RevenueStreamWidget.vue index 119f1c3..53018a4 100644 --- a/src/components/dashboard/RevenueStreamWidget.vue +++ b/src/components/dashboard/RevenueStreamWidget.vue @@ -1,95 +1,145 @@ - - diff --git a/src/components/dashboard/StatsWidget.vue b/src/components/dashboard/StatsWidget.vue index 7593931..6ef8be1 100644 --- a/src/components/dashboard/StatsWidget.vue +++ b/src/components/dashboard/StatsWidget.vue @@ -1,41 +1,122 @@ + + diff --git a/src/components/dashboard/WarehouseActivityWidget.vue b/src/components/dashboard/WarehouseActivityWidget.vue new file mode 100644 index 0000000..d07b1fd --- /dev/null +++ b/src/components/dashboard/WarehouseActivityWidget.vue @@ -0,0 +1,171 @@ + + + diff --git a/src/layout/AppTopbar.vue b/src/layout/AppTopbar.vue index 4cbbef3..d42b697 100644 --- a/src/layout/AppTopbar.vue +++ b/src/layout/AppTopbar.vue @@ -2,12 +2,54 @@ import { useLayout } from '@/layout/composables/layout'; import AppConfigurator from './AppConfigurator.vue'; import Cookies from 'js-cookie'; +import axios from 'axios'; import { useRouter } from 'vue-router'; -const router = useRouter() -const signOut = () => { - Cookies.set('bm-token', '') - router.push('/auth/login') -} + +const router = useRouter(); + +const signOut = async () => { + try { + await axios.post('/api/users/logout', {}, { withCredentials: true }); + } catch (e) { + console.warn('Logout API error:', e?.message || e); + } + + // Comprehensive cookie cleaning + Cookies.remove('bm-token'); + Cookies.remove('bm-token', { domain: '.mbmanager.ir', path: '/' }); + Cookies.remove('bm-token', { path: '/' }); + Cookies.remove('belonging_token'); + Cookies.remove('belonging_token', { domain: '.mbmanager.ir', path: '/' }); + Cookies.remove('belonging_token', { path: '/' }); + Cookies.remove('jwt'); + Cookies.remove('jwt', { domain: '.mbmanager.ir', path: '/' }); + Cookies.remove('jwt', { path: '/' }); + + // Force expire raw cookies in document.cookie + if (typeof document !== 'undefined') { + const cookiesToClear = ['bm-token', 'belonging_token', 'jwt']; + const domains = ['', '; domain=.mbmanager.ir', '; domain=' + window.location.hostname]; + cookiesToClear.forEach((name) => { + domains.forEach((dom) => { + document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/${dom}`; + }); + }); + } + + // Clear local & session storage + if (typeof localStorage !== 'undefined') { + localStorage.removeItem('bm-token'); + localStorage.removeItem('belonging_token'); + localStorage.removeItem('jwt'); + } + if (typeof sessionStorage !== 'undefined') { + sessionStorage.clear(); + } + + delete axios.defaults.headers.common['Authorization']; + + await router.replace('/auth/login'); +}; const { toggleMenu, toggleDarkMode, isDarkTheme } = useLayout(); @@ -15,7 +57,7 @@ const { toggleMenu, toggleDarkMode, isDarkTheme } = useLayout();