Add logout
This commit is contained in:
parent
6ec987110a
commit
38d5fc3369
|
|
@ -58,13 +58,17 @@ function handleDropdownSelect(data) {
|
|||
router.push('/profile')
|
||||
break
|
||||
case 'logout':
|
||||
router.push('/logout')
|
||||
userStore.handleLogout();
|
||||
break
|
||||
default:
|
||||
console.log('no action')
|
||||
}
|
||||
}
|
||||
|
||||
function logout () {
|
||||
userStore.handleLogout();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
log.debug('MainNavigationBar mounted');
|
||||
})
|
||||
|
|
@ -96,7 +100,7 @@ const profileDropdownData = [
|
|||
<div>
|
||||
<Teleport to="body">
|
||||
<MobileMenu
|
||||
:user="userStore"
|
||||
:user-store="userStore"
|
||||
:show="state.showMenu"
|
||||
:learning-path-slug="learninPathSlug()"
|
||||
:learning-path-name="learningPathName()"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const router = useRouter()
|
|||
|
||||
const props = defineProps<{
|
||||
show: boolean,
|
||||
user: object,
|
||||
userStore: object,
|
||||
learningPathName: string,
|
||||
learningPathSlug: string
|
||||
}>()
|
||||
|
|
@ -29,17 +29,19 @@ const clickLink = (to: string) => {
|
|||
>
|
||||
<div>
|
||||
<div>
|
||||
<div class="border-b border-gray-500 -mx-4 px-8 pb-4">
|
||||
<div
|
||||
v-if="userStore.loggedIn"
|
||||
class="border-b border-gray-500 -mx-4 px-8 pb-4">
|
||||
<div class="-ml-4 flex">
|
||||
<div
|
||||
v-if="user.avatar_url"
|
||||
v-if="userStore.avatar_url"
|
||||
>
|
||||
<img class="inline-block h-16 w-16 rounded-full"
|
||||
:src="user.avatar_url"
|
||||
:src="userStore.avatar_url"
|
||||
alt=""/>
|
||||
</div>
|
||||
<div class="ml-6">
|
||||
<h3>{{user.first_name}} {{user.last_name}}</h3>
|
||||
<h3>{{userStore.first_name}} {{userStore.last_name}}</h3>
|
||||
<button
|
||||
@click="clickLink('/profile')"
|
||||
class="mt-2 inline-block flex items-center">
|
||||
|
|
@ -64,9 +66,13 @@ const clickLink = (to: string) => {
|
|||
<li class="mt-6">Mediathek</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mt-6 items-center flex">
|
||||
<button
|
||||
v-if="userStore.loggedIn"
|
||||
type="button"
|
||||
@click="userStore.handleLogout()"
|
||||
class="mt-6 items-center flex">
|
||||
<IconLogout class="inline-block" /><span class="ml-1">Abmelden</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,16 +14,18 @@ export type UserState = {
|
|||
loggedIn: boolean;
|
||||
}
|
||||
|
||||
export const useUserStore = defineStore({
|
||||
id: 'user',
|
||||
state: () => ({
|
||||
const initialUserState: UserState = {
|
||||
email: '',
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
username: '',
|
||||
avatar_url: '',
|
||||
loggedIn: false
|
||||
} as UserState),
|
||||
}
|
||||
|
||||
export const useUserStore = defineStore({
|
||||
id: 'user',
|
||||
state: () => (initialUserState as UserState),
|
||||
getters: {
|
||||
getFullName(): string {
|
||||
return `${this.first_name} ${this.last_name}`.trim();
|
||||
|
|
@ -46,6 +48,13 @@ export const useUserStore = defineStore({
|
|||
});
|
||||
}
|
||||
},
|
||||
handleLogout() {
|
||||
itPost('/core/logout/', {})
|
||||
.then(data => {
|
||||
Object.assign(this, initialUserState);
|
||||
window.location.href = '/';
|
||||
})
|
||||
},
|
||||
fetchUser() {
|
||||
const appStore = useAppStore();
|
||||
itGet('/api/core/me/').then((data) => {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
|
|||
from vbv_lernwelt.core.views import (
|
||||
rate_limit_exceeded_view,
|
||||
permission_denied_view,
|
||||
check_rate_limit, cypress_reset_view, vue_home, vue_login, me_user_view, )
|
||||
check_rate_limit, cypress_reset_view, vue_home, vue_login, me_user_view, vue_logout, )
|
||||
from .wagtail_api import wagtail_api_router
|
||||
|
||||
|
||||
|
|
@ -42,6 +42,7 @@ urlpatterns = [
|
|||
path('learnpath/', include("vbv_lernwelt.learnpath.urls")),
|
||||
path('api/completion/', include("vbv_lernwelt.completion.urls")),
|
||||
re_path(r'api/core/me/$', me_user_view, name='me_user_view'),
|
||||
re_path(r'core/logout/$', vue_logout, name='vue_logout'),
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
if settings.DEBUG:
|
||||
# Static file serving when using Gunicorn + Uvicorn for local web socket development
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import requests
|
||||
import structlog
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import authenticate, login
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.core.management import call_command
|
||||
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
|
|
@ -69,6 +69,12 @@ def me_user_view(request):
|
|||
return Response(status=403)
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
def vue_logout(request):
|
||||
logout(request)
|
||||
return Response({'success': True}, 200)
|
||||
|
||||
|
||||
def permission_denied_view(request, exception):
|
||||
return render(request, "403.html", status=403)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue