| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- using Npgsql;
- using TravelAgencyWinForms.Data;
- using TravelAgencyWinForms.Models;
- using TravelAgencyWinForms.Services;
- using TravelAgencyWinForms.Utils;
- namespace TravelAgencyWinForms.Forms;
- public partial class MainForm : Form
- {
- private Button? _activeMenuButton;
- public MainForm()
- {
- InitializeComponent();
- ApplyStyle();
- LoadBanner();
- BuildMenu();
- LoadDashboard();
- FormClosing += (_, _) => CurrentUser.Clear();
- }
- private void ApplyStyle()
- {
- AppTheme.ApplyForm(this);
- menuPanel.BackColor = Color.FromArgb(76, 150, 138);
- menuHeaderPanel.BackColor = Color.FromArgb(76, 150, 138);
- menuItemsPanel.BackColor = Color.FromArgb(76, 150, 138);
- appTitleLabel.ForeColor = Color.White;
- modeLabel.ForeColor = Color.FromArgb(227, 247, 242);
- loginLabel.ForeColor = Color.FromArgb(227, 247, 242);
- userNameLabel.ForeColor = Color.White;
- contentPanel.BackColor = AppTheme.Background;
- heroPanel.BackColor = AppTheme.Surface;
- heroTitleLabel.ForeColor = AppTheme.Text;
- heroSubtitleLabel.ForeColor = AppTheme.Muted;
- upcomingGroupBox.ForeColor = AppTheme.Text;
- bookingsGroupBox.ForeColor = AppTheme.Text;
- AppTheme.StyleGrid(upcomingGrid);
- AppTheme.StyleGrid(bookingsGrid);
- appTitleLabel.Text = "Турагентство";
- modeLabel.Text = CurrentUser.IsAdmin ? "Панель администратора" : "Личный кабинет клиента";
- loginLabel.Text = CurrentUser.Login;
- userNameLabel.Text = string.IsNullOrWhiteSpace(CurrentUser.ClientName) ? CurrentUser.Login : CurrentUser.ClientName;
- heroTitleLabel.Text = CurrentUser.IsAdmin ? "Панель управления" : "Личный кабинет";
- heroSubtitleLabel.Text = CurrentUser.IsAdmin
- ? "Быстрый доступ к данным, отчётам и журналу операций"
- : "Просмотр туров, расписания и своих бронирований";
- }
- private void LoadBanner()
- {
- var image = AppTheme.LoadImage("main_dashboard_banner.png");
- if (image != null)
- bannerPictureBox.Image = image;
- }
- private void BuildMenu()
- {
- menuItemsPanel.Controls.Clear();
- AddMenuButton("Главная", LoadDashboard, true);
- if (CurrentUser.IsAdmin)
- {
- AddSection("Данные");
- AddMenuButton("Клиенты", () => OpenTable(EntityConfigs.Clients, true));
- AddMenuButton("Должности", () => OpenTable(EntityConfigs.Positions, true));
- AddMenuButton("Сотрудники", () => OpenTable(EntityConfigs.Employees, true));
- AddMenuButton("Города", () => OpenTable(EntityConfigs.Cities, true));
- AddMenuButton("Туры", () => OpenTable(EntityConfigs.Tours, true));
- AddMenuButton("Маршруты", () => OpenTable(EntityConfigs.TourCities, true));
- AddMenuButton("Расписание", () => OpenTable(EntityConfigs.TourList, true));
- AddMenuButton("Бронирования", () => OpenTable(EntityConfigs.Bookings, true));
- AddSection("Отчёты");
- AddMenuButton("Сводка", () => new ReportsForm().ShowDialog(this));
- AddMenuButton("Просроченные", () => OpenTable(EntityConfigs.OverdueView, false));
- AddMenuButton("Журнал", () => OpenTable(EntityConfigs.AuditLog, false));
- AddSection("Сервис");
- AddMenuButton("Пользователи", () => OpenTable(EntityConfigs.AppUsers, true));
- }
- else
- {
- AddSection("Мои данные");
- AddMenuButton("Личные данные", () => OpenTable(EntityConfigs.ClientDetails, false));
- AddMenuButton("Бронирования", () => OpenTable(EntityConfigs.UserBookings, false));
- AddMenuButton("Просроченные", () => OpenTable(EntityConfigs.UserOverdue, false));
- AddSection("Справочники");
- AddMenuButton("Города", () => OpenTable(EntityConfigs.Cities, false));
- AddMenuButton("Туры", () => OpenTable(EntityConfigs.Tours, false));
- AddMenuButton("Расписание", () => OpenTable(EntityConfigs.TourScheduleView, false));
- AddMenuButton("Отчёты", () => new ReportsForm().ShowDialog(this));
- }
- AddSection(string.Empty);
- AddMenuButton("Выход", Close);
- }
- private void AddMenuButton(string text, Action action, bool selected = false)
- {
- var button = new Button
- {
- Text = text,
- Width = 220,
- Height = 38,
- Margin = new Padding(0, 3, 0, 3)
- };
- AppTheme.StyleMenuButton(button);
- if (selected)
- SetActiveMenuButton(button);
- button.Click += (_, _) =>
- {
- SetActiveMenuButton(button);
- action();
- };
- menuItemsPanel.Controls.Add(button);
- }
- private void SetActiveMenuButton(Button button)
- {
- if (_activeMenuButton != null)
- AppTheme.StyleMenuButton(_activeMenuButton);
- _activeMenuButton = button;
- button.BackColor = Color.FromArgb(98, 181, 166);
- }
- private void AddSection(string text)
- {
- if (string.IsNullOrWhiteSpace(text))
- {
- menuItemsPanel.Controls.Add(new Panel { Height = 12, Width = 220 });
- return;
- }
- var label = new Label
- {
- Text = text.ToUpperInvariant(),
- Width = 220,
- Height = 26,
- ForeColor = Color.FromArgb(216, 243, 237),
- Font = new Font("Segoe UI Semibold", 8.5F),
- Margin = new Padding(0, 14, 0, 2)
- };
- menuItemsPanel.Controls.Add(label);
- }
- private void OpenTable(EntityConfig config, bool canEdit)
- {
- using var form = new TableEditorForm(config, canEdit);
- form.ShowDialog(this);
- LoadDashboard();
- }
- private void LoadDashboard()
- {
- LoadStats();
- LoadDashboardTables();
- }
- private void LoadStats()
- {
- statsPanel.Controls.Clear();
- foreach (var card in LoadStatCards())
- statsPanel.Controls.Add(card);
- }
- private IEnumerable<Control> LoadStatCards()
- {
- if (CurrentUser.IsAdmin)
- {
- yield return AppTheme.CreateCard("Клиенты", ScalarInt("SELECT COUNT(*) FROM clients"));
- yield return AppTheme.CreateCard("Сотрудники", ScalarInt("SELECT COUNT(*) FROM employees"));
- yield return AppTheme.CreateCard("Туры", ScalarInt("SELECT COUNT(*) FROM tours"));
- yield return AppTheme.CreateCard("Бронирования", ScalarInt("SELECT COUNT(*) FROM bookings"));
- yield return AppTheme.CreateCard("Просроченные", ScalarInt("SELECT COUNT(*) FROM v_overdue_client_bookings"));
- }
- else
- {
- yield return AppTheme.CreateCard("Бронирования", ScalarInt("SELECT COUNT(*) FROM bookings WHERE client_id = @client_id", new NpgsqlParameter("client_id", CurrentUser.ClientId ?? -1)));
- yield return AppTheme.CreateCard("Просроченные", ScalarInt("SELECT COUNT(*) FROM v_overdue_client_bookings WHERE client_id = @client_id", new NpgsqlParameter("client_id", CurrentUser.ClientId ?? -1)));
- yield return AppTheme.CreateCard("Туры", ScalarInt("SELECT COUNT(*) FROM tours"));
- yield return AppTheme.CreateCard("Рейсы", ScalarInt("SELECT COUNT(*) FROM tour_list WHERE start_date >= CURRENT_DATE"), "будущие даты");
- }
- }
- private void LoadDashboardTables()
- {
- upcomingGrid.DataSource = Db.Query(@"
- SELECT
- tour_name AS ""Тур"",
- start_date AS ""Дата начала"",
- end_date AS ""Дата окончания"",
- duration_days AS ""Длительность"",
- price AS ""Стоимость""
- FROM v_tour_schedule
- WHERE start_date >= CURRENT_DATE
- ORDER BY start_date
- LIMIT 8;");
- bookingsGrid.DataSource = CurrentUser.IsAdmin
- ? Db.Query(@"
- SELECT
- booking_number AS ""Номер"",
- client_name AS ""Клиент"",
- employee_name AS ""Сотрудник"",
- tour_name AS ""Тур"",
- booking_date AS ""Дата оформления"",
- status AS ""Статус""
- FROM v_booking_details
- ORDER BY booking_date DESC, booking_id DESC
- LIMIT 8;")
- : Db.Query(@"
- SELECT
- booking_number AS ""Номер"",
- client_name AS ""Клиент"",
- tour_name AS ""Тур"",
- booking_date AS ""Дата оформления"",
- status AS ""Статус""
- FROM v_booking_details
- WHERE client_id = @client_id
- ORDER BY booking_date DESC, booking_id DESC
- LIMIT 8;", new NpgsqlParameter("client_id", CurrentUser.ClientId ?? -1));
- AppTheme.StyleGrid(upcomingGrid);
- AppTheme.StyleGrid(bookingsGrid);
- PresentationHelper.ApplyHeaders(upcomingGrid);
- PresentationHelper.ApplyHeaders(bookingsGrid);
- }
- private static string ScalarInt(string sql, params NpgsqlParameter[] parameters)
- {
- var result = Db.Scalar(sql, parameters);
- return Convert.ToInt32(result ?? 0).ToString();
- }
- }
|