-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#22 add time tracking board components
- Loading branch information
Showing
5 changed files
with
340 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
<template> | ||
<v-app> | ||
<NavDrawer /> | ||
<v-container class="d-flex justify-center my-container" style="background-color: #80BA27;" w-auto> | ||
<h1>{{ boardName }}</h1> | ||
</v-container> | ||
<v-main> | ||
<v-container fluid class="flex mt-4"> | ||
<v-btn color="primary" style="margin-left: auto;" dark @click="showDialog"> | ||
<v-icon>mdi-plus</v-icon> | ||
Add Card | ||
</v-btn> | ||
<addTimeCard ref="addTimeCard" | ||
@added="(month) => reloadCardsByMonth(month)" /> | ||
<!-- Expansion Panels for each Quarter --> | ||
<v-expansion-panels style="padding-top: 20px;"> | ||
<v-expansion-panel v-for="(months, index) in quarters" :key="index" class="mb-4" > | ||
<v-expansion-panel-title> | ||
Q{{ index + 1 }} ({{ months.join(' - ') }}) | ||
</v-expansion-panel-title> | ||
<v-expansion-panel-text> | ||
<v-card class="mt-4" style="background: #f7f2f9;"> | ||
<v-row justify="center"> | ||
<Label | ||
v-for="month in months" | ||
:key="month" | ||
ref="monthLabel" | ||
:sectionTitle="month.charAt(0).toUpperCase() + month.slice(1)" | ||
:status="month" | ||
:items="monthItems[month]" | ||
@update:items="monthItems[month] = $event" | ||
@cardMoved="handleCardMoved" | ||
/> | ||
</v-row> | ||
</v-card> | ||
</v-expansion-panel-text> | ||
</v-expansion-panel> | ||
</v-expansion-panels> | ||
</v-container> | ||
</v-main> | ||
</v-app> | ||
</template> | ||
|
||
<script> | ||
import NavDrawer from "@/components/NavDrawer.vue"; | ||
import addTimeCard from "@/components/addTimeCard.vue"; | ||
import Label from "@/components/Label.vue"; | ||
import { ref, onMounted } from 'vue'; | ||
import { apiUrl } from '@/lib/getApi.js'; | ||
export default { | ||
components: { | ||
Label, | ||
NavDrawer, | ||
addTimeCard, | ||
}, | ||
setup() { | ||
const monthItems = { | ||
january: [], | ||
february: [], | ||
march: [], | ||
april: [], | ||
may: [], | ||
june: [], | ||
july:[], | ||
august:[], | ||
september:[], | ||
october:[], | ||
november:[], | ||
december:[], | ||
}; | ||
const boardName = ref("Kanban Board"); | ||
const quarters = [ | ||
['januar', 'february', 'march'], | ||
['april', 'may', 'june'], | ||
['juli', 'august', 'september'], | ||
['october', 'november', 'december'], | ||
]; | ||
return { | ||
monthItems, | ||
boardName, | ||
quarters | ||
} | ||
}, | ||
methods: { | ||
showDialog() { | ||
this.$refs.addTimeCard.showDialog(); | ||
}, | ||
reloadCardsByMonth(month) { | ||
switch (month) { | ||
case 'january': | ||
this.$refs.janLabel.loadCards(); | ||
break; | ||
case 'working_on': | ||
this.$refs.febLabel.loadCards(); | ||
break; | ||
case 'review': | ||
this.$refs.marLabel.loadCards(); | ||
break; | ||
case 'done': | ||
this.$refs.junLabel.loadCards(); | ||
break; | ||
default: | ||
console.error('Invalid status'); | ||
} | ||
}, | ||
}, | ||
} | ||
</script> | ||
|
||
|
||
<style> | ||
.my-container { | ||
border: 1px solid rgba(92, 92, 92, 0.881); | ||
border-radius: 5px; | ||
width: auto; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
<template> | ||
<v-dialog v-model="dialog" persistent max-width="600px"> | ||
<v-card> | ||
<v-card-title> | ||
<span class="text-h5">Add Time</span> | ||
</v-card-title> | ||
<v-card-text> | ||
<v-container> | ||
<v-row> | ||
<v-col cols="12"> | ||
<!-- Date picker --> | ||
<v-date-input v-model="date" label="Date" required></v-date-input> | ||
<!-- start and end time--> | ||
<v-text-field | ||
v-model="start" | ||
label="Start" | ||
required | ||
:rules="[validateTime]" | ||
placeholder="HH:mm" | ||
></v-text-field> | ||
<v-text-field | ||
v-model="end" | ||
label="End" | ||
required | ||
:rules="[validateTime]" | ||
placeholder="HH:mm"> | ||
</v-text-field> | ||
<!-- shows calculated time --> | ||
<v-text-field | ||
v-model="calculatedTime" | ||
label="Time" | ||
readonly | ||
:rules="[v => v > 0 && v <= 10|| 'Time must be greater than 0 and less than 10']"></v-text-field> | ||
</v-col> | ||
<!--Optional description--> | ||
<v-col cols="12"> | ||
<v-textarea | ||
v-model="cardDescription" | ||
label="Description" | ||
placeholder="Optional description" | ||
></v-textarea> | ||
</v-col> | ||
</v-row> | ||
</v-container> | ||
</v-card-text> | ||
<v-card-actions> | ||
<v-spacer></v-spacer> | ||
<v-btn color="blue darken-1" text @click="dialog = false">Close</v-btn> | ||
<v-btn color="blue darken-1" text @click="addCard">Save</v-btn> | ||
</v-card-actions> | ||
</v-card> | ||
</v-dialog> | ||
</template> | ||
|
||
<script> | ||
import { apiUrl } from '@/lib/getApi.js'; | ||
export default { | ||
data() { | ||
return { | ||
dialog: false, | ||
date: null, | ||
//start = end - 90 min | ||
start:new Date(new Date().getTime() - 90 * 60 * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), | ||
//end = current time | ||
end: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), | ||
calculatedTime: 1.5, | ||
cardDescription: '', | ||
} | ||
}, | ||
watch: { | ||
start: 'updateCalculatedTime', | ||
end: 'updateCalculatedTime', | ||
}, | ||
methods: { | ||
async addCard() { | ||
const userId = this.$route.params.userId; | ||
const boardId = this.$route.params.boardId; | ||
const card = { | ||
date: this.date, | ||
start: this.start, | ||
end: this.end, | ||
time: this.calculatedTime, | ||
description: this.cardDescription, | ||
}; | ||
try { | ||
const response = await fetch(`${apiUrl}/users/${userId}/boards/${boardId}/cards/`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(card), | ||
}); | ||
if (!response.ok) { | ||
throw new Error('Network response was not ok'); | ||
} | ||
this.resetForm(); | ||
this.$emit('addedMonth',this.date.getMonth+1); | ||
this.dialog = false; | ||
} catch (error) { | ||
console.error('There was an error!', error); | ||
} | ||
}, | ||
validateTime(value) { | ||
const timeRegex = /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/; | ||
return timeRegex.test(value) || 'Please enter a valid time in the format HH:mm'; | ||
}, | ||
parseTime(time) { | ||
const [hours, minutes] = time.split(':').map(Number); | ||
const date = new Date(); | ||
date.setHours(hours, minutes, 0, 0); // Setzt Stunden und Minuten | ||
return date; | ||
}, | ||
updateCalculatedTime() { | ||
const startTime = this.parseTime(this.start); | ||
const endTime = this.parseTime(this.end); | ||
const calculatedTime = (endTime - startTime) / (1000 * 60 * 60); // Berechnung in Stunden | ||
if (calculatedTime > 0) { | ||
this.calculatedTime = calculatedTime.toFixed(2); // Zeit auf zwei Dezimalstellen | ||
} else { | ||
this.calculatedTime = '0.00'; // Setze auf 0, wenn ungültig | ||
} | ||
}, | ||
resetForm() { | ||
this.start = new Date(new Date().getTime() - 90 * 60 * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | ||
this.end = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | ||
this.calculatedTime = 1.5; // Zeit zurücksetzen | ||
this.cardDescription = ''; | ||
this.date = null; // Setze das Datum zurück | ||
}, | ||
showDialog() { | ||
this.dialog = true; | ||
}, | ||
}, | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.