flowrix 1.0.1-beta.68 → 1.0.1-beta.69

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/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "flowrix",
3
3
  "configKey": "flowrix",
4
- "version": "1.0.1-beta.68",
4
+ "version": "1.0.1-beta.69",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -1,7 +1,9 @@
1
1
  export default function (): {
2
2
  router: any;
3
3
  route: any;
4
- inputData: import("vue").Ref<{}, {}>;
5
- CustomerLogin: (loginFields: any) => Promise<void>;
6
- logResponse: import("vue").Ref<never[], never[]>;
4
+ email: import("vue").Ref<string, string>;
5
+ password: import("vue").Ref<string, string>;
6
+ CustomerLogin: () => Promise<void>;
7
+ logResponse: import("vue").Ref<any, any>;
8
+ isLoading: import("vue").Ref<boolean, boolean>;
7
9
  };
@@ -4,16 +4,31 @@ import { useAuthStore } from "../../stores/auth.js";
4
4
  export default function() {
5
5
  const router = useRouter();
6
6
  const route = useRoute();
7
- const inputData = ref({});
8
- const logResponse = ref([]);
9
- const CustomerLogin = (async (loginFields) => {
10
- logResponse.value = await useAuthStore().userLogin(loginFields);
11
- });
7
+ const email = ref("");
8
+ const password = ref("");
9
+ const logResponse = ref(null);
10
+ const isLoading = ref(false);
11
+ const CustomerLogin = async () => {
12
+ isLoading.value = true;
13
+ try {
14
+ const loginFields = {
15
+ email: email.value,
16
+ password: password.value
17
+ };
18
+ logResponse.value = await useAuthStore().userLogin(loginFields);
19
+ } catch (error) {
20
+ logResponse.value = { status: "Error", message: "Login failed" };
21
+ } finally {
22
+ isLoading.value = false;
23
+ }
24
+ };
12
25
  return {
13
26
  router,
14
27
  route,
15
- inputData,
28
+ email,
29
+ password,
16
30
  CustomerLogin,
17
- logResponse
31
+ logResponse,
32
+ isLoading
18
33
  };
19
34
  }
@@ -0,0 +1,26 @@
1
+ export default function (timerDuration?: number): {
2
+ email: import("vue").Ref<string, string>;
3
+ resetCode: import("vue").Ref<string, string>;
4
+ newPassword: import("vue").Ref<string, string>;
5
+ confirmPassword: import("vue").Ref<string, string>;
6
+ showPassword: import("vue").Ref<boolean, boolean>;
7
+ showConfirmPassword: import("vue").Ref<boolean, boolean>;
8
+ isLoading: import("vue").Ref<boolean, boolean>;
9
+ errorMessage: import("vue").Ref<string, string>;
10
+ successMessage: import("vue").Ref<string, string>;
11
+ isCodeSent: import("vue").Ref<boolean, boolean>;
12
+ isCodeVerified: import("vue").Ref<boolean, boolean>;
13
+ currentStep: import("vue").Ref<number, number>;
14
+ timerCount: import("vue").Ref<number, number>;
15
+ isTimerActive: import("vue").Ref<boolean, boolean>;
16
+ formatTime: (seconds: number) => string;
17
+ togglePassword: (field: "newPassword" | "confirmPassword") => void;
18
+ handleSubmit: () => Promise<void>;
19
+ resetForm: () => void;
20
+ resendCode: () => Promise<void>;
21
+ startTimer: (duration?: number) => void;
22
+ stopTimer: () => void;
23
+ resetTimer: (duration?: number) => void;
24
+ cleanup: () => void;
25
+ router: any;
26
+ };
@@ -0,0 +1,258 @@
1
+ import { ref } from "vue";
2
+ import { useRouter, useRoute } from "#vue-router";
3
+ import { useAuthStore } from "../../stores/auth.js";
4
+ export default function(timerDuration = 60) {
5
+ const router = useRouter();
6
+ const route = useRoute();
7
+ const authStore = useAuthStore();
8
+ const email = ref("");
9
+ const resetCode = ref("");
10
+ const newPassword = ref("");
11
+ const confirmPassword = ref("");
12
+ const showPassword = ref(false);
13
+ const showConfirmPassword = ref(false);
14
+ const isLoading = ref(false);
15
+ const errorMessage = ref("");
16
+ const successMessage = ref("");
17
+ const isCodeSent = ref(false);
18
+ const isCodeVerified = ref(false);
19
+ const currentStep = ref(1);
20
+ const verifiedToken = ref("");
21
+ const timerCount = ref(timerDuration);
22
+ const isTimerActive = ref(false);
23
+ const timerInterval = ref(null);
24
+ const validateEmail = (email2) => {
25
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email2);
26
+ };
27
+ const togglePassword = (field) => {
28
+ if (field === "newPassword") {
29
+ showPassword.value = !showPassword.value;
30
+ } else {
31
+ showConfirmPassword.value = !showConfirmPassword.value;
32
+ }
33
+ };
34
+ const startTimer = (duration = timerDuration) => {
35
+ isTimerActive.value = true;
36
+ timerCount.value = duration;
37
+ timerInterval.value = setInterval(() => {
38
+ timerCount.value--;
39
+ if (timerCount.value <= 0) {
40
+ clearInterval(timerInterval.value);
41
+ isTimerActive.value = false;
42
+ }
43
+ }, 1e3);
44
+ };
45
+ const stopTimer = () => {
46
+ if (timerInterval.value) {
47
+ clearInterval(timerInterval.value);
48
+ timerInterval.value = null;
49
+ }
50
+ isTimerActive.value = false;
51
+ };
52
+ const resetTimer = (duration = timerDuration) => {
53
+ stopTimer();
54
+ timerCount.value = duration;
55
+ };
56
+ const formatTime = (seconds) => {
57
+ const mins = Math.floor(seconds / 60);
58
+ const secs = seconds % 60;
59
+ return `${mins}:${secs < 10 ? "0" : ""}${secs}`;
60
+ };
61
+ const resendCode = async () => {
62
+ if (!validateEmail(email.value)) {
63
+ errorMessage.value = "Please enter a valid email address";
64
+ return;
65
+ }
66
+ isLoading.value = true;
67
+ errorMessage.value = "";
68
+ successMessage.value = "";
69
+ try {
70
+ const response = await authStore.verifyEmail(email.value.trim());
71
+ if (response.status === "Success") {
72
+ successMessage.value = "Reset code sent to your email again!";
73
+ errorMessage.value = "";
74
+ startTimer();
75
+ } else {
76
+ errorMessage.value = formatErrorMessage(response.message) || "Failed to resend reset code. Please try again.";
77
+ successMessage.value = "";
78
+ }
79
+ } catch (error) {
80
+ errorMessage.value = "An error occurred while resending code. Please try again.";
81
+ successMessage.value = "";
82
+ } finally {
83
+ isLoading.value = false;
84
+ }
85
+ };
86
+ const sendResetCode = async () => {
87
+ if (!validateEmail(email.value)) {
88
+ errorMessage.value = "Please enter a valid email address";
89
+ successMessage.value = "";
90
+ return;
91
+ }
92
+ isLoading.value = true;
93
+ errorMessage.value = "";
94
+ successMessage.value = "";
95
+ try {
96
+ const response = await authStore.verifyEmail(email.value.trim());
97
+ if (response.status === "Success") {
98
+ successMessage.value = "Reset code sent to your email!";
99
+ errorMessage.value = "";
100
+ isCodeSent.value = true;
101
+ currentStep.value = 2;
102
+ startTimer();
103
+ } else {
104
+ errorMessage.value = formatErrorMessage(response.message) || "Failed to send reset code. Please try again.";
105
+ successMessage.value = "";
106
+ }
107
+ } catch (error) {
108
+ errorMessage.value = "An error occurred while sending reset code. Please try again.";
109
+ successMessage.value = "";
110
+ } finally {
111
+ isLoading.value = false;
112
+ }
113
+ };
114
+ const verifyResetCode = async () => {
115
+ if (!resetCode.value) {
116
+ errorMessage.value = "Please enter the reset code";
117
+ successMessage.value = "";
118
+ return;
119
+ }
120
+ isLoading.value = true;
121
+ errorMessage.value = "";
122
+ successMessage.value = "";
123
+ try {
124
+ const response = await authStore.verifyToken(email.value.trim(), resetCode.value.trim());
125
+ if (response.status === "Success") {
126
+ verifiedToken.value = response.data?.token || response.data;
127
+ successMessage.value = "Code verified successfully!";
128
+ errorMessage.value = "";
129
+ isCodeVerified.value = true;
130
+ currentStep.value = 3;
131
+ stopTimer();
132
+ } else {
133
+ errorMessage.value = formatErrorMessage(response.message) || "Invalid reset code. Please try again.";
134
+ successMessage.value = "";
135
+ }
136
+ } catch (error) {
137
+ errorMessage.value = "An error occurred while verifying code. Please try again.";
138
+ successMessage.value = "";
139
+ } finally {
140
+ isLoading.value = false;
141
+ }
142
+ };
143
+ const resetPasswordFunc = async () => {
144
+ if (newPassword.value !== confirmPassword.value) {
145
+ errorMessage.value = "Passwords do not match";
146
+ successMessage.value = "";
147
+ return;
148
+ }
149
+ if (newPassword.value.length < 8) {
150
+ errorMessage.value = "Password must be at least 8 characters long";
151
+ successMessage.value = "";
152
+ return;
153
+ }
154
+ isLoading.value = true;
155
+ errorMessage.value = "";
156
+ successMessage.value = "";
157
+ try {
158
+ const response = await authStore.resetPassword(
159
+ verifiedToken.value,
160
+ newPassword.value.trim(),
161
+ confirmPassword.value.trim()
162
+ );
163
+ if (response.status === "Success") {
164
+ const loginResponse = await authStore.userLogin({
165
+ email: email.value.trim(),
166
+ password: newPassword.value.trim()
167
+ });
168
+ if (loginResponse.status === "Success") {
169
+ resetForm();
170
+ successMessage.value = formatErrorMessage(response.message) || "Password reset successfully!";
171
+ errorMessage.value = "";
172
+ router.push("dashboard/profile");
173
+ } else {
174
+ successMessage.value = formatErrorMessage(response.message) || "Password reset successfully!";
175
+ errorMessage.value = "Password reset successful, but login failed. Please login manually.";
176
+ resetCode.value = "";
177
+ verifiedToken.value = "";
178
+ isCodeSent.value = false;
179
+ isCodeVerified.value = false;
180
+ currentStep.value = 1;
181
+ }
182
+ } else {
183
+ errorMessage.value = formatErrorMessage(response.message) || "Failed to reset password. Please try again.";
184
+ successMessage.value = "";
185
+ }
186
+ } catch (error) {
187
+ errorMessage.value = "An error occurred while resetting password. Please try again.";
188
+ successMessage.value = "";
189
+ } finally {
190
+ isLoading.value = false;
191
+ }
192
+ };
193
+ const handleSubmit = async () => {
194
+ if (currentStep.value === 1) {
195
+ await sendResetCode();
196
+ } else if (currentStep.value === 2) {
197
+ await verifyResetCode();
198
+ } else {
199
+ await resetPasswordFunc();
200
+ }
201
+ };
202
+ const formatErrorMessage = (message) => {
203
+ if (Array.isArray(message)) {
204
+ return message.join(", ");
205
+ }
206
+ return message;
207
+ };
208
+ const resetForm = () => {
209
+ email.value = "";
210
+ resetCode.value = "";
211
+ newPassword.value = "";
212
+ confirmPassword.value = "";
213
+ showPassword.value = false;
214
+ showConfirmPassword.value = false;
215
+ isLoading.value = false;
216
+ errorMessage.value = "";
217
+ successMessage.value = "";
218
+ isCodeSent.value = false;
219
+ isCodeVerified.value = false;
220
+ currentStep.value = 1;
221
+ verifiedToken.value = "";
222
+ stopTimer();
223
+ };
224
+ const cleanup = () => {
225
+ stopTimer();
226
+ };
227
+ return {
228
+ // State
229
+ email,
230
+ resetCode,
231
+ newPassword,
232
+ confirmPassword,
233
+ showPassword,
234
+ showConfirmPassword,
235
+ isLoading,
236
+ errorMessage,
237
+ successMessage,
238
+ isCodeSent,
239
+ isCodeVerified,
240
+ currentStep,
241
+ timerCount,
242
+ isTimerActive,
243
+ formatTime,
244
+ // Methods
245
+ togglePassword,
246
+ handleSubmit,
247
+ resetForm,
248
+ resendCode,
249
+ startTimer,
250
+ // Export startTimer for external control
251
+ stopTimer,
252
+ // Export stopTimer for external control
253
+ resetTimer,
254
+ // Export resetTimer for external control
255
+ cleanup,
256
+ router
257
+ };
258
+ }
@@ -34,6 +34,7 @@ export * from './Customer/useShippingAddress.js';
34
34
  export * from './Customer/useUpdatePassword.js';
35
35
  export * from './Customer/useUserCards.js';
36
36
  export * from './Customer/useWishlists.js';
37
+ export * from './Customer/usePasswordReset.js';
37
38
  export * from './Extras/useCountry.js';
38
39
  export * from './Extras/useDateFormatter.js';
39
40
  export * from './Extras/useNumberOnly.js';
@@ -34,6 +34,7 @@ export * from "./Customer/useShippingAddress.js";
34
34
  export * from "./Customer/useUpdatePassword.js";
35
35
  export * from "./Customer/useUserCards.js";
36
36
  export * from "./Customer/useWishlists.js";
37
+ export * from "./Customer/usePasswordReset.js";
37
38
  export * from "./Extras/useCountry.js";
38
39
  export * from "./Extras/useDateFormatter.js";
39
40
  export * from "./Extras/useNumberOnly.js";
@@ -43,8 +43,13 @@ export interface User {
43
43
  export interface AuthState {
44
44
  user: User | null;
45
45
  token: string | null;
46
- isAuthenticated: boolean;
47
- _hydrated: boolean;
46
+ isAuthenticated: false;
47
+ _hydrated: false;
48
+ }
49
+ export interface AuthResponse {
50
+ status: string;
51
+ message: string;
52
+ data: any | null;
48
53
  }
49
54
  export declare const useAuthStore: import("pinia").StoreDefinition<"auth", AuthState, {
50
55
  getUser: (state: AuthState) => User | null;
@@ -1,6 +1,12 @@
1
1
  import { defineStore } from "pinia";
2
2
  import { flowrixApi } from "../middleware/flowrix.js";
3
3
  import { useRuntimeConfig } from "#imports";
4
+ function formatErrorMessage(message) {
5
+ if (Array.isArray(message)) {
6
+ return message.join(", ");
7
+ }
8
+ return message;
9
+ }
4
10
  export const useAuthStore = defineStore("auth", {
5
11
  state: () => ({
6
12
  user: null,
@@ -22,13 +28,9 @@ export const useAuthStore = defineStore("auth", {
22
28
  ...config,
23
29
  cookies: rawCookies
24
30
  };
25
- const response = await flowrixApi.post(
26
- apiUrl,
27
- apiConfig,
28
- {
29
- body: userFields
30
- }
31
- );
31
+ const response = await flowrixApi.post(apiUrl, apiConfig, {
32
+ body: userFields
33
+ });
32
34
  if (response.status == "Success") {
33
35
  if (process.client) {
34
36
  const token = response?.data?.access_token;
@@ -60,13 +62,9 @@ export const useAuthStore = defineStore("auth", {
60
62
  ...config,
61
63
  cookies: rawCookies
62
64
  };
63
- const response = await flowrixApi.post(
64
- apiUrl,
65
- apiConfig,
66
- {
67
- body: userFields
68
- }
69
- );
65
+ const response = await flowrixApi.post(apiUrl, apiConfig, {
66
+ body: userFields
67
+ });
70
68
  if (response.status == "Success") {
71
69
  const authTokenCookie = useCookie("authToken", {
72
70
  sameSite: "none",
@@ -119,13 +117,9 @@ export const useAuthStore = defineStore("auth", {
119
117
  cookies: rawCookies
120
118
  };
121
119
  const apiUrl = "mystore/customer/profile/update";
122
- const response = await flowrixApi.post(
123
- apiUrl,
124
- apiConfig,
125
- {
126
- body: userData
127
- }
128
- );
120
+ const response = await flowrixApi.post(apiUrl, apiConfig, {
121
+ body: userData
122
+ });
129
123
  if (response.status === "Success") {
130
124
  await this.fetchProfile();
131
125
  return { status: response.status, message: response.message || "Profile Updated Successfully" };
@@ -172,13 +166,9 @@ export const useAuthStore = defineStore("auth", {
172
166
  cookies: rawCookies
173
167
  };
174
168
  const apiUrl = "mystore/customer/change-password";
175
- const response = await flowrixApi.post(
176
- apiUrl,
177
- apiConfig,
178
- {
179
- body: userData
180
- }
181
- );
169
+ const response = await flowrixApi.post(apiUrl, apiConfig, {
170
+ body: userData
171
+ });
182
172
  if (response.status === "Success") {
183
173
  return { status: response.status, message: response.message || "Password Update Successfully" };
184
174
  } else {
@@ -324,6 +314,86 @@ export const useAuthStore = defineStore("auth", {
324
314
  return error.data;
325
315
  }
326
316
  },
317
+ // Password Reset APIs
318
+ async verifyEmail(email) {
319
+ try {
320
+ const config = useRuntimeConfig();
321
+ let rawCookies = "";
322
+ if (process.client) {
323
+ rawCookies = document.cookie || "";
324
+ }
325
+ const apiConfig = {
326
+ ...config,
327
+ cookies: rawCookies
328
+ };
329
+ const response = await flowrixApi.post("verify-email", apiConfig, {
330
+ body: { email }
331
+ });
332
+ return response;
333
+ } catch (error) {
334
+ console.error("Verify email error:", error);
335
+ const message = error.data ? formatErrorMessage(error.data.message) : error.message || "Email verification failed";
336
+ return {
337
+ status: "Error",
338
+ message,
339
+ data: null
340
+ };
341
+ }
342
+ },
343
+ async verifyToken(email, token) {
344
+ try {
345
+ const config = useRuntimeConfig();
346
+ let rawCookies = "";
347
+ if (process.client) {
348
+ rawCookies = document.cookie || "";
349
+ }
350
+ const apiConfig = {
351
+ ...config,
352
+ cookies: rawCookies
353
+ };
354
+ const response = await flowrixApi.post("verify-token", apiConfig, {
355
+ body: { email, token }
356
+ });
357
+ return response;
358
+ } catch (error) {
359
+ console.error("Verify token error:", error);
360
+ const message = error.data ? formatErrorMessage(error.data.message) : error.message || "Token verification failed";
361
+ return {
362
+ status: "Error",
363
+ message,
364
+ data: null
365
+ };
366
+ }
367
+ },
368
+ async resetPassword(token, password, password_confirmation) {
369
+ try {
370
+ const config = useRuntimeConfig();
371
+ let rawCookies = "";
372
+ if (process.client) {
373
+ rawCookies = document.cookie || "";
374
+ }
375
+ const apiConfig = {
376
+ ...config,
377
+ cookies: rawCookies
378
+ };
379
+ const response = await flowrixApi.post("reset-password", apiConfig, {
380
+ body: {
381
+ token,
382
+ password,
383
+ password_confirmation
384
+ }
385
+ });
386
+ return response;
387
+ } catch (error) {
388
+ console.error("Reset password error:", error);
389
+ const message = error.data ? formatErrorMessage(error.data.message) : error.message || "Password reset failed";
390
+ return {
391
+ status: "Error",
392
+ message,
393
+ data: null
394
+ };
395
+ }
396
+ },
327
397
  loadAuth() {
328
398
  if (process.client) {
329
399
  const token = localStorage.getItem("auth_token");
@@ -353,7 +423,6 @@ export const useAuthStore = defineStore("auth", {
353
423
  localStorage.removeItem("auth_user");
354
424
  }
355
425
  },
356
- // Mark as hydrated without loading
357
426
  setHydrated() {
358
427
  this._hydrated = true;
359
428
  }
@@ -366,7 +435,6 @@ export const useAuthStore = defineStore("auth", {
366
435
  },
367
436
  persist: {
368
437
  enabled: true,
369
- // simple shape that works with most versions:
370
438
  key: "user",
371
439
  storage: typeof window !== "undefined" ? localStorage : void 0
372
440
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowrix",
3
- "version": "1.0.1-beta.68",
3
+ "version": "1.0.1-beta.69",
4
4
  "description": "Plug-and-play Nuxt eCommerce cart powered by FLOWRiX. Subscription required.",
5
5
  "license": "MIT",
6
6
  "type": "module",