119 lines
4.2 KiB
Vue
119 lines
4.2 KiB
Vue
<template>
|
|
<q-layout view="lHh Lpr fff">
|
|
<q-page-container>
|
|
<q-page class="window-height window-width row justify-center items-center">
|
|
<div class="column q-pa-lg">
|
|
<div class="row">
|
|
<q-card :square="false" class="shadow-24" style="width:400px;height:540px;">
|
|
<q-card-section class="bg-primary">
|
|
<h4 class="text-h5 text-white q-my-md">{{ title}}</h4>
|
|
</q-card-section>
|
|
<q-card-section>
|
|
<q-form class="q-px-sm q-pt-xl" ref="loginForm">
|
|
<q-input square clearable v-model="email" type="email" lazy-rules
|
|
:rules="[required,isEmail,short]" label="メール">
|
|
<template v-slot:prepend>
|
|
<q-icon name="email" />
|
|
</template>
|
|
</q-input>
|
|
<q-input square clearable v-model="password" :type="passwordFieldType" lazy-rules
|
|
:rules="[required, short]" label="パスワード">
|
|
|
|
<template v-slot:prepend>
|
|
<q-icon name="lock" />
|
|
</template>
|
|
<template v-slot:append>
|
|
<q-icon :name="visibilityIcon" @click="switchVisibility" class="cursor-pointer" />
|
|
</template>
|
|
</q-input>
|
|
</q-form>
|
|
</q-card-section>
|
|
|
|
<q-card-actions class="q-px-lg">
|
|
<q-btn :loading="loading" unelevated size="lg" color="secondary" @click="submit" class="full-width text-white"
|
|
label="ログイン" >
|
|
<template v-slot:loading>
|
|
<q-spinner class="on-left" />
|
|
ログイン中...
|
|
</template>
|
|
</q-btn>
|
|
</q-card-actions>
|
|
|
|
</q-card>
|
|
</div>
|
|
</div>
|
|
|
|
</q-page>
|
|
</q-page-container>
|
|
</q-layout>>
|
|
</template>
|
|
<script setup lang="ts">
|
|
import { useQuasar, QForm } from 'quasar'
|
|
// import { useRouter } from 'vue-router';
|
|
import { ref } from 'vue';
|
|
// import { Auth } from '../control/auth'
|
|
import { useAuthStore } from 'stores/useAuthStore';
|
|
const authStore = useAuthStore();
|
|
const $q = useQuasar()
|
|
const loginForm = ref<QForm>();
|
|
const loading = ref(false);
|
|
let title = ref('ログイン');
|
|
let email = ref('');
|
|
let password = ref('');
|
|
let visibility = ref(false);
|
|
let passwordFieldType = ref<'text'|'password'>('password');
|
|
let visibilityIcon = ref('visibility');
|
|
const required = (val:string) => {
|
|
return (val && val.length > 0 || '必須項目')
|
|
}
|
|
const isEmail = (val:string) => {
|
|
const emailPattern = /^(?=[a-zA-Z0-9@._%+-]{6,254}$)[a-zA-Z0-9._%+-]{1,64}@(?:[a-zA-Z0-9-]{1,63}\.){1,8}[a-zA-Z]{2,63}$/
|
|
return (emailPattern.test(val) || '無効なメールアドレス')
|
|
}
|
|
const short = (val:string) => {
|
|
return (val && val.length > 3 || '値が短く過ぎる')
|
|
}
|
|
const switchVisibility = () => {
|
|
visibility.value = !visibility.value
|
|
passwordFieldType.value = visibility.value ? 'text' : 'password'
|
|
visibilityIcon.value = visibility.value ? 'visibility_off' : 'visibility'
|
|
}
|
|
const submit = () => {
|
|
if (!loginForm.value) {
|
|
return;
|
|
}
|
|
loginForm.value.validate().then(async (success) => {
|
|
if (success) {
|
|
loading.value=true;
|
|
try {
|
|
const result = await authStore.login(email.value,password.value);
|
|
loading.value=false;
|
|
if(result){
|
|
$q.notify({
|
|
icon: 'done',
|
|
color: 'positive',
|
|
message: 'ログイン成功'
|
|
});
|
|
}
|
|
else{
|
|
$q.notify({
|
|
icon: 'error',
|
|
color: 'negative',
|
|
message: 'ログイン失敗'
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error(error);
|
|
loading.value=false;
|
|
$q.notify({
|
|
icon: 'error',
|
|
color: 'negative',
|
|
message: 'ログイン失敗'
|
|
});
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
</script>
|