mirror of
https://github.com/gotson/komga.git
synced 2025-12-24 09:24:36 +01:00
rework login screen
This commit is contained in:
parent
1e20aa15b8
commit
c9df6a01e9
8 changed files with 91 additions and 27 deletions
|
|
@ -1,6 +1,8 @@
|
|||
<template>
|
||||
<v-app>
|
||||
<router-view />
|
||||
|
||||
<SnackQueue />
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { Middleware } from 'openapi-fetch'
|
||||
import createClient from 'openapi-fetch'
|
||||
import type { paths } from '@/generated/openapi/komga'
|
||||
import { globalProperties } from '@/main'
|
||||
|
||||
// Middleware that throws on error, so it works with Pinia Colada
|
||||
const coladaMiddleware: Middleware = {
|
||||
|
|
@ -23,7 +24,11 @@ const coladaMiddleware: Middleware = {
|
|||
onError() {
|
||||
throw new Error('error', {
|
||||
cause: {
|
||||
message: 'Server is unreachable',
|
||||
message: globalProperties.$intl.formatMessage({
|
||||
description: 'Network error: error message when the server cannot be reached',
|
||||
defaultMessage: 'Server is unreachable',
|
||||
id: '/6WuF/',
|
||||
}),
|
||||
},
|
||||
})
|
||||
},
|
||||
|
|
|
|||
1
next-ui/src/components.d.ts
vendored
1
next-ui/src/components.d.ts
vendored
|
|
@ -29,6 +29,7 @@ declare module 'vue' {
|
|||
LocaleSelector: typeof import('./components/LocaleSelector.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SnackQueue: typeof import('./components/SnackQueue.vue')['default']
|
||||
ThemeSelector: typeof import('./components/ThemeSelector.vue')['default']
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
next-ui/src/components/SnackQueue.vue
Normal file
16
next-ui/src/components/SnackQueue.vue
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<template>
|
||||
<v-snackbar-queue
|
||||
v-model="messagesStore.messages"
|
||||
timer
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMessagesStore } from '@/stores/messages'
|
||||
|
||||
const messagesStore = useMessagesStore()
|
||||
</script>
|
||||
|
||||
<script lang="ts"></script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -18,3 +18,5 @@ const app = createApp(App)
|
|||
registerPlugins(app)
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
export const globalProperties = app.config.globalProperties
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
:disabled="isLoading"
|
||||
@submit.prevent="submitForm()"
|
||||
>
|
||||
<v-container max-width="550px">
|
||||
<v-container max-width="450px">
|
||||
<v-row justify="center">
|
||||
<v-col>
|
||||
<v-col cols="10">
|
||||
<v-img src="@/assets/logo.svg" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
|
@ -41,12 +41,17 @@
|
|||
"
|
||||
type="password"
|
||||
:rules="[rules.required()]"
|
||||
:error-messages="loginError"
|
||||
@update:modelValue="loginError = ''"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-row
|
||||
align="center"
|
||||
justify="space-between"
|
||||
>
|
||||
<v-col cols="auto">
|
||||
<v-checkbox
|
||||
v-model="rememberMe"
|
||||
:label="
|
||||
|
|
@ -59,6 +64,22 @@
|
|||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="auto">
|
||||
<a
|
||||
href="https://komga.org/docs/faq#i-forgot-my-password"
|
||||
target="_blank"
|
||||
class="link-underline"
|
||||
>
|
||||
{{
|
||||
$formatMessage({
|
||||
description: 'Login screen: Forgot your password link',
|
||||
defaultMessage: 'Forgot your password?',
|
||||
id: 'r6JNfI',
|
||||
})
|
||||
}}
|
||||
</a>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
|
|
@ -73,28 +94,19 @@
|
|||
"
|
||||
:loading="isLoading"
|
||||
type="submit"
|
||||
block
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-snackbar
|
||||
v-model="showError"
|
||||
color="error"
|
||||
:text="showErrorText"
|
||||
timer="red"
|
||||
>
|
||||
<template v-slot:actions>
|
||||
<v-btn
|
||||
color="white"
|
||||
variant="text"
|
||||
@click="showError = false"
|
||||
>
|
||||
Dismiss
|
||||
</v-btn>
|
||||
</template></v-snackbar
|
||||
>
|
||||
<v-divider class="my-8" />
|
||||
|
||||
<v-row justify="center">
|
||||
<v-col cols="auto">
|
||||
<div class="d-flex ga-4">
|
||||
<LocaleSelector />
|
||||
<ThemeSelector />
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
|
@ -105,15 +117,19 @@
|
|||
import { type ErrorCause, komgaClient } from '@/api/komga-client'
|
||||
import { useMutation, useQueryCache } from '@pinia/colada'
|
||||
import { useRules } from 'vuetify/labs/rules'
|
||||
import { useMessagesStore } from '@/stores/messages'
|
||||
import { useIntl } from 'vue-intl'
|
||||
import { commonMessages } from '@/utils/i18n/common-messages'
|
||||
|
||||
const rules = useRules()
|
||||
const messagesStore = useMessagesStore()
|
||||
const intl = useIntl()
|
||||
|
||||
const formValid = ref<boolean>(false)
|
||||
const username = ref('')
|
||||
const password = ref('')
|
||||
const rememberMe = ref(false)
|
||||
const showError = ref<boolean>(false)
|
||||
const showErrorText = ref<string>('')
|
||||
const loginError = ref<string>('')
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
|
@ -139,8 +155,17 @@ const { mutate: performLogin, isLoading } = useMutation({
|
|||
else void router.push('/')
|
||||
},
|
||||
onError: (error) => {
|
||||
showErrorText.value = (error.cause as ErrorCause).message || 'Invalid authentication'
|
||||
showError.value = true
|
||||
if ((error.cause as ErrorCause).status === 401)
|
||||
loginError.value = intl.formatMessage({
|
||||
description: 'Login screen: error message displayed when login failed',
|
||||
defaultMessage: 'Invalid login or password',
|
||||
id: 'AjWlka',
|
||||
})
|
||||
else
|
||||
messagesStore.messages.push({
|
||||
text:
|
||||
(error.cause as ErrorCause).message || intl.formatMessage(commonMessages.networkError),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
|||
8
next-ui/src/stores/messages.ts
Normal file
8
next-ui/src/stores/messages.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Utilities
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useMessagesStore = defineStore('messages', {
|
||||
state: () => ({
|
||||
messages: [] as object[],
|
||||
}),
|
||||
})
|
||||
|
|
@ -11,4 +11,9 @@ export const commonMessages = {
|
|||
defaultMessage: 'There might be a problem with your connection or your server.',
|
||||
id: 'hYO2n6',
|
||||
}),
|
||||
networkError: defineMessage({
|
||||
description: 'Common message: a network error happened when communicating with the server',
|
||||
defaultMessage: 'Network error',
|
||||
id: 'Z/EY89',
|
||||
}),
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue