Fetch inbox data
This commit is contained in:
parent
9d8465c950
commit
6b179885ce
|
@ -96,12 +96,18 @@ const moderationNotifications = computed(() =>
|
|||
|
||||
onMounted(async () => {
|
||||
if (store.state.auth.authenticated) {
|
||||
const [edits, reports, requests] = await Promise.all([
|
||||
const [inbox, edits, reports, requests] = await Promise.all([
|
||||
axios.get('federation/inbox/', { params: { is_read: false } }).catch(() => ({ data: { count: 0 } })),
|
||||
axios.get('mutations/', { params: { page_size: 1, q: 'is_approved:null' } }).catch(() => ({ data: { count: 0 } })),
|
||||
axios.get('manage/moderation/reports/', { params: { page_size: 1, q: 'resolved:no' } }).catch(() => ({ data: { count: 0 } })),
|
||||
axios.get('manage/moderation/requests/', { params: { page_size: 1, q: 'status:pending' } }).catch(() => ({ data: { count: 0 } }))
|
||||
])
|
||||
|
||||
store.commit('ui/incrementNotifications', {
|
||||
type: 'inbox',
|
||||
value: inbox.data.count
|
||||
})
|
||||
|
||||
store.commit('ui/incrementNotifications', {
|
||||
type: 'pendingReviewEdits',
|
||||
value: edits.data.count
|
||||
|
|
|
@ -1,10 +1,83 @@
|
|||
<script setup lang="ts">
|
||||
import type { BackendError } from '~/types'
|
||||
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
import { useStore } from '~/store'
|
||||
|
||||
import PasswordInput from '~/components/forms/PasswordInput.vue'
|
||||
|
||||
interface Props {
|
||||
next?: string
|
||||
buttonClasses?: string
|
||||
showSignup?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
next: '/library',
|
||||
buttonClasses: 'success',
|
||||
showSignup: true
|
||||
})
|
||||
|
||||
const domain = location.hostname
|
||||
const { $pgettext } = useGettext()
|
||||
const store = useStore()
|
||||
|
||||
const credentials = reactive({
|
||||
username: '',
|
||||
password: ''
|
||||
})
|
||||
|
||||
const labels = computed(() => ({
|
||||
usernamePlaceholder: $pgettext('Content/Login/Input.Placeholder', 'Enter your username or e-mail address')
|
||||
}))
|
||||
|
||||
const username = ref()
|
||||
onMounted(() => username.value.focus())
|
||||
|
||||
const isLoading = ref(false)
|
||||
const errors = ref([] as string[])
|
||||
const submit = async () => {
|
||||
isLoading.value = true
|
||||
|
||||
try {
|
||||
if (domain === store.getters['instance/domain']) {
|
||||
await store.dispatch('auth/login', {
|
||||
credentials,
|
||||
next: props.next
|
||||
})
|
||||
} else {
|
||||
await store.dispatch('auth/oauthLogin', props.next)
|
||||
}
|
||||
} catch (error) {
|
||||
const backendError = error as BackendError
|
||||
|
||||
if (backendError.response?.status === 400) {
|
||||
errors.value = ['invalid_credentials']
|
||||
} else {
|
||||
errors.value = backendError.backendErrors
|
||||
}
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
// export default {
|
||||
// created () {
|
||||
// if (this.$store.state.auth.authenticated) {
|
||||
// this.$router.push(this.next)
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form
|
||||
class="ui form"
|
||||
@submit.prevent="submit()"
|
||||
>
|
||||
<div
|
||||
v-if="error"
|
||||
v-if="errors.length > 0"
|
||||
role="alert"
|
||||
class="ui negative message"
|
||||
>
|
||||
|
@ -14,18 +87,18 @@
|
|||
</translate>
|
||||
</h4>
|
||||
<ul class="list">
|
||||
<li v-if="error == 'invalid_credentials' && $store.state.instance.settings.moderation.signup_approval_enabled.value">
|
||||
<li v-if="errors[0] == 'invalid_credentials' && $store.state.instance.settings.moderation.signup_approval_enabled.value">
|
||||
<translate translate-context="Content/Login/Error message.List item/Call to action">
|
||||
If you signed-up recently, you may need to wait before our moderation team review your account, or verify your e-mail address.
|
||||
</translate>
|
||||
</li>
|
||||
<li v-else-if="error == 'invalid_credentials'">
|
||||
<li v-else-if="errors[0] == 'invalid_credentials'">
|
||||
<translate translate-context="Content/Login/Error message.List item/Call to action">
|
||||
Please double-check that your username and password combination is correct and make sure you verified your e-mail address.
|
||||
</translate>
|
||||
</li>
|
||||
<li v-else>
|
||||
{{ error }}
|
||||
{{ errors[0] }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -88,82 +161,3 @@
|
|||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PasswordInput from '~/components/forms/PasswordInput.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PasswordInput
|
||||
},
|
||||
props: {
|
||||
next: { type: String, default: '/library' },
|
||||
buttonClasses: { type: String, default: 'success' },
|
||||
showSignup: { type: Boolean, default: true }
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// We need to initialize the component with any
|
||||
// properties that will be used in it
|
||||
credentials: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
error: '',
|
||||
isLoading: false,
|
||||
domain: location.hostname
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
labels () {
|
||||
const usernamePlaceholder = this.$pgettext('Content/Login/Input.Placeholder', 'Enter your username or e-mail address')
|
||||
return {
|
||||
usernamePlaceholder
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
if (this.$store.state.auth.authenticated) {
|
||||
this.$router.push(this.next)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.$refs.username) {
|
||||
this.$refs.username.focus()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async submit () {
|
||||
if (location.hostname === this.$store.getters['instance/domain']) {
|
||||
return await this.submitSession()
|
||||
} else {
|
||||
this.isLoading = true
|
||||
await this.$store.dispatch('auth/oauthLogin', this.next)
|
||||
}
|
||||
},
|
||||
async submitSession () {
|
||||
this.isLoading = true
|
||||
this.error = ''
|
||||
const credentials = {
|
||||
username: this.credentials.username,
|
||||
password: this.credentials.password
|
||||
}
|
||||
this.$store
|
||||
.dispatch('auth/login', {
|
||||
credentials,
|
||||
next: this.next,
|
||||
onError: error => {
|
||||
if (error.response.status === 400) {
|
||||
self.error = 'invalid_credentials'
|
||||
} else {
|
||||
self.error = error.backendErrors[0]
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
self.isLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'
|
||||
import type { NavigationGuardNext, RouteLocationNamedRaw, RouteLocationNormalized } from 'vue-router'
|
||||
import type { Permission } from '~/store/auth'
|
||||
|
||||
import store from '~/store'
|
||||
|
@ -12,3 +12,13 @@ export const hasPermissions = (permission: Permission) => (to: RouteLocationNorm
|
|||
console.log('Not authenticated. Redirecting to library.')
|
||||
next({ name: 'library.index' })
|
||||
}
|
||||
|
||||
export const requireLoggedIn = (fallbackLocation: RouteLocationNamedRaw) => (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
|
||||
if (store.state.auth.authenticated) return next()
|
||||
return next(fallbackLocation)
|
||||
}
|
||||
|
||||
export const requireLoggedOut = (fallbackLocation: RouteLocationNamedRaw) => (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
|
||||
if (!store.state.auth.authenticated) return next()
|
||||
return next(fallbackLocation)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import type { RouteRecordRaw } from 'vue-router'
|
||||
|
||||
import { requireLoggedOut } from '../guards'
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('~/views/auth/Login.vue'),
|
||||
// TODO (wvffle): Use named routes EVERYWHERE
|
||||
props: route => ({ next: route.query.next || '/library' })
|
||||
props: route => ({ next: route.query.next || '/library' }),
|
||||
beforeEnter: requireLoggedOut({ name: 'library.index' })
|
||||
},
|
||||
{
|
||||
path: '/auth/password/reset',
|
||||
|
|
Loading…
Reference in New Issue