feat(admin): add potential fathers retrieval for character management
All checks were successful
Deploy to production / deploy (push) Successful in 2m47s
All checks were successful
Deploy to production / deploy (push) Successful in 2m47s
- Implemented a new method in AdminService to fetch potential fathers for a given character based on existing relationships. - Updated AdminController to expose this functionality via a new API endpoint. - Enhanced adminRouter to include the route for retrieving potential fathers. - Modified frontend components to allow selection of potential fathers during pregnancy and birth management. - Updated internationalization files to include new translation keys related to father selection.
This commit is contained in:
@@ -176,17 +176,33 @@
|
||||
"statusActive": "Schwanger bis",
|
||||
"statusNone": "Nicht schwanger",
|
||||
"fatherId": "Vater-Charakter-ID (optional)",
|
||||
"fatherSelect": "Vater (Ehepartner / Verlobter / Liebhaber)",
|
||||
"fatherNone": "— kein Vater gespeichert —",
|
||||
"fatherHintList": "Liste aus Beziehungen dieses Charakters (Ehe, Verlobung, aktive Liebschaft).",
|
||||
"fatherHintManual": "Kein passender Partner in der Datenbank: Vater-Charakter-ID manuell eintragen.",
|
||||
"fatherManualPlaceholder": "Charakter-ID",
|
||||
"dueDays": "Tage bis zum Termin",
|
||||
"dueDaysHint": "0 = Termin heute (Geburt kann je nach Spiel-Logik zeitnah anstehen).",
|
||||
"force": "Schwangerschaft setzen",
|
||||
"clear": "Schwangerschaft entfernen",
|
||||
"successForce": "Schwangerschaft wurde gesetzt.",
|
||||
"successClear": "Schwangerschaft wurde entfernt.",
|
||||
"error": "Aktion fehlgeschlagen."
|
||||
"error": "Aktion fehlgeschlagen.",
|
||||
"relationship": {
|
||||
"married": "Ehepartner",
|
||||
"engaged": "Verlobter",
|
||||
"lover": "Liebhaber"
|
||||
}
|
||||
},
|
||||
"birth": {
|
||||
"title": "Geburt erzwingen (Admin)",
|
||||
"motherHint": "Es wird der oben genannte Charakter (Mutter) verwendet.",
|
||||
"fatherId": "Vater-Charakter-ID",
|
||||
"fatherSelect": "Vater (Ehepartner / Verlobter / Liebhaber)",
|
||||
"fatherChoose": "— Vater wählen —",
|
||||
"fatherHintList": "Liste aus Beziehungen dieses Charakters.",
|
||||
"fatherHintManual": "Kein Partner in der Liste: Vater-Charakter-ID manuell eintragen.",
|
||||
"fatherRequired": "Bitte einen Vater auswählen oder die Charakter-ID angeben.",
|
||||
"context": "Kontext",
|
||||
"contextMarriage": "Ehe",
|
||||
"contextLover": "Liebschaft",
|
||||
|
||||
@@ -231,17 +231,33 @@
|
||||
"statusActive": "Expecting until",
|
||||
"statusNone": "Not pregnant",
|
||||
"fatherId": "Father character ID (optional)",
|
||||
"fatherSelect": "Father (spouse / fiancé(e) / lover)",
|
||||
"fatherNone": "— no father stored —",
|
||||
"fatherHintList": "From this character’s relationships (marriage, engagement, active affair).",
|
||||
"fatherHintManual": "No matching partner in the database: enter the father’s character ID manually.",
|
||||
"fatherManualPlaceholder": "Character ID",
|
||||
"dueDays": "Days until due date",
|
||||
"dueDaysHint": "0 = due today (birth may follow depending on game logic).",
|
||||
"force": "Set pregnancy",
|
||||
"clear": "Clear pregnancy",
|
||||
"successForce": "Pregnancy has been set.",
|
||||
"successClear": "Pregnancy has been cleared.",
|
||||
"error": "Action failed."
|
||||
"error": "Action failed.",
|
||||
"relationship": {
|
||||
"married": "Spouse",
|
||||
"engaged": "Engaged partner",
|
||||
"lover": "Lover"
|
||||
}
|
||||
},
|
||||
"birth": {
|
||||
"title": "Force birth (admin)",
|
||||
"motherHint": "The character listed above is used as the mother.",
|
||||
"fatherId": "Father character ID",
|
||||
"fatherSelect": "Father (spouse / fiancé(e) / lover)",
|
||||
"fatherChoose": "— choose father —",
|
||||
"fatherHintList": "From this character’s relationships.",
|
||||
"fatherHintManual": "No partner in the list: enter the father’s character ID manually.",
|
||||
"fatherRequired": "Please select a father or enter the character ID.",
|
||||
"context": "Context",
|
||||
"contextMarriage": "Marriage",
|
||||
"contextLover": "Affair",
|
||||
|
||||
@@ -176,17 +176,33 @@
|
||||
"statusActive": "Embarazo hasta",
|
||||
"statusNone": "No embarazada",
|
||||
"fatherId": "ID del padre (opcional)",
|
||||
"fatherSelect": "Padre (cónyuge / prometido / amante)",
|
||||
"fatherNone": "— sin padre guardado —",
|
||||
"fatherHintList": "Según las relaciones de este personaje (matrimonio, prometido, amante activo).",
|
||||
"fatherHintManual": "Sin pareja adecuada en la base de datos: introduce manualmente el ID del padre.",
|
||||
"fatherManualPlaceholder": "ID de personaje",
|
||||
"dueDays": "Días hasta el parto previsto",
|
||||
"dueDaysHint": "0 = parto previsto hoy (el nacimiento puede seguir según la lógica del juego).",
|
||||
"force": "Establecer embarazo",
|
||||
"clear": "Quitar embarazo",
|
||||
"successForce": "Embarazo establecido.",
|
||||
"successClear": "Embarazo eliminado.",
|
||||
"error": "La acción ha fallado."
|
||||
"error": "La acción ha fallado.",
|
||||
"relationship": {
|
||||
"married": "Cónyuge",
|
||||
"engaged": "Prometido",
|
||||
"lover": "Amante"
|
||||
}
|
||||
},
|
||||
"birth": {
|
||||
"title": "Forzar nacimiento (admin)",
|
||||
"motherHint": "Se usa el personaje indicado arriba como madre.",
|
||||
"fatherId": "ID del padre",
|
||||
"fatherSelect": "Padre (cónyuge / prometido / amante)",
|
||||
"fatherChoose": "— elegir padre —",
|
||||
"fatherHintList": "Según las relaciones de este personaje.",
|
||||
"fatherHintManual": "Sin pareja en la lista: introduce el ID del padre manualmente.",
|
||||
"fatherRequired": "Elige un padre o introduce el ID de personaje.",
|
||||
"context": "Contexto",
|
||||
"contextMarriage": "Matrimonio",
|
||||
"contextLover": "Amante",
|
||||
|
||||
@@ -54,13 +54,28 @@
|
||||
<template v-else>{{ $t('admin.falukant.edituser.pregnancy.statusNone') }}</template>
|
||||
</p>
|
||||
<label class="form-field">
|
||||
{{ $t('admin.falukant.edituser.pregnancy.fatherId') }}
|
||||
<input type="number" v-model.number="adminPregnancyFatherId" min="1" placeholder="—" />
|
||||
{{ $t('admin.falukant.edituser.pregnancy.fatherSelect') }}
|
||||
<select v-if="potentialFathers.length" v-model="adminPregnancyFatherSelect">
|
||||
<option value="">{{ $t('admin.falukant.edituser.pregnancy.fatherNone') }}</option>
|
||||
<option v-for="p in potentialFathers" :key="p.characterId" :value="String(p.characterId)">
|
||||
{{ p.displayName }} — {{ fatherRelationshipLabel(p.relationshipType) }}
|
||||
</option>
|
||||
</select>
|
||||
<input
|
||||
v-else
|
||||
type="number"
|
||||
v-model.number="adminPregnancyFatherManualId"
|
||||
min="1"
|
||||
:placeholder="$t('admin.falukant.edituser.pregnancy.fatherManualPlaceholder')"
|
||||
/>
|
||||
</label>
|
||||
<p v-if="potentialFathers.length" class="admin-family-tools__hint">{{ $t('admin.falukant.edituser.pregnancy.fatherHintList') }}</p>
|
||||
<p v-else class="admin-family-tools__hint">{{ $t('admin.falukant.edituser.pregnancy.fatherHintManual') }}</p>
|
||||
<label class="form-field">
|
||||
{{ $t('admin.falukant.edituser.pregnancy.dueDays') }}
|
||||
<input type="number" v-model.number="adminDueInDays" min="1" max="365" />
|
||||
<input type="number" v-model.number="adminDueInDays" min="0" max="365" />
|
||||
</label>
|
||||
<p class="admin-family-tools__hint">{{ $t('admin.falukant.edituser.pregnancy.dueDaysHint') }}</p>
|
||||
<div class="action-buttons">
|
||||
<button type="button" @click="adminForcePregnancy">{{ $t('admin.falukant.edituser.pregnancy.force') }}</button>
|
||||
<button type="button" class="button-secondary" @click="adminClearPregnancy">{{ $t('admin.falukant.edituser.pregnancy.clear') }}</button>
|
||||
@@ -69,9 +84,24 @@
|
||||
<h4>{{ $t('admin.falukant.edituser.birth.title') }}</h4>
|
||||
<p class="admin-family-tools__hint">{{ $t('admin.falukant.edituser.birth.motherHint') }}</p>
|
||||
<label class="form-field">
|
||||
{{ $t('admin.falukant.edituser.birth.fatherId') }} *
|
||||
<input type="number" v-model.number="adminBirthFatherId" min="1" required />
|
||||
{{ $t('admin.falukant.edituser.birth.fatherSelect') }} *
|
||||
<select v-if="potentialFathers.length" v-model="adminBirthFatherSelect">
|
||||
<option value="">{{ $t('admin.falukant.edituser.birth.fatherChoose') }}</option>
|
||||
<option v-for="p in potentialFathers" :key="'b-' + p.characterId" :value="String(p.characterId)">
|
||||
{{ p.displayName }} — {{ fatherRelationshipLabel(p.relationshipType) }}
|
||||
</option>
|
||||
</select>
|
||||
<input
|
||||
v-else
|
||||
type="number"
|
||||
v-model.number="adminBirthFatherManualId"
|
||||
min="1"
|
||||
required
|
||||
:placeholder="$t('admin.falukant.edituser.pregnancy.fatherManualPlaceholder')"
|
||||
/>
|
||||
</label>
|
||||
<p v-if="potentialFathers.length" class="admin-family-tools__hint">{{ $t('admin.falukant.edituser.birth.fatherHintList') }}</p>
|
||||
<p v-else class="admin-family-tools__hint">{{ $t('admin.falukant.edituser.birth.fatherHintManual') }}</p>
|
||||
<label class="form-field">
|
||||
{{ $t('admin.falukant.edituser.birth.context') }}
|
||||
<select v-model="adminBirthContext">
|
||||
@@ -220,9 +250,12 @@ export default {
|
||||
branches: false,
|
||||
stockTypes: false
|
||||
},
|
||||
adminPregnancyFatherId: null,
|
||||
potentialFathers: [],
|
||||
adminPregnancyFatherSelect: '',
|
||||
adminPregnancyFatherManualId: null,
|
||||
adminDueInDays: 21,
|
||||
adminBirthFatherId: null,
|
||||
adminBirthFatherSelect: '',
|
||||
adminBirthFatherManualId: null,
|
||||
adminBirthContext: 'marriage',
|
||||
adminBirthLegitimacy: 'legitimate',
|
||||
adminBirthGender: ''
|
||||
@@ -300,6 +333,12 @@ export default {
|
||||
this.originalAge = this.age;
|
||||
this.users = [];
|
||||
this.activeTab = 'userdata';
|
||||
this.adminPregnancyFatherSelect = '';
|
||||
this.adminPregnancyFatherManualId = null;
|
||||
this.adminBirthFatherSelect = '';
|
||||
this.adminBirthFatherManualId = null;
|
||||
await this.loadPotentialFathers();
|
||||
this.syncFatherSelectionsFromCharacter();
|
||||
},
|
||||
async saveUser() {
|
||||
const dataToChange = {
|
||||
@@ -432,11 +471,61 @@ export default {
|
||||
this.originalUser = JSON.parse(JSON.stringify(this.editableUser));
|
||||
this.age = Math.floor((Date.now() - new Date(this.editableUser.falukantData[0].character.birthdate)) / (24 * 60 * 60 * 1000));
|
||||
this.originalAge = this.age;
|
||||
await this.loadPotentialFathers();
|
||||
this.syncFatherSelectionsFromCharacter();
|
||||
},
|
||||
fatherRelationshipLabel(relationshipType) {
|
||||
const key = `admin.falukant.edituser.pregnancy.relationship.${relationshipType}`;
|
||||
const t = this.$t(key);
|
||||
return t === key ? relationshipType : t;
|
||||
},
|
||||
async loadPotentialFathers() {
|
||||
const cid = this.editableUser?.falukantData?.[0]?.character?.id;
|
||||
if (!cid) {
|
||||
this.potentialFathers = [];
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const r = await apiClient.get(`/api/admin/falukant/character/${cid}/potential-fathers`);
|
||||
this.potentialFathers = Array.isArray(r.data?.options) ? r.data.options : [];
|
||||
} catch (e) {
|
||||
console.error('loadPotentialFathers', e);
|
||||
this.potentialFathers = [];
|
||||
}
|
||||
},
|
||||
syncFatherSelectionsFromCharacter() {
|
||||
const c = this.editableUser?.falukantData?.[0]?.character;
|
||||
if (!c) return;
|
||||
const pf = c.pregnancyFatherCharacterId ?? c.pregnancy_father_character_id;
|
||||
if (pf != null && this.potentialFathers.some((x) => x.characterId === Number(pf))) {
|
||||
this.adminPregnancyFatherSelect = String(pf);
|
||||
}
|
||||
},
|
||||
resolvePregnancyFatherCharacterId() {
|
||||
if (this.potentialFathers.length) {
|
||||
return this.adminPregnancyFatherSelect ? Number(this.adminPregnancyFatherSelect) : null;
|
||||
}
|
||||
return this.adminPregnancyFatherManualId ? Number(this.adminPregnancyFatherManualId) : null;
|
||||
},
|
||||
resolveBirthFatherCharacterId() {
|
||||
if (this.potentialFathers.length) {
|
||||
return this.adminBirthFatherSelect ? Number(this.adminBirthFatherSelect) : null;
|
||||
}
|
||||
return this.adminBirthFatherManualId ? Number(this.adminBirthFatherManualId) : null;
|
||||
},
|
||||
resolveDueInDays() {
|
||||
const raw = this.adminDueInDays;
|
||||
if (raw === '' || raw === null || raw === undefined) {
|
||||
return 21;
|
||||
}
|
||||
const n = Number(raw);
|
||||
return Number.isFinite(n) ? n : 21;
|
||||
},
|
||||
async adminForcePregnancy() {
|
||||
const characterId = this.editableUser.falukantData[0].character.id;
|
||||
const payload = { characterId, dueInDays: Number(this.adminDueInDays) || 21 };
|
||||
if (this.adminPregnancyFatherId) payload.fatherCharacterId = Number(this.adminPregnancyFatherId);
|
||||
const payload = { characterId, dueInDays: this.resolveDueInDays() };
|
||||
const fatherId = this.resolvePregnancyFatherCharacterId();
|
||||
if (fatherId != null) payload.fatherCharacterId = fatherId;
|
||||
try {
|
||||
await apiClient.post('/api/admin/falukant/character/force-pregnancy', payload);
|
||||
showSuccess(this, 'tr:admin.falukant.edituser.pregnancy.successForce');
|
||||
@@ -457,13 +546,14 @@ export default {
|
||||
},
|
||||
async adminForceBirth() {
|
||||
const motherCharacterId = this.editableUser.falukantData[0].character.id;
|
||||
if (!this.adminBirthFatherId) {
|
||||
showError(this, this.$t('admin.falukant.edituser.birth.fatherId'));
|
||||
const fatherCharacterId = this.resolveBirthFatherCharacterId();
|
||||
if (fatherCharacterId == null || Number.isNaN(fatherCharacterId)) {
|
||||
showError(this, this.$t('admin.falukant.edituser.birth.fatherRequired'));
|
||||
return;
|
||||
}
|
||||
const body = {
|
||||
motherCharacterId,
|
||||
fatherCharacterId: Number(this.adminBirthFatherId),
|
||||
fatherCharacterId,
|
||||
birthContext: this.adminBirthContext,
|
||||
legitimacy: this.adminBirthLegitimacy
|
||||
};
|
||||
|
||||
@@ -73,6 +73,12 @@
|
||||
<span class="title-label">{{ lesson.title }}</span>
|
||||
<span v-if="lesson.description" class="lesson-description">{{ lesson.description }}</span>
|
||||
</div>
|
||||
<div class="lesson-pedagogy" v-if="lesson.pedagogy">
|
||||
<span class="lesson-chip lesson-chip--phase">{{ getPhaseLabel(lesson.pedagogy.phaseLabel) }}</span>
|
||||
<span class="lesson-chip lesson-chip--mode">{{ getDidacticModeLabel(lesson.pedagogy.didacticMode) }}</span>
|
||||
<span v-if="lesson.pedagogy.blockNumber" class="lesson-chip lesson-chip--block">Block {{ lesson.pedagogy.blockNumber }}</span>
|
||||
<span v-if="lesson.pedagogy.isIntensiveReview" class="lesson-chip lesson-chip--intensive">Intensive Wiederholung</span>
|
||||
</div>
|
||||
<div class="lesson-actions-content">
|
||||
<button
|
||||
@click="openLesson(lesson.id)"
|
||||
@@ -328,6 +334,36 @@ export default {
|
||||
openLanguageAssistantSettings() {
|
||||
this.$router.push('/settings/language-assistant');
|
||||
},
|
||||
getPhaseLabel(phaseLabel) {
|
||||
switch (phaseLabel) {
|
||||
case 'quickstart':
|
||||
return 'Schnellstart';
|
||||
case 'daily_life':
|
||||
return 'Alltag';
|
||||
case 'stabilization':
|
||||
return 'Stabilisierung';
|
||||
default:
|
||||
return 'Lernphase';
|
||||
}
|
||||
},
|
||||
getDidacticModeLabel(didacticMode) {
|
||||
switch (didacticMode) {
|
||||
case 'core_input':
|
||||
return 'Neuer Stoff';
|
||||
case 'guided_dialogue':
|
||||
return 'Geführter Dialog';
|
||||
case 'pattern_drill':
|
||||
return 'Mustertraining';
|
||||
case 'real_life_scenario':
|
||||
return 'Alltagsszenario';
|
||||
case 'intensive_review':
|
||||
return 'Wiederholungsphase';
|
||||
case 'checkpoint':
|
||||
return 'Checkpoint';
|
||||
default:
|
||||
return 'Lerneinheit';
|
||||
}
|
||||
},
|
||||
editLesson() {
|
||||
showInfo(this, 'Die Bearbeitung einzelner Lektionen folgt noch.');
|
||||
}
|
||||
@@ -517,6 +553,42 @@ export default {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.lesson-pedagogy {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.lesson-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.lesson-chip--phase {
|
||||
background: rgba(120, 195, 138, 0.16);
|
||||
color: #42634e;
|
||||
}
|
||||
|
||||
.lesson-chip--mode {
|
||||
background: rgba(248, 162, 43, 0.16);
|
||||
color: #8a5411;
|
||||
}
|
||||
|
||||
.lesson-chip--block {
|
||||
background: rgba(93, 64, 55, 0.09);
|
||||
color: #6d5446;
|
||||
}
|
||||
|
||||
.lesson-chip--intensive {
|
||||
background: rgba(207, 78, 78, 0.14);
|
||||
color: #a13f3f;
|
||||
}
|
||||
|
||||
.lesson-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -43,6 +43,14 @@
|
||||
<span class="lesson-meta-label">{{ $t('socialnetwork.vocab.courses.lessonTypeLabel') }}</span>
|
||||
<strong>{{ getLessonTypeLabel(lesson.lessonType) }}</strong>
|
||||
</div>
|
||||
<div class="lesson-meta-item" v-if="lessonPedagogy.phaseLabel">
|
||||
<span class="lesson-meta-label">Phase</span>
|
||||
<strong>{{ getPhaseLabel(lessonPedagogy.phaseLabel) }}</strong>
|
||||
</div>
|
||||
<div class="lesson-meta-item" v-if="lessonPedagogy.didacticMode">
|
||||
<span class="lesson-meta-label">Fokus</span>
|
||||
<strong>{{ getDidacticModeLabel(lessonPedagogy.didacticMode) }}</strong>
|
||||
</div>
|
||||
<div class="lesson-meta-item">
|
||||
<span class="lesson-meta-label">{{ $t('socialnetwork.vocab.courses.recommendedDuration') }}</span>
|
||||
<strong>{{ formatTargetMinutes(lesson.targetMinutes) }}</strong>
|
||||
@@ -51,9 +59,22 @@
|
||||
<span class="lesson-meta-label">{{ $t('socialnetwork.vocab.courses.exerciseLoad') }}</span>
|
||||
<strong>{{ effectiveExercises?.length || 0 }} {{ $t('socialnetwork.vocab.courses.exercisesShort') }}</strong>
|
||||
</div>
|
||||
<div class="lesson-meta-item" v-if="lessonPedagogy.newUnitTarget">
|
||||
<span class="lesson-meta-label">Neue Einheiten</span>
|
||||
<strong>{{ lessonPedagogy.newUnitTarget }}</strong>
|
||||
</div>
|
||||
<div class="lesson-meta-item" v-if="lessonPedagogy.reviewWeight != null">
|
||||
<span class="lesson-meta-label">Wiederholung</span>
|
||||
<strong>{{ lessonPedagogy.reviewWeight }}%</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="lessonPedagogy.isIntensiveReview" class="lesson-intensity-banner">
|
||||
<strong>Intensive Wiederholungsphase</strong>
|
||||
<p>Diese Lektion priorisiert Wiederholung und Vertiefung. Neuer Stoff wird bewusst reduziert, damit vorhandene Muster stabil werden.</p>
|
||||
</div>
|
||||
|
||||
<div class="learn-grid">
|
||||
<div v-if="lesson && lesson.description" class="lesson-description-box">
|
||||
<h4>{{ $t('socialnetwork.vocab.courses.lessonDescription') }}</h4>
|
||||
@@ -872,6 +893,17 @@ export default {
|
||||
practicalTasks: []
|
||||
};
|
||||
},
|
||||
lessonPedagogy() {
|
||||
return this.lesson?.pedagogy || {
|
||||
didacticMode: null,
|
||||
phaseLabel: null,
|
||||
blockNumber: null,
|
||||
difficultyWeight: null,
|
||||
newUnitTarget: null,
|
||||
reviewWeight: null,
|
||||
isIntensiveReview: false
|
||||
};
|
||||
},
|
||||
assistantAvailable() {
|
||||
if (!this.assistantSettings) {
|
||||
return false;
|
||||
@@ -1280,6 +1312,36 @@ export default {
|
||||
};
|
||||
return labels[lessonType] || lessonType || this.$t('socialnetwork.vocab.courses.lessonTypeVocab');
|
||||
},
|
||||
getPhaseLabel(phaseLabel) {
|
||||
switch (phaseLabel) {
|
||||
case 'quickstart':
|
||||
return 'Schnellstart';
|
||||
case 'daily_life':
|
||||
return 'Alltag';
|
||||
case 'stabilization':
|
||||
return 'Stabilisierung';
|
||||
default:
|
||||
return 'Lernphase';
|
||||
}
|
||||
},
|
||||
getDidacticModeLabel(didacticMode) {
|
||||
switch (didacticMode) {
|
||||
case 'core_input':
|
||||
return 'Neuer Stoff';
|
||||
case 'guided_dialogue':
|
||||
return 'Geführter Dialog';
|
||||
case 'pattern_drill':
|
||||
return 'Mustertraining';
|
||||
case 'real_life_scenario':
|
||||
return 'Alltagsszenario';
|
||||
case 'intensive_review':
|
||||
return 'Wiederholungsphase';
|
||||
case 'checkpoint':
|
||||
return 'Checkpoint';
|
||||
default:
|
||||
return 'Lernfokus';
|
||||
}
|
||||
},
|
||||
formatTargetMinutes(targetMinutes) {
|
||||
const minutes = Number(targetMinutes);
|
||||
if (!minutes) {
|
||||
@@ -2187,6 +2249,24 @@ export default {
|
||||
color: #7a6848;
|
||||
}
|
||||
|
||||
.lesson-intensity-banner {
|
||||
margin-bottom: 18px;
|
||||
padding: 14px 16px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(207, 78, 78, 0.24);
|
||||
background: rgba(255, 242, 242, 0.95);
|
||||
color: #8e3d3d;
|
||||
}
|
||||
|
||||
.lesson-intensity-banner strong,
|
||||
.lesson-intensity-banner p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.lesson-intensity-banner p {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.learn-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user