Skip to content

Commit

Permalink
Add some statistics and make updating subjects easier.
Browse files Browse the repository at this point in the history
  • Loading branch information
manud99 committed Oct 27, 2024
1 parent 8994825 commit 382fd96
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 12 deletions.
4 changes: 4 additions & 0 deletions src/components/Button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export default defineComponent({
},
getColorClasses(): string {
switch (this.color) {
case "yellow":
return "bg-yellow-600 active:bg-yellow-600 hover:bg-yellow-700 ring-yellow-700";
case "red":
return "bg-red-600 active:bg-red-600 hover:bg-red-700 ring-red-700";
case "green":
return "bg-green-600 active:bg-green-600 hover:bg-green-700 ring-green-700";
case "blue":
Expand Down
59 changes: 52 additions & 7 deletions src/pages/Statistics.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Section from "../blocks/Section.vue";
import { calendarId, makeSureCalendarIdExists } from "../utils/timeEntries";
import { getCalendarId } from "../utils/settings";
import { ready } from "../google/plugin";
import { TimeEntry } from "../@types/models";
import { Subject, TimeEntry } from "../@types/models";
import { fetchEvents } from "../google/query";
import debounce from "lodash.debounce";
import { getQueryParam, updateQueryParam } from "../utils/queryParams";
Expand All @@ -27,7 +27,7 @@ import { getSubjectColor } from "../utils/subjects";
import CustomDate from "../utils/CustomDate";
const startParam = new CustomDate(getQueryParam("start") || "");
const todayMinusSixMonth = CustomDate.now().addMonths(-6);
const todayMinusSixMonth = CustomDate.now().addMonths(-3);
const startDate = startParam.isValidDate() ? startParam : todayMinusSixMonth;
const endParam = new CustomDate(getQueryParam("end") || "");
const endDate = endParam.isValidDate() ? endParam : CustomDate.now();
Expand All @@ -39,6 +39,8 @@ const timeEntries: Ref<TimeEntry[]> = ref([]);
const minutesPerWeek: Ref<{ [startOfWeek: string]: { total: number; [subject: string]: number } }> = ref({});
const debounceGetTimeEntries = debounce(getTimeEntries, 300);
const filterSubject: Ref<string> = ref("");
const startProp = computed({
get() {
return start.value.getIsoDate();
Expand All @@ -61,6 +63,11 @@ const activeSubjects = computed(() => {
return getSubjects().value.filter((subject) => subject.isActive);
});
const entriesFilteredBySubject = computed(() => {
if (filterSubject.value == "") return []
return timeEntries.value.filter((entry) => entry.subject?.name == filterSubject.value)
})
function analyzeTimeEntries() {
const hours: { [startOfWeek: string]: { total: number; [subject: string]: number } } = {};
Expand All @@ -75,7 +82,9 @@ function analyzeTimeEntries() {
if (entry.subject?.name) {
hours[weekStart][entry.subject.name] = (hours[weekStart][entry.subject.name] || 0) + duration;
}
hours[weekStart].total += duration;
if (entry.subject?.isActive) {
hours[weekStart].total += duration;
}
});
minutesPerWeek.value = hours;
Expand Down Expand Up @@ -119,7 +128,7 @@ const chartHoursPerWeek = computed(() => {
});
return {
labels: labels.map((label) => getDateAsString(label)),
labels: labels.map((label) => new CustomDate(label).getShortDate()),
datasets: subjectDatasets,
};
});
Expand Down Expand Up @@ -228,7 +237,7 @@ const lineChartOptions: ChartOptions<"line"> = {
</tr>
</thead>
<tbody class="divide-y">
<tr v-for="week in Object.keys(minutesPerWeek).reverse()" :key="week" class="divide-x">
<tr v-for="week in Object.keys(minutesPerWeek)" :key="week" class="divide-x">
<td class="px-4 py-1.5">{{ getDateAsString(week) }}</td>
<td v-for="(subject, index) in activeSubjects" :key="index" class="px-4 py-1.5 text-right">
<span v-if="(minutesPerWeek[week][subject.name] || 0) == 0">-</span>
Expand All @@ -245,15 +254,51 @@ const lineChartOptions: ChartOptions<"line"> = {
<td class="px-4 py-1.5 text-right">{{ toHoursAndMin(totalMinutes.total / 60) }}</td>
</tr>
<tr class="divide-x font-bold">
<td class="px-4 py-1.5">ECTS (25h pro Punkt)</td>
<td class="px-4 py-1.5">ECTS (30h pro Punkt)</td>
<td v-for="total in totalMinutes.subjects" class="px-4 py-1.5 text-right">
<span v-if="total == 0">-</span>
<span v-else v-text="Math.round((total / 60 / 25) * 100) / 100" />
<span v-else v-text="Math.round((total / 60 / 30) * 100) / 100" />
</td>
<td />
</tr>
</tbody>
</table>
</Section>
<Section class="bg-white">
<div class="flex flex-wrap gap-4 justify-between items-center p-4">
<h2 class="text-xl font-bold">Einträge gefiltert nach Fach</h2>
<div>
Fach:
<select v-model="filterSubject">
<option value="" disabled>Fach auswählen</option>
<option v-for="subject in activeSubjects" :value="subject.name" v-text="subject.name"/>
</select>
</div>
</div>
<div v-if="filterSubject == ''" class="p-4 text-lg">
Bitte zuerst ein Fach auswählen
</div>
<table v-else class="table-auto border-t w-full" v-if="minutesPerWeek">
<thead class="bg-gray-50 text-gray-500 text-xs font-semibold tracking-wide uppercase">
<tr class="divide-x">
<th class="px-4 py-3 text-left">Tag</th>
<th class="px-4 py-3 text-left">Beschreibung</th>
<th class="px-4 py-3 text-left">von</th>
<th class="px-4 py-3 text-left">bis</th>
<th class="px-4 py-3 text-right">Anzahl Stunden</th>
</tr>
</thead>
<tbody class="divide-y">
<tr v-for="entry in entriesFilteredBySubject" :key="entry.id" class="divide-x">
<td class="px-4 py-1.5">{{ entry.start.getDate() }}</td>
<td class="px-4 py-1.5">{{ entry.description }}</td>
<td class="px-4 py-1.5">{{ entry.start.getTime() }}</td>
<td class="px-4 py-1.5">{{ entry.end.getTime() }}</td>

<td class="px-4 py-1.5 text-right">{{ entry.end.diffInMinutes(entry.start) / 60 }}h</td>
</tr>
</tbody>
</table>
</Section>
</Page>
</template>
17 changes: 16 additions & 1 deletion src/pages/Subjects.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ function updateItem(subject: Subject) {
}
}
function toggleActive(subject: Subject, index: number) {
subject.isActive = !subject.isActive
updateSubject(subject, index)
}
function deleteItem(index: number) {
deleteSubject(index);
}
Expand Down Expand Up @@ -85,6 +90,16 @@ onMounted(async () => {

<template #cell(actions)="{ entry, index }">
<div class="flex">
<Button
class="mr-2"
:size="ButtonSize.SM"
:label="entry.isActive ? 'Aktivieren' : 'Deaktivieren'"
color="yellow"
@click="toggleActive(entry as Subject, index)"
>
<span v-if="!entry.isActive">Aktivieren</span>
<span v-else>Deaktivieren</span>
</Button>
<Button
class="mr-2"
:size="ButtonSize.SM"
Expand All @@ -94,7 +109,7 @@ onMounted(async () => {
<IconPencil class="mr-2" :size="16" />
<span>Bearbeiten</span>
</Button>
<Button :size="ButtonSize.SM" label="Löschen" @click="deleteItem(index)">
<Button :size="ButtonSize.SM" color="red" label="Löschen" @click="deleteItem(index)">
<IconGarbage class="mr-2" :size="12" />
<span>Löschen</span>
</Button>
Expand Down
12 changes: 9 additions & 3 deletions src/utils/CustomDate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ export default class CustomDate {
}

toDateString(): string {
const year = this.date.getFullYear().toString();
const month = (this.date.getMonth() + 1).toString().padStart(2, "0");
const day = this.date.getDate().toString().padStart(2, "0");
const year = this.getYear().toString();
const month = this.getMonth().toString().padStart(2, "0");
const day = this.getDay().toString().padStart(2, "0");
return `${year}-${month}-${day}`;
}

Expand All @@ -33,6 +33,12 @@ export default class CustomDate {
return this.date.toLocaleString("de-CH", { weekday: "long", day: "2-digit", month: "long", year: "numeric" });
}

getShortDate(): string {
const day = this.getDay().toString().padStart(2, "0");
const month = this.getMonth().toString().padStart(2, "0");
return `${day}.${month}.`;
}

getIsoDate(): string {
return this.date.toISOString().substring(0, 10);
}
Expand Down
4 changes: 3 additions & 1 deletion src/utils/subjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Subject } from "../@types/models";

const SUBJECTS_KEY: string = "timy_subjects";
let loaded: boolean = false;
let lastColor: number = 1;
export const subjects: Ref<Subject[]> = ref([]);

function loadSubjects() {
Expand Down Expand Up @@ -33,7 +34,8 @@ export function getOrCreateSubject(name: string): Subject {
loadSubjects();
const subject = subjects.value.find((record) => record.name === name);
if (subject) return subject;
const newSubject = { name, color: 0, isActive: true };
const newSubject = { name, color: lastColor + 1, isActive: true };
lastColor = (lastColor + 1) % Object.keys(colorMap).length
createSubject(newSubject);
return newSubject;
}
Expand Down

0 comments on commit 382fd96

Please sign in to comment.