Add basic cockpit page

This commit is contained in:
Christian Cueni 2022-12-01 15:53:26 +00:00
parent 4729bbe59f
commit d9390ef82d
10 changed files with 196 additions and 8 deletions

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import ComptenceProgress from "@/components/competences/CompetenceProgress.vue";
import PerformanceCriteriaRow from "@/components/competences/PerformanceCriteriaRow.vue"; import PerformanceCriteriaRow from "@/components/competences/PerformanceCriteriaRow.vue";
import ItProgress from "@/components/ui/ItProgress.vue";
import { useCompetenceStore } from "@/stores/competence"; import { useCompetenceStore } from "@/stores/competence";
import type { CompetencePage } from "@/types"; import type { CompetencePage } from "@/types";
import { ref } from "vue"; import { ref } from "vue";
@ -34,13 +34,13 @@ const togglePerformanceCriteria = () => {
<it-icon-arrow-down class="h-10 w-10" aria-hidden="true" /> <it-icon-arrow-down class="h-10 w-10" aria-hidden="true" />
</div> </div>
</div> </div>
<ComptenceProgress <ItProgress
:status-count=" :status-count="
competenceStore.calcStatusCount( competenceStore.calcStatusCount(
competenceStore.criteriaByCompetence(competence) competenceStore.criteriaByCompetence(competence)
) )
" "
></ComptenceProgress> ></ItProgress>
</div> </div>
<ul v-if="isOpen"> <ul v-if="isOpen">
<li <li

View File

@ -0,0 +1,25 @@
<script setup lang="ts">
const props = defineProps<{
avatarLink: string;
name: string;
}>();
</script>
<template>
<li
class="py-4 leading-[45px] border-t border-gray-500 flex flex-row justify-between"
>
<div class="flex flex-row">
<img class="h-[45px] rounded-full mr-2" :src="avatarLink" />
<p class="text-bold leading-[45px]">{{ name }}</p>
</div>
<div class="leading-[45px]">
<slot name="center"></slot>
</div>
<div class="leading-[45px]">
<slot name="link"></slot>
</div>
</li>
</template>
<style lang="scss" scoped></style>

View File

@ -10,7 +10,11 @@
"save": "Speichern", "save": "Speichern",
"learningUnit": "Lerneinheit", "learningUnit": "Lerneinheit",
"learningPath": "Lernpfad", "learningPath": "Lernpfad",
"show": "Anschauen" "show": "Anschauen",
"circles": "Circles",
"transferTask": "Transferauftrag | Transferaufträge",
"feedback": "Feedback | Feedbacks",
"examResult": "Prüfungsresultat | Prüfungsresultate"
}, },
"mainNavigation": { "mainNavigation": {
"logout": "Abmelden", "logout": "Abmelden",
@ -68,5 +72,12 @@
"imprint": "Impressum", "imprint": "Impressum",
"contact": "Kontakt", "contact": "Kontakt",
"faq": "FAQ" "faq": "FAQ"
},
"cockpit": {
"tasksDone": "Erledigte Transferaufträge von Teilnehmer.",
"feedbacksDone": "Abgeschickte Feedbacks von Teilnehmer.",
"examsDone": "Abgelegte Prüfungen von Teilnehmer.",
"progress": "Fortschritt",
"profileLink": "Profil anzeigen"
} }
} }

View File

@ -0,0 +1,130 @@
<script setup lang="ts">
import ItPersonRow from "@/components/ui/ItPersonRow.vue";
import ItProgress from "@/components/ui/ItProgress.vue";
import * as log from "loglevel";
import { ref } from "vue";
log.debug("CockpitPage created");
const data = {
circles: ["KMU Teil 1", "KMU Teil 2", "3-Säuli-Prinzip"],
transferProgress: {
fail: 0,
success: 3,
unknown: 8,
},
};
const selectedCircle = ref(1);
function setActiveClasses(index: number) {
return selectedCircle.value === index
? ["bg-blue-900", "text-white"]
: ["text-bg-900"];
}
function setActiveCircle(index: number) {
selectedCircle.value = index;
}
</script>
<template>
<div class="bg-gray-200">
<div class="container-large">
<div class="flex lg:flex-row items-center mb-9">
<h1 class="heading-3">{{ $t("general.circles") }}:</h1>
<ul class="flex flex-row leading-7 text-base font-bold ml-4">
<li
v-for="(circle, index) in data.circles"
:key="circle"
class="mr-4 last:mr-0"
>
<button
class="border-2 border-blue-900 rounded-full px-4 mr-4 last:mr-0"
:class="setActiveClasses(index)"
@click="setActiveCircle(index)"
>
{{ circle }}
</button>
</li>
</ul>
</div>
<!-- Status -->
<div class="grid gap-4 grid-rows-3 lg:grid-rows-none lg:grid-cols-3 mb-4">
<div class="px-6 py-5 bg-white">
<h1
class="bg-assignment bg-no-repeat pl-[68px] heading-3 bg-60 leading-[60px] mb-4"
>
{{ $t("general.transferTask", 2) }}
</h1>
<div class="mb-4">
<ItProgress :status-count="data.transferProgress"></ItProgress>
</div>
<p>{{ $t("cockpit.tasksDone") }}</p>
</div>
<div class="px-6 py-5 bg-white">
<h1
class="bg-feedback bg-no-repeat pl-[68px] heading-3 bg-60 leading-[60px] mb-4"
>
{{ $t("general.feedback", 2) }}
</h1>
<div class="mb-4">
<ItProgress :status-count="data.transferProgress"></ItProgress>
</div>
<p>{{ $t("cockpit.feedbacksDone") }}</p>
</div>
<div class="px-6 py-5 bg-white">
<h1
class="bg-test bg-no-repeat pl-[68px] heading-3 bg-60 leading-[60px] mb-4"
>
{{ $t("general.examResult", 2) }}
</h1>
<div class="mb-4">
<ItProgress :status-count="data.transferProgress"></ItProgress>
</div>
<p>{{ $t("cockpit.examsDone") }}</p>
</div>
</div>
<div>
<!-- progress -->
<div class="bg-white p-6">
<h1 class="heading-3 mb-5">{{ $t("cockpit.progress") }}</h1>
<ul>
<ItPersonRow name="Hansueli Meier" avatar-link="https://picsum.photos/200">
<template #center>
<div class="flex flex-row">
<div>KMU Teil 1</div>
<ul class="ml-4 flex flex-row items-center">
<li class="flex flex-row items-center mr-6">
<it-icon-smiley-thinking
class="w-8 h-8 mr-2 inline-block"
></it-icon-smiley-thinking>
<p class="text-bold inline-block">2</p>
</li>
<li class="flex flex-row items-center mr-6">
<it-icon-smiley-happy
class="w-8 h-8 mr-2 inline-block"
></it-icon-smiley-happy>
<p class="text-bold inline-block">5</p>
</li>
<li class="flex flex-row items-center">
<it-icon-smiley-neutral
class="w-8 h-8 mr-2 inline-block"
></it-icon-smiley-neutral>
<p class="text-bold inline-block">5</p>
</li>
</ul>
</div>
</template>
<template #link>
{{ $t("cockpit.profileLink") }}
</template>
</ItPersonRow>
</ul>
</div>
</div>
</div>
</div>
</template>
<style scoped></style>

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import CompetenceProgress from "@/components/competences/CompetenceProgress.vue";
import PerformanceCriteriaRow from "@/components/competences/PerformanceCriteriaRow.vue"; import PerformanceCriteriaRow from "@/components/competences/PerformanceCriteriaRow.vue";
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue"; import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
import ItProgress from "@/components/ui/ItProgress.vue";
import { useCompetenceStore } from "@/stores/competence"; import { useCompetenceStore } from "@/stores/competence";
import _ from "lodash"; import _ from "lodash";
import * as log from "loglevel"; import * as log from "loglevel";
@ -72,13 +72,13 @@ const countStatus = computed(() => {
<p class="mb-4 lg:mb-0 lg:w-1/4 inline-block lg:mr-5"> <p class="mb-4 lg:mb-0 lg:w-1/4 inline-block lg:mr-5">
{{ competence.competence_id }} {{ competence.title }} {{ competence.competence_id }} {{ competence.title }}
</p> </p>
<CompetenceProgress <ItProgress
:status-count=" :status-count="
competenceStore.calcStatusCount( competenceStore.calcStatusCount(
competenceStore.criteriaByCompetence(competence) competenceStore.criteriaByCompetence(competence)
) )
" "
></CompetenceProgress> ></ItProgress>
</li> </li>
</ul> </ul>
<router-link <router-link

View File

@ -96,6 +96,11 @@ const router = createRouter({
component: () => import("../pages/learningPath/LearningContentPage.vue"), component: () => import("../pages/learningPath/LearningContentPage.vue"),
props: true, props: true,
}, },
{
path: "/learn/:learningPathSlug/cockpit",
component: () => import("../pages/cockpit/CockpitPage.vue"),
props: true,
},
{ {
path: "/shop", path: "/shop",
component: () => import("@/pages/ShopPage.vue"), component: () => import("@/pages/ShopPage.vue"),

View File

@ -11,6 +11,12 @@ module.exports = {
fontFamily: { fontFamily: {
sans: ["Buenos Aires", "sans-serif"], sans: ["Buenos Aires", "sans-serif"],
}, },
backgroundSize: {
'auto': 'auto',
'cover': 'cover',
'contain': 'contain',
'60': '3.75rem',
},
extend: { extend: {
spacing: { spacing: {
128: "32rem", 128: "32rem",
@ -23,6 +29,9 @@ module.exports = {
"handlungsfelder-overview": "handlungsfelder-overview":
"url('/static/icons/icon-handlungsfelder-overview.svg')", "url('/static/icons/icon-handlungsfelder-overview.svg')",
"lernmedien-overview": "url('/static/icons/icon-lernmedien-overview.svg')", "lernmedien-overview": "url('/static/icons/icon-lernmedien-overview.svg')",
"assignment": "url('/static/icons/icon-lc-assignment.svg')",
"feedback": "url('/static/icons/icon-feedback.svg')",
"test": "url('/static/icons/icon-lc-test.svg')",
}, },
borderColor: (theme) => ({ borderColor: (theme) => ({
DEFAULT: theme("colors.gray.500"), DEFAULT: theme("colors.gray.500"),

View File

@ -5,8 +5,8 @@ from django.contrib.auth.decorators import user_passes_test
from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.urls import include, path, re_path from django.urls import include, path, re_path
from django.views import defaults as default_views from django.views import defaults as default_views
from ratelimit.exceptions import Ratelimited
from grapple import urls as grapple_urls from grapple import urls as grapple_urls
from ratelimit.exceptions import Ratelimited
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
from vbv_lernwelt.core.views import ( from vbv_lernwelt.core.views import (

View File

@ -0,0 +1,8 @@
<svg viewBox="0 0 61 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M39.6694 37.824L37.2574 35.412L35.9854 36.684L39.0334 39.732C39.2134 39.912 39.4414 39.996 39.6694 39.996C39.8974 39.996 40.1254 39.912 40.3054 39.732L47.3493 32.688L46.0773 31.416L39.6694 37.824Z"
fill="black"/>
<path d="M55.0896 22.2839H28.2336C26.0136 22.2839 24.2136 24.0839 24.2136 26.3039V31.9319H14.4096C14.2536 31.9319 14.0976 31.9679 13.9536 32.0519L8.39762 35.2559V32.8319C8.39762 32.3399 7.98962 31.9319 7.49762 31.9319H5.56562C4.34162 31.9319 3.34562 30.9359 3.34562 29.7119V11.1839C3.34562 9.95994 4.34162 8.96394 5.56562 8.96394H32.4336C33.6576 8.96394 34.6536 9.95994 34.6536 11.1839V19.3679H36.4536V11.1839C36.4536 8.96394 34.6536 7.16394 32.4336 7.16394H5.57762C3.35762 7.16394 1.55762 8.96394 1.55762 11.1839V29.7119C1.55762 31.9319 3.35762 33.7319 5.57762 33.7319H6.60962V36.8159C6.60962 37.1399 6.77762 37.4399 7.06562 37.5959C7.20962 37.6799 7.36562 37.7159 7.52162 37.7159C7.67762 37.7159 7.83362 37.6799 7.97762 37.5959L14.6736 33.7319H24.2376V44.8319C24.2376 47.0519 26.0376 48.8519 28.2576 48.8519H46.0296L52.7256 52.7159C52.8696 52.7999 53.0256 52.8359 53.1816 52.8359C53.3376 52.8359 53.4936 52.7999 53.6376 52.7159C53.9136 52.5599 54.0936 52.2599 54.0936 51.9359V48.8519H55.1256C57.3456 48.8519 59.1456 47.0519 59.1456 44.8319V26.3039C59.1456 24.0839 57.3456 22.2839 55.1256 22.2839H55.0896ZM57.3096 44.8319C57.3096 46.0559 56.3136 47.0519 55.0896 47.0519H53.1576C52.6656 47.0519 52.2576 47.4599 52.2576 47.9519V50.3759L46.7016 47.1719C46.5696 47.0879 46.4136 47.0519 46.2456 47.0519H28.2216C26.9976 47.0519 26.0016 46.0559 26.0016 44.8319V26.3039C26.0016 25.0799 26.9976 24.0839 28.2216 24.0839H55.0776C56.3016 24.0839 57.2976 25.0799 57.2976 26.3039V44.8319H57.3096Z"
fill="black"/>
<path d="M29.4455 15.828H8.5415V17.628H29.4455V15.828Z" fill="black"/>
<path d="M18.9455 24.156H8.5415V25.956H18.9455V24.156Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB