This commit is contained in:
ViperioN1339 2025-04-24 11:19:01 +02:00
parent 8abc9fc2f4
commit 176ff2f211
9 changed files with 218 additions and 0 deletions

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AvaloniaProject">
<option name="projectPerEditor">
<map>
<entry key="ChronoFlow.View/App.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
<entry key="ChronoFlow.View/LoginView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
<entry key="ChronoFlow.View/LoginWindow.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
<entry key="ChronoFlow.View/MainWindow.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
<entry key="ChronoFlow.View/ZeiterfassungView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
</map>
</option>
</component>
</project>

View File

@ -0,0 +1,20 @@
using System.Collections.Generic;
using ChronoFlow.Model;
namespace ChronoFlow.Controller
{
public class ZeiterfassungsController
{
private readonly List<Zeiteintrag> _eintraege = new();
public void SpeichereEintrag(Zeiteintrag eintrag)
{
_eintraege.Add(eintrag);
}
public List<Zeiteintrag> LadeAlleEintraege()
{
return new List<Zeiteintrag>(_eintraege);
}
}
}

View File

@ -0,0 +1,26 @@
using System;
namespace ChronoFlow.Model
{
public class Zeiteintrag
{
public string Mitarbeiter { get; set; }
public DateTime Startzeit { get; set; }
public DateTime Endzeit { get; set; }
public string? Projekt { get; set; }
public string? Kommentar { get; set; }
public TimeSpan Dauer => Endzeit - Startzeit;
//Felder für Mitarbeiter-Rückmeldung
public bool Erledigt { get; set; }
public string? MitarbeiterKommentar { get; set; }
public override string ToString()
{
return $"{Mitarbeiter} - {Startzeit:HH:mm} - {Endzeit:HH:mm} | {Projekt}";
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,41 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ChronoFlow.View.ZeiterfassungView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:ChronoFlow.View"
mc:Ignorable="d">
<StackPanel x:Name="EingabePanel" Spacing="10">
<TextBlock Text="Zeiterfassung" FontWeight="Bold" FontSize="20" HorizontalAlignment="Center"/>
<TextBox x:Name="MitarbeiterBox" Watermark="Mitarbeitername"/>
<DatePicker x:Name="DatumPicker"/>
<TextBox x:Name="StartzeitBox" Watermark="Startzeit (z.B. 08:00)"/>
<TextBox x:Name="EndzeitBox" Watermark="Endzeit (z.B. 16:30)"/>
<TextBox x:Name="ProjektBox" Watermark="Projektname"/>
<TextBox x:Name="KommentarBox" Watermark="Kommentar (Optional)"/>
<Button Content="Eintrag speichern" Click="SpeichernButton_Click" HorizontalAlignment="Center"/>
<TextBlock x:Name="FeedbackText" Foreground="Green" IsVisible="False"/>
<TextBlock Text="Gespeicherte Einträge:" FontWeight="Bold" Margin="0,20,0,5"></TextBlock>
<ListBox x:Name="Eintragsliste" Margin="0,20,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1" CornerRadius="4" Padding="8" Margin="4">
<StackPanel>
<!-- Anzeige -->
<TextBlock Text="{Binding}" FontWeight="Bold"></TextBlock>
<!-- Nur für Mitarbeiter sichtbar: Status-Buttons + Kommentar -->
<StackPanel Orientation="Horizontal" Spacing="8" Margin="0,5,0,0">
<Button Content="✅" Click="MarkiereErledigt_Click"/>
<Button Content="❌" Click="MarkiereNichtErledigt_Click"/>
</StackPanel>
<TextBox x:Name="KommentarEingabe" Watermark="Kommentar" LostFocus="Kommentar_LostFocus"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</UserControl>

View File

@ -0,0 +1,117 @@
using System;
using System.Collections.ObjectModel;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Media;
using ChronoFlow.Controller;
using ChronoFlow.Model;
namespace ChronoFlow.View
{
public partial class ZeiterfassungView : UserControl
{
private readonly ZeiterfassungsController _controller;
private ObservableCollection<Zeiteintrag> _anzeigeEinträge = new();
private readonly User _user;
public ZeiterfassungView(User user)
{
InitializeComponent();
_controller = new ZeiterfassungsController();
_user = user;
//ListBox an Collection binden
Eintragsliste.ItemsSource = _anzeigeEinträge;
//Eingabe-Felder für Nicht-Admins ausblenden
if (_user.Role != "Admin")
{
EingabePanel.IsVisible = false;
}
}
private void SpeichernButton_Click(object? sender, RoutedEventArgs e)
{
try
{
string mitarbeiter = MitarbeiterBox.Text ?? string.Empty;
DateTime datum = DatumPicker.SelectedDate?.Date ?? DateTime.Today;
string startText = StartzeitBox.Text ?? "";
string endText = EndzeitBox.Text ?? "";
if (!TimeSpan.TryParse(startText, out TimeSpan startZeit))
{
FeedbackText.Text = "Ungültige Startzeit!";
FeedbackText.Foreground = Brushes.Red;
FeedbackText.IsVisible = true;
return;
}
if (!TimeSpan.TryParse(endText, out TimeSpan endZeit))
{
FeedbackText.Text = "Ungültige Endzeit!";
FeedbackText.Foreground = Brushes.Red;
FeedbackText.IsVisible = true;
return;
}
var eintrag = new Zeiteintrag
{
Mitarbeiter = mitarbeiter,
Startzeit = datum.Date + startZeit,
Endzeit = datum.Date + endZeit,
Projekt = ProjektBox.Text,
Kommentar = KommentarBox.Text
};
_controller.SpeichereEintrag(eintrag);
_anzeigeEinträge.Add(eintrag);
FeedbackText.Text = "Eintrag gespeichert.";
FeedbackText.Foreground = Brushes.Green;
FeedbackText.IsVisible = true;
}
catch (Exception ex)
{
FeedbackText.Text = $"Fehler: {ex.Message}";
FeedbackText.Foreground = Brushes.Red;
FeedbackText.IsVisible = true;
}
}
private void MarkiereErledigt_Click(object? sender, RoutedEventArgs e)
{
if (sender is Button button && button.DataContext is Zeiteintrag eintrag)
{
eintrag.Erledigt = true;
RefreshListe();
}
}
private void MarkiereNichtErledigt_Click(object? sender, RoutedEventArgs e)
{
if (sender is Button button && button.DataContext is Zeiteintrag eintrag)
{
eintrag.Erledigt = false;
RefreshListe();
}
}
private void Kommentar_LostFocus(object? sender, RoutedEventArgs e)
{
if (sender is TextBox tb && tb.DataContext is Zeiteintrag eintrag)
{
eintrag.MitarbeiterKommentar = tb.Text;
}
}
private void RefreshListe()
{
Eintragsliste.ItemsSource = null;
Eintragsliste.ItemsSource = _anzeigeEinträge;
}
}
}