main
vue 352 lines 8.94 KB
Raw
1 <template>
2 <n-spin :show="loading">
3 <div class="license-box" :class="{ loading: loadingLicense && !licenseKey }">
4 <p v-if="loadingLicense || licenseKey" class="flex items-center gap-4">
5 <span>your license:</span>
6 <Icon v-if="loadingLicense" :name="LoadingIcon" />
7 </p>
8 <div v-if="!loadingLicense && !licenseKey">
9 <p v-if="!creationEnabled" class="flex items-center gap-4">no license found</p>
10 <div class="mt-2 flex items-center gap-4">
11 <div class="actions-box flex gap-2">
12 <n-button
13 v-if="!creationEnabled"
14 type="primary"
15 :loading="loadingCreation"
16 size="small"
17 @click="enableCreation()"
18 >
19 <template #icon>
20 <Icon :name="LicenseIcon" />
21 </template>
22 Create new license
23 </n-button>
24 </div>
25 </div>
26 </div>
27 <div v-if="!replaceEnabled && licenseKey" class="mt-1 flex items-center gap-4">
28 <h3>{{ licenseKey }}</h3>
29 <div class="actions-box flex gap-2">
30 <n-button secondary :disabled="replaceEnabled" size="small" @click="enableReplace()">
31 <template #icon>
32 <Icon :name="EditIcon" />
33 </template>
34 Edit
35 </n-button>
36 <n-button
37 v-if="!extendEnabled"
38 type="primary"
39 :loading="loadingExtend"
40 size="small"
41 @click="enableExtend()"
42 >
43 <template #icon>
44 <Icon :name="ExtendIcon" />
45 </template>
46 Extend
47 </n-button>
48 </div>
49 </div>
50 </div>
51
52 <div v-if="replaceEnabled" class="replace-box mt-2 flex gap-2">
53 <n-input v-model:value="licenseKeyModel" class="max-w-72! grow" clearable />
54 <n-button secondary :disabled="loadingReplace" @click="resetLicense()">Reset</n-button>
55 <n-button type="success" :loading="loadingReplace" :disabled="!licenseKeyModel" @click="replaceLicense()">
56 <template #icon>
57 <Icon :name="EditIcon" />
58 </template>
59 Replace
60 </n-button>
61 </div>
62
63 <div v-if="extendEnabled" class="extend-box mt-5 flex gap-2">
64 <n-input-number v-model:value="period" class="max-w-44! grow" :min="1">
65 <template #prefix>
66 <div class="min-w-12">Day{{ period === 1 ? "" : "s" }}</div>
67 </template>
68 </n-input-number>
69 <n-button secondary :disabled="loadingExtend" @click="resetPeriod()">Reset</n-button>
70 <n-button type="success" :loading="loadingExtend" :disabled="!period" @click="extendLicense()">
71 <template #icon>
72 <Icon :name="ExtendIcon" />
73 </template>
74 Extend
75 </n-button>
76 </div>
77
78 <div v-if="creationEnabled" class="create-box flex flex-col gap-2">
79 <n-form ref="formRef" :label-width="80" :model="creationForm" :rules>
80 <div class="grid-auto-fit-200 grid gap-2">
81 <n-form-item label="Name" path="name">
82 <n-input v-model:value.trim="creationForm.name" placeholder="Input name..." clearable />
83 </n-form-item>
84 <n-form-item label="Email" path="email">
85 <n-input v-model:value.trim="creationForm.email" placeholder="Input email..." clearable />
86 </n-form-item>
87 <n-form-item label="Company Name" path="companyName">
88 <n-input
89 v-model:value.trim="creationForm.companyName"
90 placeholder="Input Company Name..."
91 clearable
92 />
93 </n-form-item>
94 </div>
95 </n-form>
96 <div class="flex justify-end gap-2">
97 <n-button secondary :disabled="loadingCreation" @click="resetCreation()">Reset</n-button>
98 <n-button
99 type="success"
100 :loading="loadingCreation"
101 :disabled="!isCreationFormValid"
102 @click="validateCreation()"
103 >
104 <template #icon>
105 <Icon :name="LicenseIcon" />
106 </template>
107 Create License
108 </n-button>
109 </div>
110 </div>
111 </n-spin>
112 </template>
113
114 <script setup lang="ts">
115 import type { FormInst, FormItemRule, FormRules, FormValidationError } from "naive-ui"
116 /** @deprecated */
117 import type { NewLicensePayload } from "@/api/endpoints/license"
118 import type { LicenseKey } from "@/types/license.d"
119 import { NButton, NForm, NFormItem, NInput, NInputNumber, NSpin, useMessage } from "naive-ui"
120 import isEmail from "validator/es/lib/isEmail"
121 import { computed, onBeforeMount, ref } from "vue"
122 import Api from "@/api"
123 import Icon from "@/components/common/Icon.vue"
124
125 const emit = defineEmits<{
126 (e: "updated"): void
127 }>()
128
129 const LoadingIcon = "eos-icons:loading"
130 const EditIcon = "uil:edit-alt"
131 const LicenseIcon = "carbon:license"
132 const ExtendIcon = "majesticons:clock-plus-line"
133
134 const formRef = ref<FormInst>()
135 const message = useMessage()
136 const loadingLicense = ref(false)
137 const loadingReplace = ref(false)
138 const loadingExtend = ref(false)
139 const loadingCreation = ref(false)
140
141 const licenseKey = ref<LicenseKey | "">("")
142 const licenseKeyModel = ref<LicenseKey | "">("")
143 const period = ref<number>(15)
144 const creationForm = ref<NewLicensePayload>(getCreationForm())
145 const replaceEnabled = ref(false)
146 const extendEnabled = ref(false)
147 const creationEnabled = ref(false)
148
149 const isCreationFormValid = computed(() => {
150 if (!creationForm.value.name || !creationForm.value.email || !creationForm.value.companyName) {
151 return false
152 }
153 return true
154 })
155
156 const loading = computed(
157 () => loadingLicense.value || loadingReplace.value || loadingExtend.value || loadingCreation.value
158 )
159
160 const rules: FormRules = {
161 name: {
162 required: true,
163 message: "Please input name",
164 trigger: ["input", "blur"]
165 },
166 companyName: {
167 required: true,
168 message: "Please input company name",
169 trigger: ["input", "blur"]
170 },
171 email: {
172 required: true,
173 trigger: ["input", "blur"],
174 validator: (_rule: FormItemRule, value: string) => {
175 if (!value) {
176 return new Error("Email is required")
177 }
178 if (!isEmail(value)) {
179 return new Error("The email is not formatted correctly")
180 }
181 }
182 }
183 }
184
185 function getLicense() {
186 loadingLicense.value = true
187
188 Api.license
189 .getLicense()
190 .then(res => {
191 if (res.data.success) {
192 licenseKey.value = res.data?.license_key || ""
193 licenseKeyModel.value = res.data?.license_key || ""
194 } else {
195 message.warning(res.data?.message || "An error occurred. Please try again later.")
196 }
197 })
198 .catch(err => {
199 if (err.response.status !== 404) {
200 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
201 }
202 })
203 .finally(() => {
204 loadingLicense.value = false
205 })
206 }
207
208 function replaceLicense() {
209 if (licenseKeyModel.value) {
210 loadingReplace.value = true
211
212 Api.license
213 .replaceLicense(licenseKeyModel.value)
214 .then(res => {
215 if (res.data.success) {
216 disableReplace()
217 message.success(res.data?.message || "License replaced successfully")
218 emit("updated")
219 getLicense()
220 } else {
221 message.warning(res.data?.message || "An error occurred. Please try again later.")
222 }
223 })
224 .catch(err => {
225 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
226 })
227 .finally(() => {
228 loadingReplace.value = false
229 })
230 }
231 }
232
233 function extendLicense() {
234 if (period.value) {
235 loadingExtend.value = true
236
237 Api.license
238 .extendLicense(period.value)
239 .then(res => {
240 if (res.data.success) {
241 resetPeriod()
242 message.success(res.data?.message || "License extended successfully")
243 emit("updated")
244 } else {
245 message.warning(res.data?.message || "An error occurred. Please try again later.")
246 }
247 })
248 .catch(err => {
249 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
250 })
251 .finally(() => {
252 loadingExtend.value = false
253 })
254 }
255 }
256
257 function createLicense() {
258 loadingCreation.value = true
259
260 Api.license
261 .createLicense(creationForm.value)
262 .then(res => {
263 if (res.data.success) {
264 resetCreation()
265 message.success(res.data?.message || "License created successfully")
266 emit("updated")
267 getLicense()
268 } else {
269 message.warning(res.data?.message || "An error occurred. Please try again later.")
270 }
271 })
272 .catch(err => {
273 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
274 })
275 .finally(() => {
276 loadingCreation.value = false
277 })
278 }
279
280 function resetLicense() {
281 licenseKeyModel.value = licenseKey.value
282 disableReplace()
283 }
284
285 function disableReplace() {
286 replaceEnabled.value = false
287 }
288
289 function enableReplace() {
290 resetPeriod()
291 replaceEnabled.value = true
292 }
293
294 function resetPeriod() {
295 period.value = 15
296 disableExtend()
297 }
298
299 function disableExtend() {
300 extendEnabled.value = false
301 }
302
303 function enableExtend() {
304 extendEnabled.value = true
305 }
306
307 function resetCreation() {
308 creationForm.value = getCreationForm()
309 disableCreation()
310 }
311
312 function disableCreation() {
313 creationEnabled.value = false
314 }
315
316 function enableCreation() {
317 creationEnabled.value = true
318 }
319
320 function getCreationForm(): NewLicensePayload {
321 return {
322 name: "",
323 email: "",
324 companyName: ""
325 }
326 }
327
328 function validateCreation() {
329 if (!formRef.value) return
330
331 formRef.value.validate((errors?: Array<FormValidationError>) => {
332 if (!errors) {
333 createLicense()
334 } else {
335 message.warning("You must fill in the required fields correctly.")
336 return false
337 }
338 })
339 }
340
341 onBeforeMount(() => {
342 getLicense()
343 })
344 </script>
345
346 <style lang="scss" scoped>
347 .license-box {
348 &.loading {
349 min-height: 100px;
350 }
351 }
352 </style>