Compare commits

...

10 Commits

Author SHA1 Message Date
Torsten Schulz (local)
6cc8903e06 Enhance frontend components by importing API_BASE_URL for consistent API endpoint usage. This update improves code maintainability and prepares the components for future API integrations. 2025-11-13 15:18:28 +01:00
Torsten Schulz (local)
e71988e0b7 Enhance TimeEntryService with additional debug logging for better traceability of work time calculations. Added logs for netWorkTime and currentlyWorked to provide clearer insights into overtime and weekly totals, improving the debugging process while maintaining existing functionality. 2025-10-20 16:51:26 +02:00
Torsten Schulz (local)
a1b5e191f3 Refactor StatusBox component to improve end time calculations using server data. Update logic to handle elapsed time accurately, including pause states, and enhance display of currently worked hours. Adjust formatting for time outputs to ensure clarity in the user interface. 2025-10-20 16:41:11 +02:00
Torsten Schulz (local)
1eff170a7b Remove debug logging from TimeEntryService to streamline code and enhance performance. This update improves readability by eliminating unnecessary console outputs while maintaining the functionality of time calculations. 2025-10-20 11:50:37 +02:00
Torsten Schulz (local)
dfd169c78d Enhance TimeEntryService to incorporate timefix corrections for start and end times of work and pauses. Update logic to ensure accurate time calculations by integrating timefix data, improving the reliability of time entries. Add debug logging for better traceability of time calculations. 2025-10-20 11:49:33 +02:00
Torsten Schulz (local)
363f4567c2 Refactor deploy script to replace npm ci with npm install for both backend and frontend setups, enhancing reliability when package-lock.json is missing. Implement fallback mechanism to ensure successful dependency installation, improving overall script robustness. 2025-10-20 11:34:08 +02:00
Torsten Schulz (local)
d99aa96270 Remove debug logging from unhashRequest middleware, TimeEntryService, and StatusBox component to clean up code and improve performance. This update enhances readability and maintains functionality without unnecessary console outputs. 2025-10-20 11:28:06 +02:00
Torsten Schulz (local)
0bcdec68ef Refactor TimeEntryService and StatusBox component to integrate missing break minutes into time calculations. Update logic to ensure "Offen" time reflects accurate values, including breaks, and adjust frontend display to clarify time representation without redundant pause indications. Enhance output formatting for improved clarity in time displays. 2025-10-20 11:24:45 +02:00
Torsten Schulz (local)
1f20500b5f Update deploy script to include dev dependencies during npm installation for backend builds, enhancing reliability of npm ci commands. Adjust fallback mechanism to remove --omit=dev flag for consistent dependency management. 2025-10-20 10:00:30 +02:00
Torsten Schulz (local)
b16a09059f Update deploy script to allow dev dependencies during npm installation for frontend builds, ensuring successful execution of npm ci commands. Adjust fallback mechanism to remove --omit=dev flag for improved reliability in dependency management. 2025-10-20 09:57:42 +02:00
7 changed files with 159 additions and 67 deletions

View File

@@ -16,9 +16,7 @@ const unhashRequestIds = (req, res, next) => {
// Route-Parameter verarbeiten
if (req.params && typeof req.params === 'object') {
console.log('DEBUG unhashRequest: req.params before =', req.params);
req.params = unhashRequestData(req.params);
console.log('DEBUG unhashRequest: req.params after =', req.params);
}
next();

View File

@@ -232,6 +232,10 @@ class TimeEntryService {
// Hole alle Einträge von heute (wird auch für Pausen verwendet)
allEntries = await worklogRepository.findByDateRange(uid, todayStart, todayEnd);
// Hole Timefixes für alle Einträge von heute
const allEntryIds = allEntries.map(e => e.id);
const timefixMap = await worklogRepository.getTimefixesByWorklogIds(allEntryIds);
// Finde alle Start-Work-Paare von heute
const workBlocks = [];
const startWorks = {};
@@ -249,14 +253,22 @@ class TimeEntryService {
const action = state?.action || state;
if (action === 'start work') {
// Prüfe auf Timefix-Korrektur
const startFix = timefixMap.get(entry.id)?.find(f => f.fix_type === 'start work');
const startTime = startFix?.fix_date_time || entry.tstamp;
startWorks[entry.id] = {
id: entry.id,
startTime: entry.tstamp,
startTime: startTime,
endTime: null,
pauses: []
};
} else if (action === 'stop work' && entry.relatedTo_id && startWorks[entry.relatedTo_id]) {
startWorks[entry.relatedTo_id].endTime = entry.tstamp;
// Prüfe auf Timefix-Korrektur
const endFix = timefixMap.get(entry.id)?.find(f => f.fix_type === 'stop work');
const endTime = endFix?.fix_date_time || entry.tstamp;
startWorks[entry.relatedTo_id].endTime = endTime;
}
});
@@ -274,9 +286,13 @@ class TimeEntryService {
const action = state?.action || state;
if (action === 'start pause' && entry.relatedTo_id && startWorks[entry.relatedTo_id]) {
// Prüfe auf Timefix-Korrektur
const pauseStartFix = timefixMap.get(entry.id)?.find(f => f.fix_type === 'start pause');
const pauseStartTime = pauseStartFix?.fix_date_time || entry.tstamp;
startWorks[entry.relatedTo_id].pauses.push({
id: entry.id,
startTime: entry.tstamp,
startTime: pauseStartTime,
endTime: null
});
} else if (action === 'stop pause' && entry.relatedTo_id) {
@@ -284,7 +300,9 @@ class TimeEntryService {
Object.values(startWorks).forEach(block => {
const pause = block.pauses.find(p => p.id === entry.relatedTo_id);
if (pause) {
pause.endTime = entry.tstamp;
// Prüfe auf Timefix-Korrektur
const pauseEndFix = timefixMap.get(entry.id)?.find(f => f.fix_type === 'stop pause');
pause.endTime = pauseEndFix?.fix_date_time || entry.tstamp;
}
});
}
@@ -324,6 +342,8 @@ class TimeEntryService {
}
// Berechne "Offen" basierend auf timewish (oder Standard: 8 Stunden)
// WICHTIG: Diese Zeit wird OHNE fehlende Pausen berechnet
// Das Frontend addiert die fehlenden Pausen dann zur "Normales Arbeitsende" Berechnung
let open = null;
const { Timewish } = database.getModels();
@@ -458,6 +478,21 @@ class TimeEntryService {
// Fehlende Pausenzeit
const missingBreakMinutes = Math.max(0, requiredBreakMinutes - alreadyTakenBreakMinutes);
// Addiere fehlende Pausen zur "Offen" Zeit
if (open && open !== '—' && open !== 'Arbeitsende erreicht') {
const openParts = open.split(':');
const openH = parseInt(openParts[0]);
const openM = parseInt(openParts[1]);
const openS = parseInt(openParts[2] || 0);
const openMinutes = openH * 60 + openM + missingBreakMinutes;
const newOpenH = Math.floor(openMinutes / 60);
const newOpenM = openMinutes % 60;
const newOpenS = openS;
open = `${newOpenH.toString().padStart(2, '0')}:${newOpenM.toString().padStart(2, '0')}:${newOpenS.toString().padStart(2, '0')}`;
}
// Berechne Überstunden über den gesamten Zeitraum (alle Wochen)
// Neue Berechnung: Timewish-basiert
const totalOvertimeResult = await this._calculateTotalOvertime(uid, runningEntry);
@@ -465,6 +500,8 @@ class TimeEntryService {
// Berechne Überstunden für die aktuelle Woche
const weekData = await this.getWeekOverview(uid, 0);
console.log(`🔍 Wochenüberstunden-Berechnung START: userDailyHours=${userDailyHours}`);
let weekSollMinutes = 0; // Soll-Arbeitszeit für die Woche
let weekIstMinutes = 0; // Ist-Arbeitszeit für die Woche
@@ -549,13 +586,17 @@ class TimeEntryService {
});
let daySollHours = userDailyHours; // Fallback: User's daily_hours
console.log(` Tag ${day.date}: userDailyHours=${userDailyHours}, applicableTimewish=${applicableTimewish ? applicableTimewish.hours + 'h' : 'keine'}`);
if (applicableTimewish && applicableTimewish.wishtype === 2 && applicableTimewish.hours) {
daySollHours = applicableTimewish.hours;
console.log(` → Verwende Timewish: ${daySollHours}h`);
}
// Bei halbem Urlaubstag: Soll halbiert
if (day.vacation && day.vacation.halfDay) {
daySollHours = daySollHours / 2;
console.log(` → Halber Urlaubstag: ${daySollHours}h`);
}
weekSollMinutes += daySollHours * 60;
@@ -564,11 +605,15 @@ class TimeEntryService {
if (day.netWorkTime) {
const [h, m] = day.netWorkTime.split(':').map(Number);
weekIstMinutes += h * 60 + m;
console.log(` Tag ${day.date}: netWorkTime=${day.netWorkTime}, Soll=${daySollHours}h, Ist=${h}:${m}`);
}
});
// Überstunden = Ist - Soll
const overtimeMinutes = weekIstMinutes - weekSollMinutes;
console.log(`🔍 Wochenüberstunden: weekIst=${weekIstMinutes}min (${Math.floor(weekIstMinutes/60)}:${weekIstMinutes%60}), weekSoll=${weekSollMinutes}min (${Math.floor(weekSollMinutes/60)}:${weekSollMinutes%60}), overtime=${overtimeMinutes}min`);
const overtimeHours = Math.floor(Math.abs(overtimeMinutes) / 60);
const overtimeMins = Math.abs(overtimeMinutes) % 60;
const overtimeSign = overtimeMinutes >= 0 ? '+' : '-';
@@ -650,14 +695,18 @@ class TimeEntryService {
const [h, m, s] = currentlyWorked.split(':').map(Number);
dayIstMinutes = h * 60 + m;
weekIstMinutesTotal += dayIstMinutes;
console.log(` HEUTE ${day.date}: currentlyWorked=${currentlyWorked}, Soll=${daySollHours}h, Ist=${h}:${m}`);
} else if (!isToday && day.netWorkTime) {
// Für vergangene Tage: Verwende netWorkTime
const [h, m] = day.netWorkTime.split(':').map(Number);
dayIstMinutes = h * 60 + m;
weekIstMinutesTotal += dayIstMinutes;
console.log(` Vergangener Tag ${day.date}: netWorkTime=${day.netWorkTime}, Soll=${daySollHours}h, Ist=${h}:${m}`);
}
});
console.log(`🔍 Offen für Woche: weekIstTotal=${weekIstMinutesTotal}min, weekSollTotal=${weekSollMinutesTotal}min`);
// Offen für Woche = Wochensoll - Wochenist (bisher)
const openForWeekMinutes = weekSollMinutesTotal - weekIstMinutesTotal;
@@ -699,9 +748,10 @@ class TimeEntryService {
const currentTime = new Date();
// ===== GENERELL =====
// Verbleibende Zeit = Offen - Gesamt-Überstunden + fehlende Pausen
// Verbleibende Zeit = Offen - Gesamt-Überstunden
// WICHTIG: "open" enthält bereits die fehlenden Pausen!
const generalOvertimeMinutes = totalOvertimeResult.minutes || 0;
const generalRemainingMinutes = openMinutes - generalOvertimeMinutes + missingBreakMinutes;
const generalRemainingMinutes = openMinutes - generalOvertimeMinutes;
if (generalRemainingMinutes <= 0) {
adjustedEndTodayGeneral = 'Arbeitsende erreicht';
@@ -714,9 +764,10 @@ class TimeEntryService {
}
// ===== WOCHE =====
// Verbleibende Zeit = Offen - Wochen-Über/Unterstunden + fehlende Pausen
// Verbleibende Zeit = Offen - Wochen-Über/Unterstunden
// WICHTIG: "open" enthält bereits die fehlenden Pausen!
const weekOvertimeMinutes = overtimeMinutes; // Bereits berechnet
const weekRemainingMinutes = openMinutes - weekOvertimeMinutes + missingBreakMinutes;
const weekRemainingMinutes = openMinutes - weekOvertimeMinutes;
if (weekRemainingMinutes <= 0) {
adjustedEndTodayWeek = 'Arbeitsende erreicht';

View File

@@ -202,13 +202,8 @@ setup_backend() {
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
# Schnelle, reproduzierbare Installation nur Prod-Dependencies
timeout 600 bash -lc "npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress" || {
print_warning "npm ci ist fehlgeschlagen oder hat zu lange gedauert. Versuche fallback ohne timeout..."
npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress || {
print_error "npm ci (Backend) fehlgeschlagen"; exit 1;
}
}
# Backend braucht alle Dependencies (auch dev für Build-Tools)
npm install --no-audit --no-fund --loglevel=warn
if [ ! -f .env ]; then
print_warning ".env Datei nicht gefunden!"
@@ -239,12 +234,8 @@ setup_frontend() {
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
timeout 600 bash -lc "npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress" || {
print_warning "npm ci ist fehlgeschlagen oder hat zu lange gedauert. Versuche fallback ohne timeout..."
npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress || {
print_error "npm ci (Frontend) fehlgeschlagen"; exit 1;
}
}
# Frontend braucht dev-Dependencies für den Build (vite, etc.)
npm install --no-audit --no-fund --loglevel=warn
# .env.production erstellen falls nicht vorhanden
if [ ! -f ".env.production" ]; then
@@ -486,16 +477,27 @@ do_update() {
# Backend aktualisieren
print_info "Aktualisiere Backend Dependencies..."
cd $BACKEND_DIR
npm config set fund false >/dev/null 2>&1 || true
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
timeout 600 bash -lc "npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress" || {
print_warning "npm ci ist fehlgeschlagen oder hat zu lange gedauert. Versuche fallback ohne timeout..."
npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress || {
print_error "npm ci (Backend Update) fehlgeschlagen"; exit 1;
}
}
# Prüfe ob package-lock.json existiert
if [ ! -f "package-lock.json" ]; then
print_warning "package-lock.json fehlt! Verwende npm install statt npm ci"
npm install --no-audit --no-fund --loglevel=warn
else
npm config set fund false >/dev/null 2>&1 || true
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
# Backend braucht alle Dependencies (auch dev für Build-Tools)
if ! npm ci --no-audit --no-fund --loglevel=warn 2>&1; then
print_warning "npm ci fehlgeschlagen. Fallback auf npm install..."
rm -rf node_modules
npm install --no-audit --no-fund --loglevel=warn || {
print_error "npm install (Backend Update) fehlgeschlagen"
exit 1
}
fi
fi
# Frontend aktualisieren
print_info "Aktualisiere Frontend..."
@@ -510,16 +512,26 @@ VITE_API_URL=/api
EOF
fi
npm config set fund false >/dev/null 2>&1 || true
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
timeout 600 bash -lc "npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress" || {
print_warning "npm ci ist fehlgeschlagen oder hat zu lange gedauert. Versuche fallback ohne timeout..."
npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress || {
print_error "npm ci (Frontend Update) fehlgeschlagen"; exit 1;
}
}
# Prüfe ob package-lock.json existiert
if [ ! -f "package-lock.json" ]; then
print_warning "package-lock.json fehlt! Verwende npm install statt npm ci"
npm install --no-audit --no-fund --loglevel=warn
else
npm config set fund false >/dev/null 2>&1 || true
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
# Frontend braucht dev-Dependencies für den Build (vite, etc.)
if ! npm ci --no-audit --no-fund --loglevel=warn 2>&1; then
print_warning "npm ci fehlgeschlagen. Fallback auf npm install..."
rm -rf node_modules
npm install --no-audit --no-fund --loglevel=warn || {
print_error "npm install (Frontend Update) fehlgeschlagen"
exit 1
}
fi
fi
# Sauberer Build
rm -rf dist/

View File

@@ -117,16 +117,12 @@ const fetchWorklogData = async () => {
if (response.ok) {
const result = await response.json()
console.log('DEBUG fetchWorklogData: result =', result)
console.log('DEBUG fetchWorklogData: currentState =', currentState.value)
// Das Backend gibt direkt das Entry-Objekt zurück, nicht { entry: ... }
if (result && result.startTime && (currentState.value === 'start work' || currentState.value === 'stop pause')) {
// Arbeit läuft
workStartTime.value = new Date(result.startTime).getTime()
pauseDurations.value = result.pauses || []
lastPauseStartTime.value = null
console.log('DEBUG: Arbeit läuft, startTime:', result.startTime, 'pauses:', pauseDurations.value.length)
} else if (result && result.startTime && currentState.value === 'start pause') {
// In Pause
workStartTime.value = new Date(result.startTime).getTime()
@@ -135,13 +131,11 @@ const fetchWorklogData = async () => {
if (result.currentPauseStart) {
lastPauseStartTime.value = new Date(result.currentPauseStart).getTime()
}
console.log('DEBUG: In Pause, startTime:', result.startTime, 'currentPauseStart:', result.currentPauseStart)
} else {
// Nicht am Arbeiten
workStartTime.value = null
lastPauseStartTime.value = null
pauseDurations.value = []
console.log('DEBUG: Nicht am Arbeiten')
}
}
} catch (error) {
@@ -247,19 +241,46 @@ const updateOpenTime = () => {
openTime.value = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
// Berechne "Normales Arbeitsende" = Jetzt + Offen + fehlende Pausen
const totalRemainingSeconds = remainingSeconds + (missingBreakMinutes.value * 60)
// Berechne "Normales Arbeitsende" = Jetzt + Offen (Pausen sind bereits in Offen enthalten)
const totalRemainingSeconds = remainingSeconds
const endTimestamp = now + (totalRemainingSeconds * 1000)
const endDate = new Date(endTimestamp)
const endHours = endDate.getHours()
const endMinutes = endDate.getMinutes()
const endSeconds = endDate.getSeconds()
// Zeige auch fehlende Pausen an (falls vorhanden)
if (missingBreakMinutes.value > 0) {
regularEndTime.value = `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}:${endSeconds.toString().padStart(2, '0')} (+${missingBreakMinutes.value}min Pause)`
} else {
regularEndTime.value = `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}:${endSeconds.toString().padStart(2, '0')}`
// Ausgabe ohne zusätzlichen Pausen-Hinweis; Zeit stammt bereits inkl. Pausen aus Backend
regularEndTime.value = `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}:${endSeconds.toString().padStart(2, '0')} Uhr`
// Override: Berechne Normales Arbeitsende aus Server "open" Zeit
// Nur überschreiben wenn wir Server-Daten haben
if (serverOpenTime.value && serverTimestamp.value) {
// Parse Server-Offen-Zeit
const openParts = serverOpenTime.value.split(':')
const openSeconds = parseInt(openParts[0]) * 3600 + parseInt(openParts[1]) * 60 + parseInt(openParts[2] || 0)
// Berechne vergangene Zeit seit Server-Timestamp
const now = Date.now()
const elapsedMs = now - serverTimestamp.value
let elapsedSeconds = Math.floor(elapsedMs / 1000)
// Wenn in Pause, zähle die Zeit nicht
if (currentState.value === 'start pause') {
elapsedSeconds = 0
}
const remainingSeconds = openSeconds - elapsedSeconds
if (remainingSeconds > 0) {
const endTs = now + (remainingSeconds * 1000)
const endDt = new Date(endTs)
const eh = endDt.getHours()
const em = endDt.getMinutes()
const es = endDt.getSeconds()
regularEndTime.value = `${eh.toString().padStart(2, '0')}:${em.toString().padStart(2, '0')}:${es.toString().padStart(2, '0')} Uhr`
} else {
regularEndTime.value = 'Erreicht'
}
}
} else {
openTime.value = 'Arbeitsende erreicht'
@@ -297,11 +318,9 @@ const handleAction = async (action) => {
}
// Aktualisiere Status und Worklog-Daten sofort
console.log('DEBUG: Lade Daten nach Stempel-Aktion neu...')
await fetchCurrentState()
await fetchWorklogData()
await fetchStats()
console.log('DEBUG: Daten neu geladen, stats =', stats.value)
// Event auslösen für andere Komponenten (z.B. WeekOverview)
window.dispatchEvent(new CustomEvent('worklog-updated'))
@@ -347,7 +366,6 @@ const rightButton = computed(() => {
// Event-Handler für Login
const handleLoginCompleted = async () => {
console.log('DEBUG: Login completed, lade Daten neu...')
await fetchCurrentState()
await fetchWorklogData()
await fetchStats()
@@ -383,17 +401,21 @@ onBeforeUnmount(() => {
})
const displayRows = computed(() => {
// Verwende Server-Wert für "Derzeit gearbeitet" wenn verfügbar (zeigt gesamte Tagesarbeitszeit)
const workedDisplay = (stats.value?.currentlyWorked && stats.value.currentlyWorked !== '—')
? stats.value.currentlyWorked + ' h'
: (currentlyWorkedTime.value === '—' ? currentlyWorkedTime.value : currentlyWorkedTime.value + ' h');
const rows = {
'Derzeit gearbeitet': currentlyWorkedTime.value, // Verwende berechneten Wert
'Offen': openTime.value, // Verwende berechneten Wert
'Normales Arbeitsende': regularEndTime.value // Verwende berechneten Wert
'Derzeit gearbeitet': workedDisplay,
'Offen': openTime.value === '—' || openTime.value.includes('erreicht') ? openTime.value : openTime.value + ' h',
'Normales Arbeitsende': regularEndTime.value // Verwende berechneten Wert (hat bereits "Uhr")
}
// Füge andere Stats hinzu
const map = [
['overtime', 'overtime'], // Label wird dynamisch gesetzt
['totalOvertime', 'totalOvertime'], // Label wird dynamisch gesetzt
// ['Überstunden (Alt-Style)', 'totalOvertimeOldStyle'], // DEBUG: Versteckt, da getWeekOverview nicht korrekte Zeiten liefert
['Wochenarbeitszeit', 'weekWorktime'],
['Arbeitsfreie Stunden', 'nonWorkingHours'],
['Offen für Woche', 'openForWeek'],
@@ -416,16 +438,19 @@ const displayRows = computed(() => {
if (key === 'overtime') {
const isNegative = val.startsWith('-');
const displayLabel = isNegative ? 'Fehlzeit (Woche)' : 'Überstunden (Woche)';
const displayValue = isNegative ? val.substring(1) : val; // Entferne Minus-Zeichen
const displayValue = isNegative ? val.substring(1) + ' h' : val + ' h'; // Entferne Minus-Zeichen, füge " h" hinzu
rows[displayLabel] = displayValue;
} else if (key === 'totalOvertime') {
const isNegative = val.startsWith('-');
const displayLabel = isNegative ? 'Fehlzeit (Gesamt)' : 'Überstunden (Gesamt)';
const displayValue = isNegative ? val.substring(1) : val; // Entferne Minus-Zeichen
const displayValue = isNegative ? val.substring(1) + ' h' : val + ' h'; // Entferne Minus-Zeichen, füge " h" hinzu
rows[displayLabel] = displayValue;
} else if (key === 'adjustedEndTodayGeneral' || key === 'adjustedEndTodayWeek') {
// Füge " Uhr" zu Uhrzeiten hinzu
rows[label] = val + ' Uhr';
// Füge " Uhr" zu Uhrzeiten hinzu (außer bei "Arbeitsende erreicht")
rows[label] = val.includes('erreicht') ? val : val + ' Uhr';
} else if (key === 'weekWorktime' || key === 'openForWeek' || key === 'nonWorkingHours') {
// Füge " h" zu Zeiten hinzu (außer bei "—")
rows[label] = val === '—' ? val : val + ' h';
} else {
rows[label] = val;
}

View File

@@ -76,7 +76,9 @@
<script setup>
import { ref, onMounted } from 'vue'
import { useAuthStore } from '../stores/authStore'
import { API_BASE_URL } from '@/config/api'
const API_URL = API_BASE_URL
const authStore = useAuthStore()
const now = new Date()
const selectedMonth = ref(now.getMonth() + 1)

View File

@@ -89,7 +89,9 @@ import { ref } from 'vue'
import { useAuthStore } from '../stores/authStore'
import { useModal } from '../composables/useModal'
import Modal from '../components/Modal.vue'
import { API_BASE_URL } from '@/config/api'
const API_URL = API_BASE_URL
const authStore = useAuthStore()
const loading = ref(false)

View File

@@ -48,7 +48,9 @@
<script setup>
import { ref, onMounted } from 'vue'
import { useAuthStore } from '../stores/authStore'
import { API_BASE_URL } from '@/config/api'
const API_URL = API_BASE_URL
const authStore = useAuthStore()
const selectedYear = ref(new Date().getFullYear())
const statistics = ref(null)