erp-city-vue-components 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -0
- package/package.json +20 -0
- package/src/components/AddressForm.vue +249 -0
- package/src/components/AuthButton.vue +35 -0
- package/src/components/AuthSidebar.vue +218 -0
- package/src/components/CartButton.vue +18 -0
- package/src/components/CartDetails.vue +152 -0
- package/src/components/FavoriteProductCard.vue +35 -0
- package/src/components/FavoritesSidebar.vue +47 -0
- package/src/components/OrderConfirmation.vue +30 -0
- package/src/components/OrdersSidebar.vue +129 -0
- package/src/components/PaymentOrderConfirmation.vue +28 -0
- package/src/components/ProductCard.vue +69 -0
- package/src/components/QuantityInput.vue +44 -0
- package/src/components/Sidebar.vue +66 -0
- package/src/composables/handlesFormErrors.js +39 -0
- package/src/config.js +11 -0
- package/src/index.js +24 -0
- package/src/state/authState.js +189 -0
- package/src/state/cartState.js +106 -0
- package/src/state/favoritesState.js +94 -0
- package/src/state/ordersState.js +42 -0
- package/src/state/productsState.js +16 -0
- package/src/state/sidebarState.js +45 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export { default as Sidebar } from './components/Sidebar.vue';
|
|
2
|
+
export { default as CartButton } from './components/CartButton.vue';
|
|
3
|
+
export { default as AuthButton } from './components/AuthButton.vue';
|
|
4
|
+
export { default as AuthSidebar } from './components/AuthSidebar.vue';
|
|
5
|
+
export { default as OrdersSidebar } from './components/OrdersSidebar.vue';
|
|
6
|
+
export { default as FavoritesSidebar } from './components/FavoritesSidebar.vue';
|
|
7
|
+
export { default as CartDetails } from './components/CartDetails.vue';
|
|
8
|
+
export { default as AddressForm } from './components/AddressForm.vue';
|
|
9
|
+
export { default as OrderConfirmation } from './components/OrderConfirmation.vue';
|
|
10
|
+
export { default as PaymentOrderConfirmation } from './components/PaymentOrderConfirmation.vue';
|
|
11
|
+
export { default as ProductCard } from './components/ProductCard.vue';
|
|
12
|
+
export { default as FavoriteProductCard } from './components/FavoriteProductCard.vue';
|
|
13
|
+
export { default as QuantityInput } from './components/QuantityInput.vue';
|
|
14
|
+
|
|
15
|
+
export { authState } from './state/authState.js';
|
|
16
|
+
export { cartState } from './state/cartState.js';
|
|
17
|
+
export { favoritesState } from './state/favoritesState.js';
|
|
18
|
+
export { ordersState } from './state/ordersState.js';
|
|
19
|
+
export { productsState } from './state/productsState.js';
|
|
20
|
+
export { sidebarState } from './state/sidebarState.js';
|
|
21
|
+
|
|
22
|
+
export { useHandlesFormErrors } from './composables/handlesFormErrors.js';
|
|
23
|
+
|
|
24
|
+
export { erpCityUiConfig, setErpCityUiConfig } from './config.js';
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { reactive } from 'vue';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { route } from 'ziggy-js';
|
|
4
|
+
import { favoritesState } from './favoritesState.js';
|
|
5
|
+
import { ordersState } from './ordersState.js';
|
|
6
|
+
import { erpCityUiConfig } from '../config.js';
|
|
7
|
+
|
|
8
|
+
const STORAGE_KEY = 'erp_auth';
|
|
9
|
+
const hasStorage = typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';
|
|
10
|
+
|
|
11
|
+
function normalizeAuthPayload(payload = {}) {
|
|
12
|
+
return {
|
|
13
|
+
user: payload.user ?? null,
|
|
14
|
+
token: payload.token ?? null,
|
|
15
|
+
token_type: payload.token_type ?? payload.tokenType ?? null,
|
|
16
|
+
expires_at: payload.expires_at ?? payload.expiresAt ?? null,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function readStoredAuth() {
|
|
21
|
+
if (! hasStorage) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const value = window.localStorage.getItem(STORAGE_KEY);
|
|
27
|
+
return value ? normalizeAuthPayload(JSON.parse(value)) : null;
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.warn('Failed to parse stored ERP auth', e);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function persistAuth(auth) {
|
|
35
|
+
if (! hasStorage) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (! auth || ! auth.token) {
|
|
40
|
+
window.localStorage.removeItem(STORAGE_KEY);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(auth));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function applyAuthHeader(token, tokenType = 'Bearer') {
|
|
48
|
+
if (token) {
|
|
49
|
+
axios.defaults.headers.common['Authorization'] = `${tokenType ?? 'Bearer'} ${token}`;
|
|
50
|
+
} else {
|
|
51
|
+
delete axios.defaults.headers.common['Authorization'];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isTokenExpired(expiresAt) {
|
|
56
|
+
if (! expiresAt) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const expires = new Date(expiresAt);
|
|
61
|
+
|
|
62
|
+
return Number.isNaN(expires.getTime()) ? false : expires.getTime() <= Date.now();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const storedAuth = readStoredAuth();
|
|
66
|
+
|
|
67
|
+
if (storedAuth?.token) {
|
|
68
|
+
applyAuthHeader(storedAuth.token, storedAuth.token_type);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const authState = reactive({
|
|
72
|
+
user: storedAuth?.user ?? null,
|
|
73
|
+
token: storedAuth?.token ?? null,
|
|
74
|
+
tokenType: storedAuth?.token_type ?? null,
|
|
75
|
+
expiresAt: storedAuth?.expires_at ?? null,
|
|
76
|
+
status: 'idle',
|
|
77
|
+
error: null,
|
|
78
|
+
|
|
79
|
+
get isAuthenticated() {
|
|
80
|
+
return Boolean(this.user && this.token && ! this.tokenExpired());
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
tokenExpired() {
|
|
84
|
+
if (isTokenExpired(this.expiresAt)) {
|
|
85
|
+
this.clearAuth();
|
|
86
|
+
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return false;
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
setAuth(payload) {
|
|
94
|
+
const auth = normalizeAuthPayload(payload);
|
|
95
|
+
|
|
96
|
+
if (! auth.token || ! auth.user || isTokenExpired(auth.expires_at)) {
|
|
97
|
+
this.clearAuth();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
auth.token_type = auth.token_type ?? 'Bearer';
|
|
102
|
+
|
|
103
|
+
this.user = auth.user;
|
|
104
|
+
this.token = auth.token;
|
|
105
|
+
this.tokenType = auth.token_type;
|
|
106
|
+
this.expiresAt = auth.expires_at;
|
|
107
|
+
this.error = null;
|
|
108
|
+
|
|
109
|
+
persistAuth(auth);
|
|
110
|
+
applyAuthHeader(this.token, this.tokenType);
|
|
111
|
+
|
|
112
|
+
if (erpCityUiConfig.showFavorites) {
|
|
113
|
+
favoritesState.fetchFavorites();
|
|
114
|
+
}
|
|
115
|
+
if (erpCityUiConfig.showOrders) {
|
|
116
|
+
ordersState.fetchOrders();
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
clearAuth() {
|
|
121
|
+
this.user = null;
|
|
122
|
+
this.token = null;
|
|
123
|
+
this.tokenType = null;
|
|
124
|
+
this.expiresAt = null;
|
|
125
|
+
this.error = null;
|
|
126
|
+
|
|
127
|
+
persistAuth(null);
|
|
128
|
+
applyAuthHeader(null);
|
|
129
|
+
favoritesState.reset();
|
|
130
|
+
ordersState.reset();
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
async bootstrap() {
|
|
134
|
+
try {
|
|
135
|
+
const { data } = await axios.get(route('erp.auth.session'));
|
|
136
|
+
|
|
137
|
+
if (data.authenticated && data.token && data.user) {
|
|
138
|
+
this.setAuth(data);
|
|
139
|
+
} else {
|
|
140
|
+
this.clearAuth();
|
|
141
|
+
}
|
|
142
|
+
} catch (e) {
|
|
143
|
+
console.warn('Failed to bootstrap ERP auth', e);
|
|
144
|
+
this.clearAuth();
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
async login(payload) {
|
|
149
|
+
this.status = 'loading';
|
|
150
|
+
this.error = null;
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
const { data } = await axios.post(route('erp.auth.login'), payload);
|
|
154
|
+
this.setAuth(data);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
this.error = error.response?.data?.message || 'Autentificarea a eșuat.';
|
|
157
|
+
this.clearAuth();
|
|
158
|
+
throw error;
|
|
159
|
+
} finally {
|
|
160
|
+
this.status = 'idle';
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
async register(payload) {
|
|
165
|
+
this.status = 'loading';
|
|
166
|
+
this.error = null;
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
const { data } = await axios.post(route('erp.auth.register'), payload);
|
|
170
|
+
this.setAuth(data);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
this.error = error.response?.data?.message || 'Înregistrarea a eșuat.';
|
|
173
|
+
this.clearAuth();
|
|
174
|
+
throw error;
|
|
175
|
+
} finally {
|
|
176
|
+
this.status = 'idle';
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
async logout() {
|
|
181
|
+
this.status = 'loading';
|
|
182
|
+
try {
|
|
183
|
+
await axios.post(route('erp.auth.logout'));
|
|
184
|
+
} finally {
|
|
185
|
+
this.status = 'idle';
|
|
186
|
+
this.clearAuth();
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { reactive } from 'vue';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { route } from 'ziggy-js';
|
|
4
|
+
import {productsState} from "./productsState.js";
|
|
5
|
+
|
|
6
|
+
export const cartState = reactive({
|
|
7
|
+
items: [],
|
|
8
|
+
coupon: null,
|
|
9
|
+
couponError: null,
|
|
10
|
+
couponLoading: false,
|
|
11
|
+
|
|
12
|
+
get count() {
|
|
13
|
+
return this.items.reduce((sum, item) => sum + item.quantity, 0);
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
get subtotal() {
|
|
17
|
+
return this.items.reduce((sum, item) => {
|
|
18
|
+
const product = productsState.getProduct(item.id);
|
|
19
|
+
return sum + (product ? product.price * item.quantity : 0);
|
|
20
|
+
}, 0);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
get discountAmount() {
|
|
24
|
+
if (!this.coupon || !this.subtotal) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const percent = this.coupon.discountPercent ?? 0;
|
|
29
|
+
return (this.subtotal * percent) / 100;
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
get price() {
|
|
33
|
+
return Math.max(0, this.subtotal - this.discountAmount);
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
setCart(newCart) {
|
|
37
|
+
this.items = newCart;
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
async loadCart() {
|
|
41
|
+
const { data } = await axios.get(route('erp.cart.index'));
|
|
42
|
+
this.setCart(data);
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
async addToCart(productId, quantity = 1, price) {
|
|
46
|
+
const { data } = await axios.post(route('erp.cart.add'), { id: productId, quantity, price });
|
|
47
|
+
this.setCart(data);
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
async updateQuantity(productId, quantity, price) {
|
|
51
|
+
const { data } = await axios.post(route('erp.cart.update'), { id: productId, quantity, price });
|
|
52
|
+
this.setCart(data);
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
async removeItem(productId) {
|
|
56
|
+
const { data } = await axios.delete(route('erp.cart.remove', productId));
|
|
57
|
+
this.setCart(data);
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
async clearCart() {
|
|
61
|
+
const { data } = await axios.delete(route('erp.cart.clear'));
|
|
62
|
+
this.setCart(data);
|
|
63
|
+
this.coupon = null;
|
|
64
|
+
this.couponError = null;
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
async applyCoupon(code) {
|
|
68
|
+
const normalized = (code || '').trim();
|
|
69
|
+
this.couponError = null;
|
|
70
|
+
|
|
71
|
+
if (!normalized) {
|
|
72
|
+
this.coupon = null;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.couponLoading = true;
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const { data } = await axios.post(route('erp.cart.coupon.apply'), { code: normalized });
|
|
80
|
+
const coupon = data?.data;
|
|
81
|
+
this.coupon = coupon
|
|
82
|
+
? {
|
|
83
|
+
code: coupon.code,
|
|
84
|
+
discountPercent: coupon.discount_percent,
|
|
85
|
+
}
|
|
86
|
+
: null;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const message = error?.response?.data?.message || 'Cupon invalid.';
|
|
89
|
+
this.couponError = message;
|
|
90
|
+
this.coupon = null;
|
|
91
|
+
} finally {
|
|
92
|
+
this.couponLoading = false;
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
async clearCoupon() {
|
|
97
|
+
this.coupon = null;
|
|
98
|
+
this.couponError = null;
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
await axios.delete(route('erp.cart.coupon.clear'));
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.warn('Failed to clear coupon', error);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { reactive } from 'vue';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { route } from 'ziggy-js';
|
|
4
|
+
|
|
5
|
+
function normalizeFavoriteId(favorite) {
|
|
6
|
+
if (typeof favorite === 'object' && favorite !== null) {
|
|
7
|
+
return Number(favorite.id);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return Number(favorite);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const favoritesState = reactive({
|
|
14
|
+
ids: [],
|
|
15
|
+
loading: false,
|
|
16
|
+
error: null,
|
|
17
|
+
|
|
18
|
+
isFavorite(productId) {
|
|
19
|
+
return this.ids.includes(Number(productId));
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
setFavorites(favorites = []) {
|
|
23
|
+
if (! Array.isArray(favorites)) {
|
|
24
|
+
this.ids = [];
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this.ids = favorites
|
|
29
|
+
.map(normalizeFavoriteId)
|
|
30
|
+
.filter(id => Number.isInteger(id) && id > 0);
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
reset() {
|
|
34
|
+
this.ids = [];
|
|
35
|
+
this.error = null;
|
|
36
|
+
this.loading = false;
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
async fetchFavorites() {
|
|
40
|
+
this.loading = true;
|
|
41
|
+
this.error = null;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const { data } = await axios.get(route('erp.account.favorites.index'));
|
|
45
|
+
this.setFavorites(data.favorites);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (error.response?.status === 401) {
|
|
48
|
+
this.reset();
|
|
49
|
+
} else {
|
|
50
|
+
this.error = error.response?.data?.message || 'Nu am putut încărca favoritele.';
|
|
51
|
+
}
|
|
52
|
+
} finally {
|
|
53
|
+
this.loading = false;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
toggleLocal(productId) {
|
|
58
|
+
const id = Number(productId);
|
|
59
|
+
|
|
60
|
+
if (! Number.isInteger(id) || id <= 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (this.ids.includes(id)) {
|
|
65
|
+
this.ids = this.ids.filter(existingId => existingId !== id);
|
|
66
|
+
} else {
|
|
67
|
+
this.ids = [...this.ids, id];
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
async toggle(productId) {
|
|
72
|
+
if (! productId) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.loading = true;
|
|
77
|
+
this.error = null;
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const { data } = await axios.post(route('erp.account.favorites.toggle', productId));
|
|
81
|
+
|
|
82
|
+
if (Array.isArray(data?.favorites)) {
|
|
83
|
+
this.setFavorites(data.favorites);
|
|
84
|
+
} else {
|
|
85
|
+
this.toggleLocal(productId);
|
|
86
|
+
}
|
|
87
|
+
} catch (error) {
|
|
88
|
+
this.error = error.response?.data?.message || 'Nu am putut actualiza favoritele.';
|
|
89
|
+
throw error;
|
|
90
|
+
} finally {
|
|
91
|
+
this.loading = false;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { reactive } from 'vue';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { route } from 'ziggy-js';
|
|
4
|
+
|
|
5
|
+
export const ordersState = reactive({
|
|
6
|
+
orders: [],
|
|
7
|
+
loading: false,
|
|
8
|
+
error: null,
|
|
9
|
+
|
|
10
|
+
setOrders(orders = []) {
|
|
11
|
+
if (! Array.isArray(orders)) {
|
|
12
|
+
this.orders = [];
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
this.orders = orders;
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
reset() {
|
|
20
|
+
this.orders = [];
|
|
21
|
+
this.error = null;
|
|
22
|
+
this.loading = false;
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
async fetchOrders() {
|
|
26
|
+
this.loading = true;
|
|
27
|
+
this.error = null;
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const { data } = await axios.get(route('erp.account.orders.index'));
|
|
31
|
+
this.setOrders(data.orders);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error.response?.status === 401) {
|
|
34
|
+
this.reset();
|
|
35
|
+
} else {
|
|
36
|
+
this.error = error.response?.data?.message || 'Nu am putut încărca comenzile.';
|
|
37
|
+
}
|
|
38
|
+
} finally {
|
|
39
|
+
this.loading = false;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { reactive } from 'vue';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { route } from 'ziggy-js';
|
|
4
|
+
|
|
5
|
+
export const productsState = reactive({
|
|
6
|
+
products: [],
|
|
7
|
+
|
|
8
|
+
getProduct(id) {
|
|
9
|
+
return this.products.find(product => product.id === id);
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
async loadProducts() {
|
|
13
|
+
const { data } = await axios.get(route('products.index'));
|
|
14
|
+
this.products = data;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {reactive} from 'vue';
|
|
2
|
+
|
|
3
|
+
export const sidebarState = reactive({
|
|
4
|
+
isOpen: false,
|
|
5
|
+
currentView: null,
|
|
6
|
+
title: '',
|
|
7
|
+
withBack: false,
|
|
8
|
+
viewStack: [],
|
|
9
|
+
nextView: null,
|
|
10
|
+
|
|
11
|
+
open(view) {
|
|
12
|
+
this.currentView = view;
|
|
13
|
+
|
|
14
|
+
if (this.currentView) {
|
|
15
|
+
this.viewStack.push(this.currentView);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
this.isOpen = true;
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
close() {
|
|
22
|
+
this.isOpen = false;
|
|
23
|
+
this.currentView = null;
|
|
24
|
+
this.title = '';
|
|
25
|
+
this.withBack = false;
|
|
26
|
+
this.viewStack = [];
|
|
27
|
+
this.nextView = null;
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
setHeader(title, withBack) {
|
|
31
|
+
this.title = title;
|
|
32
|
+
this.withBack = withBack;
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
goBack() {
|
|
36
|
+
if (this.viewStack.length > 1) {
|
|
37
|
+
// Remove current view
|
|
38
|
+
this.viewStack.pop();
|
|
39
|
+
// Set previous view (last in stack)
|
|
40
|
+
this.currentView = this.viewStack[this.viewStack.length - 1];
|
|
41
|
+
} else {
|
|
42
|
+
this.close();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|