@unsource/ui 2.1.4 → 2.2.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/dist/module.json +1 -1
- package/dist/module.mjs +6 -2
- package/dist/runtime/components/UnAuth.d.vue.ts +34 -0
- package/dist/runtime/components/UnAuth.vue +326 -0
- package/dist/runtime/components/UnAuth.vue.d.ts +34 -0
- package/dist/runtime/components/UnAuthInputs.d.vue.ts +23 -0
- package/dist/runtime/components/UnAuthInputs.vue +86 -0
- package/dist/runtime/components/UnAuthInputs.vue.d.ts +23 -0
- package/dist/runtime/components/UnAuthShortHand.d.vue.ts +8 -0
- package/dist/runtime/components/UnAuthShortHand.vue +19 -0
- package/dist/runtime/components/UnAuthShortHand.vue.d.ts +8 -0
- package/dist/runtime/components/UnCodeInput.d.vue.ts +6 -0
- package/dist/runtime/components/UnCodeInput.vue +31 -0
- package/dist/runtime/components/UnCodeInput.vue.d.ts +6 -0
- package/dist/runtime/components/UnFormItem.vue +2 -3
- package/dist/runtime/components/UnIRDatePicker.vue +1 -1
- package/dist/runtime/components/UnInput.d.vue.ts +2 -2
- package/dist/runtime/components/UnInput.vue.d.ts +2 -2
- package/dist/runtime/components/UnLog.vue +2 -0
- package/dist/runtime/components/UnMap.vue +42 -24
- package/dist/runtime/components/UnMultiUploader.vue +47 -44
- package/dist/runtime/components/UnNormalInput.d.vue.ts +51 -0
- package/dist/runtime/components/UnNormalInput.vue +110 -0
- package/dist/runtime/components/UnNormalInput.vue.d.ts +51 -0
- package/dist/runtime/components/UnSelect.vue +17 -5
- package/dist/runtime/components/UnTimer.d.vue.ts +16 -0
- package/dist/runtime/components/UnTimer.vue +31 -0
- package/dist/runtime/components/UnTimer.vue.d.ts +16 -0
- package/dist/runtime/components/UnUploadFile.vue +38 -25
- package/dist/runtime/composables/reuseable.d.ts +3 -3
- package/package.json +7 -7
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -47,7 +47,10 @@ const module = defineNuxtModule({
|
|
|
47
47
|
"nuxt-swiper": {},
|
|
48
48
|
"@vueuse/nuxt": {},
|
|
49
49
|
"@nuxtjs/i18n": {
|
|
50
|
-
version: "^
|
|
50
|
+
version: "^10.0.0",
|
|
51
|
+
defaults: {
|
|
52
|
+
strategy: "no_prefix"
|
|
53
|
+
}
|
|
51
54
|
}
|
|
52
55
|
},
|
|
53
56
|
// Default configuration options of the Nuxt module
|
|
@@ -63,7 +66,8 @@ const module = defineNuxtModule({
|
|
|
63
66
|
"numeral",
|
|
64
67
|
"persian-number",
|
|
65
68
|
"ajv",
|
|
66
|
-
"handlebars"
|
|
69
|
+
"handlebars",
|
|
70
|
+
"vue-json-pretty"
|
|
67
71
|
];
|
|
68
72
|
}
|
|
69
73
|
},
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
logo?: string;
|
|
3
|
+
head?: string;
|
|
4
|
+
type: 'login' | 'recover' | 'otp' | 'register';
|
|
5
|
+
userTypes?: Record<string, string>[];
|
|
6
|
+
loginType?: 'otp' | 'password';
|
|
7
|
+
mutiType?: boolean;
|
|
8
|
+
userParams?: Record<string, string | boolean>;
|
|
9
|
+
otpPage?: string;
|
|
10
|
+
redirectPage?: string;
|
|
11
|
+
profilePage?: string;
|
|
12
|
+
profileFormPage?: string;
|
|
13
|
+
loginPage?: string;
|
|
14
|
+
passLoginPage?: string;
|
|
15
|
+
successLoginAlert?: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
buttonTitle?: string;
|
|
18
|
+
forgetPassword?: boolean;
|
|
19
|
+
click?: Record<string, never>;
|
|
20
|
+
shortHand?: boolean;
|
|
21
|
+
};
|
|
22
|
+
declare var __VLS_29: {};
|
|
23
|
+
type __VLS_Slots = {} & {
|
|
24
|
+
default?: (props: typeof __VLS_29) => any;
|
|
25
|
+
};
|
|
26
|
+
declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
28
|
+
declare const _default: typeof __VLS_export;
|
|
29
|
+
export default _default;
|
|
30
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
31
|
+
new (): {
|
|
32
|
+
$slots: S;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-col items-stretch gap-8 grow px-2 py-6 self-stretch">
|
|
3
|
+
<div class="grow-1 p-3 basis-50">
|
|
4
|
+
<div
|
|
5
|
+
v-if="logo"
|
|
6
|
+
class="flex flex-col items-center children:text-center gap-3 px-4 py-0"
|
|
7
|
+
>
|
|
8
|
+
<UnNuxtIcon
|
|
9
|
+
:name="logo"
|
|
10
|
+
class="!text-8xl text-primary-500"
|
|
11
|
+
/>
|
|
12
|
+
</div>
|
|
13
|
+
<template v-if="['login', 'recover'].includes(type)">
|
|
14
|
+
<UnAuthInputs
|
|
15
|
+
v-model="form"
|
|
16
|
+
:type="type === 'recover' ? type : loginType"
|
|
17
|
+
:head
|
|
18
|
+
:have-tabs="true"
|
|
19
|
+
:login-page
|
|
20
|
+
:pass-login-page
|
|
21
|
+
:have-login-type="mutiType"
|
|
22
|
+
/>
|
|
23
|
+
<div
|
|
24
|
+
v-if="type === 'login'"
|
|
25
|
+
class="flex items-center gap-2 mt-4"
|
|
26
|
+
>
|
|
27
|
+
<p class="text-(sm gray-600)">
|
|
28
|
+
با ورود،
|
|
29
|
+
<NuxtLink
|
|
30
|
+
to="https://parand.app/terms"
|
|
31
|
+
target="_blank"
|
|
32
|
+
class="text-gra-900 font-bold underline"
|
|
33
|
+
>قوانین و
|
|
34
|
+
مقررات
|
|
35
|
+
</NuxtLink>
|
|
36
|
+
استفاده از اپلیکیشن را میپذیرم
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
<div
|
|
41
|
+
v-else-if="type === 'otp'"
|
|
42
|
+
class="flex flex-col items-stretch gap-24"
|
|
43
|
+
>
|
|
44
|
+
<div class="flex flex-col items-stretch gap-6">
|
|
45
|
+
<div class="flex justify-between">
|
|
46
|
+
<p class="text-(gray-600 lg) font-semibold">
|
|
47
|
+
{{ $t("\u06A9\u062F \u062A\u0627\u06CC\u06CC\u062F \u0631\u0627 \u0648\u0627\u0631\u062F \u06A9\u0646\u06CC\u062F") }}
|
|
48
|
+
</p>
|
|
49
|
+
<div
|
|
50
|
+
class="text-xs text-gray-600 underline cursor-pointer"
|
|
51
|
+
@click="navigateTo({ name: 'login' })"
|
|
52
|
+
>
|
|
53
|
+
{{ $t("\u062A\u063A\u06CC\u06CC\u0631 \u0634\u0645\u0627\u0631\u0647 \u0645\u0648\u0628\u0627\u06CC\u0644 ") }}
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
<UnCodeInput
|
|
57
|
+
v-model="otp"
|
|
58
|
+
class="flex gap-1 self-center justify-between"
|
|
59
|
+
@complete="checkOTP"
|
|
60
|
+
/>
|
|
61
|
+
<div class="flex justify-center items-center gap-2 text-gray-400 text-xs">
|
|
62
|
+
<p v-if="!isExpired">
|
|
63
|
+
{{ $t("\u0632\u0645\u0627\u0646 \u0628\u0627\u0642\u06CC\u200C\u0645\u0627\u0646\u062F\u0647: ") }}
|
|
64
|
+
</p>
|
|
65
|
+
<p
|
|
66
|
+
v-else
|
|
67
|
+
class="text-primary-500 cursor-pointer"
|
|
68
|
+
@click="sendAgain"
|
|
69
|
+
>
|
|
70
|
+
{{ $t("\u0627\u0631\u0633\u0627\u0644 \u0645\u062C\u062F\u062F") }}
|
|
71
|
+
</p>
|
|
72
|
+
<UnTimer
|
|
73
|
+
v-if="!isExpired"
|
|
74
|
+
:key="expiredAt"
|
|
75
|
+
v-model="isExpired"
|
|
76
|
+
:time="expiredAt"
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<form>
|
|
81
|
+
<input
|
|
82
|
+
v-model="otp"
|
|
83
|
+
name="one-time-code"
|
|
84
|
+
class="w-0 h-0"
|
|
85
|
+
type="text"
|
|
86
|
+
autocomplete="one-time-code"
|
|
87
|
+
inputmode="numeric"
|
|
88
|
+
autofocus
|
|
89
|
+
pattern="\d{6}"
|
|
90
|
+
>
|
|
91
|
+
</form>
|
|
92
|
+
</div>
|
|
93
|
+
<slot />
|
|
94
|
+
</div>
|
|
95
|
+
<div class="flex flex-col gap-4 p-3 sticky bottom-2">
|
|
96
|
+
<template v-if="shortHand">
|
|
97
|
+
<UnAuthShortHand
|
|
98
|
+
v-if="forgetPassword"
|
|
99
|
+
:description="$t('\u062D\u0633\u0627\u0628 \u06A9\u0627\u0631\u0628\u0631\u06CC \u0646\u062F\u0627\u0631\u06CC\u062F\u061F ')"
|
|
100
|
+
:text-link="$t('\u062B\u0628\u062A \u0646\u0627\u0645 \u06A9\u0646\u06CC\u062F')"
|
|
101
|
+
link="/signup"
|
|
102
|
+
/>
|
|
103
|
+
<UnAuthShortHand
|
|
104
|
+
v-else-if="otp"
|
|
105
|
+
:description="$t('\u0634\u0645\u0627\u0631\u0647 \u062A\u0644\u0641\u0646 \u0627\u0634\u062A\u0628\u0627\u0647 \u0627\u0633\u062A\u061F')"
|
|
106
|
+
:text-link="$t('\u0648\u06CC\u0631\u0627\u06CC\u0634')"
|
|
107
|
+
:link="`/login?type=${route.query.type || 'personal'}`"
|
|
108
|
+
/>
|
|
109
|
+
<UnAuthShortHand
|
|
110
|
+
v-else
|
|
111
|
+
:description="$t('\u062D\u0633\u0627\u0628 \u06A9\u0627\u0631\u0628\u0631\u06CC \u062F\u0627\u0631\u06CC\u062F\u061F ')"
|
|
112
|
+
:text-link="$t('\u0648\u0627\u0631\u062F \u0634\u0648\u06CC\u062F')"
|
|
113
|
+
link="/login"
|
|
114
|
+
/>
|
|
115
|
+
</template>
|
|
116
|
+
<UnButton
|
|
117
|
+
:loading="loading"
|
|
118
|
+
:label="buttonTitle || ButtonTitle"
|
|
119
|
+
:disable="disable"
|
|
120
|
+
variant="primary-fill"
|
|
121
|
+
@click="submit"
|
|
122
|
+
/>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
<UnLog :data="form" />
|
|
126
|
+
</template>
|
|
127
|
+
|
|
128
|
+
<script setup>
|
|
129
|
+
import {
|
|
130
|
+
computed,
|
|
131
|
+
navigateTo,
|
|
132
|
+
onMounted,
|
|
133
|
+
p2e,
|
|
134
|
+
ref,
|
|
135
|
+
useCookie,
|
|
136
|
+
useI18n,
|
|
137
|
+
useNuxtApp,
|
|
138
|
+
usePost,
|
|
139
|
+
useRoute,
|
|
140
|
+
useToken,
|
|
141
|
+
useUser,
|
|
142
|
+
useUserId
|
|
143
|
+
} from "#imports";
|
|
144
|
+
const { successLoginAlert = "\u062E\u0648\u0634 \u0622\u0645\u062F\u06CC\u062F", redirectPage = "index", profilePage = "profile", profileFormPage, otpPage = "login-otp", type, loginType = "password", userParams = {} } = defineProps({
|
|
145
|
+
logo: { type: String, required: false },
|
|
146
|
+
head: { type: String, required: false },
|
|
147
|
+
type: { type: String, required: true },
|
|
148
|
+
userTypes: { type: Array, required: false },
|
|
149
|
+
loginType: { type: String, required: false },
|
|
150
|
+
mutiType: { type: Boolean, required: false },
|
|
151
|
+
userParams: { type: Object, required: false },
|
|
152
|
+
otpPage: { type: String, required: false },
|
|
153
|
+
redirectPage: { type: String, required: false },
|
|
154
|
+
profilePage: { type: String, required: false },
|
|
155
|
+
profileFormPage: { type: String, required: false },
|
|
156
|
+
loginPage: { type: String, required: false },
|
|
157
|
+
passLoginPage: { type: String, required: false },
|
|
158
|
+
successLoginAlert: { type: String, required: false },
|
|
159
|
+
title: { type: String, required: false },
|
|
160
|
+
buttonTitle: { type: String, required: false },
|
|
161
|
+
forgetPassword: { type: Boolean, required: false },
|
|
162
|
+
click: { type: Object, required: false },
|
|
163
|
+
shortHand: { type: Boolean, required: false }
|
|
164
|
+
});
|
|
165
|
+
const route = useRoute();
|
|
166
|
+
const { $toast } = useNuxtApp();
|
|
167
|
+
const { t } = useI18n();
|
|
168
|
+
const loading = ref(false);
|
|
169
|
+
const phoneNumber = useCookie("phoneNumber");
|
|
170
|
+
const form = ref({});
|
|
171
|
+
const expiredAt = useCookie("expiredAt", {
|
|
172
|
+
maxAge: 365 * 24 * 60 * 60 * 1e3
|
|
173
|
+
});
|
|
174
|
+
const ButtonTitle = computed(
|
|
175
|
+
() => type === "login" && loginType == "otp" ? t("\u0627\u0631\u0633\u0627\u0644 \u06A9\u062F") : type === "login" && loginType == "password" ? t("\u0648\u0631\u0648\u062F") : type === "otp" ? t("\u062A\u0627\u06CC\u06CC\u062F") : type === "recover" ? t("\u062B\u0628\u062A") : type === "register" ? t("\u062B\u0628\u062A \u0646\u0627\u0645") : ""
|
|
176
|
+
);
|
|
177
|
+
const isValid = computed(() => form.value.phoneNumber && form.value.phoneNumber?.length === 11);
|
|
178
|
+
const loginByOtp = async () => {
|
|
179
|
+
if (!isValid.value || loading.value) return;
|
|
180
|
+
loading.value = true;
|
|
181
|
+
const { result } = await usePost("/login-by-phone-otp", {
|
|
182
|
+
phoneNumber: p2e(form.value.phoneNumber)
|
|
183
|
+
// template: template[config.userType]
|
|
184
|
+
});
|
|
185
|
+
if (result) {
|
|
186
|
+
expiredAt.value = result.expiredAt;
|
|
187
|
+
phoneNumber.value = p2e(form.value.phoneNumber);
|
|
188
|
+
await navigateTo({ name: otpPage, query: route.query });
|
|
189
|
+
}
|
|
190
|
+
loading.value = false;
|
|
191
|
+
};
|
|
192
|
+
const otp = ref("");
|
|
193
|
+
const token = useToken();
|
|
194
|
+
const userId = useUserId();
|
|
195
|
+
if (["login", "register"].includes(type) && token.value && userId.value) {
|
|
196
|
+
navigateTo({ name: redirectPage });
|
|
197
|
+
}
|
|
198
|
+
const user = useUser();
|
|
199
|
+
const isExpired = ref(false);
|
|
200
|
+
const disable = computed(
|
|
201
|
+
() => type === "login" && loginType == "otp" ? !form.value?.phoneNumber : type === "login" && loginType == "password" ? !form.value?.phoneNumber || !form.value?.password : type === "otp" ? otp.value?.length < 6 : type === "recover" ? !form.value?.password || !form.value?.confirmedPassword || form.value?.password !== form.value?.confirmedPassword : type === "register" ? !form.value?.phoneNumber || !form.value?.password : false
|
|
202
|
+
);
|
|
203
|
+
let ac;
|
|
204
|
+
const getOtpFromPhone = async () => {
|
|
205
|
+
if (ac) {
|
|
206
|
+
ac.abort();
|
|
207
|
+
}
|
|
208
|
+
ac = new AbortController();
|
|
209
|
+
if ("OTPCredential" in window) {
|
|
210
|
+
navigator.credentials.get({
|
|
211
|
+
otp: { transport: ["sms"] },
|
|
212
|
+
signal: ac.signal
|
|
213
|
+
}).then((e) => {
|
|
214
|
+
otp.value = e.code;
|
|
215
|
+
checkOTP(otp.value);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const checkOTP = async (code = "") => {
|
|
220
|
+
if (loading.value) return;
|
|
221
|
+
loading.value = true;
|
|
222
|
+
const { result } = await usePost("/get-token-by-otp", { phoneNumber: phoneNumber.value, code: code || otp.value }, {
|
|
223
|
+
params: {
|
|
224
|
+
"with-profile": true,
|
|
225
|
+
...userParams
|
|
226
|
+
},
|
|
227
|
+
headers: {
|
|
228
|
+
"no-error": true
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
if (result) {
|
|
232
|
+
token.value = result.token.type + " " + result.token.token;
|
|
233
|
+
userId.value = result.user.id;
|
|
234
|
+
user.value = result.user;
|
|
235
|
+
if (result.user.profile || !profileFormPage) {
|
|
236
|
+
navigateTo({ name: profilePage });
|
|
237
|
+
} else {
|
|
238
|
+
navigateTo({ name: profileFormPage || "profile-form" });
|
|
239
|
+
}
|
|
240
|
+
$toast.success(successLoginAlert);
|
|
241
|
+
} else {
|
|
242
|
+
$toast.success(t("\u06A9\u062F \u0648\u0627\u0631\u062F \u0634\u062F\u0647 \u0635\u062D\u06CC\u062D \u0646\u0645\u06CC\u0628\u0627\u0634\u062F."));
|
|
243
|
+
loading.value = false;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
const sendAgain = async () => {
|
|
247
|
+
if (loading.value) return;
|
|
248
|
+
loading.value = true;
|
|
249
|
+
const { result } = await usePost("/login-by-phone-otp", {
|
|
250
|
+
phoneNumber: phoneNumber.value
|
|
251
|
+
});
|
|
252
|
+
if (result) {
|
|
253
|
+
getOtpFromPhone();
|
|
254
|
+
expiredAt.value = result.expiredAt;
|
|
255
|
+
isExpired.value = false;
|
|
256
|
+
$toast.success("\u06A9\u062F \u0628\u0627 \u0645\u0648\u0641\u0642\u06CC\u062A \u0627\u0631\u0633\u0627\u0644 \u0634\u062F");
|
|
257
|
+
}
|
|
258
|
+
loading.value = false;
|
|
259
|
+
};
|
|
260
|
+
const setPassword = async () => {
|
|
261
|
+
if (loading.value) return;
|
|
262
|
+
loading.value = true;
|
|
263
|
+
const { result } = await usePost("/set-pass", {
|
|
264
|
+
password: form.value.password
|
|
265
|
+
}, {
|
|
266
|
+
headers: {
|
|
267
|
+
"no-error": true
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
if (result) {
|
|
271
|
+
$toast.success("\u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u0628\u0627 \u0645\u0648\u0641\u0642\u06CC\u062A \u062A\u063A\u06CC\u06CC\u0631 \u06CC\u0627\u0641\u062A");
|
|
272
|
+
navigateTo({ name: "profile" });
|
|
273
|
+
} else {
|
|
274
|
+
$toast.success("\u0631\u0645\u0632 \u0628\u0627\u06CC\u062F \u062D\u062F\u0627\u0642\u0644 8 \u06A9\u0627\u0631\u0627\u06A9\u062A\u0631 \u0628\u0627\u0634\u062F.");
|
|
275
|
+
loading.value = false;
|
|
276
|
+
}
|
|
277
|
+
loading.value = false;
|
|
278
|
+
};
|
|
279
|
+
const loginByPass = async () => {
|
|
280
|
+
if (loading.value) return;
|
|
281
|
+
loading.value = true;
|
|
282
|
+
const { result } = await usePost("/login-by-pass", {
|
|
283
|
+
phoneNumber: p2e(form.value.phoneNumber),
|
|
284
|
+
password: form.value.password
|
|
285
|
+
}, {
|
|
286
|
+
params: {
|
|
287
|
+
"with-profile": true,
|
|
288
|
+
...userParams
|
|
289
|
+
},
|
|
290
|
+
headers: {
|
|
291
|
+
"no-error": true
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
if (result) {
|
|
295
|
+
token.value = result.token.type + " " + result.token.token;
|
|
296
|
+
userId.value = result.user.id;
|
|
297
|
+
user.value = result.user;
|
|
298
|
+
if (result.user.profile || !profileFormPage) {
|
|
299
|
+
navigateTo({ name: profilePage });
|
|
300
|
+
} else {
|
|
301
|
+
navigateTo({ name: profileFormPage || "profile-form" });
|
|
302
|
+
}
|
|
303
|
+
$toast.success(successLoginAlert);
|
|
304
|
+
} else {
|
|
305
|
+
$toast.error("\u0627\u0637\u0644\u0627\u0639\u0627\u062A \u0648\u0627\u0631\u062F \u0634\u062F\u0647 \u0635\u062D\u06CC\u062D \u0646\u0645\u06CC\u0628\u0627\u0634\u062F.");
|
|
306
|
+
loading.value = false;
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
const submit = async () => {
|
|
310
|
+
if (type === "login" && loginType === "otp") {
|
|
311
|
+
return loginByOtp();
|
|
312
|
+
}
|
|
313
|
+
if (type === "login" && loginType === "password") {
|
|
314
|
+
return loginByPass();
|
|
315
|
+
}
|
|
316
|
+
if (type === "recover") {
|
|
317
|
+
return setPassword();
|
|
318
|
+
}
|
|
319
|
+
if (type === "otp") {
|
|
320
|
+
return checkOTP();
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
onMounted(() => {
|
|
324
|
+
getOtpFromPhone();
|
|
325
|
+
});
|
|
326
|
+
</script>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
logo?: string;
|
|
3
|
+
head?: string;
|
|
4
|
+
type: 'login' | 'recover' | 'otp' | 'register';
|
|
5
|
+
userTypes?: Record<string, string>[];
|
|
6
|
+
loginType?: 'otp' | 'password';
|
|
7
|
+
mutiType?: boolean;
|
|
8
|
+
userParams?: Record<string, string | boolean>;
|
|
9
|
+
otpPage?: string;
|
|
10
|
+
redirectPage?: string;
|
|
11
|
+
profilePage?: string;
|
|
12
|
+
profileFormPage?: string;
|
|
13
|
+
loginPage?: string;
|
|
14
|
+
passLoginPage?: string;
|
|
15
|
+
successLoginAlert?: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
buttonTitle?: string;
|
|
18
|
+
forgetPassword?: boolean;
|
|
19
|
+
click?: Record<string, never>;
|
|
20
|
+
shortHand?: boolean;
|
|
21
|
+
};
|
|
22
|
+
declare var __VLS_29: {};
|
|
23
|
+
type __VLS_Slots = {} & {
|
|
24
|
+
default?: (props: typeof __VLS_29) => any;
|
|
25
|
+
};
|
|
26
|
+
declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
28
|
+
declare const _default: typeof __VLS_export;
|
|
29
|
+
export default _default;
|
|
30
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
31
|
+
new (): {
|
|
32
|
+
$slots: S;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TabItem } from './UnTab.vue.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
type?: 'recover' | 'otp' | 'password';
|
|
4
|
+
userTypes?: TabItem[];
|
|
5
|
+
head?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
haveLoginType?: boolean;
|
|
8
|
+
forgetPass?: boolean;
|
|
9
|
+
loginPage?: string;
|
|
10
|
+
passLoginPage?: string;
|
|
11
|
+
forgetPage?: string;
|
|
12
|
+
};
|
|
13
|
+
type __VLS_ModelProps = {
|
|
14
|
+
modelValue: Record<string, any>;
|
|
15
|
+
};
|
|
16
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
17
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
18
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
19
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
20
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
21
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
|
+
declare const _default: typeof __VLS_export;
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-col items-stretch gap-6">
|
|
3
|
+
<div class="flex justify-between items-center">
|
|
4
|
+
<p class="text-(gray-600 2xl) font-semibold">
|
|
5
|
+
{{ head }}
|
|
6
|
+
</p>
|
|
7
|
+
<NuxtLink
|
|
8
|
+
v-if="haveLoginType"
|
|
9
|
+
:to="{ name: type === 'password' ? loginPage : passLoginPage, query: { role: route.query.role } }"
|
|
10
|
+
class="text-xs text-primary-500 underline cursor-pointer"
|
|
11
|
+
>
|
|
12
|
+
{{ type === "password" ? $t("\u0648\u0631\u0648\u062F \u0628\u0627 \u06A9\u062F \u06CC\u06A9\u0628\u0627\u0631 \u0645\u0635\u0631\u0641") : $t("\u0648\u0631\u0648\u062F \u0628\u0627 \u0631\u0645\u0632 \u0639\u0628\u0648\u0631") }}
|
|
13
|
+
</NuxtLink>
|
|
14
|
+
</div>
|
|
15
|
+
<p
|
|
16
|
+
v-if="description"
|
|
17
|
+
class="text-(gray-600 base)"
|
|
18
|
+
>
|
|
19
|
+
{{ description }}
|
|
20
|
+
</p>
|
|
21
|
+
<UnTab
|
|
22
|
+
v-if="userTypes?.length"
|
|
23
|
+
route-target="query"
|
|
24
|
+
routable
|
|
25
|
+
mini
|
|
26
|
+
:items="userTypes"
|
|
27
|
+
class="self-start"
|
|
28
|
+
/>
|
|
29
|
+
<UnNormalInput
|
|
30
|
+
v-if="type !== 'recover'"
|
|
31
|
+
v-model="modelValue.phoneNumber"
|
|
32
|
+
:placeholder="$t('\u0634\u0645\u0627\u0631\u0647 \u0645\u0648\u0628\u0627\u06CC\u0644')"
|
|
33
|
+
input-mode="numeric"
|
|
34
|
+
/>
|
|
35
|
+
<template v-if="haveLoginType && type === 'password'">
|
|
36
|
+
<UnNormalInput
|
|
37
|
+
v-model="modelValue.password"
|
|
38
|
+
:placeholder="$t('\u0631\u0645\u0632 \u0639\u0628\u0648\u0631')"
|
|
39
|
+
input-type="password"
|
|
40
|
+
:password="true"
|
|
41
|
+
/>
|
|
42
|
+
<NuxtLink
|
|
43
|
+
v-if="forgetPass"
|
|
44
|
+
:to="{ name: forgetPage }"
|
|
45
|
+
class="text-sm text-gray-400 underline cursor-pointer flex justify-center items-center"
|
|
46
|
+
>
|
|
47
|
+
{{ $t("\u0641\u0631\u0627\u0645\u0648\u0634\u06CC \u0631\u0645\u0632 \u0639\u0628\u0648\u0631") }}
|
|
48
|
+
</NuxtLink>
|
|
49
|
+
</template>
|
|
50
|
+
<template v-if="type === 'recover'">
|
|
51
|
+
<UnNormalInput
|
|
52
|
+
v-model="modelValue.password"
|
|
53
|
+
:placeholder="$t('\u0631\u0645\u0632 \u0639\u0628\u0648\u0631')"
|
|
54
|
+
input-type="password"
|
|
55
|
+
:password="true"
|
|
56
|
+
/>
|
|
57
|
+
<UnNormalInput
|
|
58
|
+
v-model="modelValue.confirmedPassword"
|
|
59
|
+
:placeholder="$t('\u062A\u06A9\u0631\u0627\u0631 \u0631\u0645\u0632 \u0639\u0628\u0648\u0631')"
|
|
60
|
+
input-type="password"
|
|
61
|
+
:password="true"
|
|
62
|
+
/>
|
|
63
|
+
</template>
|
|
64
|
+
</div>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<script setup>
|
|
68
|
+
import { useRoute } from "#imports";
|
|
69
|
+
const route = useRoute();
|
|
70
|
+
const {
|
|
71
|
+
forgetPage = "forget-password",
|
|
72
|
+
loginPage = "login",
|
|
73
|
+
passLoginPage = "login-pass"
|
|
74
|
+
} = defineProps({
|
|
75
|
+
type: { type: String, required: false },
|
|
76
|
+
userTypes: { type: Array, required: false },
|
|
77
|
+
head: { type: String, required: false },
|
|
78
|
+
description: { type: String, required: false },
|
|
79
|
+
haveLoginType: { type: Boolean, required: false },
|
|
80
|
+
forgetPass: { type: Boolean, required: false },
|
|
81
|
+
loginPage: { type: String, required: false },
|
|
82
|
+
passLoginPage: { type: String, required: false },
|
|
83
|
+
forgetPage: { type: String, required: false }
|
|
84
|
+
});
|
|
85
|
+
const modelValue = defineModel({ type: Object, ...{ required: true } });
|
|
86
|
+
</script>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TabItem } from './UnTab.vue.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
type?: 'recover' | 'otp' | 'password';
|
|
4
|
+
userTypes?: TabItem[];
|
|
5
|
+
head?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
haveLoginType?: boolean;
|
|
8
|
+
forgetPass?: boolean;
|
|
9
|
+
loginPage?: string;
|
|
10
|
+
passLoginPage?: string;
|
|
11
|
+
forgetPage?: string;
|
|
12
|
+
};
|
|
13
|
+
type __VLS_ModelProps = {
|
|
14
|
+
modelValue: Record<string, any>;
|
|
15
|
+
};
|
|
16
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
17
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
18
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
19
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
20
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
21
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
|
+
declare const _default: typeof __VLS_export;
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
link?: string;
|
|
3
|
+
textLink: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
7
|
+
declare const _default: typeof __VLS_export;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<p class="text-(xs text) font-extrabold gap-1">
|
|
3
|
+
{{ description }}
|
|
4
|
+
<NuxtLink
|
|
5
|
+
:to="link || '#'"
|
|
6
|
+
class="text-primary-500"
|
|
7
|
+
>
|
|
8
|
+
{{ textLink }}
|
|
9
|
+
</NuxtLink>
|
|
10
|
+
</p>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup>
|
|
14
|
+
defineProps({
|
|
15
|
+
link: { type: String, required: false },
|
|
16
|
+
textLink: { type: String, required: true },
|
|
17
|
+
description: { type: String, required: false }
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
link?: string;
|
|
3
|
+
textLink: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
7
|
+
declare const _default: typeof __VLS_export;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {
|
|
4
|
+
$emit: typeof emit;
|
|
5
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
6
|
+
declare const emit: (event: "complete" | "change", ...args: any[]) => void;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-otp-input
|
|
3
|
+
id="code-input"
|
|
4
|
+
ref="otpInput"
|
|
5
|
+
:value="value"
|
|
6
|
+
dir="ltr"
|
|
7
|
+
input-classes="otp-input"
|
|
8
|
+
separator=""
|
|
9
|
+
:num-inputs="6"
|
|
10
|
+
:should-auto-focus="true"
|
|
11
|
+
:is-input-num="true"
|
|
12
|
+
@on-change="onChange"
|
|
13
|
+
@on-complete="emit('complete', $event)"
|
|
14
|
+
/>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup>
|
|
18
|
+
import VOtpInput from "vue3-otp-input";
|
|
19
|
+
const emit = defineEmits(["complete", "change"]);
|
|
20
|
+
const value = defineModel();
|
|
21
|
+
const onChange = ($event) => {
|
|
22
|
+
value.value = $event;
|
|
23
|
+
emit("change");
|
|
24
|
+
};
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<style>
|
|
28
|
+
#code-input .otp-input {
|
|
29
|
+
@apply w-15 h-15 bg-white b-rd-2 text-center gap-2 <md:(w-12 h-12);
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {
|
|
4
|
+
$emit: typeof emit;
|
|
5
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
6
|
+
declare const emit: (event: "complete" | "change", ...args: any[]) => void;
|
|
@@ -56,10 +56,9 @@
|
|
|
56
56
|
<UnSelect
|
|
57
57
|
v-else-if="Type === 'select' && options?.length"
|
|
58
58
|
v-model="modelValue"
|
|
59
|
-
:
|
|
59
|
+
:items="options.map((e) => ({ title: e.title, value: e.key }))"
|
|
60
|
+
value-key="value"
|
|
60
61
|
:light="true"
|
|
61
|
-
value-key="key"
|
|
62
|
-
label-key="title"
|
|
63
62
|
:searchable="true"
|
|
64
63
|
:disabled="item.disabled"
|
|
65
64
|
:is-error
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
value ? moment(value, format[type]).locale(locale).format(display[type]) : focused ? "" : placeholder
|
|
22
22
|
}}
|
|
23
23
|
</p>
|
|
24
|
-
<
|
|
24
|
+
<UnNuxtIcon
|
|
25
25
|
name="solar:close-circle-bold-duotone"
|
|
26
26
|
class="text-5 c-gray-400"
|
|
27
27
|
@click.prevent.stop="emit('append')"
|