add more infos to overview, fix redo lessons button, add readings to review for clarification
This commit is contained in:
@@ -1,5 +1,67 @@
|
||||
<template lang="pug">
|
||||
v-app.zen-app.overflow-hidden
|
||||
v-navigation-drawer(
|
||||
v-if="store.token || viewState === 'zooming'"
|
||||
v-model="drawer"
|
||||
temporary
|
||||
location="right"
|
||||
color="#1e1e24"
|
||||
class="border-none"
|
||||
width="280"
|
||||
)
|
||||
.d-flex.flex-column.h-100.pa-4
|
||||
.d-flex.align-center.mb-6.px-2
|
||||
img.mr-3(:src="logo" height="32" width="32" alt="Logo")
|
||||
span.text-h6.font-weight-bold {{ $t('nav.menu') }}
|
||||
|
||||
v-list.pa-0(nav bg-color="transparent")
|
||||
v-list-item.mb-2(
|
||||
to="/"
|
||||
rounded="lg"
|
||||
:active="$route.path === '/'"
|
||||
)
|
||||
template(v-slot:prepend)
|
||||
v-icon(color="#00cec9" icon="mdi-view-dashboard")
|
||||
v-list-item-title.font-weight-bold {{ $t('nav.dashboard') }}
|
||||
|
||||
v-list-item.mb-2(
|
||||
to="/collection"
|
||||
rounded="lg"
|
||||
:active="$route.path === '/collection'"
|
||||
)
|
||||
template(v-slot:prepend)
|
||||
v-icon(color="#00cec9" icon="mdi-bookshelf")
|
||||
v-list-item-title.font-weight-bold {{ $t('nav.collection') }}
|
||||
|
||||
v-divider.my-4.border-subtle
|
||||
|
||||
.d-flex.flex-column.gap-2
|
||||
v-btn.justify-start.px-4(
|
||||
variant="text"
|
||||
block
|
||||
color="grey-lighten-1"
|
||||
@click="showSettings = true; drawer = false"
|
||||
)
|
||||
v-icon(start icon="mdi-cog")
|
||||
| {{ $t('nav.settings') }}
|
||||
|
||||
v-btn.justify-start.px-4(
|
||||
variant="text"
|
||||
block
|
||||
color="grey-lighten-1"
|
||||
:loading="syncing"
|
||||
@click="manualSync"
|
||||
)
|
||||
v-icon(start icon="mdi-sync")
|
||||
| {{ $t('nav.sync') }}
|
||||
|
||||
v-btn.justify-start.px-4.text-red-lighten-2(
|
||||
variant="text"
|
||||
block
|
||||
@click="handleLogout"
|
||||
)
|
||||
v-icon(start icon="mdi-logout")
|
||||
| {{ $t('nav.logout') }}
|
||||
.parallax-bg(
|
||||
:style="parallaxStyle"
|
||||
:class="{ 'zooming': viewState === 'zooming' }"
|
||||
@@ -22,67 +84,6 @@
|
||||
v-if="store.token || viewState === 'zooming'"
|
||||
:class="{ 'app-entering': viewState === 'zooming', 'app-visible': viewState === 'app' }"
|
||||
)
|
||||
v-navigation-drawer(
|
||||
v-model="drawer"
|
||||
temporary
|
||||
location="right"
|
||||
color="#1e1e24"
|
||||
class="border-none"
|
||||
width="280"
|
||||
)
|
||||
.d-flex.flex-column.h-100.pa-4
|
||||
.d-flex.align-center.mb-6.px-2
|
||||
img.mr-3(:src="logo" height="32" width="32" alt="Logo")
|
||||
span.text-h6.font-weight-bold {{ $t('nav.menu') }}
|
||||
|
||||
v-list.pa-0(nav bg-color="transparent")
|
||||
v-list-item.mb-2(
|
||||
to="/"
|
||||
rounded="lg"
|
||||
:active="$route.path === '/'"
|
||||
)
|
||||
template(v-slot:prepend)
|
||||
v-icon(color="#00cec9" icon="mdi-view-dashboard")
|
||||
v-list-item-title.font-weight-bold {{ $t('nav.dashboard') }}
|
||||
|
||||
v-list-item.mb-2(
|
||||
to="/collection"
|
||||
rounded="lg"
|
||||
:active="$route.path === '/collection'"
|
||||
)
|
||||
template(v-slot:prepend)
|
||||
v-icon(color="#00cec9" icon="mdi-bookshelf")
|
||||
v-list-item-title.font-weight-bold {{ $t('nav.collection') }}
|
||||
|
||||
v-divider.my-4.border-subtle
|
||||
|
||||
.d-flex.flex-column.gap-2
|
||||
v-btn.justify-start.px-4(
|
||||
variant="text"
|
||||
block
|
||||
color="grey-lighten-1"
|
||||
@click="showSettings = true; drawer = false"
|
||||
)
|
||||
v-icon(start icon="mdi-cog")
|
||||
| {{ $t('nav.settings') }}
|
||||
|
||||
v-btn.justify-start.px-4(
|
||||
variant="text"
|
||||
block
|
||||
color="grey-lighten-1"
|
||||
:loading="syncing"
|
||||
@click="manualSync"
|
||||
)
|
||||
v-icon(start icon="mdi-sync")
|
||||
| {{ $t('nav.sync') }}
|
||||
|
||||
v-btn.justify-start.px-4.text-red-lighten-2(
|
||||
variant="text"
|
||||
block
|
||||
@click="handleLogout"
|
||||
)
|
||||
v-icon(start icon="mdi-logout")
|
||||
| {{ $t('nav.logout') }}
|
||||
|
||||
v-app-bar.px-2.app-bar-blur.safe-area-header(
|
||||
flat
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@use 'readings';
|
||||
@use 'radicals';
|
||||
@use 'buttons';
|
||||
@use 'cards';
|
||||
@use 'kanji/index' as kanji;
|
||||
|
||||
20
client/src/styles/components/_radicals.scss
Normal file
20
client/src/styles/components/_radicals.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
@use '../abstracts' as *;
|
||||
|
||||
.radical-section {
|
||||
width: 100%;
|
||||
background: $color-zinc-900;
|
||||
border-radius: $radius-md;
|
||||
padding: $spacing-md;
|
||||
margin-bottom: $spacing-lg;
|
||||
}
|
||||
|
||||
.radical-chip {
|
||||
border-radius: $radius-md;
|
||||
border: $border-width-sm solid $color-border;
|
||||
background-color: $color-surface-lighter;
|
||||
|
||||
img {
|
||||
filter: invert(1);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
28
client/src/styles/components/_readings.scss
Normal file
28
client/src/styles/components/_readings.scss
Normal file
@@ -0,0 +1,28 @@
|
||||
@use '../abstracts' as *;
|
||||
|
||||
.readings-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: $spacing-lg;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.reading-box {
|
||||
background: $color-reading-box;
|
||||
padding: $spacing-lg;
|
||||
border-radius: $radius-lg;
|
||||
text-align: center;
|
||||
|
||||
.label {
|
||||
font-size: $font-xs;
|
||||
color: #666;
|
||||
letter-spacing: 0.0625rem;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: $spacing-xs;
|
||||
}
|
||||
|
||||
.val {
|
||||
font-size: 1.1rem;
|
||||
font-weight: $weight-bold;
|
||||
}
|
||||
}
|
||||
@@ -16,52 +16,6 @@
|
||||
height: $size-hero-wrapper;
|
||||
}
|
||||
|
||||
.radical-section {
|
||||
width: 100%;
|
||||
background: $color-zinc-900;
|
||||
border-radius: $radius-md;
|
||||
padding: $spacing-md;
|
||||
margin-bottom: $spacing-lg;
|
||||
}
|
||||
|
||||
.radical-chip {
|
||||
border-radius: $radius-md;
|
||||
border: $border-width-sm solid $color-border;
|
||||
background-color: $color-surface-lighter;
|
||||
|
||||
img {
|
||||
filter: invert(1);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.readings-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: $spacing-lg;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.reading-box {
|
||||
background: $color-reading-box;
|
||||
padding: $spacing-lg;
|
||||
border-radius: $radius-lg;
|
||||
text-align: center;
|
||||
|
||||
.label {
|
||||
font-size: $font-xs;
|
||||
color: #666;
|
||||
letter-spacing: 0.0625rem;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: $spacing-xs;
|
||||
}
|
||||
|
||||
.val {
|
||||
font-size: 1.1rem;
|
||||
font-weight: $weight-bold;
|
||||
}
|
||||
}
|
||||
|
||||
.lesson-canvas-wrapper {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@@ -45,3 +45,10 @@
|
||||
.gap-2 {
|
||||
gap: $spacing-sm;
|
||||
}
|
||||
|
||||
.reading-box--small {
|
||||
padding: $spacing-sm;
|
||||
.val {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,18 @@
|
||||
:svg-content="preloadedSvg"
|
||||
)
|
||||
|
||||
.radical-section.mb-4(v-if="selectedItem?.radicals?.length")
|
||||
.text-caption.text-grey-darken-1.text-uppercase.mb-3.font-weight-bold
|
||||
|{{ $t('lesson.components') }}
|
||||
.d-flex.flex-wrap.gap-3.justify-center
|
||||
v-sheet.radical-chip(
|
||||
v-for="rad in selectedItem.radicals" :key="rad.meaning")
|
||||
.d-flex.align-center.gap-2.px-3.py-1
|
||||
v-avatar(size="24" rounded="0")
|
||||
img(v-if="rad.image" :src="rad.image")
|
||||
span.text-h6.font-weight-bold.text-white(v-else) {{ rad.char }}
|
||||
.text-caption.text-grey-lighten-1 {{ rad.meaning }}
|
||||
|
||||
.readings-container.mb-4
|
||||
.reading-group(v-if="hasReading(selectedItem?.onyomi)")
|
||||
.reading-label {{ $t('collection.onyomi') }}
|
||||
@@ -105,6 +117,17 @@
|
||||
.reading-label {{ $t('collection.nanori') }}
|
||||
.reading-value {{ selectedItem?.nanori.join(', ') }}
|
||||
|
||||
.px-2.mb-4(v-if="selectedItem?.stats?.total > 0")
|
||||
.d-flex.justify-space-between.align-center.mb-1
|
||||
.text-caption.text-grey {{ $t('stats.accuracy') }}
|
||||
.text-caption.font-weight-bold {{ accuracyStats.text }}
|
||||
v-progress-linear(
|
||||
:model-value="accuracyStats.percent"
|
||||
color="light-blue"
|
||||
height="6"
|
||||
rounded
|
||||
)
|
||||
|
||||
v-row.px-2.pb-2
|
||||
v-col.pr-2(cols="6")
|
||||
v-btn.text-white(
|
||||
@@ -142,6 +165,16 @@ const searchQuery = ref('');
|
||||
const preparingId = ref(null);
|
||||
const preloadedSvg = ref('');
|
||||
|
||||
const accuracyStats = computed(() => {
|
||||
if (!selectedItem.value?.stats || selectedItem.value.stats.total === 0) {
|
||||
return { percent: 100, text: 'No history' };
|
||||
}
|
||||
const { correct, total } = selectedItem.value.stats;
|
||||
const percent = Math.round((correct / total) * 100);
|
||||
const text = `${correct} / ${total}`;
|
||||
return { percent, text };
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await store.fetchCollection();
|
||||
loading.value = false;
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
img(v-if="rad.image" :src="rad.image")
|
||||
span.text-h6.font-weight-bold.text-white(v-else) {{ rad.char }}
|
||||
.text-caption.text-grey-lighten-1 {{ rad.meaning }}
|
||||
.readings-grid
|
||||
.reading-box
|
||||
.readings-grid(v-if="(currentItem.onyomi && currentItem.onyomi.length > 0) || (currentItem.kunyomi && currentItem.kunyomi.length > 0)")
|
||||
.reading-box(v-if="currentItem.onyomi && currentItem.onyomi.length > 0")
|
||||
.label {{ $t('collection.onyomi') }}
|
||||
.val.text-cyan-lighten-3 {{ currentItem.onyomi[0] || '-' }}
|
||||
.reading-box
|
||||
.val.text-cyan-lighten-3 {{ currentItem.onyomi.join(', ') }}
|
||||
.reading-box(v-if="currentItem.kunyomi && currentItem.kunyomi.length > 0")
|
||||
.label {{ $t('collection.kunyomi') }}
|
||||
.val.text-pink-lighten-3 {{ currentItem.kunyomi[0] || '-' }}
|
||||
.val.text-pink-lighten-3 {{ currentItem.kunyomi.join(', ') }}
|
||||
|
||||
v-window-item(value="demo")
|
||||
.d-flex.flex-column.align-center.justify-center.h-100.pa-6
|
||||
@@ -111,12 +111,14 @@ import {
|
||||
ref, computed, onMounted, nextTick, watch,
|
||||
} from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useAppStore } from '@/stores/appStore';
|
||||
import KanjiCanvas from '@/components/kanji/KanjiCanvas.vue';
|
||||
import KanjiSvgViewer from '@/components/kanji/KanjiSvgViewer.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const store = useAppStore();
|
||||
const route = useRoute();
|
||||
const currentItem = ref(null);
|
||||
const phase = ref('primer');
|
||||
const subPhase = ref('guided');
|
||||
@@ -179,7 +181,12 @@ async function handleDrawComplete() {
|
||||
canvas.value?.reset();
|
||||
canvasOpacity.value = 1;
|
||||
} else {
|
||||
await store.submitLesson(currentItem.value.wkSubjectId);
|
||||
const isRedo = !!route.query.subjectId;
|
||||
|
||||
if (!isRedo) {
|
||||
await store.submitLesson(currentItem.value.wkSubjectId);
|
||||
}
|
||||
|
||||
sessionDone.value += 1;
|
||||
store.lessonQueue.shift();
|
||||
loadNext();
|
||||
@@ -200,7 +207,15 @@ function useHint() {
|
||||
|
||||
onMounted(async () => {
|
||||
loading.value = true;
|
||||
await store.fetchLessonQueue();
|
||||
const { subjectId } = route.query;
|
||||
const historyState = window.history.state;
|
||||
|
||||
if (subjectId && historyState && historyState.item) {
|
||||
store.lessonQueue = [historyState.item];
|
||||
} else {
|
||||
await store.fetchLessonQueue();
|
||||
}
|
||||
|
||||
sessionTotal.value = store.lessonQueue.length;
|
||||
loadNext();
|
||||
loading.value = false;
|
||||
|
||||
@@ -28,8 +28,15 @@
|
||||
.text-center.mb-6
|
||||
.text-caption.text-grey.text-uppercase.tracking-wide.mb-1
|
||||
| {{ $t('review.meaning') }}
|
||||
.text-h3.font-weight-bold.text-white.text-shadow
|
||||
.text-h3.font-weight-bold.text-white.text-shadow.mb-4
|
||||
| {{ currentItem.meaning }}
|
||||
.readings-grid(v-if="(currentItem.onyomi && currentItem.onyomi.length > 0) || (currentItem.kunyomi && currentItem.kunyomi.length > 0)")
|
||||
.reading-box.reading-box--small(v-if="currentItem.onyomi && currentItem.onyomi.length > 0")
|
||||
.label {{ $t('collection.onyomi') }}
|
||||
.val.text-cyan-lighten-3 {{ currentItem.onyomi.join(', ') }}
|
||||
.reading-box.reading-box--small(v-if="currentItem.kunyomi && currentItem.kunyomi.length > 0")
|
||||
.label {{ $t('collection.kunyomi') }}
|
||||
.val.text-pink-lighten-3 {{ currentItem.kunyomi.join(', ') }}
|
||||
|
||||
.review-canvas-area
|
||||
KanjiCanvas(
|
||||
|
||||
Reference in New Issue
Block a user