feat: implement core domain models, authentication service, and UI components for the attendance system
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:Asistencia.ViewModels"
|
||||
x:Class="Asistencia.Views.AsistenciaView"
|
||||
x:DataType="vm:AsistenciaViewModel">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:AsistenciaViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<ScrollViewer>
|
||||
<StackPanel Spacing="0" Margin="32,24">
|
||||
|
||||
<Button Content="Volver" Classes="secondary"
|
||||
HorizontalAlignment="Left"
|
||||
Command="{Binding VolverCommand}"
|
||||
Margin="0,0,0,16" />
|
||||
|
||||
<TextBlock Text="{Binding NombreCurso}" Classes="page-header" />
|
||||
|
||||
<Border Classes="card" Margin="0,0,0,20">
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock Text="{Binding InfoCurso}"
|
||||
FontSize="14" Foreground="{DynamicResource TextSecondary}" />
|
||||
|
||||
<TextBlock Text="{Binding MensajeEstado}"
|
||||
FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryNavy}" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="8" Margin="0,8,0,0">
|
||||
<Button Content="Iniciar Sesion"
|
||||
Classes="success"
|
||||
Command="{Binding IniciarSesionCommand}"
|
||||
IsVisible="{Binding !EnSesion}" />
|
||||
<Button Content="Finalizar Sesion"
|
||||
Classes="danger"
|
||||
Command="{Binding FinalizarSesionCommand}"
|
||||
IsVisible="{Binding EnSesion}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto" Margin="0,0,0,16">
|
||||
<TextBlock Grid.Column="0"
|
||||
Classes="section-title"
|
||||
Text="Alumnos"
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="16">
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<Border Background="{DynamicResource SuccessColor}"
|
||||
CornerRadius="4" Width="12" Height="12" />
|
||||
<TextBlock Text="{Binding Presentes}" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<Border Background="{DynamicResource WarningColor}"
|
||||
CornerRadius="4" Width="12" Height="12" />
|
||||
<TextBlock Text="{Binding Tardanzas}" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<Border Background="{DynamicResource DangerColor}"
|
||||
CornerRadius="4" Width="12" Height="12" />
|
||||
<TextBlock Text="{Binding Ausentes}" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Border Classes="card" Padding="0">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
|
||||
<Border Grid.Row="0" Background="{DynamicResource BackgroundSecondary}"
|
||||
CornerRadius="12,12,0,0" Padding="16,12">
|
||||
<Grid ColumnDefinitions="*,120">
|
||||
<TextBlock Grid.Column="0" Text="Alumno"
|
||||
FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBlock Grid.Column="1" Text="Estado"
|
||||
FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextSecondary}"
|
||||
HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<ListBox Grid.Row="1"
|
||||
ItemsSource="{Binding Alumnos}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Padding="0">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:AlumnoAsistenciaViewModel">
|
||||
<Border Padding="16,12"
|
||||
BorderBrush="{DynamicResource BorderColor}"
|
||||
BorderThickness="0,0,0,1">
|
||||
<Grid ColumnDefinitions="*,120">
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{Binding NombreCompleto}"
|
||||
FontSize="14"
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<Button Grid.Column="1"
|
||||
HorizontalAlignment="Center"
|
||||
Command="{Binding $parent[ListBox].((vm:AsistenciaViewModel)DataContext).MarcarAlumnoCommand}"
|
||||
CommandParameter="{Binding}"
|
||||
Background="{Binding TipoAsistenciaColor}"
|
||||
CornerRadius="20"
|
||||
Padding="16,6"
|
||||
FontSize="13"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="White"
|
||||
BorderThickness="0"
|
||||
MinWidth="100">
|
||||
<TextBlock Text="{Binding TipoAsistenciaTexto}"
|
||||
Foreground="White" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Classes="card" Margin="0,16,0,0"
|
||||
IsVisible="{Binding !Alumnos.Count}"
|
||||
Background="#FFF3CD">
|
||||
<TextBlock Text="No hay alumnos en este curso."
|
||||
FontSize="14" Foreground="#856404" />
|
||||
</Border>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Asistencia.Views;
|
||||
|
||||
public partial class AsistenciaView : UserControl
|
||||
{
|
||||
public AsistenciaView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:Asistencia.ViewModels"
|
||||
xmlns:models="using:Asistencia.Models"
|
||||
x:Class="Asistencia.Views.DashboardView"
|
||||
x:DataType="vm:DashboardViewModel">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:DashboardViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<ScrollViewer>
|
||||
<StackPanel Spacing="0" Margin="32,24">
|
||||
|
||||
<TextBlock Text="Panel Principal" Classes="page-header" />
|
||||
|
||||
<Border Classes="card" Margin="0,0,0,24">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" Spacing="4">
|
||||
<TextBlock Text="Bienvenido"
|
||||
FontSize="14" Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBlock Text="{Binding NombreProfesor}"
|
||||
FontSize="24" FontWeight="Bold"
|
||||
Foreground="{DynamicResource TextPrimary}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="8">
|
||||
<Button Content="Mi Perfil"
|
||||
Command="{Binding AbrirPerfilCommand}"
|
||||
Classes="secondary" />
|
||||
<Button Content="Cerrar Sesion"
|
||||
Command="{Binding CerrarSesionCommand}"
|
||||
Classes="danger" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="Mis Cursos" Classes="section-title" Margin="0,0,0,12" />
|
||||
|
||||
<ItemsControl ItemsSource="{Binding Cursos}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:CursoAbierto">
|
||||
<Border Classes="card" Margin="0,0,0,12">
|
||||
<Grid ColumnDefinitions="*,Auto" RowDefinitions="Auto,Auto,Auto">
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="{Binding Curso.NombreCurso}"
|
||||
FontSize="18" FontWeight="Bold"
|
||||
Foreground="{DynamicResource TextPrimary}" />
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="1"
|
||||
Text="{Binding Sala}"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}"
|
||||
Margin="0,4,0,0">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding StringFormat="{}{0} | {1}">
|
||||
<Binding Path="Sede" />
|
||||
<Binding Path="HoraInicio" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
Content="Tomar Asistencia"
|
||||
Classes="primary"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,12,0,0"
|
||||
Command="{Binding $parent[ItemsControl].((vm:DashboardViewModel)DataContext).AbrirAsistenciaCommand}"
|
||||
CommandParameter="{Binding}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<Border Classes="card" Margin="0,24,0,0"
|
||||
IsVisible="{Binding !Cursos.Count}"
|
||||
Background="#FFF3CD">
|
||||
<TextBlock Text="No tiene cursos asignados actualmente."
|
||||
FontSize="14" Foreground="#856404" />
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Asistencia.Views;
|
||||
|
||||
public partial class DashboardView : UserControl
|
||||
{
|
||||
public DashboardView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:Asistencia.ViewModels"
|
||||
x:Class="Asistencia.Views.LoginView"
|
||||
x:DataType="vm:LoginViewModel">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:LoginViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<Panel Background="{DynamicResource BackgroundSecondary}">
|
||||
<Border HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
CornerRadius="16" Padding="48" Width="420"
|
||||
Background="{DynamicResource BackgroundPrimary}"
|
||||
BorderBrush="{DynamicResource BorderColor}" BorderThickness="1">
|
||||
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock Text="Sistema de Asistencia"
|
||||
FontSize="28" FontWeight="Bold"
|
||||
Foreground="{DynamicResource PrimaryNavy}"
|
||||
HorizontalAlignment="Center" />
|
||||
|
||||
<TextBlock Text="Inicie sesion con su cuenta"
|
||||
FontSize="14" Foreground="{DynamicResource TextSecondary}"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,24" />
|
||||
|
||||
<TextBlock Text="RUT" FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextPrimary}" />
|
||||
<TextBox Watermark="Ej: 12345678-9"
|
||||
Text="{Binding Rut}"
|
||||
FontSize="14" Margin="0,0,0,8" />
|
||||
|
||||
<TextBlock Text="Contrasena" FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextPrimary}" />
|
||||
<TextBox Watermark="Ingrese su contrasena"
|
||||
Text="{Binding Password}"
|
||||
PasswordChar="*"
|
||||
FontSize="14" Margin="0,0,0,16" />
|
||||
|
||||
<Button Content="Iniciar Sesion"
|
||||
Command="{Binding LoginCommand}"
|
||||
Classes="primary"
|
||||
HorizontalAlignment="Stretch"
|
||||
Height="44"
|
||||
IsEnabled="{Binding !IsLoading}" />
|
||||
|
||||
<TextBlock Text="{Binding ErrorMessage}"
|
||||
Foreground="{DynamicResource DangerColor}"
|
||||
FontSize="13"
|
||||
HorizontalAlignment="Center"
|
||||
IsVisible="{Binding HasError}"
|
||||
Margin="0,8,0,0" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Panel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Asistencia.Views;
|
||||
|
||||
public partial class LoginView : UserControl
|
||||
{
|
||||
public LoginView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:Asistencia.ViewModels"
|
||||
xmlns:views="using:Asistencia.Views"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="1024" d:DesignHeight="700"
|
||||
x:Class="Asistencia.Views.MainWindow"
|
||||
x:DataType="vm:MainWindowViewModel"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
Title="Sistema de Asistencia"
|
||||
Width="1024" Height="700"
|
||||
MinWidth="800" MinHeight="600"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:MainWindowViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<Panel>
|
||||
<ContentControl Content="{Binding CurrentView}" />
|
||||
</Panel>
|
||||
</Window>
|
||||
@@ -0,0 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace Asistencia.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:Asistencia.ViewModels"
|
||||
x:Class="Asistencia.Views.PerfilView"
|
||||
x:DataType="vm:PerfilViewModel">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:PerfilViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<ScrollViewer>
|
||||
<StackPanel Spacing="0" Margin="32,24" MaxWidth="600">
|
||||
|
||||
<Button Content="Volver" Classes="secondary"
|
||||
HorizontalAlignment="Left"
|
||||
Command="{Binding VolverCommand}"
|
||||
Margin="0,0,0,16" />
|
||||
|
||||
<TextBlock Text="Mi Perfil" Classes="page-header" />
|
||||
|
||||
<Border Classes="card" Margin="0,0,0,20">
|
||||
<StackPanel Spacing="16">
|
||||
<TextBlock Text="Informacion Personal"
|
||||
Classes="card-title" Margin="0,0,0,8" />
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="RUT" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBlock Text="{Binding Rut}" FontSize="15"
|
||||
FontWeight="SemiBold" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Nombre Completo" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBlock Text="{Binding NombreCompleto}" FontSize="15"
|
||||
FontWeight="SemiBold" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Telefono" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBlock Text="{Binding Fono}" FontSize="15" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Direccion" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBlock Text="{Binding Direccion}" FontSize="15" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Classes="card" Margin="0,0,0,20">
|
||||
<StackPanel Spacing="16">
|
||||
<TextBlock Text="Email" Classes="card-title" Margin="0,0,0,8" />
|
||||
<TextBox Text="{Binding Email}" FontSize="14"
|
||||
Watermark="correo@ejemplo.com" />
|
||||
<Button Content="Guardar Email"
|
||||
Classes="primary"
|
||||
HorizontalAlignment="Left"
|
||||
Command="{Binding GuardarEmailCommand}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Classes="card" Margin="0,0,0,20">
|
||||
<StackPanel Spacing="16">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<TextBlock Grid.Column="0" Text="Cambiar Contrasena"
|
||||
Classes="card-title" />
|
||||
<Button Grid.Column="1"
|
||||
Content="Cambiar Contrasena"
|
||||
Classes="secondary"
|
||||
Command="{Binding ToggleCambioClaveCommand}"
|
||||
FontSize="13" />
|
||||
</Grid>
|
||||
|
||||
<StackPanel Spacing="12"
|
||||
IsVisible="{Binding MostrarCambioClave}">
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Contrasena Actual" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBox Text="{Binding ClaveActual}"
|
||||
PasswordChar="*" FontSize="14" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Nueva Contrasena" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBox Text="{Binding NuevaClave}"
|
||||
PasswordChar="*" FontSize="14" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Confirmar Contrasena" FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondary}" />
|
||||
<TextBox Text="{Binding ConfirmarClave}"
|
||||
PasswordChar="*" FontSize="14" />
|
||||
</StackPanel>
|
||||
|
||||
<Button Content="Cambiar Contrasena"
|
||||
Classes="primary"
|
||||
HorizontalAlignment="Left"
|
||||
Command="{Binding CambiarClaveCommand}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Classes="card"
|
||||
IsVisible="{Binding TieneExito}"
|
||||
Background="#D4EDDA" BorderBrush="#C3E6CB" Margin="0,0,0,12">
|
||||
<TextBlock Text="{Binding MensajeExito}"
|
||||
FontSize="14" Foreground="#155724" />
|
||||
</Border>
|
||||
|
||||
<Border Classes="card"
|
||||
IsVisible="{Binding TieneError}"
|
||||
Background="#F8D7DA" BorderBrush="#F5C6CB" Margin="0,0,0,12">
|
||||
<TextBlock Text="{Binding MensajeError}"
|
||||
FontSize="14" Foreground="#721C24" />
|
||||
</Border>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Asistencia.Views;
|
||||
|
||||
public partial class PerfilView : UserControl
|
||||
{
|
||||
public PerfilView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user