Enhance DiaryView with mobile and desktop tab navigation improvements
This commit refines the DiaryView component by implementing a responsive tab navigation system for both mobile and desktop views. It introduces new CSS styles for better layout management and user interaction, ensuring a seamless experience when switching between 'Teilnehmer' and 'Aktivitäten' sections. The active tab state is now visually indicated, improving usability across devices.
This commit is contained in:
@@ -54,7 +54,7 @@
|
||||
<button type="submit">Zeiten aktualisieren</button>
|
||||
</form>
|
||||
</div>
|
||||
<div v-if="date !== 'new' && date !== null" style="overflow: visible">
|
||||
<div v-if="date !== 'new' && date !== null" class="diary-content">
|
||||
<!-- Tab-Navigation für Mobile -->
|
||||
<div class="mobile-tabs">
|
||||
<button
|
||||
@@ -385,14 +385,16 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button v-if="trainingPlan && trainingPlan.length && trainingPlan.length > 0"
|
||||
@click="generatePDF">Als PDF
|
||||
herunterladen</button>
|
||||
<div style="margin-top: 1rem; margin-bottom: 2rem; padding-bottom: 1rem;">
|
||||
<button v-if="trainingPlan && trainingPlan.length && trainingPlan.length > 0"
|
||||
@click="generatePDF">Als PDF
|
||||
herunterladen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column mobile-sidebar" :class="{ 'mobile-tab-content': true, 'active': activeTab === 'members' || activeTab === 'activities' }" style="padding-bottom:4em">
|
||||
<!-- Mobile: Nur Mitglieder-Tab -->
|
||||
<div class="mobile-tab-section" v-show="activeTab === 'members'">
|
||||
<div class="mobile-tab-section" :class="{ 'active': activeTab === 'members' }" v-show="activeTab === 'members'">
|
||||
<div>
|
||||
<button @click="addAccident">Unfall buchen</button>
|
||||
<div v-if="accidents.length > 0">
|
||||
@@ -446,6 +448,96 @@
|
||||
<div class="add-participant">
|
||||
<button @click="openQuickAddDialog" class="quick-add-btn">+ Schnell hinzufügen</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Mobile: Nur Aktivitäten-Tab -->
|
||||
<div class="mobile-tab-section" :class="{ 'active': activeTab === 'activities' }" v-show="activeTab === 'activities'">
|
||||
<h3 class="clickable" @click="toggleActivitiesBox">Aktivitäten <span>{{ showActivitiesBox ? '-' :
|
||||
'+' }}</span></h3>
|
||||
<div v-if="showActivitiesBox" class="collapsible-box">
|
||||
<textarea v-model="newActivity"></textarea>
|
||||
<button @click="addActivity">Aktivität hinzufügen</button>
|
||||
<ul>
|
||||
<li v-for="activity in activities" :key="activity.id">
|
||||
{{ activity.description }}
|
||||
</li>
|
||||
</ul>
|
||||
<multiselect v-model="selectedActivityTags" :options="availableTags"
|
||||
placeholder="Tags auswählen" label="name" track-by="id" multiple :close-on-select="true"
|
||||
@tag="addNewTag" @remove="removeActivityTag" :allow-empty="false"
|
||||
@keydown.enter.prevent="addNewTagFromInput" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- Desktop: Beide Bereiche immer sichtbar -->
|
||||
<div class="desktop-sidebar">
|
||||
<div>
|
||||
<button @click="addAccident">Unfall buchen</button>
|
||||
<div v-if="accidents.length > 0">
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="clickable" @click="toggleActivitiesBox">Aktivitäten <span>{{ showActivitiesBox ? '-' :
|
||||
'+' }}</span></h3>
|
||||
<div v-if="showActivitiesBox" class="collapsible-box">
|
||||
<textarea v-model="newActivity"></textarea>
|
||||
<button @click="addActivity">Aktivität hinzufügen</button>
|
||||
<ul>
|
||||
<li v-for="activity in activities" :key="activity.id">
|
||||
{{ activity.description }}
|
||||
</li>
|
||||
</ul>
|
||||
<multiselect v-model="selectedActivityTags" :options="availableTags"
|
||||
placeholder="Tags auswählen" label="name" track-by="id" multiple :close-on-select="true"
|
||||
@tag="addNewTag" @remove="removeActivityTag" :allow-empty="false"
|
||||
@keydown.enter.prevent="addNewTagFromInput" />
|
||||
</div>
|
||||
<h3>Teilnehmer ({{ participants.length }})</h3>
|
||||
<ul>
|
||||
<li v-for="member in sortedMembers()" :key="member.id" class="checkbox-item participant-row"
|
||||
:class="{
|
||||
'row-inactive': !member.active,
|
||||
'row-test': member.testMembership && !member.memberFormHandedOver,
|
||||
'row-test-form': member.testMembership && member.memberFormHandedOver
|
||||
}">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" :value="member.id" @change="toggleParticipant(member.id)"
|
||||
:checked="isParticipant(member.id)">
|
||||
</label>
|
||||
<span class="clickable participant-name" @click.stop="openNotesModal(member)">
|
||||
<span v-if="member && member.testMembership && member.trainingParticipations >= 6" class="warning-icon warning-icon-severe" title="6 oder mehr Trainingsteilnahmen">🛑</span>
|
||||
<span v-else-if="member && member.testMembership && member.trainingParticipations >= 3" class="warning-icon" title="3 oder mehr Trainingsteilnahmen">⚠️</span>
|
||||
{{
|
||||
member ? member.firstName : ''
|
||||
}} {{
|
||||
member ? member.lastName : ''
|
||||
}}
|
||||
</span>
|
||||
<div class="participant-actions">
|
||||
<!-- Gruppenzuordnung für aktive Teilnehmer -->
|
||||
<select v-if="isParticipant(member.id) && groups.length > 0"
|
||||
:value="getMemberGroup(member.id)"
|
||||
@change="updateMemberGroup(member.id, $event.target.value)"
|
||||
@input="updateMemberGroup(member.id, $event.target.value)"
|
||||
style="margin-left: 10px; font-size: 8px; width: 5em;">
|
||||
<option value="">-</option>
|
||||
<option v-for="group in groups" :key="group.id" :value="String(group.id)">
|
||||
{{ group.name }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="false" @click="openNotesModal(member)" class="clickable">📝</span>
|
||||
<span @click="showPic(member)" class="img-icon" v-if="member.hasImage">🖼</span>
|
||||
<span v-if="member.testMembership === true && member.memberFormHandedOver !== true"
|
||||
@click.stop="markFormHandedOver(member)"
|
||||
class="pointer form-handover-icon"
|
||||
title="Mitgliedsformular ausgehändigt">
|
||||
📄
|
||||
</span>
|
||||
<span class="pointer" @click="openTagInfos(member)">ℹ️</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="add-participant">
|
||||
<button @click="openQuickAddDialog" class="quick-add-btn">+ Schnell hinzufügen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3427,7 +3519,157 @@ img {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Tab-Navigation für Mobile */
|
||||
.mobile-tabs {
|
||||
display: none;
|
||||
width: 100%;
|
||||
border-bottom: 2px solid #ddd;
|
||||
margin-bottom: 1rem;
|
||||
background: #f5f5f5;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.tab-button {
|
||||
flex: 1;
|
||||
padding: 0.75rem 1rem;
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
border-bottom: 3px solid transparent;
|
||||
transition: all 0.3s ease;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.tab-button:hover {
|
||||
background: #e9e9e9;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.tab-button.active {
|
||||
border-bottom-color: #007bff;
|
||||
color: #007bff;
|
||||
font-weight: 600;
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* Mobile Tab Content */
|
||||
.mobile-tab-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mobile-tab-section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.desktop-sidebar {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Diary Content Container */
|
||||
.diary-content {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.mobile-tabs {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.diary-content {
|
||||
overflow: visible;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Sicherstellen, dass Tab-Content genug Platz am Ende hat */
|
||||
.column.mobile-tab-content.active {
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
|
||||
.columns {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.column {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.column.mobile-tab-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.column.mobile-tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mobile-sidebar .desktop-sidebar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-sidebar .mobile-tab-section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Besseres Scrollen - nur eine Haupt-Scrollbar */
|
||||
.diary {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.columns {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.column:first-child {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-y: visible;
|
||||
}
|
||||
|
||||
.column:last-child {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Tabelle horizontal scrollbar nur wenn nötig */
|
||||
table {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-y: visible;
|
||||
}
|
||||
|
||||
table thead,
|
||||
table tbody,
|
||||
table tr {
|
||||
display: table;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
/* Teilnehmerliste ohne eigene Scrollbar - nutzt Haupt-Scroll */
|
||||
.mobile-tab-section ul {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Tab-Content ohne eigene Scrollbar */
|
||||
.mobile-tab-content {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.mobile-tab-section {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.notes-body {
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -3437,6 +3679,43 @@ img {
|
||||
height: auto;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
/* Header Row anpassen */
|
||||
.diary-header-row {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.diary-header-row label {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.diary-header-row button {
|
||||
width: 100%;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.mobile-tabs {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-tab-section {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.desktop-sidebar {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.column.mobile-tab-content {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.mobile-sidebar .desktop-sidebar {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Render Container */
|
||||
|
||||
Reference in New Issue
Block a user