Commit
This commit is contained in:
22
UP01Task2App/UP01Task2App/Models/Client.cs
Normal file
22
UP01Task2App/UP01Task2App/Models/Client.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace UP01Task2App.Models
|
||||
{
|
||||
public class Client
|
||||
{
|
||||
public string Surname { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Patronymic { get; set; }
|
||||
public DateTime? BirthDate { get; set; }
|
||||
public string Adress { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
public int SubscriptionNumber { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Surname + " " + Name + " " + Patronymic;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
UP01Task2App/UP01Task2App/Models/Record.cs
Normal file
14
UP01Task2App/UP01Task2App/Models/Record.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace UP01Task2App.Models
|
||||
{
|
||||
public class Record
|
||||
{
|
||||
public Client Client { get; set; }
|
||||
public Trainer Trainer { get; set; }
|
||||
DateOnly RecordDate { set; get; }
|
||||
TimeOnly RecordTime { set; get; }
|
||||
}
|
||||
}
|
||||
14
UP01Task2App/UP01Task2App/Models/Trainer.cs
Normal file
14
UP01Task2App/UP01Task2App/Models/Trainer.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace UP01Task2App.Models
|
||||
{
|
||||
public class Trainer
|
||||
{
|
||||
public string Surmname { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Patronymic { get; set; }
|
||||
public string Speciality { get; set; }
|
||||
}
|
||||
}
|
||||
71
UP01Task2App/UP01Task2App/Services/JsonService.cs
Normal file
71
UP01Task2App/UP01Task2App/Services/JsonService.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
using System.Windows.Shapes;
|
||||
using UP01Task2App.Models;
|
||||
|
||||
namespace UP01Task2App.Services
|
||||
{
|
||||
internal class JsonService
|
||||
{
|
||||
private const string trainerPath = "data/trainers.json";
|
||||
private const string clientPath = "data/clients.json";
|
||||
private const string recordPath = "data/records.json";
|
||||
|
||||
private void SaveToJson<T>(string path, List<T> data)
|
||||
{
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
data ??= new List<T>();
|
||||
|
||||
string json = JsonSerializer.Serialize(data, options);
|
||||
|
||||
string? dir = System.IO.Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
File.WriteAllText(path, json, Encoding.UTF8);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentException("Не удалось сохранить данные");
|
||||
}
|
||||
}
|
||||
|
||||
private List<T> ReadFromJson<T>(string path)
|
||||
{
|
||||
if (!File.Exists(path) || new FileInfo(path).Length == 0)
|
||||
return new List<T>();
|
||||
|
||||
string json = File.ReadAllText(path);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
return new List<T>();
|
||||
|
||||
try
|
||||
{
|
||||
return JsonSerializer.Deserialize<List<T>>(json) ?? new List<T>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<T>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Trainer> ReadTrainerDataFromJson() => ReadFromJson<Trainer>(trainerPath);
|
||||
public List<Client> ReadClientDataFromJson() => ReadFromJson<Client>(clientPath);
|
||||
public List<Record> ReadRecordDataFromJson() => ReadFromJson<Record>(recordPath);
|
||||
|
||||
public void SaveTrainerDataToJson(List<Trainer> trainersList) => SaveToJson(trainerPath, trainersList);
|
||||
public void SaveClientDataToJson(List<Client> clientsList) => SaveToJson(clientPath, clientsList);
|
||||
public void SaveRecordDataToJson(List<Record> recordsList) => SaveToJson(recordPath, recordsList);
|
||||
}
|
||||
}
|
||||
39
UP01Task2App/UP01Task2App/Services/ValidationHelper.cs
Normal file
39
UP01Task2App/UP01Task2App/Services/ValidationHelper.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace UP01Task2App.Services
|
||||
{
|
||||
public static class ValidationHelper
|
||||
{
|
||||
public static void ValidateNotNullTextBox(TextBox obj, string fieldName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(obj.Text))
|
||||
throw new ArgumentException($"Поле \"{fieldName}\" не должно быть пустым");
|
||||
}
|
||||
public static void ValidateNumTextBox(TextBox obj, string fieldName)
|
||||
{
|
||||
foreach (var c in obj.Text)
|
||||
{
|
||||
if (!char.IsDigit(c))
|
||||
throw new ArgumentException($"В поле \"{fieldName}\" можно вводить только числа");
|
||||
}
|
||||
}
|
||||
public static void ValidateDateNotInFutureTextBox(DatePicker obj, string fieldName)
|
||||
{
|
||||
if (obj.SelectedDate > DateTime.Now)
|
||||
throw new ArgumentException($"В поле \"{fieldName}\" выбранная дата не может быть в будущем");
|
||||
}
|
||||
public static void ValidateNotNullDatePicker(DatePicker obj, string fieldName)
|
||||
{
|
||||
if (obj.SelectedDate == null)
|
||||
throw new ArgumentException($"Выберите дату в поле \"{fieldName}\"");
|
||||
}
|
||||
public static void ValidateIntRangeTextBox(TextBox obj, string fieldName)
|
||||
{
|
||||
if (!int.TryParse(obj.Text, out int _))
|
||||
throw new ArgumentException($"Введенное число в \"{fieldName}\" слишком большое или маленькое");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace UP01Task2App.ViewModels
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public class BaseViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void OnPropertyChanged([CallerMemberName] string name = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
public class RelayCommand : ICommand
|
||||
{
|
||||
private readonly Action _execute;
|
||||
private readonly Func<bool> _canExecute;
|
||||
|
||||
public RelayCommand(Action execute, Func<bool> canExecute = null)
|
||||
{
|
||||
_execute = execute;
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;
|
||||
|
||||
public void Execute(object parameter) => _execute();
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
}
|
||||
@@ -11,32 +11,32 @@
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel HorizontalAlignment="Left">
|
||||
<TextBlock Text="Фамилия"/>
|
||||
<TextBox Text="{Binding LastName}" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBox Name="SurnameTextBox" Style="{StaticResource TextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Имя"/>
|
||||
<TextBox Text="{Binding FirstName}" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBox Name="NameTextBox" Style="{StaticResource TextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Отчество"/>
|
||||
<TextBox Text="{Binding MiddleName}" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBox Name="PatronymicTextBox" Style="{StaticResource TextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Дата рождения"/>
|
||||
<DatePicker SelectedDate="{Binding BirthDate}" Style="{StaticResource DatePickerStyle}" />
|
||||
<DatePicker Name="BirthDateDatePicker" Style="{StaticResource DatePickerStyle}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Margin="20,0,0,0">
|
||||
<TextBlock Text="Фактический адрес"/>
|
||||
<TextBox Text="{Binding Address}" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBox Name="AdressTextBox" Style="{StaticResource TextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Телефон"/>
|
||||
<TextBox Text="{Binding Phone}" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBox Name="PhoneNumberTextBox" Style="{StaticResource TextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Номер абонемента"/>
|
||||
<TextBox Text="{Binding MembershipNumber}" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBox Name="SubscriptionMumberTextBox" Style="{StaticResource TextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Пол"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="5">
|
||||
<RadioButton Content="М" GroupName="rg1"/>
|
||||
<RadioButton Content="Ж" GroupName="rg1"/>
|
||||
<RadioButton Name="rbMan" Content="М" GroupName="rg1"/>
|
||||
<RadioButton Name="rbWoman" Content="Ж" GroupName="rg1"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
@@ -47,33 +47,27 @@
|
||||
|
||||
<TextBlock Text="Список клиентов" FontSize="18" Margin="0,0,0,10"/>
|
||||
|
||||
<ListBox ItemsSource="{Binding Clients}"
|
||||
SelectedItem="{Binding SelectedClient}"
|
||||
Height="250"
|
||||
DisplayMemberPath="LastName"/>
|
||||
<ListBox ItemsSource="{Binding ClientsUI}"
|
||||
Height="250"/>
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Margin="10">
|
||||
<StackPanel>
|
||||
<Button Content="Добавить клиента"
|
||||
Command="{Binding AddClientCommand}"
|
||||
Style="{StaticResource ButtonStyle}"
|
||||
Margin="10"/>
|
||||
Margin="10" Click="Button_Click"/>
|
||||
|
||||
<Button Content="Изменить клиента"
|
||||
Command="{Binding EditClientCommand}"
|
||||
Style="{StaticResource ButtonStyle}"
|
||||
Margin="10"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<Button Content="Запись клиента"
|
||||
Command="{Binding AddAppointmentCommand}"
|
||||
Style="{StaticResource ButtonStyle}"
|
||||
Margin="10"/>
|
||||
|
||||
<Button Content="Просмотреть записи"
|
||||
Command="{Binding ViewAppointmentsCommand}"
|
||||
Style="{StaticResource ButtonStyle}"
|
||||
Margin="10"/>
|
||||
</StackPanel>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
@@ -9,6 +12,8 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using UP01Task2App.Models;
|
||||
using UP01Task2App.Services;
|
||||
|
||||
namespace UP01Task2App.Windows
|
||||
{
|
||||
@@ -17,9 +22,91 @@ namespace UP01Task2App.Windows
|
||||
/// </summary>
|
||||
public partial class ClientWindow : Window
|
||||
{
|
||||
private JsonService Json = new();
|
||||
public List<Client> ClientsList = new();
|
||||
public List<Trainer> TrainersList = new();
|
||||
public List<Record> RecordsList = new();
|
||||
|
||||
public ObservableCollection<Client> ClientsUI { get; set; } = new();
|
||||
public ClientWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ClientsList = Json.ReadClientDataFromJson();
|
||||
TrainersList = Json.ReadTrainerDataFromJson();
|
||||
RecordsList = Json.ReadRecordDataFromJson();
|
||||
|
||||
UpdateClientUI();
|
||||
|
||||
this.DataContext = this;
|
||||
}
|
||||
|
||||
private void UpdateClientUI()
|
||||
{
|
||||
ClientsUI.Clear();
|
||||
foreach (var item in ClientsList)
|
||||
{
|
||||
ClientsUI.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateFields()
|
||||
{
|
||||
try
|
||||
{
|
||||
ValidationHelper.ValidateNotNullTextBox(SurnameTextBox, "Фамилия");
|
||||
ValidationHelper.ValidateNotNullTextBox(NameTextBox, "Имя");
|
||||
ValidationHelper.ValidateNotNullTextBox(PatronymicTextBox, "Отчество");
|
||||
ValidationHelper.ValidateNotNullDatePicker(BirthDateDatePicker, "Дата рождения");
|
||||
ValidationHelper.ValidateDateNotInFutureTextBox(BirthDateDatePicker, "Дата рождения");
|
||||
ValidationHelper.ValidateNotNullTextBox(AdressTextBox, "Фактический адрес");
|
||||
ValidationHelper.ValidateNotNullTextBox(PhoneNumberTextBox, "Телефон");
|
||||
ValidationHelper.ValidateNumTextBox(PhoneNumberTextBox, "Телефон");
|
||||
ValidationHelper.ValidateNotNullTextBox(SubscriptionMumberTextBox, "Номер абонемента");
|
||||
ValidationHelper.ValidateNumTextBox(SubscriptionMumberTextBox, "Номер абонемента");
|
||||
ValidationHelper.ValidateIntRangeTextBox(SubscriptionMumberTextBox, "Номер абонемента");
|
||||
|
||||
if (rbMan.IsChecked == null && rbWoman.IsChecked == null)
|
||||
{
|
||||
throw new ArgumentException("Выберите пол");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ValidateFields())
|
||||
{
|
||||
ClientsList.Add(new Client
|
||||
{
|
||||
Surname = SurnameTextBox.Text,
|
||||
Name = NameTextBox.Text,
|
||||
Adress = AdressTextBox.Text,
|
||||
BirthDate = BirthDateDatePicker.SelectedDate,
|
||||
Patronymic = PatronymicTextBox.Text,
|
||||
PhoneNumber = PhoneNumberTextBox.Text,
|
||||
SubscriptionNumber = int.Parse(SubscriptionMumberTextBox.Text)
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
Json.SaveClientDataToJson(ClientsList);
|
||||
MessageBox.Show("Данные сохранены");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
|
||||
UpdateClientUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user