diff --git a/frontend/src/components/CourtDrawingDialog.vue b/frontend/src/components/CourtDrawingDialog.vue
index ae60af9d..61375208 100644
--- a/frontend/src/components/CourtDrawingDialog.vue
+++ b/frontend/src/components/CourtDrawingDialog.vue
@@ -14,6 +14,31 @@
@update-drawing-data="handleDrawingDataUpdate"
@update-fields="handleFieldsUpdate"
/>
+
+
+
+
+
+
@@ -58,23 +83,57 @@ export default {
initialDescription: {
type: String,
default: null
+ },
+ showDiaryFields: {
+ type: Boolean,
+ default: false
+ },
+ showGroupSelect: {
+ type: Boolean,
+ default: false
+ },
+ groups: {
+ type: Array,
+ default: () => []
+ },
+ initialDuration: {
+ type: [Number, String, null],
+ default: null
+ },
+ initialDurationText: {
+ type: String,
+ default: ''
+ },
+ initialGroupId: {
+ type: [String, Number, null],
+ default: ''
}
},
emits: ['update:modelValue', 'close', 'ok'],
data() {
return {
currentDrawingData: null,
- currentFields: null
+ currentFields: null,
+ diaryFields: {
+ duration: null,
+ durationText: '',
+ groupId: ''
+ }
};
},
computed: {
isValid() {
// Mindestens Aufschlag und Zielposition müssen gesetzt sein
- return this.currentDrawingData &&
+ const drawingValid = this.currentDrawingData &&
this.currentDrawingData.selectedStartPosition &&
this.currentDrawingData.strokeType &&
this.currentDrawingData.spinType &&
this.currentDrawingData.targetPosition;
+ if (!drawingValid) return false;
+ if (this.showGroupSelect) {
+ return Boolean(this.diaryFields.groupId);
+ }
+ return true;
}
},
watch: {
@@ -98,6 +157,14 @@ export default {
description: this.initialDescription || ''
};
}
+ this.diaryFields = {
+ duration: this.initialDuration ?? null,
+ durationText: this.initialDurationText || '',
+ groupId: this.initialGroupId !== null && this.initialGroupId !== undefined ? String(this.initialGroupId) : ''
+ };
+ if (this.diaryFields.durationText) {
+ this.calculateDurationFromText();
+ }
this.$nextTick(() => {
// Warte bis der Dialog vollständig gerendert ist
setTimeout(() => {
@@ -109,6 +176,11 @@ export default {
} else {
// Dialog wird geschlossen - Felder zurücksetzen
this.currentFields = null;
+ this.diaryFields = {
+ duration: null,
+ durationText: '',
+ groupId: ''
+ };
}
}
},
@@ -125,6 +197,33 @@ export default {
}
},
methods: {
+ calculateDurationFromText() {
+ const input = this.diaryFields.durationText;
+ if (!input || !input.trim()) {
+ this.diaryFields.duration = null;
+ return;
+ }
+
+ const normalized = input.replace(/\s+/g, '').replace(/\*/g, 'x');
+ let total = 0;
+
+ for (const part of normalized.split('+')) {
+ if (!part) continue;
+ if (part.includes('x')) {
+ const [count, minutes] = part.split('x').map(Number);
+ if (Number.isFinite(count) && Number.isFinite(minutes)) {
+ total += count * minutes;
+ }
+ } else {
+ const minutes = Number(part);
+ if (Number.isFinite(minutes)) {
+ total += minutes;
+ }
+ }
+ }
+
+ this.diaryFields.duration = total > 0 ? total : null;
+ },
handleDrawingDataUpdate(data) {
this.currentDrawingData = { ...data };
},
@@ -140,7 +239,16 @@ export default {
// Sammle alle Daten zusammen
const result = {
drawingData: { ...this.currentDrawingData },
- fields: this.currentFields ? { ...this.currentFields } : null,
+ fields: this.currentFields ? {
+ ...this.currentFields,
+ duration: this.diaryFields.duration,
+ durationText: this.diaryFields.durationText,
+ groupId: this.diaryFields.groupId
+ } : {
+ duration: this.diaryFields.duration,
+ durationText: this.diaryFields.durationText,
+ groupId: this.diaryFields.groupId
+ },
code: this.currentDrawingData.code || (this.currentFields ? this.currentFields.code : ''),
name: this.currentFields ? this.currentFields.name : '',
description: this.currentFields ? this.currentFields.description : ''
@@ -190,4 +298,27 @@ export default {
background: var(--surface-muted);
border-color: var(--primary-soft);
}
+
+.diary-fields {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
+ gap: 0.75rem;
+ margin-top: 1rem;
+ padding-top: 1rem;
+ border-top: 1px solid var(--border-color);
+}
+
+.diary-field {
+ display: flex;
+ flex-direction: column;
+ gap: 0.35rem;
+ color: var(--text-color);
+ font-size: 0.875rem;
+ font-weight: 600;
+}
+
+.diary-field input,
+.diary-field select {
+ width: 100%;
+}
diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json
index c183ccfe..92c09f82 100644
--- a/frontend/src/i18n/locales/de.json
+++ b/frontend/src/i18n/locales/de.json
@@ -1840,7 +1840,12 @@
"courtDrawing": {
"title": "Tischtennis-Übung konfigurieren",
"cancel": "Abbrechen",
- "ok": "OK"
+ "ok": "OK",
+ "durationMinutes": "Dauer (Minuten)",
+ "durationText": "Dauer (Text)",
+ "durationTextPlaceholder": "z.B. 2x5",
+ "group": "Gruppe",
+ "selectGroup": "Gruppe auswählen..."
},
"imageDialog": {
"title": "Bild",
diff --git a/frontend/src/i18n/locales/en-GB.json b/frontend/src/i18n/locales/en-GB.json
index 03f40ed3..17813545 100644
--- a/frontend/src/i18n/locales/en-GB.json
+++ b/frontend/src/i18n/locales/en-GB.json
@@ -141,6 +141,16 @@
"filterStandard": "Standard activities",
"filterCustom": "Custom"
},
+ "courtDrawing": {
+ "title": "Configure table tennis exercise",
+ "cancel": "Cancel",
+ "ok": "OK",
+ "durationMinutes": "Duration (minutes)",
+ "durationText": "Duration (text)",
+ "durationTextPlaceholder": "e.g. 2x5",
+ "group": "Group",
+ "selectGroup": "Select group..."
+ },
"tournaments": {
"numberOfTables": "Number of tables",
"table": "Table",
diff --git a/frontend/src/views/DiaryView.vue b/frontend/src/views/DiaryView.vue
index 2cdc7244..3feff2bf 100644
--- a/frontend/src/views/DiaryView.vue
+++ b/frontend/src/views/DiaryView.vue
@@ -299,7 +299,7 @@
@@ -2819,6 +2825,8 @@ export default {
name: result.name || (result.fields && result.fields.name) || this.editingGroupActivity.groupPredefinedActivity.name || '',
code: code,
description: result.description || (result.fields && result.fields.description) || this.editingGroupActivity.groupPredefinedActivity.description || '',
+ durationText: (result.fields && result.fields.durationText) || this.editingGroupActivity.groupPredefinedActivity.durationText || '',
+ duration: (result.fields && result.fields.duration) || this.editingGroupActivity.groupPredefinedActivity.duration || null,
drawingData: result.drawingData || null
};
@@ -2841,8 +2849,8 @@ export default {
name: result.name || (result.fields && result.fields.name) || this.editingGroupActivity.groupPredefinedActivity.name || '',
code: code,
description: result.description || (result.fields && result.fields.description) || this.editingGroupActivity.groupPredefinedActivity.description || '',
- durationText: this.editingGroupActivity.groupPredefinedActivity.durationText || '',
- duration: this.editingGroupActivity.groupPredefinedActivity.duration || null,
+ durationText: (result.fields && result.fields.durationText) || this.editingGroupActivity.groupPredefinedActivity.durationText || '',
+ duration: (result.fields && result.fields.duration) || this.editingGroupActivity.groupPredefinedActivity.duration || null,
imageLink: this.editingGroupActivity.groupPredefinedActivity.imageLink || '',
drawingData: result.drawingData || null
};
@@ -2900,6 +2908,8 @@ export default {
name: result.name || (result.fields && result.fields.name) || '',
code: code,
description: result.description || (result.fields && result.fields.description) || '',
+ durationText: (result.fields && result.fields.durationText) || '',
+ duration: (result.fields && result.fields.duration) || null,
drawingData: result.drawingData || null
};
@@ -2909,6 +2919,15 @@ export default {
// Setze die Aktivität im Formular
this.chooseNewItemSuggestion(activityToUse);
+ if (result.fields && result.fields.duration !== undefined && result.fields.duration !== null && result.fields.duration !== '') {
+ this.newPlanItem.duration = result.fields.duration;
+ }
+ if (result.fields && typeof result.fields.durationText === 'string') {
+ this.newPlanItem.durationText = result.fields.durationText;
+ }
+ if (this.addNewGroupActivity && result.fields && result.fields.groupId) {
+ this.newPlanItem.groupId = String(result.fields.groupId);
+ }
// Erstelle automatisch den Plan-Eintrag
await this.addPlanItem();