feat(vocab): implement user vocab lesson progress reset functionality
All checks were successful
Deploy to production / deploy (push) Successful in 2m59s
All checks were successful
Deploy to production / deploy (push) Successful in 2m59s
- Added `resetUserVocabLessonProgress` method in `AdminController` to allow admins to reset a user's progress for a specific vocab lesson. - Introduced corresponding route in `adminRouter` for the new reset functionality. - Enhanced `VocabService` with methods to purge lesson progress for users, ensuring that only the specified lesson's progress is affected. - Updated UI components in `UsersView` to facilitate the selection of courses and lessons for resetting progress, including confirmation dialogs and loading states. - Added localization support for the new reset functionality across multiple languages. - Implemented reset functionality in `VocabLessonView` for users to reset their own lesson progress.
This commit is contained in:
@@ -5,6 +5,14 @@
|
||||
<div class="lesson-header">
|
||||
<button @click="back" class="btn-back">{{ $t('general.back') }}</button>
|
||||
<h2>{{ lesson.title }}</h2>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-reset-lesson"
|
||||
:disabled="resettingLessonProgress"
|
||||
@click="confirmResetLessonProgress"
|
||||
>
|
||||
{{ resettingLessonProgress ? $t('general.loading') : $t('socialnetwork.vocab.courses.resetLessonProgress') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Tabs für Lernen und Übungen -->
|
||||
@@ -942,7 +950,8 @@ export default {
|
||||
lessonStatePersistenceReady: false,
|
||||
lessonStateSaveTimer: null,
|
||||
lessonStateSaveInFlight: false,
|
||||
pendingLessonStatePayload: null
|
||||
pendingLessonStatePayload: null,
|
||||
resettingLessonProgress: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -1373,6 +1382,44 @@ export default {
|
||||
const userId = this.user?.id || 'guest';
|
||||
return `vocab-lesson-state:${LESSON_STATE_VERSION}:${userId}:${this.courseId}:${this.lessonId}`;
|
||||
},
|
||||
clearLocalLessonStateCache() {
|
||||
const storageKey = this.getLessonStateStorageKey();
|
||||
if (!storageKey) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
window.localStorage.removeItem(storageKey);
|
||||
} catch (error) {
|
||||
console.warn('[VocabLessonView] Lokaler Lektions-Cache konnte nicht gelöscht werden:', error);
|
||||
}
|
||||
},
|
||||
confirmResetLessonProgress() {
|
||||
if (!this.lessonId || this.resettingLessonProgress) {
|
||||
return;
|
||||
}
|
||||
if (!window.confirm(this.$t('socialnetwork.vocab.courses.resetLessonProgressConfirm'))) {
|
||||
return;
|
||||
}
|
||||
this.resetLessonProgressOnServer();
|
||||
},
|
||||
async resetLessonProgressOnServer() {
|
||||
if (!this.lessonId || this.resettingLessonProgress) {
|
||||
return;
|
||||
}
|
||||
this.resettingLessonProgress = true;
|
||||
try {
|
||||
await apiClient.delete(`/api/vocab/lessons/${this.lessonId}/progress`);
|
||||
this.clearLocalLessonStateCache();
|
||||
this.$root?.$refs?.messageDialog?.open?.('tr:socialnetwork.vocab.courses.resetLessonProgressSuccess');
|
||||
await this.loadLesson();
|
||||
} catch (e) {
|
||||
console.error('[VocabLessonView] Lektion zurücksetzen fehlgeschlagen:', e);
|
||||
const msg = e?.response?.data?.error || this.$t('socialnetwork.vocab.courses.resetLessonProgressError');
|
||||
this.$root?.$refs?.messageDialog?.open?.(msg);
|
||||
} finally {
|
||||
this.resettingLessonProgress = false;
|
||||
}
|
||||
},
|
||||
buildPersistedLessonState() {
|
||||
return {
|
||||
version: LESSON_STATE_VERSION,
|
||||
@@ -3104,6 +3151,29 @@ export default {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.lesson-header h2 {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.btn-reset-lesson {
|
||||
flex-shrink: 0;
|
||||
padding: 8px 14px;
|
||||
border: 1px solid rgba(140, 90, 60, 0.35);
|
||||
border-radius: 4px;
|
||||
background: rgba(255, 248, 240, 0.95);
|
||||
color: #6b4420;
|
||||
cursor: pointer;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.btn-reset-lesson:disabled {
|
||||
opacity: 0.65;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.lesson-overview-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user