191 lines
6.2 KiB
Vue
191 lines
6.2 KiB
Vue
<script setup>
|
|
import { ref, computed } from 'vue';
|
|
import { Dark, Quasar, useQuasar } from 'quasar';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useRouter } from 'vue-router';
|
|
import axios from 'axios';
|
|
|
|
import { useSession } from 'src/composables/useSession';
|
|
|
|
const quasar = useQuasar();
|
|
const session = useSession();
|
|
const router = useRouter();
|
|
const { t, locale } = useI18n();
|
|
|
|
const userLocale = computed({
|
|
get() {
|
|
return locale.value;
|
|
},
|
|
set(value) {
|
|
locale.value = value;
|
|
|
|
if (value === 'en') value = 'en-GB';
|
|
|
|
// FIXME: Dynamic imports from absolute paths are not compatible with vite:
|
|
// https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations
|
|
try {
|
|
const langList = import.meta.glob('../../node_modules/quasar/lang/*.mjs');
|
|
langList[`../../node_modules/quasar/lang/${value}.mjs`]().then((lang) => {
|
|
Quasar.lang.set(lang.default);
|
|
});
|
|
} catch (error) {
|
|
//
|
|
}
|
|
},
|
|
});
|
|
|
|
const darkMode = computed({
|
|
get() {
|
|
return Dark.isActive;
|
|
},
|
|
set(value) {
|
|
Dark.set(value);
|
|
},
|
|
});
|
|
|
|
const username = ref('');
|
|
const password = ref('');
|
|
const keepLogin = ref(true);
|
|
|
|
async function onSubmit() {
|
|
try {
|
|
const { data } = await axios.post('Accounts/login', {
|
|
user: username.value,
|
|
password: password.value,
|
|
});
|
|
|
|
if (!data) return;
|
|
|
|
await session.login(data.token, keepLogin.value);
|
|
|
|
quasar.notify({
|
|
message: t('login.loginSuccess'),
|
|
type: 'positive',
|
|
});
|
|
|
|
const currentRoute = router.currentRoute.value;
|
|
if (currentRoute.query && currentRoute.query.redirect) {
|
|
router.push(currentRoute.query.redirect);
|
|
} else {
|
|
router.push({ name: 'Dashboard' });
|
|
}
|
|
} catch (e) {
|
|
//
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<QLayout>
|
|
<QPageContainer>
|
|
<QPage id="login">
|
|
<QPageSticky position="top-right">
|
|
<QToolbar>
|
|
<QBtn
|
|
id="switchLanguage"
|
|
:label="t('globals.language')"
|
|
icon="translate"
|
|
color="primary"
|
|
size="sm"
|
|
flat
|
|
rounded
|
|
>
|
|
<QMenu auto-close>
|
|
<QList dense>
|
|
<QItem
|
|
@click="userLocale = 'en'"
|
|
:active="userLocale == 'en'"
|
|
v-ripple
|
|
clickable
|
|
>
|
|
{{ t('globals.lang.en') }}
|
|
</QItem>
|
|
<QItem
|
|
@click="userLocale = 'es'"
|
|
:active="userLocale == 'es'"
|
|
v-ripple
|
|
clickable
|
|
>
|
|
{{ t('globals.lang.es') }}
|
|
</QItem>
|
|
</QList>
|
|
</QMenu>
|
|
</QBtn>
|
|
<QList>
|
|
<QItem>
|
|
<QItemSection>
|
|
<QItemLabel caption>
|
|
{{ t(`globals.darkMode`) }}
|
|
</QItemLabel>
|
|
</QItemSection>
|
|
<QItemSection side>
|
|
<QToggle
|
|
v-model="darkMode"
|
|
checked-icon="dark_mode"
|
|
unchecked-icon="light_mode"
|
|
/>
|
|
</QItemSection>
|
|
</QItem>
|
|
</QList>
|
|
</QToolbar>
|
|
</QPageSticky>
|
|
<div class="login-form q-pa-xl">
|
|
<QImg
|
|
src="~/assets/logo.svg"
|
|
alt="Logo"
|
|
fit="contain"
|
|
:ratio="16 / 9"
|
|
class="q-mb-md"
|
|
/>
|
|
<QForm @submit="onSubmit" class="q-gutter-md">
|
|
<QInput
|
|
v-model="username"
|
|
:label="t('login.username')"
|
|
lazy-rules
|
|
:rules="[
|
|
(val) =>
|
|
(val && val.length > 0) || t('login.fieldRequired'),
|
|
]"
|
|
/>
|
|
<QInput
|
|
type="password"
|
|
v-model="password"
|
|
:label="t('login.password')"
|
|
lazy-rules
|
|
:rules="[
|
|
(val) =>
|
|
(val && val.length > 0) || t('login.fieldRequired'),
|
|
]"
|
|
/>
|
|
<QToggle v-model="keepLogin" :label="t('login.keepLogin')" />
|
|
|
|
<div>
|
|
<QBtn
|
|
:label="t('login.submit')"
|
|
type="submit"
|
|
color="primary"
|
|
class="full-width"
|
|
rounded
|
|
unelevated
|
|
/>
|
|
</div>
|
|
</QForm>
|
|
</div>
|
|
</QPage>
|
|
</QPageContainer>
|
|
</QLayout>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
#login {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-height: inherit;
|
|
}
|
|
|
|
.login-form {
|
|
width: 400px;
|
|
}
|
|
</style>
|