LevelOS-Core/UI/Dashboards/Configurações/Database/FrmConfigBanco.cs

338 lines
15 KiB
C#

using CCH;
using CustomMessageBox;
using DAL;
using Microsoft.Data.SqlClient; // Certifique-se de ter este pacote NuGet instalado
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using TLL;
namespace UI
{
public class FrmConfigBanco : Form
{
// ── Cores LevelOS ──────────────────────────────────────────────────
private static readonly Color Surface = Color.White;
private static readonly Color Surface2 = Color.FromArgb(241, 245, 249);
private static readonly Color BorderCol = Color.FromArgb(226, 232, 240);
private static readonly Color TextPri = Color.FromArgb(15, 23, 42);
private static readonly Color TextSec = Color.FromArgb(71, 85, 105);
private static readonly Color TextMuted = Color.FromArgb(148, 163, 184);
private static readonly Color Blue = Color.FromArgb(37, 99, 235);
private static readonly Color Green = Color.FromArgb(22, 163, 74);
private static readonly Color Red = Color.FromArgb(220, 38, 38);
private static readonly Color NavyDark = Color.FromArgb(15, 30, 60);
// ── Controles ──────────────────────────────────────────────────────
private readonly TextBox txtHost = new();
private readonly TextBox txtPort = new();
private readonly TextBox txtBanco = new();
private readonly TextBox txtUsuario = new();
private readonly TextBox txtSenha = new();
private readonly TextBox txtTimeout = new();
private readonly CheckBox chkEncrypt = new();
private readonly CheckBox chkTrust = new();
private readonly Button btnSalvar = new();
private readonly Button btnTestar = new();
private readonly Button btnCancelar = new();
private readonly Label lblStatus = new();
public FrmConfigBanco()
{
Text = "LevelOS — Configuração do Banco de Dados";
Size = new Size(660, 680);
StartPosition = FormStartPosition.CenterScreen;
BackColor = Surface2;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
BuildLayout();
CarregarValores();
// ── Eventos ──────────────────────────────────────────────────
btnSalvar.Click += BtnSalvar_Click;
btnTestar.Click += BtnTestar_Click;
btnCancelar.Click += (s, e) => Close();
//Carregar dados
if (!File.Exists(AppFileSystem.AppFileDBSystem))
{
NT_MessageBox.Show("Arquivo de configuração do banco de dados ausente, por favor contacte o administrador do sistema para solucionar o problema", "Erro de SQL:101",
MessageBoxButtons.OK,MessageBoxIcon.Error);
}
else
{
DatabaseHelper.Carregar(AppFileSystem.AppFileDBSystem, AppInfoSystem.AppKeyMasterCrip);
this.txtHost.Text = DadosDaConexao.Host;
this.txtPort.Text = DadosDaConexao.Port.ToString();
this.txtBanco.Text = DadosDaConexao.Banco;
this.txtUsuario.Text = DadosDaConexao.Usuario;
this.txtSenha.Text = DadosDaConexao.Senha;
this.chkEncrypt.Checked = DadosDaConexao.Encrypt;
this.txtTimeout.Text = DadosDaConexao.ConnectTimeout.ToString();
this.chkTrust.Checked = DadosDaConexao.TrustServerCertificate;
}
}
private void BuildLayout()
{
// 1. TOPBAR
var topbar = new Panel { Dock = DockStyle.Top, Height = 75, BackColor = NavyDark };
topbar.Paint += DrawTopbar;
Controls.Add(topbar);
// 2. RODAPÉ
var footer = new Panel { Dock = DockStyle.Bottom, Height = 65, BackColor = Surface };
footer.Paint += (s, e) => e.Graphics.DrawLine(new Pen(BorderCol), 0, 0, footer.Width, 0);
Controls.Add(footer);
StyleButton(btnCancelar, "Cancelar", Surface, TextSec, BorderCol);
btnCancelar.SetBounds(20, 15, 100, 35);
btnCancelar.Anchor = AnchorStyles.Left;
footer.Controls.Add(btnCancelar);
StyleButton(btnSalvar, "✔ Salvar", Blue, Color.White);
btnSalvar.SetBounds(footer.Width - 120, 15, 100, 35);
btnSalvar.Anchor = AnchorStyles.Right;
footer.Controls.Add(btnSalvar);
StyleButton(btnTestar, "Testar conexão", Surface, TextPri, BorderCol);
btnTestar.SetBounds(btnSalvar.Left - 145, 15, 135, 35);
btnTestar.Anchor = AnchorStyles.Right;
footer.Controls.Add(btnTestar);
lblStatus.SetBounds(130, 15, 250, 35);
lblStatus.TextAlign = ContentAlignment.MiddleLeft;
lblStatus.Font = new Font("Segoe UI", 9f);
lblStatus.Anchor = AnchorStyles.Left | AnchorStyles.Right;
footer.Controls.Add(lblStatus);
// 3. CONTAINER DE CONTEÚDO
var pnlContainer = new Panel { Dock = DockStyle.Fill, AutoScroll = true, Padding = new Padding(0, 10, 0, 20) };
Controls.Add(pnlContainer);
pnlContainer.BringToFront();
// 4. CARD BRANCO
var card = new Panel { BackColor = Surface, Width = 560, Left = 40, Top = 20 };
pnlContainer.Controls.Add(card);
int cy = 30;
cy = AddSection(card, "SERVIDOR", cy);
AddLabel(card, "Host / IP", 30, cy);
AddLabel(card, "Porta", 430, cy);
cy += 20;
StyleInput(txtHost, "ex: localhost ou 192.168.0.1");
txtHost.SetBounds(30, cy, 385, 30); card.Controls.Add(txtHost);
StyleInput(txtPort, "1433");
txtPort.SetBounds(430, cy, 100, 30); card.Controls.Add(txtPort);
cy += 45;
cy = AddSection(card, "BANCO DE DADOS", cy);
AddLabel(card, "Nome do Banco", 30, cy);
cy += 20;
StyleInput(txtBanco, "ex: LevelOS_DB");
txtBanco.SetBounds(30, cy, 500, 30); card.Controls.Add(txtBanco);
cy += 45;
cy = AddSection(card, "AUTENTICAÇÃO", cy);
AddLabel(card, "Usuário", 30, cy);
AddLabel(card, "Senha", 285, cy);
cy += 20;
StyleInput(txtUsuario, "sa");
txtUsuario.SetBounds(30, cy, 245, 30); card.Controls.Add(txtUsuario);
StyleInput(txtSenha, "••••••••");
txtSenha.SetBounds(285, cy, 245, 30); txtSenha.PasswordChar = '●'; card.Controls.Add(txtSenha);
cy += 45;
cy = AddSection(card, "AVANÇADO", cy);
AddLabel(card, "Timeout de conexão (segundos)", 30, cy);
cy += 20;
StyleInput(txtTimeout, "3");
txtTimeout.SetBounds(30, cy, 100, 30); card.Controls.Add(txtTimeout);
cy += 40;
StyleCheckbox(chkEncrypt, "Encrypt Connection");
chkEncrypt.SetBounds(30, cy, 250, 25); card.Controls.Add(chkEncrypt);
cy += 30;
StyleCheckbox(chkTrust, "Trust Server Certificate");
chkTrust.SetBounds(30, cy, 250, 25); card.Controls.Add(chkTrust);
cy += 40;
card.Height = cy;
}
// ── Lógica de Negócio ──────────────────────────────────────────────
private void CarregarValores()
{
txtHost.Text = DbConfig.Host;
txtPort.Text = DbConfig.Port.ToString();
txtBanco.Text = DbConfig.Banco;
txtUsuario.Text = DbConfig.Usuario;
txtSenha.Text = DbConfig.Senha;
txtTimeout.Text = DbConfig.ConnectTimeout.ToString();
chkEncrypt.Checked = DbConfig.Encrypt;
chkTrust.Checked = DbConfig.TrustServerCertificate;
}
private void BtnSalvar_Click(object? sender, EventArgs e)
{
if (!Validar()) return;
DbConfig.Host = txtHost.Text.Trim();
DbConfig.Port = int.TryParse(txtPort.Text, out int p) ? p : 1433;
DbConfig.Banco = txtBanco.Text.Trim();
DbConfig.Usuario = txtUsuario.Text.Trim();
DbConfig.Senha = txtSenha.Text;
DbConfig.ConnectTimeout = int.TryParse(txtTimeout.Text, out int t) ? t : 3;
DbConfig.Encrypt = chkEncrypt.Checked;
DbConfig.TrustServerCertificate = chkTrust.Checked;
//Preenchendo dados da conexao
DadosDaConexao.Host = DbConfig.Host;
DadosDaConexao.Port = DbConfig.Port;
DadosDaConexao.Banco =DbConfig.Banco;
DadosDaConexao.Usuario = DbConfig.Usuario;
DadosDaConexao.Senha = DbConfig.Senha;
DadosDaConexao.ConnectTimeout = DbConfig.ConnectTimeout;
DadosDaConexao.Encrypt = chkEncrypt.Checked;
DadosDaConexao.TrustServerCertificate = chkTrust.Checked;
//salvar em arquivo criptografado
DatabaseHelper.Salvar(AppFileSystem.AppFileDBSystem, AppInfoSystem.AppKeyMasterCrip);
SetStatus("✔ Configurações salvas!", Green);
}
private void BtnTestar_Click(object? sender, EventArgs e)
{
if (!Validar()) return;
SetStatus("⏳ Testando...", TextMuted);
btnTestar.Enabled = false;
Application.DoEvents(); // Força a interface a atualizar o status
try
{
using var conn = new SqlConnection(BuildConnStr());
conn.Open();
SetStatus($"✔ Conectado! SQL {conn.ServerVersion}", Green);
}
catch (Exception ex)
{
SetStatus($"✖ Erro: {ex.Message}", Red);
}
finally
{
btnTestar.Enabled = true;
}
}
private string BuildConnStr()
{
SqlConnectionStringBuilder builder = new()
{
DataSource = $"{txtHost.Text.Trim()},{txtPort.Text.Trim()}",
InitialCatalog = txtBanco.Text.Trim(),
UserID = txtUsuario.Text.Trim(),
Password = txtSenha.Text,
ConnectTimeout = int.TryParse(txtTimeout.Text, out int t) ? t : 3,
Encrypt = chkEncrypt.Checked,
TrustServerCertificate = chkTrust.Checked
};
return builder.ConnectionString;
}
private bool Validar()
{
if (string.IsNullOrWhiteSpace(txtHost.Text)) { SetStatus("✖ Informe o Host.", Red); txtHost.Focus(); return false; }
if (string.IsNullOrWhiteSpace(txtBanco.Text)) { SetStatus("✖ Informe o Banco.", Red); txtBanco.Focus(); return false; }
if (string.IsNullOrWhiteSpace(txtUsuario.Text)) { SetStatus("✖ Informe o Usuário.", Red); txtUsuario.Focus(); return false; }
return true;
}
private void SetStatus(string msg, Color color)
{
lblStatus.Text = msg;
lblStatus.ForeColor = color;
}
// ── Helpers de UI ──────────────────────────────────────────────────
private void DrawTopbar(object sender, PaintEventArgs e)
{
var g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
var rect = new Rectangle(25, 20, 34, 34);
using var path = RoundRectPath(rect, 8);
g.FillPath(new SolidBrush(Blue), path);
g.DrawString("S", new Font("Segoe UI", 14, FontStyle.Bold), Brushes.White, rect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
g.DrawString("Configuração do Banco", new Font("Segoe UI Semibold", 12.5f), Brushes.White, 70, 18);
g.DrawString("Defina os parâmetros de conexão com o SQL Server", new Font("Segoe UI", 9), new SolidBrush(Color.FromArgb(148, 163, 184)), 70, 40);
}
private int AddSection(Panel p, string title, int y)
{
var line = new Panel { BackColor = BorderCol, Height = 1, Width = p.Width - 60, Left = 30, Top = y };
p.Controls.Add(line);
var lbl = new Label { Text = title, Font = new Font("Segoe UI", 7, FontStyle.Bold), ForeColor = TextMuted, Top = y - 7, Left = 35, AutoSize = true, BackColor = Surface };
p.Controls.Add(lbl);
lbl.BringToFront();
return y + 20;
}
private void AddLabel(Panel p, string txt, int x, int y)
{
p.Controls.Add(new Label { Text = txt, Font = new Font("Segoe UI Semibold", 9), ForeColor = TextSec, Left = x, Top = y, AutoSize = true });
}
private void StyleInput(TextBox t, string placeholder)
{
t.BorderStyle = BorderStyle.FixedSingle;
t.Font = new Font("Segoe UI", 10);
t.PlaceholderText = placeholder;
t.BackColor = Color.FromArgb(250, 251, 253);
}
private void StyleCheckbox(CheckBox chk, string text)
{
chk.Text = text; chk.Font = new Font("Segoe UI", 9.5f);
chk.ForeColor = TextSec; chk.Cursor = Cursors.Hand;
}
private void StyleButton(Button b, string txt, Color bg, Color fg, Color? borda = null)
{
b.Text = txt; b.FlatStyle = FlatStyle.Flat; b.BackColor = bg; b.ForeColor = fg; b.Cursor = Cursors.Hand;
b.Font = new Font("Segoe UI Semibold", 9.5f);
b.FlatAppearance.BorderSize = borda.HasValue ? 1 : 0;
if (borda.HasValue) b.FlatAppearance.BorderColor = borda.Value;
}
private static GraphicsPath RoundRectPath(Rectangle r, int radius)
{
var path = new GraphicsPath();
int d = radius * 2;
path.AddArc(r.X, r.Y, d, d, 180, 90);
path.AddArc(r.Right - d, r.Y, d, d, 270, 90);
path.AddArc(r.Right - d, r.Bottom - d, d, d, 0, 90);
path.AddArc(r.X, r.Bottom - d, d, d, 90, 90);
path.CloseFigure();
return path;
}
}
// ── Dados (DbConfig) ──────────────────────────────────────────────────
public static class DbConfig
{
public static string Host { get; set; } = "localhost";
public static int Port { get; set; } = 1433;
public static string Banco { get; set; } = "";
public static string Usuario { get; set; } = "sa";
public static string Senha { get; set; } = "";
public static int ConnectTimeout { get; set; } = 3;
public static bool Encrypt { get; set; } = true;
public static bool TrustServerCertificate { get; set; } = true;
}
}