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; } }