Add mobile selection

This commit is contained in:
Christian Cueni 2022-10-24 13:31:15 +02:00
parent 9b8bbf5ebc
commit 7ce195f518
5 changed files with 73 additions and 32 deletions

View File

@ -5,6 +5,7 @@ import { computed } from "vue";
interface DropdownSelectable {
id: number | string;
name: string;
iconName?: string;
}
// https://stackoverflow.com/questions/64775876/vue-3-pass-reactive-object-to-component-with-two-way-binding
@ -40,8 +41,11 @@ const dropdownSelected = computed({
<Listbox v-model="dropdownSelected" as="div">
<div class="mt-1 relative w-full">
<ListboxButton
class="bg-white relative w-full border pl-5 pr-10 py-3 text-left cursor-default font-bold"
class="bg-white relative w-full border pl-5 pr-10 py-3 text-left cursor-default font-bold flex flex-row items-center"
>
<span v-if="dropdownSelected.iconName" class="mr-4">
<component :is="dropdownSelected.iconName"></component>
</span>
<span class="block truncate">{{ dropdownSelected.name }}</span>
<span
class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none"
@ -70,7 +74,11 @@ const dropdownSelected = computed({
active ? 'text-white bg-blue-900' : 'text-black',
'cursor-default select-none relative py-2 pl-3 pr-9',
]"
class="flex flex-row items-center"
>
<span v-if="item.iconName" class="mr-4">
<component :is="item.iconName"></component>
</span>
<span
:class="[
dropdownSelected ? 'font-semibold' : 'font-normal',

View File

@ -2,10 +2,10 @@
import CompetenceProgress from "@/components/competences/CompetenceProgress.vue";
import PerformanceCriteriaRow from "@/components/competences/PerformanceCriteriaRow.vue";
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
import {useCompetenceStore} from "@/stores/competence";
import { useCompetenceStore } from "@/stores/competence";
import _ from "lodash";
import * as log from "loglevel";
import {computed} from "vue";
import { computed } from "vue";
log.debug("CompetenceIndexPage created");
@ -133,7 +133,10 @@ const countStatus = computed(() => {
<it-icon-arrow-right></it-icon-arrow-right>
</router-link>
</div>
<div v-if="failedCriteria.length > 0" class="bg-white px-8 py-4 lg:py-8 l mb-4 lg:mb-8">
<div
v-if="failedCriteria.length > 0"
class="bg-white px-8 py-4 lg:py-8 l mb-4 lg:mb-8"
>
<div class="border-b flex flex-row items-center pb-4 mb-4">
<it-icon-smiley-thinking class="w-11 h-11 mr-5"></it-icon-smiley-thinking>
<h3>«Das muss ich nochmals anschauen»</h3>

View File

@ -9,15 +9,44 @@ import {computed, ref} from "vue";
log.debug("CompetencesMainView created");
const competenceStore = useCompetenceStore();
interface MenuItem {
id: CourseCompletionStatus;
name: string;
iconName: string;
}
const activeState: Ref<CourseCompletionStatus> = ref("fail");
const competenceStore = useCompetenceStore();
const shownCriteria = computed(() => {
return competenceStore.flatPerformanceCriteria.filter((criteria) => {
return criteria.completion_status === activeState.value;
return criteria.completion_status === activeMenuItem.value.id;
});
});
const mobileMenuItems: MenuItem[] = [
{
id: "fail",
name: "«Das muss ich nochmals anschauen»",
iconName: "it-icon-smiley-thinking",
},
{
id: "success",
name: "«Ja, ich kann das»",
iconName: "it-icon-smiley-happy",
},
{
id: "unknown",
name: "Nicht eingeschätzt",
iconName: "it-icon-smiley-neutral",
},
];
const activeMenuItem: Ref<MenuItem> = ref(mobileMenuItems[0]);
function updateActiveState(status: CourseCompletionStatus) {
activeMenuItem.value =
mobileMenuItems.find((item) => status === item.id) || mobileMenuItems[0];
}
</script>
<template>
@ -38,32 +67,30 @@ const shownCriteria = computed(() => {
class="w-full lg:w-96 mt-4 lg:mt-0"
:items="competenceStore.availableCircles"
></ItDropdownSelect>
<div class="lg:hidden w-full">
<ItDropdownSelect
v-model="activeMenuItem"
class="w-full lg:w-96 mt-4 lg:mt-0"
:items="mobileMenuItems"
></ItDropdownSelect>
</div>
</div>
<div class="bg-white p-8">
<div class="border-b flex flex-col lg:flex-row lg:items-center pb-4 mb-4">
<div
class="border-b flex flex-col lg:flex-row lg:items-center pb-4 mb-4 hidden lg:block"
>
<button
:class="{ 'bg-gray-200': activeState === 'fail' }"
v-for="item in mobileMenuItems"
:key="item.id"
:class="{
'bg-gray-200': activeMenuItem.id === item.id,
'mr-6': item.id !== 'unknown',
}"
class="flex flex-row items-center py-4 px-2 mr-6"
@click="activeState = 'fail'"
@click="updateActiveState(item.id)"
>
<span class="inline-block mr-2">«Das muss ich nochmals anschauen»</span>
<span><it-icon-smiley-thinking></it-icon-smiley-thinking></span>
</button>
<button
:class="{ 'bg-gray-200': activeState === 'success' }"
class="flex flex-row items-center py-4 px-2 mr-6"
@click="activeState = 'success'"
>
<span class="inline-block mr-2">«Ja, ich kann das»</span>
<span><it-icon-smiley-happy></it-icon-smiley-happy></span>
</button>
<button
:class="{ 'bg-gray-200': activeState === 'unknown' }"
class="flex flex-row items-center py-4 px-2"
@click="activeState = 'unknown'"
>
<span class="inline-block mr-2">Nicht eingeschätzt</span>
<span><it-icon-smiley-neutral></it-icon-smiley-neutral></span>
<span class="inline-block mr-2">{{ item.name }}</span>
<component :is="item.iconName"></component>
</button>
</div>
<ul class="mb-6">

View File

@ -68,7 +68,7 @@ const createContinueUrl = (learningPath: LearningPath): [string, boolean] => {
</button>
</div>
<LearningPathDiagram
class="mx-auto max-w-[1920px] max-h-[380px] w-full"
class="mx-auto max-w-[1920px] max-h-[380px] w-full px-4"
identifier="mainVisualization"
:vertical="false"
></LearningPathDiagram>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import {useMediaLibraryStore} from "@/stores/mediaLibrary";
import { useMediaLibraryStore } from "@/stores/mediaLibrary";
import * as log from "loglevel";
import {onMounted} from "vue";
import { onMounted } from "vue";
log.debug("MediaLibraryView created");
@ -25,7 +25,10 @@ onMounted(async () => {
<template>
<div class="bg-gray-200">
<nav class="px-6 py-4 border-b bg-white">
<ul v-if="mediaLibraryStore.mediaLibraryPage" class="overflow-auto whitespace-nowrap scrollbar">
<ul
v-if="mediaLibraryStore.mediaLibraryPage"
class="overflow-auto whitespace-nowrap scrollbar"
>
<li class="lg:ml-12 inline-block">
<router-link :to="mediaLibraryStore.mediaLibraryPage.frontend_url">
Übersicht