Skip to content

Commit 8b3795e

Browse files
refactor(vue3): migrate CreateAccount to script setup ts
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent b6e7ccb commit 8b3795e

1 file changed

Lines changed: 159 additions & 97 deletions

File tree

src/views/CreateAccount.vue

Lines changed: 159 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,12 @@
6363
</div>
6464
</template>
6565

66-
<script>
66+
<script setup lang="ts">
6767
import { t } from '@nextcloud/l10n'
68+
import { computed, getCurrentInstance, onBeforeMount, reactive, ref, toRefs } from 'vue'
6869
6970
// eslint-disable-next-line n/no-missing-import
7071
import md5 from 'crypto-js/md5'
71-
// eslint-disable-next-line n/no-missing-import
72-
import useVuelidate from '@vuelidate/core'
73-
// eslint-disable-next-line n/no-missing-import
74-
import { required, email, minLength } from '@vuelidate/validators'
7572
7673
7774
import axios from '@nextcloud/axios'
@@ -90,111 +87,176 @@ import {
9087
mdiChevronRight,
9188
} from '@mdi/js'
9289
93-
export default {
90+
defineOptions({
9491
name: 'CreateAccount',
95-
components: {
96-
NcNoteCard,
97-
NcTextField,
98-
NcPasswordField,
99-
NcButton,
100-
NcLoadingIcon,
101-
NcIconSvgWrapper,
102-
},
103-
setup() {
104-
return {
105-
v$: useVuelidate(),
106-
mdiEmail,
107-
mdiChevronRight,
108-
}
109-
},
92+
})
11093
111-
data() {
112-
return {
113-
loading: false,
114-
email: '',
115-
password: '',
116-
passwordConfirm: '',
117-
settings: loadState('libresign', 'settings'),
118-
message: loadState('libresign', 'message'),
119-
errorMessage: '',
120-
enabledFeatures: [],
121-
}
122-
},
94+
const instance = getCurrentInstance()
95+
const route = computed(() => instance?.proxy?.$route ?? { params: {} })
96+
const router = computed(() => instance?.proxy?.$router)
12397
124-
validations: {
125-
email: { required, email },
126-
password: { required, minLength: minLength(4) },
127-
passwordConfirm: { required, minLength: minLength(4) },
128-
},
129-
computed: {
130-
emailError() {
131-
if (this.v$.email.$model) {
132-
if (this.v$.email.$error) {
133-
return this.t('libresign', 'This is not a valid email')
134-
} else if (this.isEqualEmail === false) {
135-
return this.t('libresign', 'The email entered is not the same as the email in the invitation')
136-
}
137-
}
138-
return ''
98+
const state = reactive({
99+
loading: false,
100+
email: '',
101+
password: '',
102+
passwordConfirm: '',
103+
settings: loadState('libresign', 'settings'),
104+
message: loadState('libresign', 'message'),
105+
errorMessage: '',
106+
enabledFeatures: [] as unknown[],
107+
})
108+
109+
const {
110+
loading,
111+
email,
112+
password,
113+
passwordConfirm,
114+
errorMessage,
115+
} = toRefs(state)
116+
117+
const emailTouched = ref(false)
118+
const passwordTouched = ref(false)
119+
const passwordConfirmTouched = ref(false)
120+
121+
const isRequired = (value: string) => value.length > 0
122+
const isEmailValid = (value: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
123+
const hasMinLength = (value: string, length: number) => value.length >= length
124+
125+
function createValidationField(source: typeof email, touched: typeof emailTouched, validators: Record<string, () => boolean>) {
126+
const requiredValidator = validators.required ?? (() => true)
127+
const emailValidator = validators.email ?? (() => true)
128+
const minLengthValidator = validators.minLength ?? (() => true)
129+
130+
return {
131+
get $model() {
132+
return source.value
139133
},
140-
showErrorEmail() {
141-
return this.emailError.length > 2
134+
set $model(value: string) {
135+
source.value = value
142136
},
143-
passwordError() {
144-
if (this.password && this.passwordConfirm) {
145-
if (this.password.length <= 4) {
146-
return this.t('libresign', 'Your password must be greater than 4 digits')
147-
}
148-
}
149-
return ''
137+
async $touch() {
138+
touched.value = true
150139
},
151-
confirmPasswordError() {
152-
if (this.password && this.passwordConfirm) {
153-
if (this.password !== this.passwordConfirm) {
154-
return this.t('libresign', 'Passwords does not match')
155-
}
140+
get $error() {
141+
return touched.value && [requiredValidator, emailValidator, minLengthValidator].some((validator) => !validator())
142+
},
143+
get required() {
144+
return {
145+
get $invalid() {
146+
return !requiredValidator()
147+
},
156148
}
157-
return ''
158149
},
159-
canSave() {
160-
return this.password.length > 0
161-
&& this.passwordConfirm.length > 0
162-
&& this.passwordError.length === 0
163-
&& this.confirmPasswordError.length === 0
164-
&& this.email.length > 0
165-
&& !this.showErrorEmail
166-
&& !this.loading
150+
get email() {
151+
return {
152+
get $invalid() {
153+
return !emailValidator()
154+
},
155+
}
167156
},
168-
isEqualEmail() {
169-
return this.settings.accountHash === md5(this.email).toString()
157+
get minLength() {
158+
return {
159+
get $invalid() {
160+
return !minLengthValidator()
161+
},
162+
}
170163
},
171-
},
172-
created() {
173-
if (this.message) {
174-
showWarning(this.message)
164+
}
165+
}
166+
167+
const v$ = {
168+
email: createValidationField(email, emailTouched, {
169+
required: () => isRequired(email.value),
170+
email: () => isEmailValid(email.value),
171+
}),
172+
password: createValidationField(password, passwordTouched, {
173+
required: () => isRequired(password.value),
174+
minLength: () => hasMinLength(password.value, 4),
175+
}),
176+
passwordConfirm: createValidationField(passwordConfirm, passwordConfirmTouched, {
177+
required: () => isRequired(passwordConfirm.value),
178+
minLength: () => hasMinLength(passwordConfirm.value, 4),
179+
}),
180+
}
181+
182+
const emailError = computed(() => {
183+
if (email.value) {
184+
if (v$.email.$error) {
185+
return t('libresign', 'This is not a valid email')
175186
}
176-
},
187+
if (!isEqualEmail.value) {
188+
return t('libresign', 'The email entered is not the same as the email in the invitation')
189+
}
190+
}
191+
return ''
192+
})
177193
178-
methods: {
179-
t,
180-
async createAccount() {
181-
this.loading = true
182-
await axios.post(generateOcsUrl('/apps/libresign/api/v1/account/create/{uuid}'), {
183-
uuid: this.$route.params.uuid,
184-
email: this.email,
185-
password: this.password,
186-
})
187-
.then(() => {
188-
const url = this.$router.resolve({ name: 'SignPDF' })
189-
window.location.href = url.href
190-
})
191-
.catch(({ response }) => {
192-
this.errorMessage = response.data.ocs.data.message
193-
})
194-
this.loading = false
195-
},
196-
},
194+
const showErrorEmail = computed(() => emailError.value.length > 2)
195+
196+
const passwordError = computed(() => {
197+
if (state.password && state.passwordConfirm && state.password.length <= 4) {
198+
return t('libresign', 'Your password must be greater than 4 digits')
199+
}
200+
return ''
201+
})
202+
203+
const confirmPasswordError = computed(() => {
204+
if (state.password && state.passwordConfirm && state.password !== state.passwordConfirm) {
205+
return t('libresign', 'Passwords does not match')
206+
}
207+
return ''
208+
})
209+
210+
const isEqualEmail = computed(() => state.settings.accountHash === md5(email.value).toString())
211+
212+
const canSave = computed(() => {
213+
return state.password.length > 0
214+
&& state.passwordConfirm.length > 0
215+
&& passwordError.value.length === 0
216+
&& confirmPasswordError.value.length === 0
217+
&& state.email.length > 0
218+
&& !showErrorEmail.value
219+
&& !state.loading
220+
})
221+
222+
onBeforeMount(() => {
223+
if (state.message) {
224+
showWarning(state.message)
225+
}
226+
})
227+
228+
async function createAccount() {
229+
state.loading = true
230+
try {
231+
await axios.post(generateOcsUrl('/apps/libresign/api/v1/account/create/{uuid}'), {
232+
uuid: route.value.params.uuid,
233+
email: state.email,
234+
password: state.password,
235+
})
236+
const url = router.value.resolve({ name: 'SignPDF' })
237+
window.location.href = url.href
238+
} catch (error: any) {
239+
state.errorMessage = error.response.data.ocs.data.message
240+
}
241+
state.loading = false
197242
}
243+
244+
defineExpose({
245+
v$,
246+
email,
247+
password,
248+
passwordConfirm,
249+
loading,
250+
errorMessage,
251+
settings: state.settings,
252+
emailError,
253+
showErrorEmail,
254+
passwordError,
255+
confirmPasswordError,
256+
canSave,
257+
isEqualEmail,
258+
createAccount,
259+
})
198260
</script>
199261

200262
<style lang="scss">

0 commit comments

Comments
 (0)