diverse änderungen
This commit is contained in:
parent
176ff2f211
commit
dc760febde
@ -1,20 +1,38 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using ChronoFlow.Model;
|
using ChronoFlow.Model;
|
||||||
|
using ChronoFlow.Persistence;
|
||||||
|
|
||||||
namespace ChronoFlow.Controller
|
namespace ChronoFlow.Controller
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Vermittelt zwischen der View und dem Speichersystem (SQLite)
|
||||||
|
/// </summary>
|
||||||
public class ZeiterfassungsController
|
public class ZeiterfassungsController
|
||||||
{
|
{
|
||||||
private readonly List<Zeiteintrag> _eintraege = new();
|
private readonly SqliteZeiterfassungsService _dbService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Konstruktor: Initialisiert die Verbindung zum SQLite-Dienst
|
||||||
|
/// </summary>
|
||||||
|
public ZeiterfassungsController()
|
||||||
|
{
|
||||||
|
_dbService = new SqliteZeiterfassungsService();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Speichert einen neuen Zeiteintrag dauerhaft in der SQLite-Datenbank
|
||||||
|
/// </summary>
|
||||||
public void SpeichereEintrag(Zeiteintrag eintrag)
|
public void SpeichereEintrag(Zeiteintrag eintrag)
|
||||||
{
|
{
|
||||||
_eintraege.Add(eintrag);
|
_dbService.SpeichereEintrag(eintrag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lädt alle vorhandenen Einträge aus der Datenbank
|
||||||
|
/// </summary>
|
||||||
public List<Zeiteintrag> LadeAlleEintraege()
|
public List<Zeiteintrag> LadeAlleEintraege()
|
||||||
{
|
{
|
||||||
return new List<Zeiteintrag>(_eintraege);
|
return _dbService.LadeAlleZeiteintraege();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,5 +10,7 @@ namespace ChronoFlow.Model
|
|||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
public string Password { get; set; } //vorerst im Klartext, wird später geändert
|
public string Password { get; set; } //vorerst im Klartext, wird später geändert
|
||||||
public string Role { get; set; } //"Admin" oder "Mitarbeiter"
|
public string Role { get; set; } //"Admin" oder "Mitarbeiter"
|
||||||
|
public string Mitarbeiternummer { get; set; } = "";
|
||||||
|
public string Abteilung { get; set; } = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,4 +10,8 @@
|
|||||||
<ProjectReference Include="..\ChronoFlow.Model\ChronoFlow.Model.csproj" />
|
<ProjectReference Include="..\ChronoFlow.Model\ChronoFlow.Model.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.0-preview.3.25171.6" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
184
ChronoFlow.Persistence/SqliteZeiterfassungsService.cs
Normal file
184
ChronoFlow.Persistence/SqliteZeiterfassungsService.cs
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using Microsoft.Data.Sqlite;
|
||||||
|
using ChronoFlow.Model;
|
||||||
|
|
||||||
|
namespace ChronoFlow.Persistence
|
||||||
|
{
|
||||||
|
public class SqliteZeiterfassungsService
|
||||||
|
{
|
||||||
|
private readonly string _dbPath = "chrono_data_v2.sb";
|
||||||
|
|
||||||
|
public SqliteZeiterfassungsService()
|
||||||
|
{
|
||||||
|
// Prüfe, ob die DB existiert, sonst erstelle sie
|
||||||
|
if (!File.Exists(_dbPath))
|
||||||
|
ErstelleDatenbank();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ErstelleDatenbank()
|
||||||
|
{
|
||||||
|
Console.WriteLine("🛠️ ErstelleDatenbank wurde aufgerufen!");
|
||||||
|
|
||||||
|
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
var cmd1 = connection.CreateCommand();
|
||||||
|
cmd1.CommandText = @"
|
||||||
|
CREATE TABLE IF NOT EXISTS Zeiteintraege (
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
Mitarbeiter TEXT NOT NULL,
|
||||||
|
Startzeit TEXT NOT NULL,
|
||||||
|
Endzeit TEXT NOT NULL,
|
||||||
|
Projekt TEXT,
|
||||||
|
Kommentar TEXT,
|
||||||
|
Erledigt INTEGER,
|
||||||
|
MitarbeiterKommentar TEXT
|
||||||
|
);";
|
||||||
|
cmd1.ExecuteNonQuery();
|
||||||
|
|
||||||
|
var cmd2 = connection.CreateCommand();
|
||||||
|
cmd2.CommandText = @"
|
||||||
|
CREATE TABLE IF NOT EXISTS Benutzer (
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
Username TEXT NOT NULL,
|
||||||
|
Password TEXT NOT NULL,
|
||||||
|
Role TEXT NOT NULL,
|
||||||
|
Mitarbeiternummer TEXT,
|
||||||
|
Abteilung TEXT
|
||||||
|
);";
|
||||||
|
cmd2.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SpeichereEintrag(Zeiteintrag eintrag)
|
||||||
|
{
|
||||||
|
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = @"
|
||||||
|
INSERT INTO Zeiteintraege
|
||||||
|
(Mitarbeiter, Startzeit, Endzeit, Projekt, Kommentar, Erledigt, MitarbeiterKommentar)
|
||||||
|
VALUES ($Mitarbeiter, $Startzeit, $Endzeit, $Projekt, $Kommentar, $Erledigt, $MitarbeiterKommentar);
|
||||||
|
";
|
||||||
|
|
||||||
|
cmd.Parameters.AddWithValue("$Mitarbeiter", eintrag.Mitarbeiter);
|
||||||
|
cmd.Parameters.AddWithValue("$Startzeit", eintrag.Startzeit.ToString("o"));
|
||||||
|
cmd.Parameters.AddWithValue("$Endzeit", eintrag.Endzeit.ToString("o"));
|
||||||
|
cmd.Parameters.AddWithValue("$Projekt", eintrag.Projekt ?? "");
|
||||||
|
cmd.Parameters.AddWithValue("$Kommentar", eintrag.Kommentar ?? "");
|
||||||
|
cmd.Parameters.AddWithValue("$Erledigt", eintrag.Erledigt ? 1 : 0);
|
||||||
|
cmd.Parameters.AddWithValue("$MitarbeiterKommentar", eintrag.MitarbeiterKommentar ?? "");
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Zeiteintrag> LadeAlleZeiteintraege()
|
||||||
|
{
|
||||||
|
var eintraege = new List<Zeiteintrag>();
|
||||||
|
|
||||||
|
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = "SELECT * FROM Zeiteintraege;";
|
||||||
|
|
||||||
|
using var reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
eintraege.Add(new Zeiteintrag
|
||||||
|
{
|
||||||
|
Mitarbeiter = reader.GetString(1),
|
||||||
|
Startzeit = DateTime.Parse(reader.GetString(2)),
|
||||||
|
Endzeit = DateTime.Parse(reader.GetString(3)),
|
||||||
|
Projekt = reader.GetString(4),
|
||||||
|
Kommentar = reader.GetString(5),
|
||||||
|
Erledigt = Convert.ToInt32(reader["Erledigt"]) == 1,
|
||||||
|
MitarbeiterKommentar = reader.GetString(7)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return eintraege;
|
||||||
|
}
|
||||||
|
public List<string> LadeAlleMitarbeiterNamen()
|
||||||
|
{
|
||||||
|
var namen = new List<string>();
|
||||||
|
|
||||||
|
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = "SELECT Username From Benutzer Where Role = 'Mitarbeiter';";
|
||||||
|
|
||||||
|
using var reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
namen.Add(reader.GetString(0));
|
||||||
|
}
|
||||||
|
return namen;
|
||||||
|
}
|
||||||
|
public List<User> LadeAlleBenutzer()
|
||||||
|
{
|
||||||
|
var benutzerListe = new List<User>();
|
||||||
|
|
||||||
|
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = "SELECT Username, Password, Role, Mitarbeiternummer, Abteilung FROM Benutzer;";
|
||||||
|
|
||||||
|
using var reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
benutzerListe.Add(new User
|
||||||
|
{
|
||||||
|
Username = reader.GetString(0),
|
||||||
|
Password = reader.GetString(1),
|
||||||
|
Role = reader.GetString(2),
|
||||||
|
Mitarbeiternummer = reader.IsDBNull(3) ? "" : reader.GetString(3),
|
||||||
|
Abteilung = reader.IsDBNull(4) ? "" : reader.GetString(4)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return benutzerListe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ErstelleStandardAdmin()
|
||||||
|
{
|
||||||
|
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = @"
|
||||||
|
INSERT INTO Benutzer (Username, Password, Role, Mitarbeiternummer, Abteilung)
|
||||||
|
VALUES ('admin', 'admin', 'Admin', '0001', 'IT');
|
||||||
|
";
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
|
Console.WriteLine("✅ Standard-Admin erfolgreich eingefügt.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> LadeAlleBenutzernamen()
|
||||||
|
{
|
||||||
|
var benutzernamen = new List<string>();
|
||||||
|
|
||||||
|
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
using var cmd = connection.CreateCommand();//<--- Wir erstellen cmd
|
||||||
|
cmd.CommandText = "SELECT Username From Benutzer;";
|
||||||
|
|
||||||
|
using var reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
benutzernamen.Add(reader.GetString(0));
|
||||||
|
}
|
||||||
|
return benutzernamen;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ using Avalonia;
|
|||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using ChronoFlow.View;
|
using ChronoFlow.View;
|
||||||
|
using ChronoFlow.Persistence;
|
||||||
|
|
||||||
namespace ChronoFlow;
|
namespace ChronoFlow;
|
||||||
|
|
||||||
@ -16,6 +17,13 @@ public partial class App : Application
|
|||||||
{
|
{
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
|
// ⬇ Initialisiert den SQLite-Service beim Programmstart,
|
||||||
|
// um sicherzustellen, dass die Datenbank-Datei und alle benötigten Tabellen
|
||||||
|
// (z.B. Zeiteintraege, Benutzer) vorhanden sind.
|
||||||
|
// Ohne diesen Aufruf würden neue Tabellen nicht angelegt werden,
|
||||||
|
// falls die Datei chrono_data.sb noch nicht existiert.
|
||||||
|
var dbInit = new SqliteZeiterfassungsService();
|
||||||
|
|
||||||
// Starte das Programm mit dem Login-Fenster
|
// Starte das Programm mit dem Login-Fenster
|
||||||
desktop.MainWindow = new LoginWindow();
|
desktop.MainWindow = new LoginWindow();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
|
using System.Linq;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.Metadata;
|
||||||
using ChronoFlow.Controller;
|
using ChronoFlow.Controller;
|
||||||
|
using ChronoFlow.Persistence;
|
||||||
|
|
||||||
namespace ChronoFlow.View
|
namespace ChronoFlow.View
|
||||||
{
|
{
|
||||||
@ -15,6 +18,9 @@ namespace ChronoFlow.View
|
|||||||
{
|
{
|
||||||
InitializeComponent(); // Verbindet XAML mit diesem Code
|
InitializeComponent(); // Verbindet XAML mit diesem Code
|
||||||
_loginController = new LoginController(); // Unsere "Logik-Klasse"
|
_loginController = new LoginController(); // Unsere "Logik-Klasse"
|
||||||
|
var service = new SqliteZeiterfassungsService();
|
||||||
|
service.ErstelleStandardAdmin();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -22,11 +28,20 @@ namespace ChronoFlow.View
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void LoginButton_Click(object? sender, RoutedEventArgs e)
|
private void LoginButton_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// Holt Benutzername und Passwort aus den Eingabefeldern
|
var username = UsernameBox.Text?.Trim();
|
||||||
string username = UsernameBox?.Text ?? string.Empty;
|
var password = PasswordBox.Text?.Trim();
|
||||||
string password = PasswordBox?.Text ?? string.Empty;
|
|
||||||
// Übergibt die Eingaben an den LoginController
|
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||||||
var user = _loginController.Authenticate(username, password);
|
{
|
||||||
|
ErrorText.Text = "Bitte Benutzername und Passwort eingeben";
|
||||||
|
ErrorText.IsVisible = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var service = new SqliteZeiterfassungsService();
|
||||||
|
var benutzerListe = service.LadeAlleBenutzer();
|
||||||
|
|
||||||
|
var user = benutzerListe.FirstOrDefault(u => u.Username == username && u.Password == password);
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,13 +6,14 @@
|
|||||||
x:Class="ChronoFlow.View.MainWindow"
|
x:Class="ChronoFlow.View.MainWindow"
|
||||||
Title="ChronoFlow.View">
|
Title="ChronoFlow.View">
|
||||||
|
|
||||||
<SplitView x:Name="PaneView" DisplayMode="CompactInline" IsPaneOpen="True" CompactPaneLength="40" OpenPaneLength="150">
|
<SplitView x:Name="PaneView" DisplayMode="CompactInline" IsPaneOpen="True" CompactPaneLength="38" OpenPaneLength="200">
|
||||||
|
|
||||||
<SplitView.Pane>
|
<SplitView.Pane>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<Button Content="☰" Click="PaneOpenClose_Click"/>
|
<Button Content="☰" Click="PaneOpenClose_Click"/>
|
||||||
<Button Content="⏱ Zeiterfassung" Click="Zeiterfassung_Click"/>
|
<Button Content="⏱ Zeiterfassung" Click="Zeiterfassung_Click"/>
|
||||||
<Button Content="📄 Auswertung"/>
|
<Button Content="📄 Auswertung"/>
|
||||||
|
<Button Content="👤 Mitarbeiter hinzufügen" Click="MitarbeiterHinzufuegen_Click"/>
|
||||||
<Button Content="⚙ Einstellungen"/>
|
<Button Content="⚙ Einstellungen"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</SplitView.Pane>
|
</SplitView.Pane>
|
||||||
|
|||||||
@ -22,6 +22,7 @@ public partial class MainWindow : Window
|
|||||||
|
|
||||||
// ✅ Register-Aufruf mit stabiler local variable
|
// ✅ Register-Aufruf mit stabiler local variable
|
||||||
_viewManager.Register("Zeiterfassung", () => new ZeiterfassungView(currentUser));
|
_viewManager.Register("Zeiterfassung", () => new ZeiterfassungView(currentUser));
|
||||||
|
_viewManager.Register("MitarbeiterHinzufuegen", () => new MitarbeiterHinzufuegenView());
|
||||||
|
|
||||||
// Begrüßungsanzeige
|
// Begrüßungsanzeige
|
||||||
ContentArea.Content = new TextBlock
|
ContentArea.Content = new TextBlock
|
||||||
@ -45,4 +46,9 @@ public partial class MainWindow : Window
|
|||||||
{
|
{
|
||||||
_viewManager.Show("Zeiterfassung");
|
_viewManager.Show("Zeiterfassung");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MitarbeiterHinzufuegen_Click(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_viewManager.Show("MitarbeiterHinzufuegen");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
22
ChronoFlow.View/MitarbeiterHinzufuegenView.axaml
Normal file
22
ChronoFlow.View/MitarbeiterHinzufuegenView.axaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
x:Class="ChronoFlow.View.MitarbeiterHinzufuegenView">
|
||||||
|
|
||||||
|
<StackPanel Margin="20" Spacing="10">
|
||||||
|
<TextBlock Text="➕ Mitarbeiter hinzufügen" FontWeight="Bold" FontSize="20" HorizontalAlignment="Center"/>
|
||||||
|
|
||||||
|
<TextBox x:Name="UsernameBox" Watermark="Benutzername"/>
|
||||||
|
<TextBox x:Name="PasswordBox" Watermark="Passwort"/>
|
||||||
|
|
||||||
|
<ComboBox x:Name="RoleBox" PlaceholderText="Rolle auswählen">
|
||||||
|
<ComboBoxItem Content="Mitarbeiter"/>
|
||||||
|
<ComboBoxItem Content="Admin"/>
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
|
<TextBox x:Name="MitarbeiternummerBox" Watermark="Mitarbeiternummer"/>
|
||||||
|
<TextBox x:Name="AbteilungBox" Watermark="Abteilung"/>
|
||||||
|
|
||||||
|
<Button Content="💾 Speichern" Click="SpeichernButton_Click" HorizontalAlignment="Center"/>
|
||||||
|
<TextBlock x:Name="FeedbackText" Foreground="Green" IsVisible="False" TextAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
69
ChronoFlow.View/MitarbeiterHinzufuegenView.axaml.cs
Normal file
69
ChronoFlow.View/MitarbeiterHinzufuegenView.axaml.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using ChronoFlow.Model;
|
||||||
|
using Microsoft.Data.Sqlite;
|
||||||
|
using ChronoFlow.Persistence;
|
||||||
|
|
||||||
|
namespace ChronoFlow.View
|
||||||
|
{
|
||||||
|
public partial class MitarbeiterHinzufuegenView : UserControl
|
||||||
|
{
|
||||||
|
public MitarbeiterHinzufuegenView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SpeichernButton_Click(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var service = new SqliteZeiterfassungsService();
|
||||||
|
|
||||||
|
string username = UsernameBox.Text ?? "";
|
||||||
|
string password = PasswordBox.Text ?? "";
|
||||||
|
string rolle = (RoleBox.SelectedItem as ComboBoxItem)?.Content?.ToString() ?? "";
|
||||||
|
string mitarbeiternummer = MitarbeiternummerBox.Text ?? "";
|
||||||
|
string abteilung = AbteilungBox.Text ?? "";
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(rolle))
|
||||||
|
{
|
||||||
|
FeedbackText.Text = "⚠ Bitte alle Pflichtfelder ausfüllen!";
|
||||||
|
FeedbackText.Foreground = Brushes.Red;
|
||||||
|
FeedbackText.IsVisible = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var connection = new SqliteConnection("Data Source=chrono_data.sb");
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = @"
|
||||||
|
INSERT INTO Benutzer (Username, Password, Role, Mitarbeiternummer, Abteilung)
|
||||||
|
VALUES ($Username, $Password, $Role, $Mitarbeiternummer, $Abteilung);";
|
||||||
|
|
||||||
|
cmd.Parameters.AddWithValue("$Username", username);
|
||||||
|
cmd.Parameters.AddWithValue("$Password", password);
|
||||||
|
cmd.Parameters.AddWithValue("$Role", rolle);
|
||||||
|
cmd.Parameters.AddWithValue("$Mitarbeiternummer", mitarbeiternummer);
|
||||||
|
cmd.Parameters.AddWithValue("$Abteilung", abteilung);
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
|
FeedbackText.Text = "✅ Mitarbeiter erfolgreich gespeichert.";
|
||||||
|
FeedbackText.Foreground = Brushes.Green;
|
||||||
|
FeedbackText.IsVisible = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
FeedbackText.Text = $"❌ Fehler: {ex.Message}";
|
||||||
|
FeedbackText.Foreground = Brushes.Red;
|
||||||
|
FeedbackText.IsVisible = true;
|
||||||
|
|
||||||
|
Console.WriteLine("❌ Ausnahme beim Speichern:");
|
||||||
|
Console.WriteLine(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Avalonia.Collections;
|
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Microsoft.Data.Sqlite;
|
||||||
|
|
||||||
namespace ChronoFlow.View
|
namespace ChronoFlow.View
|
||||||
{
|
{
|
||||||
@ -44,5 +44,6 @@ namespace ChronoFlow.View
|
|||||||
{
|
{
|
||||||
_registieredViews[name] = viewFactory;
|
_registieredViews[name] = viewFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,7 +8,10 @@
|
|||||||
|
|
||||||
<StackPanel x:Name="EingabePanel" Spacing="10">
|
<StackPanel x:Name="EingabePanel" Spacing="10">
|
||||||
<TextBlock Text="Zeiterfassung" FontWeight="Bold" FontSize="20" HorizontalAlignment="Center"/>
|
<TextBlock Text="Zeiterfassung" FontWeight="Bold" FontSize="20" HorizontalAlignment="Center"/>
|
||||||
<TextBox x:Name="MitarbeiterBox" Watermark="Mitarbeitername"/>
|
<ComboBox x:Name="MitarbeiterBoxDropdown"
|
||||||
|
Width="250"
|
||||||
|
PlaceholderText="Mitarbeitername auswählen"
|
||||||
|
Margin="0,5"/>
|
||||||
<DatePicker x:Name="DatumPicker"/>
|
<DatePicker x:Name="DatumPicker"/>
|
||||||
<TextBox x:Name="StartzeitBox" Watermark="Startzeit (z.B. 08:00)"/>
|
<TextBox x:Name="StartzeitBox" Watermark="Startzeit (z.B. 08:00)"/>
|
||||||
<TextBox x:Name="EndzeitBox" Watermark="Endzeit (z.B. 16:30)"/>
|
<TextBox x:Name="EndzeitBox" Watermark="Endzeit (z.B. 16:30)"/>
|
||||||
|
|||||||
@ -1,44 +1,59 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq; // Wichtig für .Where und .Select
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using ChronoFlow.Controller;
|
using ChronoFlow.Controller;
|
||||||
using ChronoFlow.Model;
|
using ChronoFlow.Model;
|
||||||
|
using ChronoFlow.Persistence; // Wichtig für SqliteZeiterfassungsService
|
||||||
|
|
||||||
namespace ChronoFlow.View
|
namespace ChronoFlow.View
|
||||||
{
|
{
|
||||||
public partial class ZeiterfassungView : UserControl
|
public partial class ZeiterfassungView : UserControl
|
||||||
{
|
{
|
||||||
private readonly ZeiterfassungsController _controller;
|
private readonly ZeiterfassungsController _controller;
|
||||||
|
private readonly ObservableCollection<Zeiteintrag> _anzeigeEinträge;
|
||||||
private ObservableCollection<Zeiteintrag> _anzeigeEinträge = new();
|
|
||||||
|
|
||||||
|
|
||||||
private readonly User _user;
|
private readonly User _user;
|
||||||
|
|
||||||
public ZeiterfassungView(User user)
|
public ZeiterfassungView(User user)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_controller = new ZeiterfassungsController();
|
|
||||||
_user = user;
|
_user = user;
|
||||||
|
|
||||||
//ListBox an Collection binden
|
_controller = new ZeiterfassungsController();
|
||||||
|
_anzeigeEinträge = new ObservableCollection<Zeiteintrag>();
|
||||||
|
|
||||||
|
// ✅ Benutzer aus Datenbank laden und Dropdown füllen
|
||||||
|
var benutzer = new SqliteZeiterfassungsService().LadeAlleBenutzer();
|
||||||
|
var nurMitarbeiter = benutzer
|
||||||
|
.Where(b => b.Role == "Mitarbeiter")
|
||||||
|
.Select(b => b.Username)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
MitarbeiterBoxDropdown.ItemsSource = nurMitarbeiter;
|
||||||
|
|
||||||
|
// Einträge aus SQLite laden
|
||||||
|
var geladeneEintraege = _controller.LadeAlleEintraege();
|
||||||
|
foreach (var eintrag in geladeneEintraege)
|
||||||
|
{
|
||||||
|
_anzeigeEinträge.Add(eintrag);
|
||||||
|
}
|
||||||
|
|
||||||
Eintragsliste.ItemsSource = _anzeigeEinträge;
|
Eintragsliste.ItemsSource = _anzeigeEinträge;
|
||||||
|
|
||||||
//Eingabe-Felder für Nicht-Admins ausblenden
|
// Eingabeformular nur für Admin sichtbar
|
||||||
if (_user.Role != "Admin")
|
if (_user.Role != "Admin" && EingabePanel != null)
|
||||||
{
|
{
|
||||||
EingabePanel.IsVisible = false;
|
EingabePanel.IsVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SpeichernButton_Click(object? sender, RoutedEventArgs e)
|
private void SpeichernButton_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string mitarbeiter = MitarbeiterBox.Text ?? string.Empty;
|
string mitarbeiter = MitarbeiterBoxDropdown.SelectedItem?.ToString() ?? "";
|
||||||
DateTime datum = DatumPicker.SelectedDate?.Date ?? DateTime.Today;
|
DateTime datum = DatumPicker.SelectedDate?.Date ?? DateTime.Today;
|
||||||
string startText = StartzeitBox.Text ?? "";
|
string startText = StartzeitBox.Text ?? "";
|
||||||
string endText = EndzeitBox.Text ?? "";
|
string endText = EndzeitBox.Text ?? "";
|
||||||
@ -65,11 +80,13 @@ namespace ChronoFlow.View
|
|||||||
Startzeit = datum.Date + startZeit,
|
Startzeit = datum.Date + startZeit,
|
||||||
Endzeit = datum.Date + endZeit,
|
Endzeit = datum.Date + endZeit,
|
||||||
Projekt = ProjektBox.Text,
|
Projekt = ProjektBox.Text,
|
||||||
Kommentar = KommentarBox.Text
|
Kommentar = KommentarBox.Text,
|
||||||
|
Erledigt = false
|
||||||
};
|
};
|
||||||
|
|
||||||
_controller.SpeichereEintrag(eintrag);
|
_controller.SpeichereEintrag(eintrag);
|
||||||
_anzeigeEinträge.Add(eintrag);
|
_anzeigeEinträge.Add(eintrag);
|
||||||
|
|
||||||
FeedbackText.Text = "Eintrag gespeichert.";
|
FeedbackText.Text = "Eintrag gespeichert.";
|
||||||
FeedbackText.Foreground = Brushes.Green;
|
FeedbackText.Foreground = Brushes.Green;
|
||||||
FeedbackText.IsVisible = true;
|
FeedbackText.IsVisible = true;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user