last changes
This commit is contained in:
parent
8ca1fb91dd
commit
b617d39c8f
1
.idea/.idea.ChronoFlow/.idea/avalonia.xml
generated
1
.idea/.idea.ChronoFlow/.idea/avalonia.xml
generated
@ -6,6 +6,7 @@
|
||||
<entry key="ChronoFlow.View/Admin/AdminMainView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
|
||||
<entry key="ChronoFlow.View/Admin/ConfirmDialog.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
|
||||
<entry key="ChronoFlow.View/Admin/MitarbeiterListeView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
|
||||
<entry key="ChronoFlow.View/Admin/ProjektErstellenView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
|
||||
<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" />
|
||||
|
||||
@ -22,5 +22,6 @@ namespace ChronoFlow.Model
|
||||
Abteilung = "";
|
||||
OriginalUsername = "";
|
||||
}
|
||||
public DateTime LetzterLogin { get; set; } = DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
@ -37,5 +37,8 @@ namespace ChronoFlow.Model
|
||||
return "Green";
|
||||
}
|
||||
}
|
||||
public DateTime LetzteBearbeitung { get; set; }
|
||||
public bool IstNeu { get; set; } // wird im ViewModel gesetzt
|
||||
public bool WurdeSeitLoginBearbeitet { get; set; }
|
||||
}
|
||||
}
|
||||
@ -92,6 +92,7 @@ namespace ChronoFlow.Persistence
|
||||
AddColumnIfMissing(connection, "Benutzer", "Mitarbeitennummer", "TEXT");
|
||||
AddColumnIfMissing(connection, "Benutzer", "Abteilung", "TEXT");
|
||||
AddColumnIfMissing(connection, "Benutzer", "MussPasswortAendern", "INTEGER DEFAULT 1");
|
||||
AddColumnIfMissing(connection, "Zeiteintraege", "LetzteBearbeitung", "TEXT");
|
||||
}
|
||||
|
||||
private void AddColumnIfMissing(SqliteConnection connection, string tableName, string columnName, string columnType)
|
||||
@ -247,9 +248,10 @@ namespace ChronoFlow.Persistence
|
||||
var cmd = connection.CreateCommand();
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO Zeiteintraege
|
||||
(Mitarbeiter, Startzeit, Endzeit, Projekt, Kommentar, Erledigt, MitarbeiterKommentar)
|
||||
VALUES ($Mitarbeiter, $Startzeit, $Endzeit, $Projekt, $Kommentar, $Erledigt, $MitarbeiterKommentar);
|
||||
";
|
||||
(Mitarbeiter, Startzeit, Endzeit, Projekt, Kommentar, Erledigt, MitarbeiterKommentar, LetzteBearbeitung)
|
||||
VALUES
|
||||
($Mitarbeiter, $Startzeit, $Endzeit, $Projekt, $Kommentar, $Erledigt, $MitarbeiterKommentar, $LetzteBearbeitung);";
|
||||
|
||||
|
||||
cmd.Parameters.AddWithValue("$Mitarbeiter", eintrag.Mitarbeiter);
|
||||
cmd.Parameters.AddWithValue("$Startzeit", eintrag.Startzeit.ToString("o"));
|
||||
@ -258,6 +260,7 @@ namespace ChronoFlow.Persistence
|
||||
cmd.Parameters.AddWithValue("$Kommentar", eintrag.Kommentar ?? "");
|
||||
cmd.Parameters.AddWithValue("$Erledigt", eintrag.Erledigt ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("$MitarbeiterKommentar", eintrag.MitarbeiterKommentar ?? "");
|
||||
cmd.Parameters.AddWithValue("$LetzteBearbeitung", DateTime.Now.ToString("o"));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
@ -302,13 +305,13 @@ namespace ChronoFlow.Persistence
|
||||
cmd.CommandText = @"
|
||||
UPDATE Zeiteintraege
|
||||
SET Projekt = $Projekt,
|
||||
Kommentar = $Kommentar,
|
||||
Startzeit = $Startzeit,
|
||||
Endzeit = $Endzeit,
|
||||
Mitarbeiter = $Mitarbeiter,
|
||||
Erledigt = $Erledigt
|
||||
WHERE Id = $Id;
|
||||
";
|
||||
Kommentar = $Kommentar,
|
||||
Startzeit = $Startzeit,
|
||||
Endzeit = $Endzeit,
|
||||
Mitarbeiter = $Mitarbeiter,
|
||||
Erledigt = $Erledigt,
|
||||
LetzteBearbeitung = $LetzteBearbeitung
|
||||
WHERE Id = $Id;";
|
||||
|
||||
cmd.Parameters.AddWithValue("$Projekt", projekt.Projekt);
|
||||
cmd.Parameters.AddWithValue("$Kommentar", projekt.Kommentar ?? "");
|
||||
@ -317,6 +320,7 @@ namespace ChronoFlow.Persistence
|
||||
cmd.Parameters.AddWithValue("$Mitarbeiter", projekt.Mitarbeiter);
|
||||
cmd.Parameters.AddWithValue("$Erledigt", projekt.Erledigt ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("$Id", projekt.Id);
|
||||
cmd.Parameters.AddWithValue("$LetzteBearbeitung", DateTime.Now.ToString("o"));
|
||||
|
||||
int rowsAffected = cmd.ExecuteNonQuery();
|
||||
Console.WriteLine($"✏ Projekt aktualisiert (Id={projekt.Id}, Rows affected: {rowsAffected})");
|
||||
@ -464,34 +468,39 @@ namespace ChronoFlow.Persistence
|
||||
Console.WriteLine($"🔒 Passwort für Benutzer '{username}' zurückgesetzt (Rows affected: {rowsAffected})");
|
||||
}
|
||||
|
||||
public async Task<List<Zeiteintrag>> GetEintraegeFuerMitarbeiterAsync(string mitarbeiterName)
|
||||
public async Task<List<Zeiteintrag>> GetEintraegeFuerMitarbeiterAsync(string name)
|
||||
{
|
||||
var eintraege = new List<Zeiteintrag>();
|
||||
|
||||
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||
await connection.OpenAsync();
|
||||
|
||||
var cmd = connection.CreateCommand();
|
||||
cmd.CommandText = @"
|
||||
SELECT * FROM Zeiteintraege
|
||||
WHERE Mitarbeiter = $Mitarbeiter;
|
||||
";
|
||||
cmd.Parameters.AddWithValue("$Mitarbeiter", mitarbeiterName);
|
||||
SELECT Id, Mitarbeiter, Startzeit, Endzeit, Projekt, Kommentar, Erledigt, MitarbeiterKommentar, LetzteBearbeitung
|
||||
FROM Zeiteintraege
|
||||
WHERE Mitarbeiter = $Name;
|
||||
";
|
||||
cmd.Parameters.AddWithValue("$Name", name);
|
||||
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
eintraege.Add(new Zeiteintrag
|
||||
{
|
||||
Id = reader.GetInt32(0),
|
||||
Mitarbeiter = reader.GetString(1),
|
||||
Startzeit = DateTime.Parse(reader.GetString(2)),
|
||||
Endzeit = DateTime.Parse(reader.GetString(3)),
|
||||
Startzeit = reader.GetDateTime(2),
|
||||
Endzeit = reader.GetDateTime(3),
|
||||
Projekt = reader.GetString(4),
|
||||
Kommentar = reader.GetString(5),
|
||||
Erledigt = Convert.ToInt32(reader["Erledigt"]) == 1,
|
||||
MitarbeiterKommentar = reader.GetString(7)
|
||||
Erledigt = reader.GetBoolean(6),
|
||||
MitarbeiterKommentar = reader.GetString(7),
|
||||
LetzteBearbeitung = reader.IsDBNull(8) ? DateTime.MinValue : reader.GetDateTime(8)
|
||||
});
|
||||
}
|
||||
|
||||
return eintraege;
|
||||
}
|
||||
|
||||
@ -502,19 +511,22 @@ namespace ChronoFlow.Persistence
|
||||
|
||||
var cmd = connection.CreateCommand();
|
||||
cmd.CommandText = @"
|
||||
UPDATE Zeiteintraege
|
||||
SET Erledigt = $Erledigt,
|
||||
MitarbeiterKommentar = $Kommentar
|
||||
WHERE Id = $Id;
|
||||
";
|
||||
UPDATE Zeiteintraege
|
||||
SET Erledigt = $Erledigt,
|
||||
MitarbeiterKommentar = $Kommentar,
|
||||
LetzteBearbeitung = $Bearbeitet
|
||||
WHERE Id = $Id;
|
||||
";
|
||||
|
||||
cmd.Parameters.AddWithValue("$Erledigt", erledigt ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("$Kommentar", mitarbeiterKommentar ?? "");
|
||||
cmd.Parameters.AddWithValue("$Bearbeitet", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
cmd.Parameters.AddWithValue("$Id", id);
|
||||
|
||||
int rowsAffected = await cmd.ExecuteNonQueryAsync();
|
||||
Console.WriteLine($"✏ Zeiteintrag (Id={id}) aktualisiert: erledigt={erledigt}, kommentar gesetzt.");
|
||||
Console.WriteLine($"✏ Zeiteintrag (Id={id}) aktualisiert: erledigt={erledigt}, LetzteBearbeitung gesetzt.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -3,57 +3,37 @@
|
||||
xmlns:model="clr-namespace:ChronoFlow.Model;assembly=ChronoFlow.Model"
|
||||
x:Class="ChronoFlow.View.Admin.AdminMainView">
|
||||
|
||||
<SplitView x:Name="AdminPane" DisplayMode="CompactInline" IsPaneOpen="True" CompactPaneLength="37" OpenPaneLength="200">
|
||||
<DockPanel>
|
||||
<!-- 🧭 Top-Menüleiste für Admins -->
|
||||
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Background="Black" Margin="5" Spacing="10">
|
||||
<Button Content="📋 Alle bestehenden Projekte" Click="AlleProjekte_Click"/>
|
||||
<Button Content="👥 Mitarbeiterliste" Click="MitarbeiterListe_Click"/>
|
||||
<Button Content="✅ Abgeschlossene Projekte" Click="AbgeschlosseneProjekte_Click"/>
|
||||
<Button Content="➕ Mitarbeiter hinzufügen" Click="MitarbeiterHinzufuegen_Click"/>
|
||||
<Button Content="➕ Projekt erstellen" Click="ProjektErstellen_Click"/>
|
||||
|
||||
<!-- Linke Sidebar (SplitView-Pane) -->
|
||||
<SplitView.Pane>
|
||||
<StackPanel>
|
||||
<!-- Burger-Button -->
|
||||
<Button Content="☰" Click="TogglePane_Click"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Navigation Buttons -->
|
||||
<Button Content="🏠 Dashboard" Click="Dashboard_Click"/>
|
||||
<Button Content="📋 Alle Projekte anzeigen" Click="AlleProjekte_Click"/>
|
||||
<Button Content="👥 Mitarbeiter-Liste" Click="MitarbeiterListe_Click"/>
|
||||
<Button Content="✅ Abgeschlossene Projekte" Click="AbgeschlosseneProjekte_Click" />
|
||||
<Button Content="⚙ Einstellungen" Click="Einstellungen_Click"/>
|
||||
</StackPanel>
|
||||
</SplitView.Pane>
|
||||
<!-- Hauptinhalt -->
|
||||
<StackPanel Margin="20" Spacing="15">
|
||||
<TextBlock Text="Admin-Dashboard" FontSize="24" FontWeight="Bold" HorizontalAlignment="Center"/>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<SplitView.Content>
|
||||
<StackPanel Margin="20" Spacing="15">
|
||||
|
||||
<!-- Überschrift -->
|
||||
<TextBlock Text="Admin-Dashboard" FontSize="24" FontWeight="Bold" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="Zuletzt hinzugefügte Projekte" FontSize="18" FontWeight="SemiBold" Margin="0,20,0,10"/>
|
||||
|
||||
<!-- Aktions-Buttons (oben) -->
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="10">
|
||||
<Button Content="➕ Mitarbeiter hinzufügen" Width="200" Height="50" Click="MitarbeiterHinzufuegen_Click"/>
|
||||
<Button Content="➕ Projekt erstellen" Width="200" Height="50" Click="ProjektErstellen_Click"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Anzeige der letzten Projekte -->
|
||||
<TextBlock Text="Zuletzt hinzugefügte Projekte" FontSize="18" FontWeight="SemiBold" Margin="0,20,0,10"/>
|
||||
|
||||
<ItemsControl x:Name="LetzteProjekteListe">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type model:Zeiteintrag}">
|
||||
<Border BorderBrush="Gray" BorderThickness="1" Padding="10" Margin="0,5">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Projekt}" FontWeight="Bold"/>
|
||||
<TextBlock Text="{Binding Mitarbeiter}"/>
|
||||
<TextBlock Text="{Binding Startzeit, StringFormat='Start: {0:G}'}"/>
|
||||
<TextBlock Text="{Binding Endzeit, StringFormat='Ende: {0:G}'}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
</ItemsControl>
|
||||
|
||||
</StackPanel>
|
||||
</SplitView.Content>
|
||||
|
||||
</SplitView>
|
||||
<ItemsControl x:Name="LetzteProjekteListe">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type model:Zeiteintrag}">
|
||||
<Border BorderBrush="Gray" BorderThickness="1" Padding="10" Margin="0,5">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Projekt}" FontWeight="Bold"/>
|
||||
<TextBlock Text="{Binding Mitarbeiter}"/>
|
||||
<TextBlock Text="{Binding Startzeit, StringFormat='Start: {0:G}'}"/>
|
||||
<TextBlock Text="{Binding Endzeit, StringFormat='Ende: {0:G}'}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
|
||||
@ -67,12 +67,6 @@ namespace ChronoFlow.View.Admin
|
||||
{
|
||||
_viewManager.Show("ProjektErstellen");
|
||||
}
|
||||
|
||||
private void Dashboard_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_viewManager.Show("AdminMain");
|
||||
}
|
||||
|
||||
private void AlleProjekte_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_viewManager.Show("AlleProjekte");
|
||||
@ -83,15 +77,9 @@ namespace ChronoFlow.View.Admin
|
||||
_viewManager.Show("MitarbeiterListe");
|
||||
}
|
||||
|
||||
private void Einstellungen_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_viewManager.Show("Einstellungen");
|
||||
}
|
||||
|
||||
|
||||
private void TogglePane_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AdminPane.IsPaneOpen = !AdminPane.IsPaneOpen;
|
||||
}
|
||||
|
||||
|
||||
public void AktualisiereLetzteProjekte()
|
||||
{
|
||||
@ -102,5 +90,7 @@ namespace ChronoFlow.View.Admin
|
||||
{
|
||||
_viewManager.Show("AbgeschlosseneProjekte");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
x:Class="ChronoFlow.View.Admin.MitarbeiterBearbeitenDialog"
|
||||
Width="450" Height="600"
|
||||
Title="Mitarbeiter bearbeiten">
|
||||
|
||||
<StackPanel Margin="20" Spacing="10">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="20" Spacing="15">
|
||||
<TextBlock Text="Username:" />
|
||||
<TextBox x:Name="UsernameBox" />
|
||||
|
||||
@ -28,4 +28,5 @@
|
||||
IsVisible="False"
|
||||
Margin="0,10,0,0" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Window>
|
||||
@ -4,7 +4,8 @@
|
||||
Width="500" Height="600"
|
||||
Title="Projekt bearbeiten">
|
||||
|
||||
<StackPanel Margin="20" Spacing="12">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="20" Spacing="15">
|
||||
<TextBlock Text="Projektname:" />
|
||||
<TextBox x:Name="ProjektnameBox" />
|
||||
|
||||
@ -25,4 +26,5 @@
|
||||
<Button Content="❌ Abbrechen" Width="130" Click="AbbrechenButton_Click" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Window>
|
||||
@ -2,7 +2,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="ChronoFlow.View.Admin.ProjektErstellenView">
|
||||
|
||||
<StackPanel Margin="20" Spacing="10">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="20" Spacing="15">
|
||||
|
||||
<TextBlock Text="Neues Projekt erstellen" FontSize="20" FontWeight="Bold" HorizontalAlignment="Center" />
|
||||
|
||||
@ -29,11 +30,12 @@
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Center" Margin="0,10,0,0">
|
||||
<Button Content="✅ Speichern" Click="SpeichernButton_Click" Width="115" />
|
||||
<Button Content="⬅ Zurück zum Dashboard" Click="ZurueckButton_Click" Width="150" />
|
||||
<Button Content="⬅ Zurück zum Dashboard" Click="ZurueckButton_Click" Width="180" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock x:Name="FeedbackText" Foreground="Red" IsVisible="False" />
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
</UserControl>
|
||||
@ -1,8 +1,15 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:themes="clr-namespace:Avalonia.Themes.Fluent;assembly=Avalonia.Themes.Fluent"
|
||||
x:Class="ChronoFlow.App"
|
||||
RequestedThemeVariant="Default">
|
||||
xmlns:conv="clr-namespace:ChronoFlow.View.Converter"
|
||||
x:Class="ChronoFlow.App">
|
||||
|
||||
<Application.Resources>
|
||||
<conv:BoolToBrushConverter x:Key="BoolToBrushConverter"
|
||||
TrueBrush="Blue"
|
||||
FalseBrush="Gray"/>
|
||||
</Application.Resources>
|
||||
|
||||
<Application.Styles>
|
||||
<themes:FluentTheme />
|
||||
</Application.Styles>
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="0.10.4" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.6" />
|
||||
<PackageReference Include="ReactiveUI" Version="20.3.1" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.1" />
|
||||
<PackageReference Include="WCKY.Avalonia.AnimationLibrary" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
24
ChronoFlow.View/Converter/BoolToBrushConverter.cs
Normal file
24
ChronoFlow.View/Converter/BoolToBrushConverter.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace ChronoFlow.View.Converter
|
||||
{
|
||||
public class BoolToBrushConverter : IValueConverter
|
||||
{
|
||||
public IBrush TrueBrush { get; set; } = Brushes.Blue;
|
||||
public IBrush FalseBrush { get; set; } = Brushes.Gray;
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is bool b)
|
||||
return b ? TrueBrush : FalseBrush;
|
||||
|
||||
return FalseBrush;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
@ -106,6 +106,7 @@ namespace ChronoFlow.View
|
||||
try
|
||||
{
|
||||
Console.WriteLine("🚀 Öffne MainWindow...");
|
||||
user.LetzterLogin = DateTime.Now;
|
||||
var main = new MainWindow(user);
|
||||
main.Show();
|
||||
Console.WriteLine("✅ MainWindow wurde geöffnet.");
|
||||
@ -120,5 +121,6 @@ namespace ChronoFlow.View
|
||||
ErrorText.IsVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,9 +5,18 @@
|
||||
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="600"
|
||||
x:Class="ChronoFlow.View.MainWindow"
|
||||
Title="ChronoFlow">
|
||||
|
||||
<DockPanel LastChildFill="True">
|
||||
<Button Content="🔓 Logout"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="5"
|
||||
Padding="8,4"
|
||||
Click="Logout_Click"
|
||||
DockPanel.Dock="Top"
|
||||
Background="Transparent"
|
||||
BorderBrush="Gray"/>
|
||||
<Grid>
|
||||
<ContentControl x:Name="ContentArea" />
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
|
||||
</Window>
|
||||
@ -2,6 +2,7 @@ using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using ChronoFlow.Model;
|
||||
using ChronoFlow.Persistence;
|
||||
using ChronoFlow.View.Admin;
|
||||
using ChronoFlow.View.Mitarbeiter;
|
||||
|
||||
@ -27,7 +28,8 @@ namespace ChronoFlow.View
|
||||
_viewManager.Register("AlleProjekte", () => new AlleProjekteView(_viewManager));
|
||||
_viewManager.Register("MitarbeiterListe", () => new MitarbeiterListeView(_viewManager));
|
||||
_viewManager.Register("AbgeschlosseneProjekte", () => new AbgeschlosseneProjekteView(_viewManager));
|
||||
_viewManager.Register("Zeiterfassung", () => new EmployeeTasksView(_loggedInUser.Username));
|
||||
_viewManager.Register("Zeiterfassung", () =>
|
||||
new EmployeeTasksView(_loggedInUser, new SqliteZeiterfassungsService()));
|
||||
|
||||
if (_loggedInUser.Role == "Admin")
|
||||
{
|
||||
@ -60,5 +62,12 @@ namespace ChronoFlow.View
|
||||
{
|
||||
_viewManager.Show("AdminMain");
|
||||
}
|
||||
private void Logout_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var loginWindow = new LoginWindow();
|
||||
loginWindow.Show();
|
||||
|
||||
this.Close(); // Aktuelles Fenster schließen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,28 +1,45 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:ChronoFlow.ViewModels.Mitarbeiter"
|
||||
xmlns:converter="clr-namespace:ChronoFlow.View.Converter"
|
||||
x:Class="ChronoFlow.View.Mitarbeiter.EmployeeTasksView">
|
||||
<StackPanel Margin="20" Spacing="10">
|
||||
<TextBlock Text="Meine Aufgaben" FontSize="24" FontWeight="Bold"/>
|
||||
<UserControl.Resources>
|
||||
<converter:BoolToBrushConverter x:Key="BoolToBrushConverter"/>
|
||||
</UserControl.Resources>
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="20" Spacing="10">
|
||||
<TextBlock Text="Meine Aufgaben" FontSize="24" FontWeight="Bold"/>
|
||||
|
||||
<ItemsControl ItemsSource="{Binding Eintraege}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderThickness="1" BorderBrush="Gray" CornerRadius="4" Padding="10" Margin="5">
|
||||
<StackPanel Spacing="5">
|
||||
<TextBlock Text="{Binding Projekt}" FontWeight="Bold"/>
|
||||
<CheckBox Content="Erledigt" IsChecked="{Binding Erledigt}"/>
|
||||
<TextBox Text="{Binding MitarbeiterKommentar}" Watermark="Kommentar hinzufügen..."/>
|
||||
<TextBlock Text="{Binding Endzeit, StringFormat='Deadline: {0:dd.MM.yyyy}'}"
|
||||
Foreground="{Binding PrioritaetsFarbe}"
|
||||
FontWeight="Bold" FontSize="14"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<!-- 🟢 Der Hinweis kommt vor dem ItemsControl -->
|
||||
<TextBlock Text="🎉 Du hast aktuell keine Aufgaben!"
|
||||
FontSize="16"
|
||||
FontStyle="Italic"
|
||||
FontWeight="Medium"
|
||||
HorizontalAlignment="Center"
|
||||
IsVisible="{Binding HatKeineEintraege}"/>
|
||||
|
||||
<Button Content="Änderungen speichern" Command="{Binding SpeichereEintraegeCommand}"/>
|
||||
<TextBlock Text="{Binding StatusText}" Foreground="Green" FontStyle="Italic"/>
|
||||
</StackPanel>
|
||||
<!-- 📝 Die eigentliche Aufgabenliste -->
|
||||
<ItemsControl ItemsSource="{Binding Eintraege}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="{Binding WurdeSeitLoginBearbeitet, Converter={StaticResource BoolToBrushConverter}}"
|
||||
BorderThickness="1" CornerRadius="4" Padding="10" Margin="5">
|
||||
<StackPanel Spacing="5">
|
||||
<TextBlock Text="{Binding Projekt}" FontWeight="Bold"/>
|
||||
<CheckBox Content="Erledigt" IsChecked="{Binding Erledigt}"/>
|
||||
<TextBox Text="{Binding MitarbeiterKommentar}" Watermark="Kommentar hinzufügen..."/>
|
||||
<TextBlock Text="{Binding Endzeit, StringFormat='Deadline: {0:dd.MM.yyyy}'}"
|
||||
Foreground="{Binding PrioritaetsFarbe}"
|
||||
FontWeight="Bold" FontSize="14"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<Button Content="Änderungen speichern" Command="{Binding SpeichereEintraegeCommand}"/>
|
||||
<TextBlock Text="{Binding StatusText}" Foreground="Green" FontStyle="Italic"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
</UserControl>
|
||||
@ -1,20 +1,16 @@
|
||||
using Avalonia.Controls;
|
||||
using ChronoFlow.ViewModels.Mitarbeiter;
|
||||
using ChronoFlow.Persistence;
|
||||
using ChronoFlow.Model;
|
||||
|
||||
namespace ChronoFlow.View.Mitarbeiter
|
||||
{
|
||||
public partial class EmployeeTasksView : UserControl
|
||||
{
|
||||
public EmployeeTasksView(string benutzername)
|
||||
public EmployeeTasksView(User user, IZeiterfassungsRepository repository)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Benutzername dynamisch übergeben
|
||||
DataContext = new EmployeeTasksViewModel(
|
||||
new SqliteZeiterfassungsService(),
|
||||
benutzername
|
||||
);
|
||||
DataContext = new EmployeeTasksViewModel(user, repository);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
@ -9,46 +11,75 @@ namespace ChronoFlow.ViewModels.Mitarbeiter
|
||||
{
|
||||
public partial class EmployeeTasksViewModel : ObservableObject
|
||||
{
|
||||
// Liste aller Zeiteinträge für den aktuell eingeloggten Mitarbeiter
|
||||
private readonly User _benutzer;
|
||||
private readonly IZeiterfassungsRepository _repository;
|
||||
private readonly string aktuellerBenutzername;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<Zeiteintrag> eintraege = new();
|
||||
|
||||
// Ausgabe für Erfolg/Nachricht
|
||||
[ObservableProperty]
|
||||
private string? statusText;
|
||||
|
||||
private readonly IZeiterfassungsRepository repository;
|
||||
private readonly string aktuellerBenutzername;
|
||||
public bool HatKeineEintraege => Eintraege.Count == 0;
|
||||
|
||||
// Konstruktor erhält Repository (z. B. SqliteZeiterfassungsService) + aktuellen Benutzernamen
|
||||
public EmployeeTasksViewModel(IZeiterfassungsRepository repository, string aktuellerBenutzername)
|
||||
partial void OnEintraegeChanged(ObservableCollection<Zeiteintrag>? oldValue, ObservableCollection<Zeiteintrag> newValue)
|
||||
{
|
||||
this.repository = repository;
|
||||
this.aktuellerBenutzername = aktuellerBenutzername;
|
||||
|
||||
// Direkt beim Start laden
|
||||
_ = LadeEintraegeAsync();
|
||||
OnPropertyChanged(nameof(HatKeineEintraege));
|
||||
}
|
||||
|
||||
public EmployeeTasksViewModel(User benutzer, IZeiterfassungsRepository repository)
|
||||
{
|
||||
_benutzer = benutzer;
|
||||
_repository = repository;
|
||||
aktuellerBenutzername = benutzer.Username;
|
||||
|
||||
Console.WriteLine($"[DEBUG] ViewModel erstellt für Benutzer: {aktuellerBenutzername}");
|
||||
|
||||
_ = LadeEintraegeAsync(); // Lade Daten automatisch beim Öffnen
|
||||
}
|
||||
|
||||
// Lädt alle Einträge für den Benutzer aus der Datenbank
|
||||
[RelayCommand]
|
||||
public async Task LadeEintraegeAsync()
|
||||
{
|
||||
var eintraegeAusDb = await repository.GetEintraegeFuerMitarbeiterAsync(aktuellerBenutzername);
|
||||
Eintraege = new ObservableCollection<Zeiteintrag>(eintraegeAusDb);
|
||||
StatusText = $"🔄 {Eintraege.Count} Einträge geladen.";
|
||||
var eintraegeAusDb = await _repository.GetEintraegeFuerMitarbeiterAsync(aktuellerBenutzername);
|
||||
|
||||
var offene = eintraegeAusDb
|
||||
.Where(e => !e.Erledigt)
|
||||
.OrderBy(e => e.Endzeit)
|
||||
.ToList();
|
||||
|
||||
// 🔔 Setze Markierung für geänderte Aufgaben
|
||||
foreach (var eintrag in offene)
|
||||
{
|
||||
eintrag.WurdeSeitLoginBearbeitet = eintrag.LetzteBearbeitung > _benutzer.LetzterLogin;
|
||||
|
||||
// 🔍 Debug-Ausgabe zur Prüfung
|
||||
Console.WriteLine($"[DEBUG] Eintrag {eintrag.Id}: Endzeit={eintrag.Endzeit}, LetzteBearbeitung={eintrag.LetzteBearbeitung}, LetzterLogin={_benutzer.LetzterLogin}, Markiert={eintrag.WurdeSeitLoginBearbeitet}");
|
||||
}
|
||||
|
||||
|
||||
if (offene.Any(e => e.WurdeSeitLoginBearbeitet))
|
||||
StatusText = "📢 Es wurden Aufgaben seit Ihrem letzten Login geändert.";
|
||||
|
||||
Eintraege = new ObservableCollection<Zeiteintrag>(offene);
|
||||
}
|
||||
|
||||
// Speichert Änderungen (Status + Kommentar) für alle sichtbaren Einträge
|
||||
|
||||
[RelayCommand]
|
||||
public async Task SpeichereEintraegeAsync()
|
||||
{
|
||||
foreach (var eintrag in Eintraege)
|
||||
{
|
||||
await repository.UpdateStatusUndKommentarAsync(eintrag.Id, eintrag.Erledigt, eintrag.MitarbeiterKommentar);
|
||||
await _repository.UpdateStatusUndKommentarAsync(
|
||||
eintrag.Id,
|
||||
eintrag.Erledigt,
|
||||
eintrag.MitarbeiterKommentar
|
||||
);
|
||||
}
|
||||
|
||||
StatusText = "✅ Änderungen gespeichert.";
|
||||
await LadeEintraegeAsync(); // automatisch neu laden
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="ChronoFlow.View.MitarbeiterHinzufuegenView">
|
||||
|
||||
<StackPanel Margin="20" Spacing="10">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="20" Spacing="15">
|
||||
<TextBlock Text="➕ Mitarbeiter hinzufügen" FontWeight="Bold" FontSize="20" HorizontalAlignment="Center"/>
|
||||
|
||||
<TextBox x:Name="UsernameBox" Watermark="Benutzername"/>
|
||||
@ -20,4 +21,5 @@
|
||||
<Button Content="⬅ Zurück zum Dashboard" Click="ZurueckZumDashboard_Click" HorizontalAlignment="Center" Margin="0,10,0,0"/>
|
||||
<TextBlock x:Name="FeedbackText" Foreground="Green" IsVisible="False" TextAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
Loading…
Reference in New Issue
Block a user