Zeiterfassung + Änderungen
This commit is contained in:
parent
dbd708aab7
commit
8abc9fc2f4
29
ChronoFlow.Controller/LoginController.cs
Normal file
29
ChronoFlow.Controller/LoginController.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Datei: Controller/LoginController.cs
|
||||||
|
using ChronoFlow.Model;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace ChronoFlow.Controller;
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
/// Verwaltet die Authentifizierung von Benutzern.
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public class LoginController
|
||||||
|
{
|
||||||
|
//Beispielhafte Benutzerliste (später DB)
|
||||||
|
private List<User> _users = new()
|
||||||
|
{
|
||||||
|
new User { Username = "admin", Password = "admin123", Role = "Admin" },
|
||||||
|
new User { Username = "max", Password = "max123", Role = "Mitarbeiter" }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prüft, ob ein Benutzer mit den eingegebenen Daten existiert.
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public User? Authenticate(string username, string password)
|
||||||
|
{
|
||||||
|
return _users.FirstOrDefault(u => u.Username == username && u.Password == password);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
ChronoFlow.Model/User.cs
Normal file
14
ChronoFlow.Model/User.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace ChronoFlow.Model
|
||||||
|
{
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
/// Repräsentiert einen Benutzer mit Benutzernamen, Passwort und Rolle.
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
public string Username { get; set; }
|
||||||
|
public string Password { get; set; } //vorerst im Klartext, wird später geändert
|
||||||
|
public string Role { get; set; } //"Admin" oder "Mitarbeiter"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<Application xmlns="https://github.com/avaloniaui"
|
<Application xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
x:Class="ChronoFlow.View.App"
|
x:Class="ChronoFlow.App"
|
||||||
RequestedThemeVariant="Default">
|
RequestedThemeVariant="Default">
|
||||||
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
using ChronoFlow.View;
|
||||||
|
|
||||||
namespace ChronoFlow.View;
|
namespace ChronoFlow;
|
||||||
|
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
@ -15,7 +16,8 @@ public partial class App : Application
|
|||||||
{
|
{
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
desktop.MainWindow = new MainWindow();
|
// Starte das Programm mit dem Login-Fenster
|
||||||
|
desktop.MainWindow = new LoginWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnFrameworkInitializationCompleted();
|
base.OnFrameworkInitializationCompleted();
|
||||||
|
|||||||
@ -24,4 +24,14 @@
|
|||||||
<ProjectReference Include="..\ChronoFlow.Controller\ChronoFlow.Controller.csproj" />
|
<ProjectReference Include="..\ChronoFlow.Controller\ChronoFlow.Controller.csproj" />
|
||||||
<ProjectReference Include="..\ChronoFlow.Model\ChronoFlow.Model.csproj" />
|
<ProjectReference Include="..\ChronoFlow.Model\ChronoFlow.Model.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Assets\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="ZeiterfassungView.axaml.cs">
|
||||||
|
<DependentUpon>ZeiterfassungView.axaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
18
ChronoFlow.View/LoginWindow.axaml
Normal file
18
ChronoFlow.View/LoginWindow.axaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!-- Datei: View/LoginWindow.axaml -->
|
||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
x:Class="ChronoFlow.View.LoginWindow"
|
||||||
|
Title="ChronoFlow Login" Width="400" Height="250" WindowStartupLocation="CenterScreen">
|
||||||
|
|
||||||
|
<StackPanel Margin="20" Spacing="10">
|
||||||
|
<TextBlock Text="ChronoFlow – Login" FontWeight="Bold" FontSize="18" HorizontalAlignment="Center"/>
|
||||||
|
|
||||||
|
<TextBox x:Name="UsernameBox" Watermark="Benutzername"/>
|
||||||
|
<TextBlock Text="PasswordBox" FontSize="18" TextAlignment="Center" Margin="0,0,0,10"/>
|
||||||
|
<TextBox x:Name = "PasswordBox" PasswordChar="*" Text="Enabled"/>
|
||||||
|
|
||||||
|
<TextBlock x:Name="ErrorText" Foreground="Red" IsVisible="False"/>
|
||||||
|
|
||||||
|
<Button Content="Anmelden" Click="LoginButton_Click" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Window>
|
||||||
46
ChronoFlow.View/LoginWindow.axaml.cs
Normal file
46
ChronoFlow.View/LoginWindow.axaml.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
using ChronoFlow.Controller;
|
||||||
|
|
||||||
|
namespace ChronoFlow.View
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Das Fenster für den Benutzer-Login.
|
||||||
|
/// </summary>
|
||||||
|
public partial class LoginWindow : Window
|
||||||
|
{
|
||||||
|
private LoginController _loginController;
|
||||||
|
|
||||||
|
public LoginWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent(); // Verbindet XAML mit diesem Code
|
||||||
|
_loginController = new LoginController(); // Unsere "Logik-Klasse"
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wird ausgeführt, wenn der Benutzer auf "Anmelden" klickt.
|
||||||
|
/// </summary>
|
||||||
|
private void LoginButton_Click(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// Holt Benutzername und Passwort aus den Eingabefeldern
|
||||||
|
string username = UsernameBox?.Text ?? string.Empty;
|
||||||
|
string password = PasswordBox?.Text ?? string.Empty;
|
||||||
|
// Übergibt die Eingaben an den LoginController
|
||||||
|
var user = _loginController.Authenticate(username, password);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// Wenn erfolgreich: öffne das MainWindow
|
||||||
|
var main = new MainWindow(user);
|
||||||
|
main.Show();
|
||||||
|
this.Close(); // Schließe das Login-Fenster
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Wenn fehlgeschlagen: Fehlermeldung anzeigen
|
||||||
|
ErrorText.Text = "Login fehlgeschlagen. Bitte prüfen Sie Ihre Eingaben.";
|
||||||
|
ErrorText.IsVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,5 +5,21 @@
|
|||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="ChronoFlow.View.MainWindow"
|
x:Class="ChronoFlow.View.MainWindow"
|
||||||
Title="ChronoFlow.View">
|
Title="ChronoFlow.View">
|
||||||
Welcome to Avalonia!
|
|
||||||
|
<SplitView x:Name="PaneView" DisplayMode="CompactInline" IsPaneOpen="True" CompactPaneLength="40" OpenPaneLength="150">
|
||||||
|
|
||||||
|
<SplitView.Pane>
|
||||||
|
<StackPanel>
|
||||||
|
<Button Content="☰" Click="PaneOpenClose_Click"/>
|
||||||
|
<Button Content="⏱ Zeiterfassung" Click="Zeiterfassung_Click"/>
|
||||||
|
<Button Content="📄 Auswertung"/>
|
||||||
|
<Button Content="⚙ Einstellungen"/>
|
||||||
|
</StackPanel>
|
||||||
|
</SplitView.Pane>
|
||||||
|
|
||||||
|
<SplitView.Content>
|
||||||
|
<ContentControl x:Name="ContentArea" />
|
||||||
|
</SplitView.Content>
|
||||||
|
|
||||||
|
</SplitView>
|
||||||
</Window>
|
</Window>
|
||||||
@ -1,11 +1,48 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
using ChronoFlow.Model;
|
||||||
|
|
||||||
namespace ChronoFlow.View;
|
namespace ChronoFlow.View;
|
||||||
|
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
public MainWindow()
|
private readonly ViewManager _viewManager;
|
||||||
|
private readonly User _loggedInUser;
|
||||||
|
|
||||||
|
public MainWindow(User user)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
_loggedInUser = user;
|
||||||
|
|
||||||
|
// ✅ Workaround: Lokale Kopie für Lambda-Nutzung im Register
|
||||||
|
var currentUser = _loggedInUser;
|
||||||
|
|
||||||
|
_viewManager = new ViewManager(ContentArea);
|
||||||
|
|
||||||
|
// ✅ Register-Aufruf mit stabiler local variable
|
||||||
|
_viewManager.Register("Zeiterfassung", () => new ZeiterfassungView(currentUser));
|
||||||
|
|
||||||
|
// Begrüßungsanzeige
|
||||||
|
ContentArea.Content = new TextBlock
|
||||||
|
{
|
||||||
|
Text = $"Willkommen bei ChronoFlow, {currentUser.Username}!",
|
||||||
|
FontSize = 24,
|
||||||
|
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center,
|
||||||
|
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fenstertitel dynamisch setzen
|
||||||
|
this.Title = $"ChronoFlow - Willkommen {currentUser.Username} ({currentUser.Role})";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PaneOpenClose_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
PaneView.IsPaneOpen = !PaneView.IsPaneOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Zeiterfassung_Click(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_viewManager.Show("Zeiterfassung");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
48
ChronoFlow.View/ViewManager.cs
Normal file
48
ChronoFlow.View/ViewManager.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Avalonia.Collections;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace ChronoFlow.View
|
||||||
|
{
|
||||||
|
///<summary>
|
||||||
|
/// Verwaltet alle Views der Anwendung und wechselt sie bei Bedarf.
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public class ViewManager
|
||||||
|
{
|
||||||
|
private readonly ContentControl _targetControl;
|
||||||
|
private readonly Dictionary<string, Func<UserControl>> _registieredViews = new();
|
||||||
|
|
||||||
|
public ViewManager(ContentControl targetControl)
|
||||||
|
{
|
||||||
|
_targetControl = targetControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
/// Registriert eine View mit einem Namen
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public void Show(string name, Func<UserControl> viewFactory)
|
||||||
|
{
|
||||||
|
_registieredViews[name] = viewFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
/// Zeigt die View mit dem gegebenen Namen an.
|
||||||
|
/// </summary>
|
||||||
|
public void Show(string name)
|
||||||
|
{
|
||||||
|
if(_registieredViews.TryGetValue(name, out var factory))
|
||||||
|
_targetControl.Content = factory();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"View {name} is not registered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Register(string name, Func<UserControl> viewFactory)
|
||||||
|
{
|
||||||
|
_registieredViews[name] = viewFactory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user