-
-
-
+
{{ $t('diary.trainingPlan') }}
+
@@ -761,6 +739,8 @@ import MemberActivityStatsDialog from '../components/MemberActivityStatsDialog.v
import AccidentFormDialog from '../components/AccidentFormDialog.vue';
import QuickAddMemberDialog from '../components/QuickAddMemberDialog.vue';
import MemberGalleryDialog from '../components/MemberGalleryDialog.vue';
+import DiaryParticipantsPanel from '../components/DiaryParticipantsPanel.vue';
+import DiaryActivitiesPanel from '../components/DiaryActivitiesPanel.vue';
import {
connectSocket,
disconnectSocket,
@@ -807,7 +787,9 @@ export default {
MemberActivityStatsDialog,
AccidentFormDialog,
QuickAddMemberDialog,
- MemberGalleryDialog
+ MemberGalleryDialog,
+ DiaryParticipantsPanel,
+ DiaryActivitiesPanel
},
data() {
return {
@@ -878,7 +860,9 @@ export default {
addNewItem: false,
addNewGroupActivity: false,
addNewTimeblock: false,
- showGeneralData: false,
+ showTrainingDayPanel: true,
+ showDetailsPanel: false,
+ showGroupsPanel: false,
editingGroupId: null,
doMemberTagUpdates: true,
showTagHistoryModal: false,
@@ -937,7 +921,10 @@ export default {
// Court Drawing Dialog
showDrawingDialog: false,
// Tab-Navigation für Mobile
- activeTab: 'plan' // 'plan', 'members', 'activities'
+ activeTab: 'plan', // 'plan', 'members', 'activities'
+ isMobileView: typeof window !== 'undefined' ? window.innerWidth <= 768 : false,
+ participantSearchQuery: '',
+ participantFilter: 'all'
};
},
watch: {
@@ -978,6 +965,71 @@ export default {
const presentSet = new Set(this.participants);
return this.members.filter(m => presentSet.has(m.id));
},
+ timeblockCount() {
+ return (this.trainingPlan || []).filter(item => item && item.isTimeblock).length;
+ },
+ standalonePlanItemCount() {
+ return (this.trainingPlan || []).filter(item => item && !item.isTimeblock).length;
+ },
+ activePlanEditorType() {
+ if (this.editingActivityId) return 'activity';
+ if (this.editingGroupActivityId) return 'groupActivity';
+ return null;
+ },
+ activePlanEditorItem() {
+ if (this.editingActivityId) {
+ return (this.trainingPlan || []).find(item => Number(item.id) === Number(this.editingActivityId)) || null;
+ }
+ if (this.editingGroupActivityId) {
+ for (const item of this.trainingPlan || []) {
+ const match = (item.groupActivities || []).find(groupItem => Number(groupItem.id) === Number(this.editingGroupActivityId));
+ if (match) return match;
+ }
+ }
+ return null;
+ },
+ activeAssignmentType() {
+ if (this.activityMembersOpenId) return 'activity';
+ if (this.groupActivityMembersOpenId) return 'groupActivity';
+ return null;
+ },
+ activeAssignmentItem() {
+ if (this.activityMembersOpenId) {
+ return (this.trainingPlan || []).find(item => Number(item.id) === Number(this.activityMembersOpenId)) || null;
+ }
+ if (this.groupActivityMembersOpenId) {
+ for (const item of this.trainingPlan || []) {
+ const match = (item.groupActivities || []).find(groupItem => Number(groupItem.id) === Number(this.groupActivityMembersOpenId));
+ if (match) return match;
+ }
+ }
+ return null;
+ },
+ filteredDiaryMembers() {
+ const search = (this.participantSearchQuery || '').trim().toLowerCase();
+
+ return this.sortedMembers().filter(member => {
+ const isPresent = this.isParticipant(member.id);
+
+ if (this.participantFilter === 'present' && !isPresent) return false;
+ if (this.participantFilter === 'absent' && isPresent) return false;
+ if (this.participantFilter === 'test' && !member.testMembership) return false;
+
+ if (!search) return true;
+
+ const haystack = [
+ member.firstName,
+ member.lastName,
+ member.phone,
+ member.email
+ ]
+ .filter(Boolean)
+ .join(' ')
+ .toLowerCase();
+
+ return haystack.includes(search);
+ });
+ },
isNewMemberValid() {
return this.newMember.firstName.trim() !== '' &&
@@ -997,8 +1049,52 @@ export default {
// Kann gelöscht werden wenn alle Listen leer sind
return !hasTrainingPlan && !hasParticipants && !hasActivities && !hasAccidents && !hasNotes;
},
+ diaryTimeRangeLabel() {
+ if (this.trainingStart && this.trainingEnd) {
+ return `${this.trainingStart} - ${this.trainingEnd}`;
+ }
+ if (this.trainingStart) {
+ return this.trainingStart;
+ }
+ if (this.trainingEnd) {
+ return this.trainingEnd;
+ }
+ return this.$t('diary.trainingWindowUnset');
+ },
+ normalizedNextStartTime() {
+ const raw = this.calculateNextTime;
+ if (!raw) return '–';
+ const value = String(raw);
+ return value.length >= 5 ? value.slice(0, 5) : value;
+ },
+ diaryStatusText() {
+ if (!this.date) {
+ return this.$t('diary.noActiveTrainingDay');
+ }
+
+ const hasTimes = Boolean(this.trainingStart || this.trainingEnd);
+ const hasParticipants = this.participants.length > 0;
+ const hasPlan = this.trainingPlan.length > 0;
+ const hasActivities = this.activities.length > 0;
+
+ if (hasTimes && hasParticipants && hasPlan) {
+ return this.$t('diary.statusReady');
+ }
+
+ if (!hasParticipants && !hasPlan && !hasActivities && !hasTimes) {
+ return this.$t('diary.statusEmpty');
+ }
+
+ return this.$t('diary.statusInProgress');
+ }
},
methods: {
+ isDiaryDayConfigured() {
+ const hasTimes = Boolean(this.trainingStart || this.trainingEnd);
+ const hasParticipants = Array.isArray(this.participants) && this.participants.length > 0;
+ const hasPlan = Array.isArray(this.trainingPlan) && this.trainingPlan.length > 0;
+ return hasTimes && hasParticipants && hasPlan;
+ },
// Dialog Helper Methods
async showInfo(title, message, details = '', type = 'info') {
this.infoDialog = {
@@ -1261,7 +1357,9 @@ export default {
this.calculateIntermediateTimes();
this.initializeSortable();
await this.loadGroups();
- this.showGeneralData = false;
+ this.showTrainingDayPanel = !this.isDiaryDayConfigured();
+ this.showDetailsPanel = false;
+ this.showGroupsPanel = false;
this.startCheckingTime();
} else {
this.newDate = '';
@@ -2234,12 +2332,14 @@ export default {
this.addNewTimeblock = false;
this.selectedTimeblockId = timeblockId;
},
- toggleShowGeneralData() {
- this.showGeneralData = !this.showGeneralData;
- },
getFormattedDate(date) {
return (new Date(date)).toLocaleDateString('de-DE', { year: 'numeric', month: '2-digit', day: '2-digit' });
},
+ formatDisplayTime(timeValue) {
+ if (!timeValue) return '';
+ const value = String(timeValue);
+ return value.length >= 5 ? value.slice(0, 5) : value;
+ },
editGroup(groupId) {
this.editingGroupId = groupId;
},
@@ -2788,6 +2888,17 @@ export default {
this.editShowDropdown = false;
this.editSearchResults = [];
},
+ cancelCurrentPlanEdit() {
+ if (this.activePlanEditorType === 'groupActivity') {
+ this.cancelGroupActivityEdit();
+ return;
+ }
+ this.cancelActivityEdit();
+ },
+ closeCurrentAssignmentPanel() {
+ this.activityMembersOpenId = null;
+ this.groupActivityMembersOpenId = null;
+ },
async loadTrainingPlan() {
try {
@@ -3393,6 +3504,9 @@ export default {
}
}
},
+ updateViewportState() {
+ this.isMobileView = typeof window !== 'undefined' ? window.innerWidth <= 768 : false;
+ }
},
async mounted() {
await this.init();
@@ -3411,6 +3525,7 @@ export default {
window.removeEventListener('click', tryInit, { once: true });
};
window.addEventListener('click', tryInit, { once: true });
+ window.addEventListener('resize', this.updateViewportState);
},
beforeUnmount() {
if (this.timeChecker) {
@@ -3422,6 +3537,7 @@ export default {
// Socket.IO trennen
disconnectSocket();
+ window.removeEventListener('resize', this.updateViewportState);
}
};
@@ -3435,6 +3551,105 @@ form div {
margin-bottom: 10px;
}
+.diary-general-card {
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+ padding: 1rem 1.25rem;
+ border: 1px solid #d9e4ec;
+ border-radius: 12px;
+ background: #f9fbfd;
+}
+
+.diary-general-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 1rem;
+}
+
+.diary-general-header h3 {
+ margin: 0.2rem 0 0;
+}
+
+.diary-general-label {
+ font-size: 0.8rem;
+ font-weight: 700;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+ color: #517287;
+}
+
+.diary-general-stats {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1rem;
+ margin-top: 0.9rem;
+}
+
+.diary-general-stat {
+ min-width: 130px;
+}
+
+.diary-general-stat span {
+ display: block;
+ font-size: 0.76rem;
+ font-weight: 700;
+ letter-spacing: 0.03em;
+ text-transform: uppercase;
+ color: #5f7b8b;
+}
+
+.diary-general-form {
+ margin-top: 1rem;
+}
+
+.diary-overview-panels {
+ display: flex;
+ flex-direction: column;
+ gap: 0.85rem;
+ margin-bottom: 1rem;
+}
+
+.diary-toggle-card {
+ border: 1px solid #d9e4ec;
+ border-radius: 12px;
+ background: #f9fbfd;
+ overflow: hidden;
+}
+
+.diary-toggle-head {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 1rem;
+ padding: 0.95rem 1.15rem;
+ background: transparent;
+ border: none;
+ cursor: pointer;
+ text-align: left;
+}
+
+.diary-toggle-symbol {
+ font-size: 1.4rem;
+ line-height: 1;
+ color: #315066;
+}
+
+.diary-toggle-body {
+ padding: 0 1.15rem 1.1rem;
+}
+
+.diary-groups-grid {
+ display: grid;
+ grid-template-columns: 1.4fr 1fr;
+ gap: 1rem;
+}
+
+.diary-groups-grid h4 {
+ margin-top: 0;
+}
+
button[type="button"] {
margin-left: 10px;
}
@@ -4152,6 +4367,346 @@ img {
flex: 1;
}
+.diary-workspace-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 1rem;
+ margin-bottom: 1rem;
+ padding: 1rem 1.25rem;
+ border: 1px solid #d9e4ec;
+ border-radius: 12px;
+ background: linear-gradient(180deg, #f8fbfd 0%, #eef5f9 100%);
+}
+
+.diary-workspace-copy h3 {
+ margin: 0.2rem 0 0.35rem;
+}
+
+.diary-workspace-label {
+ font-size: 0.8rem;
+ font-weight: 700;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+ color: #517287;
+}
+
+.diary-workspace-status {
+ margin: 0;
+ color: #45606f;
+}
+
+.diary-workspace-stats {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(110px, 1fr));
+ gap: 0.75rem;
+ width: min(560px, 100%);
+}
+
+.diary-stat-card {
+ padding: 0.8rem 0.9rem;
+ border-radius: 10px;
+ background: #fff;
+ border: 1px solid #d9e4ec;
+}
+
+.diary-stat-label {
+ display: block;
+ font-size: 0.76rem;
+ font-weight: 700;
+ letter-spacing: 0.03em;
+ text-transform: uppercase;
+ color: #5f7b8b;
+}
+
+.diary-stat-value {
+ display: block;
+ margin-top: 0.25rem;
+ font-size: 1rem;
+ color: #173042;
+}
+
+.participant-toolbar {
+ display: flex;
+ flex-direction: column;
+ gap: 0.65rem;
+ margin-bottom: 0.85rem;
+}
+
+.participant-search-input {
+ width: 100%;
+ padding: 0.55rem 0.7rem;
+ border: 1px solid #ccd8e0;
+ border-radius: 8px;
+ background: #fff;
+}
+
+.participant-filter-chips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.45rem;
+}
+
+.participant-filter-chip {
+ border: 1px solid #ccd8e0;
+ background: #f3f7fa;
+ color: #365266;
+ border-radius: 999px;
+ padding: 0.35rem 0.75rem;
+ font-size: 0.85rem;
+ cursor: pointer;
+}
+
+.participant-filter-chip.active {
+ background: #dcebf5;
+ border-color: #8eb7d1;
+ color: #14374c;
+ font-weight: 600;
+}
+
+.plan-toolbar {
+ display: flex;
+ justify-content: space-between;
+ gap: 1rem;
+ align-items: flex-start;
+ margin-bottom: 1rem;
+ padding: 0.9rem 1rem;
+ border: 1px solid #d9e4ec;
+ border-radius: 10px;
+ background: #f8fbfd;
+}
+
+.plan-toolbar-stats {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1rem;
+}
+
+.plan-toolbar-stat {
+ min-width: 100px;
+}
+
+.plan-toolbar-label {
+ display: block;
+ font-size: 0.76rem;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.03em;
+ color: #5f7b8b;
+}
+
+.plan-toolbar-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ justify-content: flex-end;
+}
+
+.plan-empty-state {
+ margin-bottom: 0.9rem;
+ padding: 0.8rem 0.9rem;
+ border-radius: 8px;
+ background: #f3f7fa;
+ color: #516978;
+}
+
+.plan-composer {
+ margin-bottom: 1rem;
+ padding: 0.95rem 1rem;
+ border: 1px solid #d9e4ec;
+ border-radius: 10px;
+ background: #f8fbfd;
+}
+
+.plan-composer-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 1rem;
+ margin-bottom: 0.85rem;
+}
+
+.plan-composer-grid {
+ display: grid;
+ grid-template-columns: 1.8fr 1fr 1.2fr;
+ gap: 0.85rem;
+}
+
+.plan-composer-field label {
+ display: block;
+ margin-bottom: 0.3rem;
+ font-size: 0.82rem;
+ font-weight: 700;
+ color: #4d6979;
+}
+
+.plan-composer-field input,
+.plan-composer-field select {
+ width: 100%;
+}
+
+.plan-composer-activity-input {
+ display: flex;
+ gap: 0.5rem;
+ align-items: flex-start;
+}
+
+.plan-composer-input-wrap {
+ flex: 1;
+ position: relative;
+}
+
+.plan-composer-duration {
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+}
+
+.plan-composer-actions {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 0.9rem;
+}
+
+.plan-row-actions {
+ position: relative;
+ display: inline-flex;
+ gap: 0.35rem;
+ align-items: center;
+ flex-wrap: wrap;
+}
+
+.plan-row-action-button {
+ border: 1px solid #cfdbe3;
+ background: #f3f7fa;
+ color: #274455;
+ border-radius: 7px;
+ padding: 0.22rem 0.55rem;
+ font-size: 0.78rem;
+ cursor: pointer;
+}
+
+.plan-row-action-button-primary {
+ background: #dcebf5;
+ border-color: #8eb7d1;
+}
+
+.plan-row-action-button-danger {
+ background: #fff0f0;
+ border-color: #dfb4b4;
+ color: #8a2f2f;
+}
+
+.plan-timeblock-row {
+ background: #f8fbfd;
+}
+
+.plan-group-activity-row td {
+ background: #fcfdfe;
+}
+
+.plan-group-activity-cell {
+ display: flex;
+ align-items: center;
+ gap: 0.45rem;
+ padding-left: 0.75rem;
+}
+
+.plan-type-badge {
+ display: inline-flex;
+ align-items: center;
+ border-radius: 999px;
+ padding: 0.1rem 0.5rem;
+ font-size: 0.72rem;
+ font-weight: 700;
+ letter-spacing: 0.03em;
+ text-transform: uppercase;
+}
+
+.plan-type-badge-timeblock {
+ background: #dcebf5;
+ color: #173c52;
+}
+
+.plan-type-badge-group {
+ background: #e9f3e6;
+ color: #245037;
+}
+
+.plan-row-muted {
+ color: #607785;
+ font-size: 0.84rem;
+}
+
+.plan-editor {
+ margin-bottom: 1rem;
+ padding: 0.95rem 1rem;
+ border: 1px solid #d9e4ec;
+ border-radius: 10px;
+ background: #fffaf2;
+}
+
+.plan-editor-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 1rem;
+ margin-bottom: 0.85rem;
+}
+
+.plan-editor-grid {
+ display: grid;
+ grid-template-columns: 1.8fr 1fr;
+ gap: 0.85rem;
+}
+
+.plan-editor-field label {
+ display: block;
+ margin-bottom: 0.3rem;
+ font-size: 0.82rem;
+ font-weight: 700;
+ color: #4d6979;
+}
+
+.plan-editor-actions {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 0.9rem;
+}
+
+.plan-assignment-panel {
+ margin-bottom: 1rem;
+ padding: 0.95rem 1rem;
+ border: 1px solid #d9e4ec;
+ border-radius: 10px;
+ background: #f6faf7;
+}
+
+.plan-assignment-toolbar {
+ display: flex;
+ gap: 0.6rem;
+ align-items: center;
+ margin-bottom: 0.85rem;
+ flex-wrap: wrap;
+}
+
+.plan-assignment-list {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(180px, 1fr));
+ gap: 0.45rem 0.8rem;
+}
+
+.plan-assignment-row {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.plan-add-hint {
+ color: #607785;
+ font-style: italic;
+}
+
/* Tab-Navigation für Mobile */
.mobile-tabs {
display: none;
@@ -4176,6 +4731,18 @@ img {
color: #666;
}
+.mobile-tab-count {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 1.5rem;
+ margin-left: 0.35rem;
+ padding: 0.05rem 0.35rem;
+ border-radius: 999px;
+ background: rgba(255, 255, 255, 0.2);
+ font-size: 0.78rem;
+}
+
.tab-button:hover {
background: #e9e9e9;
color: #333;
@@ -4208,6 +4775,46 @@ img {
/* Responsive Design */
@media (max-width: 768px) {
+ .diary-workspace-header {
+ flex-direction: column;
+ }
+
+ .diary-workspace-stats {
+ grid-template-columns: repeat(2, minmax(120px, 1fr));
+ }
+
+ .plan-toolbar {
+ flex-direction: column;
+ }
+
+ .plan-composer-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .plan-editor-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .plan-assignment-list {
+ grid-template-columns: 1fr;
+ }
+
+ .plan-composer-actions {
+ justify-content: flex-start;
+ }
+
+ .plan-editor-actions {
+ justify-content: flex-start;
+ }
+
+ .plan-toolbar-actions {
+ justify-content: flex-start;
+ }
+
+ .diary-groups-grid {
+ grid-template-columns: 1fr;
+ }
+
.mobile-tabs {
display: flex;
}