diff --git a/MLL/ModeloBackup.cs b/MLL/ModeloBackup.cs new file mode 100644 index 0000000..8a6d1d5 --- /dev/null +++ b/MLL/ModeloBackup.cs @@ -0,0 +1,67 @@ +using System; + +namespace MLL +{ + public class ModeloBackup + { + public ModeloBackup() + { + + } + public ModeloBackup(int id, string nome, string tipoBackup, string origem, string destinoTipo, int? destinoId, string caminhoDestino, bool compactar, bool usarCriptografia, string algoritmoCriptografia, string frequencia, TimeSpan? horario, int manterUltimos, string statusUltimoBackup, DateTime? dataUltimoBackup, string logUltimoBackup, bool ativo, DateTime criadoEm, DateTime? atualizadoEm) + { + Id = id; + Nome = nome; + TipoBackup = tipoBackup; + Origem = origem; + DestinoTipo = destinoTipo; + DestinoId = destinoId; + CaminhoDestino = caminhoDestino; + Compactar = compactar; + UsarCriptografia = usarCriptografia; + AlgoritmoCriptografia = algoritmoCriptografia; + Frequencia = frequencia; + Horario = horario; + ManterUltimos = manterUltimos; + StatusUltimoBackup = statusUltimoBackup; + DataUltimoBackup = dataUltimoBackup; + LogUltimoBackup = logUltimoBackup; + Ativo = ativo; + CriadoEm = criadoEm; + AtualizadoEm = atualizadoEm; + } + + public int Id { get; set; } + + public string Nome { get; set; } + public string TipoBackup { get; set; } + public string Origem { get; set; } + public string DestinoTipo { get; set; } + + public int? DestinoId { get; set; } + + public string CaminhoDestino { get; set; } + + public bool Compactar { get; set; } + public bool UsarCriptografia { get; set; } + + public string AlgoritmoCriptografia { get; set; } + + public string Frequencia { get; set; } + + public TimeSpan? Horario { get; set; } + + public int ManterUltimos { get; set; } + + public string StatusUltimoBackup { get; set; } + + public DateTime? DataUltimoBackup { get; set; } + + public string LogUltimoBackup { get; set; } + + public bool Ativo { get; set; } + + public DateTime CriadoEm { get; set; } + public DateTime? AtualizadoEm { get; set; } + } +} \ No newline at end of file diff --git a/MLL/ModeloBackupAutomatico.cs b/MLL/ModeloBackupAutomatico.cs new file mode 100644 index 0000000..e524fa0 --- /dev/null +++ b/MLL/ModeloBackupAutomatico.cs @@ -0,0 +1,50 @@ +using System; + +namespace MLL +{ + public class ModeloBackupAutomatico + { + public ModeloBackupAutomatico(int id, int idBackup, bool ativo, string frequencia, int? intervaloMinutos, TimeSpan? horario, int? diaSemana, int? diaMes, DateTime? ultimaExecucao, DateTime? proximaExecucao, bool executando, DateTime criadoEm, DateTime? atualizadoEm) + { + Id = id; + IdBackup = idBackup; + Ativo = ativo; + Frequencia = frequencia; + IntervaloMinutos = intervaloMinutos; + Horario = horario; + DiaSemana = diaSemana; + DiaMes = diaMes; + UltimaExecucao = ultimaExecucao; + ProximaExecucao = proximaExecucao; + Executando = executando; + CriadoEm = criadoEm; + AtualizadoEm = atualizadoEm; + } + public ModeloBackupAutomatico() + { + } + public int Id { get; set; } + + public int IdBackup { get; set; } + + public bool Ativo { get; set; } + public string Frequencia { get; set; } + public int? IntervaloMinutos { get; set; } + + public TimeSpan? Horario { get; set; } + + public int? DiaSemana { get; set; } + + public int? DiaMes { get; set; } + + public DateTime? UltimaExecucao { get; set; } + + public DateTime? ProximaExecucao { get; set; } + + public bool Executando { get; set; } + + public DateTime CriadoEm { get; set; } + + public DateTime? AtualizadoEm { get; set; } + } +} \ No newline at end of file diff --git a/MLL/ModeloBackupExecucao.cs b/MLL/ModeloBackupExecucao.cs new file mode 100644 index 0000000..3907d11 --- /dev/null +++ b/MLL/ModeloBackupExecucao.cs @@ -0,0 +1,35 @@ +using System; + +namespace MLL +{ + public class ModeloBackupExecucao + { + public ModeloBackupExecucao(int id, int idBackup, DateTime dataExecucao, string status, string mensagem, long? tamanhoArquivo, int? duracaoSegundos) + { + Id = id; + IdBackup = idBackup; + DataExecucao = dataExecucao; + Status = status; + Mensagem = mensagem; + TamanhoArquivo = tamanhoArquivo; + DuracaoSegundos = duracaoSegundos; + } + public ModeloBackupExecucao() + { + } + + public int Id { get; set; } + + public int IdBackup { get; set; } + + public DateTime DataExecucao { get; set; } + + public string Status { get; set; } + + public string Mensagem { get; set; } + + public long? TamanhoArquivo { get; set; } + + public int? DuracaoSegundos { get; set; } + } +} \ No newline at end of file diff --git a/MLL/ModeloCloudStorage.cs b/MLL/ModeloCloudStorage.cs new file mode 100644 index 0000000..ca2c151 --- /dev/null +++ b/MLL/ModeloCloudStorage.cs @@ -0,0 +1,74 @@ +using System; + +namespace MLL +{ + public class ModeloCloudStorage + { + public int Id { get; set; } + + public string Nome { get; set; } + public string Tipo { get; set; } // 'gdrive', 'onedrive', 'webdav' + + // OAuth + public string ClientId { get; set; } + public string ClientSecret { get; set; } + public string AccessToken { get; set; } + public string RefreshToken { get; set; } + public DateTime? TokenExpiraEm { get; set; } + + // WebDAV + public string Url { get; set; } + public string Usuario { get; set; } + public string Senha { get; set; } + + // Geral + public string PastaBase { get; set; } + + public bool Ativo { get; set; } + + public DateTime CriadoEm { get; set; } + public DateTime? AtualizadoEm { get; set; } + + // ========================= + // 🏗️ CONSTRUTORES + // ========================= + + // 🔹 Construtor vazio (ORM / DAL) + public ModeloCloudStorage() + { + Ativo = true; + CriadoEm = DateTime.Now; + } + + // 🔹 Construtor com parâmetros principais + public ModeloCloudStorage( + string nome, + string tipo, + string pastaBase = null, + string clientId = null, + string clientSecret = null, + string accessToken = null, + string refreshToken = null, + DateTime? tokenExpiraEm = null, + string url = null, + string usuario = null, + string senha = null + ) : this() + { + Nome = nome; + Tipo = tipo; + + PastaBase = pastaBase; + + ClientId = clientId; + ClientSecret = clientSecret; + AccessToken = accessToken; + RefreshToken = refreshToken; + TokenExpiraEm = tokenExpiraEm; + + Url = url; + Usuario = usuario; + Senha = senha; + } + } +} \ No newline at end of file diff --git a/MLL/ModeloSmtp.cs b/MLL/ModeloSmtpCliente.cs similarity index 100% rename from MLL/ModeloSmtp.cs rename to MLL/ModeloSmtpCliente.cs diff --git a/MLL/ModeloSshCliente.cs b/MLL/ModeloSshCliente.cs index f5c34de..4a7b0f4 100644 --- a/MLL/ModeloSshCliente.cs +++ b/MLL/ModeloSshCliente.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace MLL { - internal class ModeloSshCliente + public class ModeloSshCliente { public ModeloSshCliente() { diff --git a/MLL/ModeloTelegramCliente.cs b/MLL/ModeloTelegramCliente.cs new file mode 100644 index 0000000..d72e56b --- /dev/null +++ b/MLL/ModeloTelegramCliente.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MLL +{ + public class ModeloTelegramCliente + { + public ModeloTelegramCliente() + { + Id = 0; + Nome = ""; + Tipo = ""; + BotToken = ""; + ApiId = 0; + ApiHash = ""; + Telefone = ""; + SessionString = ""; + ChatId = ""; + Ativo = false; + CriadoEm = DateTime.MinValue; + AtualizadoEm = DateTime.MinValue; + } + public ModeloTelegramCliente(int id, string nome, string tipo, string botToken, int? apiId, string apiHash, string telefone, string sessionString, string chatId, bool ativo, DateTime criadoEm, DateTime? atualizadoEm) + { + Id = id; + Nome = nome; + Tipo = tipo; + BotToken = botToken; + ApiId = apiId; + ApiHash = apiHash; + Telefone = telefone; + SessionString = sessionString; + ChatId = chatId; + Ativo = ativo; + CriadoEm = criadoEm; + AtualizadoEm = atualizadoEm; + } + + public int Id { get; set; } + public string Nome { get; set; } + public string Tipo { get; set; } + public string BotToken { get; set; } + public int? ApiId { get; set; } + public string ApiHash { get; set; } + public string Telefone { get; set; } + public string SessionString { get; set; } + public string ChatId { get; set; } + public bool Ativo { get; set; } + public DateTime CriadoEm { get; set; } + public DateTime? AtualizadoEm { get; set; } + } +} diff --git a/UI/Dashboards/Cadastros/BackupAutomaticoCadastroPanel.cs b/UI/Dashboards/Cadastros/BackupAutomaticoCadastroPanel.cs new file mode 100644 index 0000000..9e87616 --- /dev/null +++ b/UI/Dashboards/Cadastros/BackupAutomaticoCadastroPanel.cs @@ -0,0 +1,115 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class BackupAutomaticoCadastroPanel : FormularioModelo + { + private ModeloBackupAutomatico _auto = new ModeloBackupAutomatico(); + + // Controles - Vínculo e Status + private LV_TEXTBOX1 txtId, txtIdBackup, txtNomeBackup; + private CheckBox chkAtivo, chkExecutando; + + // Controles - Recorrência + private ComboBox cbFrequencia, cbDiaSemana; + private NumericUpDown numIntervalo, numDiaMes; + private DateTimePicker dtpHorario; + + // Controles - Monitoramento de Tempo + private LV_TEXTBOX1 txtUltimaExec, txtProximaExec; + + public BackupAutomaticoCadastroPanel() + { + this.Titulo = "Agendamento Inteligente de Backup"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Identificação do Job --- + content.Controls.Add(CreateSectionHeader("VÍNCULO DA TAREFA", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtIdBackup = AddInput(content, "ID BACKUP", 100, 50, 100, 30); + txtNomeBackup = AddInput(content, "ROTINA ASSOCIADA", 210, 50, 350, 30, true); + + chkAtivo = new CheckBox { Text = "AGENDAMENTO ATIVO", Location = new Point(580, 66), AutoSize = true, Font = new Font("Segoe UI", 9, FontStyle.Bold) }; + chkExecutando = new CheckBox { Text = "EM EXECUÇÃO AGORA", Location = new Point(735, 66), AutoSize = true, Enabled = false }; + + content.Controls.Add(chkAtivo); + content.Controls.Add(chkExecutando); + + // --- SEÇÃO 2: Regras de Frequência --- + content.Controls.Add(CreateSectionHeader("PERIODICIDADE E REGRAS", 115)); + + Label lblFreq = new Label { Text = "FREQUÊNCIA", Location = new Point(20, 143), AutoSize = true }; + cbFrequencia = new ComboBox { Location = new Point(20, 160), Size = new Size(150, 30), DropDownStyle = ComboBoxStyle.DropDownList }; + cbFrequencia.Items.AddRange(new object[] { "INTERVALO", "DIARIO", "SEMANAL", "MENSAL" }); + + Label lblInt = new Label { Text = "INTERVALO (MIN)", Location = new Point(180, 143), AutoSize = true }; + numIntervalo = new NumericUpDown { Location = new Point(180, 160), Size = new Size(100, 30), Maximum = 1440 }; + + Label lblHora = new Label { Text = "HORÁRIO FIXO", Location = new Point(290, 143), AutoSize = true }; + dtpHorario = new DateTimePicker { Location = new Point(290, 160), Size = new Size(100, 30), Format = DateTimePickerFormat.Time, ShowUpDown = true }; + + Label lblSemana = new Label { Text = "DIA DA SEMANA", Location = new Point(400, 143), AutoSize = true }; + cbDiaSemana = new ComboBox { Location = new Point(400, 160), Size = new Size(130, 30), DropDownStyle = ComboBoxStyle.DropDownList }; + cbDiaSemana.Items.AddRange(new object[] { "Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado" }); + + Label lblDiaMes = new Label { Text = "DIA DO MÊS", Location = new Point(540, 143), AutoSize = true }; + numDiaMes = new NumericUpDown { Location = new Point(540, 160), Size = new Size(80, 30), Minimum = 1, Maximum = 31 }; + + content.Controls.Add(lblFreq); content.Controls.Add(cbFrequencia); + content.Controls.Add(lblInt); content.Controls.Add(numIntervalo); + content.Controls.Add(lblHora); content.Controls.Add(dtpHorario); + content.Controls.Add(lblSemana); content.Controls.Add(cbDiaSemana); + content.Controls.Add(lblDiaMes); content.Controls.Add(numDiaMes); + + // --- SEÇÃO 3: Linha do Tempo --- + content.Controls.Add(CreateSectionHeader("PRÓXIMAS ETAPAS", 220)); + txtUltimaExec = AddInput(content, "ÚLTIMA VEZ QUE RODOU", 20, 250, 250, 30, true); + txtProximaExec = AddInput(content, "AGENDADO PARA", 280, 250, 250, 30, true); + txtProximaExec.BackColor = Color.LightYellow; + + content.Height = 350; + + // Lógica para habilitar/desabilitar campos baseado na frequência + cbFrequencia.SelectedIndexChanged += (s, e) => ActualizarInterfaceFrequencia(); + } + + private void ActualizarInterfaceFrequencia() + { + string freq = cbFrequencia.Text; + numIntervalo.Enabled = (freq == "INTERVALO"); + dtpHorario.Enabled = (freq != "INTERVALO"); + cbDiaSemana.Enabled = (freq == "SEMANAL"); + numDiaMes.Enabled = (freq == "MENSAL"); + } + + private void PreencherModel() + { + _auto.IdBackup = int.TryParse(txtIdBackup.Text, out int idB) ? idB : 0; + _auto.Ativo = chkAtivo.Checked; + _auto.Frequencia = cbFrequencia.Text; + _auto.IntervaloMinutos = (int)numIntervalo.Value; + _auto.Horario = dtpHorario.Value.TimeOfDay; + _auto.DiaSemana = cbDiaSemana.SelectedIndex; + _auto.DiaMes = (int)numDiaMes.Value; + } + + protected override void OnNovo() { _auto = new ModeloBackupAutomatico(); cbFrequencia.SelectedIndex = 1; } + protected override void OnSalvar() { PreencherModel(); MessageBox.Show("Agendamento automático configurado!", "LevelOS Scheduler"); } + protected override void OnCancelar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnAlterar() { } + + + + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/BackupAutomaticoCadastroPanel.resx b/UI/Dashboards/Cadastros/BackupAutomaticoCadastroPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/Dashboards/Cadastros/BackupAutomaticoCadastroPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/BackupCadastroPanel.cs b/UI/Dashboards/Cadastros/BackupCadastroPanel.cs new file mode 100644 index 0000000..0bb58e5 --- /dev/null +++ b/UI/Dashboards/Cadastros/BackupCadastroPanel.cs @@ -0,0 +1,119 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class BackupCadastroPanel : FormularioModelo + { + private ModeloBackup _backup = new ModeloBackup(); + + // Controles - Configuração Geral + private LV_TEXTBOX1 txtId, txtNome, txtOrigem, txtCaminhoDestino; + private ComboBox cbTipoBackup, cbDestinoTipo, cbFrequencia; + + // Controles - Segurança e Compactação + private CheckBox chkCompactar, chkCriptografia, chkAtivo; + private LV_TEXTBOX1 txtAlgoritmo, txtManterUltimos; + + // Controles - Agendamento + private DateTimePicker dtpHorario; + + // Controles - Status e Logs (Somente Leitura) + private LV_TEXTBOX1 txtStatusUltimo, txtDataUltimo, txtLogUltimo; + + public BackupCadastroPanel() + { + this.Titulo = "Configuração e Agendamento de Backup"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Definição do Backup --- + content.Controls.Add(CreateSectionHeader("O QUE SERÁ SALVO?", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtNome = AddInput(content, "NOME DA ROTINA (EX: BACKUP DIÁRIO DB)", 100, 50, 300, 30); + + Label lblTipo = new Label { Text = "TIPO", Location = new Point(410, 33), AutoSize = true }; + cbTipoBackup = new ComboBox { Location = new Point(410, 50), Size = new Size(130, 30), DropDownStyle = ComboBoxStyle.DropDownList }; + cbTipoBackup.Items.AddRange(new object[] { "database", "arquivos", "completo" }); + + txtOrigem = AddInput(content, "ORIGEM (NOME DO BANCO OU DIRETÓRIO)", 20, 105, 520, 30); + chkAtivo = new CheckBox { Text = "ATIVO", Location = new Point(560, 121), AutoSize = true, Checked = true }; + + content.Controls.Add(lblTipo); + content.Controls.Add(cbTipoBackup); + content.Controls.Add(chkAtivo); + + // --- SEÇÃO 2: Destino e Frequência --- + content.Controls.Add(CreateSectionHeader("ONDE E QUANDO?", 165)); + + Label lblDest = new Label { Text = "DESTINO", Location = new Point(20, 178), AutoSize = true }; + cbDestinoTipo = new ComboBox { Location = new Point(20, 195), Size = new Size(120, 30), DropDownStyle = ComboBoxStyle.DropDownList }; + cbDestinoTipo.Items.AddRange(new object[] { "local", "ftp", "ssh", "nuvem" }); + + txtCaminhoDestino = AddInput(content, "CAMINHO DE DESTINO / PASTA REMOTA", 150, 195, 390, 30); + + Label lblFreq = new Label { Text = "FREQUÊNCIA", Location = new Point(20, 233), AutoSize = true }; + cbFrequencia = new ComboBox { Location = new Point(20, 250), Size = new Size(120, 30), DropDownStyle = ComboBoxStyle.DropDownList }; + cbFrequencia.Items.AddRange(new object[] { "manual", "diario", "semanal", "mensal" }); + + Label lblHora = new Label { Text = "HORÁRIO", Location = new Point(150, 233), AutoSize = true }; + dtpHorario = new DateTimePicker { Location = new Point(150, 250), Size = new Size(100, 30), Format = DateTimePickerFormat.Time, ShowUpDown = true }; + + txtManterUltimos = AddInput(content, "RETENÇÃO (QTD)", 270, 250, 100, 30); + + content.Controls.Add(lblDest); + content.Controls.Add(cbDestinoTipo); + content.Controls.Add(lblFreq); + content.Controls.Add(cbFrequencia); + content.Controls.Add(lblHora); + content.Controls.Add(dtpHorario); + + // --- SEÇÃO 3: Segurança --- + content.Controls.Add(CreateSectionHeader("OPÇÕES DE ARQUIVO", 305)); + chkCompactar = new CheckBox { Text = "COMPACTAR (.ZIP)", Location = new Point(20, 335), AutoSize = true }; + chkCriptografia = new CheckBox { Text = "CRIPTOGRAFAR", Location = new Point(160, 335), AutoSize = true }; + txtAlgoritmo = AddInput(content, "ALGORITMO", 300, 325, 150, 30); + + content.Controls.Add(chkCompactar); + content.Controls.Add(chkCriptografia); + + // --- SEÇÃO 4: Última Execução (Monitoramento) --- + content.Controls.Add(CreateSectionHeader("MONITORAMENTO", 380)); + txtStatusUltimo = AddInput(content, "STATUS", 20, 410, 120, 30, true); + txtDataUltimo = AddInput(content, "DATA ÚLT. EXECUÇÃO", 150, 410, 180, 30, true); + txtLogUltimo = AddInput(content, "LOG / MENSAGEM", 340, 410, 495, 30, true); + + content.Height = 480; + } + + private void PreencherModel() + { + _backup.Nome = txtNome.Text; + _backup.TipoBackup = cbTipoBackup.Text; + _backup.Origem = txtOrigem.Text; + _backup.DestinoTipo = cbDestinoTipo.Text; + _backup.CaminhoDestino = txtCaminhoDestino.Text; + _backup.Compactar = chkCompactar.Checked; + _backup.UsarCriptografia = chkCriptografia.Checked; + _backup.AlgoritmoCriptografia = txtAlgoritmo.Text; + _backup.Frequencia = cbFrequencia.Text; + _backup.Horario = dtpHorario.Value.TimeOfDay; + _backup.ManterUltimos = int.TryParse(txtManterUltimos.Text, out int m) ? m : 5; + _backup.Ativo = chkAtivo.Checked; + } + + protected override void OnNovo() { _backup = new ModeloBackup(); cbTipoBackup.SelectedIndex = 0; } + protected override void OnSalvar() { PreencherModel(); MessageBox.Show("Rotina de backup agendada!", "LevelOS Security"); } + protected override void OnCancelar() { } + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar(){ } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/CloudStorageCadastroPanel.cs b/UI/Dashboards/Cadastros/CloudStorageCadastroPanel.cs new file mode 100644 index 0000000..7092b25 --- /dev/null +++ b/UI/Dashboards/Cadastros/CloudStorageCadastroPanel.cs @@ -0,0 +1,136 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class CloudStorageCadastroPanel : FormularioModelo + { + private ModeloCloudStorage _cloud = new ModeloCloudStorage(); + + private LV_TEXTBOX1 txtId, txtNome, txtPastaBase; + private ComboBox cbTipo; + private CheckBox chkAtivo; + + private LV_TEXTBOX1 txtClientId, txtClientSecret, txtTokenStatus; + private Button btnAutenticar; + + private LV_TEXTBOX1 txtUrl, txtUsuario, txtSenha; + + public CloudStorageCadastroPanel() + { + this.Titulo = "Configuração de Armazenamento em Nuvem"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Identificação --- + content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DA CONTA", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtNome = AddInput(content, "NOME DA CONEXÃO", 100, 50, 290, 30); + + cbTipo = AddComboBox(content, "PROVEDOR", 400, 50, 150); + cbTipo.Items.AddRange(new object[] { "gdrive", "onedrive", "webdav" }); + cbTipo.SelectedIndex = 0; + + txtPastaBase = AddInput(content, "PASTA DESTINO (EX: /LevelOS_Backups)", 560, 50, 255, 30); + + chkAtivo = new CheckBox + { + Text = "ATIVO", + Location = new Point(20, 100), + AutoSize = true, + Checked = true, + Font = new Font("Segoe UI", 8.5f, FontStyle.Bold) + }; + content.Controls.Add(chkAtivo); + + // --- SEÇÃO 2: OAuth2 --- + content.Controls.Add(CreateSectionHeader("AUTENTICAÇÃO OAUTH2 (GOOGLE / ONEDRIVE)", 125)); + + txtClientId = AddInput(content, "CLIENT ID", 20, 155, 350, 30); + txtClientSecret = AddInput(content, "CLIENT SECRET", 380, 155, 350, 30); + txtClientSecret.PasswordChar = '●'; + + // Botão alinhado com os inputs acima (Y = 155 + 16 = 171 do input, botão na próxima linha) + btnAutenticar = new Button + { + Text = "🔗 Vincular Conta", + Location = new Point(20, 200), + Size = new Size(150, 30), + BackColor = Color.FromArgb(66, 133, 244), + ForeColor = Color.White, + FlatStyle = FlatStyle.Flat, + Font = new Font("Segoe UI", 9, FontStyle.Bold), + FlatAppearance = { BorderSize = 0 } + }; + btnAutenticar.Click += (s, e) => + MessageBox.Show("Abrindo navegador para autorização...", "LevelOS Cloud"); + content.Controls.Add(btnAutenticar); + + // STATUS DO TOKEN em linha própria, label Y=245, input Y=261 + txtTokenStatus = AddInput(content, "STATUS DO TOKEN", 20, 245, 710, 30, true); + + // --- SEÇÃO 3: WebDAV --- + content.Controls.Add(CreateSectionHeader("CONFIGURAÇÃO WEBDAV (NEXTCLOUD / OWNCLOUD)", 295)); + + txtUrl = AddInput(content, "URL DO SERVIDOR (EX: https://nuvem.seucloud.com/remote.php/dav/files/user/)", 20, 325, 490, 30); + txtUsuario = AddInput(content, "USUÁRIO", 520, 325, 150, 30); + txtSenha = AddInput(content, "SENHA / APP KEY", 680, 325, 135, 30); + txtSenha.PasswordChar = '●'; + + content.Height = 395; + + // Lógica para alternar habilitação por tipo + cbTipo.SelectedIndexChanged += (s, e) => + { + bool isWebDav = cbTipo.Text == "webdav"; + txtClientId.Enabled = !isWebDav; + txtClientSecret.Enabled = !isWebDav; + btnAutenticar.Enabled = !isWebDav; + txtUrl.Enabled = isWebDav; + txtUsuario.Enabled = isWebDav; + txtSenha.Enabled = isWebDav; + }; + } + + private void PreencherModel() + { + _cloud.Nome = txtNome.Text; + _cloud.Tipo = cbTipo.Text; + _cloud.PastaBase = txtPastaBase.Text; + _cloud.ClientId = txtClientId.Text; + _cloud.ClientSecret = txtClientSecret.Text; + _cloud.Url = txtUrl.Text; + _cloud.Usuario = txtUsuario.Text; + _cloud.Senha = txtSenha.Text; + _cloud.Ativo = chkAtivo.Checked; + } + + protected override void OnSalvar() + { + PreencherModel(); + MessageBox.Show($"Configuração {cbTipo.Text} salva com sucesso!", "LevelOS Cloud"); + } + + protected override void OnNovo() + { + _cloud = new ModeloCloudStorage(); + cbTipo.SelectedIndex = 0; + } + + protected override void OnExcluir() + { + MessageBox.Show("Configuração excluída.", "LevelOS Cloud"); + } + + protected override void OnAlterar() { throw new NotImplementedException(); } + protected override void OnLocalizar() { throw new NotImplementedException(); } + protected override void OnCancelar() { } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/CloudStorageCadastroPanel.resx b/UI/Dashboards/Cadastros/CloudStorageCadastroPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/Dashboards/Cadastros/CloudStorageCadastroPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/ItensSaidaCadastroPanel.cs b/UI/Dashboards/Cadastros/ItensSaidaCadastroPanel.cs new file mode 100644 index 0000000..d848903 --- /dev/null +++ b/UI/Dashboards/Cadastros/ItensSaidaCadastroPanel.cs @@ -0,0 +1,130 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class ItensSaidaCadastroPanel : FormularioModelo + { + private ModeloItensSaida _saida = new ModeloItensSaida(); + + // Controles - Identificação e Item + private LV_TEXTBOX1 txtId, txtCodigo, txtCodItem, txtDescricaoItem; + private Button btnBuscaItem; + + // Controles - Quantidade e Responsável + private LV_TEXTBOX1 txtQtdSai, txtDataSaida, txtFuncionario; + + // Controles - Origem e Documentação (OS, OP, OV, NOTA) + private LV_TEXTBOX1 txtOs, txtOp, txtOv, txtNota, txtNatureza; + + // Controles - Notas + private LV_TEXTBOX1 txtObs; + + public ItensSaidaCadastroPanel() + { + this.Titulo = "Lançamento de Saída / Baixa de Estoque"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Item Selecionado --- + content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO PRODUTO", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtCodigo = AddInput(content, "CÓD. MOV.", 100, 50, 110, 30); + + txtCodItem = AddInput(content, "CÓD. ITEM", 220, 50, 100, 30); + btnBuscaItem = CriarBotaoLupa(325, 66, OnBuscaItem); + txtDescricaoItem = AddInput(content, "DESCRIÇÃO DO PRODUTO", 365, 50, 470, 30, true); + + // --- SEÇÃO 2: Dados da Movimentação --- + content.Controls.Add(CreateSectionHeader("DADOS DA BAIXA", 115)); + + txtQtdSai = AddInput(content, "QTD. SAÍDA", 20, 145, 130, 30); + txtQtdSai.BackColor = Color.FromArgb(255, 240, 240); // Tom avermelhado para indicar saída/baixa + + txtDataSaida = AddInput(content, "DATA SAÍDA", 160, 145, 130, 30); + txtFuncionario = AddInput(content, "RESPONSÁVEL PELA BAIXA", 300, 145, 330, 30); + txtNatureza = AddInput(content, "NATUREZA (EX: VENDA/AVARIA)", 640, 145, 195, 30); + + // --- SEÇÃO 3: Vínculos e Documentos (OS, OP, OV, NOTA) --- + content.Controls.Add(CreateSectionHeader("DOCUMENTOS DE ORIGEM", 210)); + + txtOs = AddInput(content, "ORDEM SERV. (OS)", 20, 240, 150, 30); + txtOp = AddInput(content, "ORDEM PROD. (OP)", 180, 240, 150, 30); + txtOv = AddInput(content, "ORDEM VENDA (OV)", 340, 240, 150, 30); + txtNota = AddInput(content, "NOTA FISCAL", 500, 240, 180, 30); + + // --- SEÇÃO 4: Observações --- + content.Controls.Add(CreateSectionHeader("OBSERVAÇÕES GERAIS", 305)); + txtObs = AddInput(content, "MOTIVO DETALHADO DA SAÍDA", 20, 335, 815, 60); + + content.Height = 430; + } + + private Button CriarBotaoLupa(int x, int y, EventHandler clickEvent) + { + var btn = new Button + { + Text = "🔍", + Location = new Point(x, y), + Size = new Size(32, 30), + BackColor = AccentBlue, + ForeColor = Color.White, + FlatStyle = FlatStyle.Flat, + Cursor = Cursors.Hand + }; + btn.FlatAppearance.BorderSize = 0; + btn.Click += clickEvent; + content.Controls.Add(btn); + return btn; + } + + private void OnBuscaItem(object sender, EventArgs e) => MessageBox.Show("Busca de Itens"); + + private void PreencherModel() + { + _saida.CODIGO = txtCodigo.Text; + _saida.COD_ITEM = txtCodItem.Text; + _saida.QTD_SAI = txtQtdSai.Text; + _saida.FUNCIONARIO = txtFuncionario.Text; + _saida.NOTA = txtNota.Text; + _saida.OS = txtOs.Text; + _saida.OP = txtOp.Text; + _saida.OBSERVACAO = txtObs.Text; + _saida.DATA_SAIDA = txtDataSaida.Text; + _saida.NATUREZA = txtNatureza.Text; + _saida.OV = txtOv.Text; + } + + protected override void OnNovo() + { + _saida = new ModeloItensSaida(); + txtDataSaida.Text = DateTime.Now.ToString("dd/MM/yyyy"); + txtCodItem.Focus(); + } + + protected override void OnSalvar() + { + try + { + PreencherModel(); + MessageBox.Show("Baixa de estoque registrada!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show("Erro ao salvar: " + ex.Message); + } + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { OnNovo(); } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/ItensSerialCadastroPanel.cs b/UI/Dashboards/Cadastros/ItensSerialCadastroPanel.cs new file mode 100644 index 0000000..ff0eab0 --- /dev/null +++ b/UI/Dashboards/Cadastros/ItensSerialCadastroPanel.cs @@ -0,0 +1,141 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class ItensSerialCadastroPanel : FormularioModelo + { + private ModeloItensSerial _serial = new ModeloItensSerial(); + + // Controles - Identificação + private LV_TEXTBOX1 txtId, txtCodigo, txtCodItem, txtSerial, txtNomeItem; + private Button btnBuscaItem; + + // Controles - Histórico de Entrada + private LV_TEXTBOX1 txtCodEntrada, txtNfEntrada; + + // Controles - Histórico de Saída + private LV_TEXTBOX1 txtCodSaida, txtNfSaida, txtDataMovim; + + // Status e Notas + private LV_TEXTBOX1 txtObs; + private ComboBox cbBaixado; + + public ItensSerialCadastroPanel() + { + this.Titulo = "Rastreamento de Número de Série / Garantia"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: O Produto e seu RG (Serial) --- + content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO HARDWARE", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtCodigo = AddInput(content, "CÓD. VÍNCULO", 100, 50, 110, 30); + + txtCodItem = AddInput(content, "CÓD. ITEM", 220, 50, 90, 30); + btnBuscaItem = CriarBotaoLupa(315, 66, OnBuscaItem); + txtNomeItem = AddInput(content, "NOME DO PRODUTO", 355, 50, 480, 30, true); + + txtSerial = AddInput(content, "NÚMERO DE SÉRIE (S/N)", 20, 105, 380, 30); + txtSerial.BackColor = Color.LightYellow; + txtSerial.Font = new Font("Segoe UI", 10, FontStyle.Bold); + + Label lblStatus = new Label { Text = "ESTÁ BAIXADO?", Location = new Point(415, 88), AutoSize = true }; + cbBaixado = new ComboBox + { + Location = new Point(415, 105), + Size = new Size(120, 30), + DropDownStyle = ComboBoxStyle.DropDownList, + FlatStyle = FlatStyle.Flat + }; + cbBaixado.Items.AddRange(new object[] { "NÃO", "SIM" }); + cbBaixado.SelectedIndex = 0; + content.Controls.Add(lblStatus); + content.Controls.Add(cbBaixado); + + // --- SEÇÃO 2: Origem (Entrada) --- + content.Controls.Add(CreateSectionHeader("HISTÓRICO DE ENTRADA / COMPRA", 165)); + + txtCodEntrada = AddInput(content, "ID MOV. ENTRADA", 20, 195, 150, 30); + txtNfEntrada = AddInput(content, "NF-e ENTRADA", 185, 195, 150, 30); + + // --- SEÇÃO 3: Destino (Saída) --- + content.Controls.Add(CreateSectionHeader("HISTÓRICO DE SAÍDA / VENDA", 250)); + + txtCodSaida = AddInput(content, "ID MOV. SAÍDA", 20, 280, 150, 30); + txtNfSaida = AddInput(content, "NF-e SAÍDA", 185, 280, 150, 30); + txtDataMovim = AddInput(content, "DATA ÚLT. MOV.", 350, 280, 150, 30); + + // --- SEÇÃO 4: Observações de Garantia --- + content.Controls.Add(CreateSectionHeader("OBSERVAÇÕES TÉCNICAS / ESTADO", 345)); + txtObs = AddInput(content, "EX: ESTADO FÍSICO, DETALHES DE GARANTIA, ETC.", 20, 375, 815, 50); + + content.Height = 460; + } + + private Button CriarBotaoLupa(int x, int y, EventHandler clickEvent) + { + var btn = new Button + { + Text = "🔍", + Location = new Point(x, y), + Size = new Size(32, 30), + BackColor = AccentBlue, + ForeColor = Color.White, + FlatStyle = FlatStyle.Flat, + Cursor = Cursors.Hand + }; + btn.FlatAppearance.BorderSize = 0; + btn.Click += clickEvent; + content.Controls.Add(btn); + return btn; + } + + private void OnBuscaItem(object sender, EventArgs e) => MessageBox.Show("Busca de Itens"); + + private void PreencherModel() + { + _serial.CODIGO = txtCodigo.Text; + _serial.COD_ITEM = txtCodItem.Text; + _serial.SERIAL = txtSerial.Text; + _serial.COD_NF_ENTRADA = txtNfEntrada.Text; + _serial.COD_NF_SAIDA = txtNfSaida.Text; + _serial.COD_ENTRADA = txtCodEntrada.Text; + _serial.COD_SAIDA = txtCodSaida.Text; + _serial.DATA_MOVIM = txtDataMovim.Text; + _serial.BAIXADO = cbBaixado.SelectedItem.ToString(); + _serial.OBS = txtObs.Text; + } + + protected override void OnNovo() + { + _serial = new ModeloItensSerial(); + txtSerial.Focus(); + } + + protected override void OnSalvar() + { + try + { + PreencherModel(); + MessageBox.Show("Número de série registrado no histórico!", "Garantia LevelOS", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show("Erro: " + ex.Message); + } + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { OnNovo(); } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/ItensVendaCadastroPanel.cs b/UI/Dashboards/Cadastros/ItensVendaCadastroPanel.cs new file mode 100644 index 0000000..7374e46 --- /dev/null +++ b/UI/Dashboards/Cadastros/ItensVendaCadastroPanel.cs @@ -0,0 +1,148 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class ItensVendaCadastroPanel : FormularioModelo + { + private ModeloItensVenda _itemVenda = new ModeloItensVenda(); + + // Controles - Vínculos e Identificação + private LV_TEXTBOX1 txtId, txtCodigo, txtItemCodigo, txtBarcode, txtDescricao; + private Button btnBuscaItem; + + // Controles - Comercial (Valores e Lucro) + private LV_TEXTBOX1 txtQtd, txtVlrUn, txtDesconto, txtVlrTotal, txtVendaTabela, txtCusto; + + // Controles - Rastreabilidade e Fiscal + private LV_TEXTBOX1 txtSeriais, txtLotes, txtXped, txtNitemped, txtInfAdic; + + // Auxiliares + private LV_TEXTBOX1 txtUn, txtServico, txtDia; + + public ItensVendaCadastroPanel() + { + this.Titulo = "Detalhamento do Item da Venda"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Dados do Produto --- + content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO ITEM", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtCodigo = AddInput(content, "CÓD. VENDA", 100, 50, 100, 30); + txtItemCodigo = AddInput(content, "CÓD. ITEM", 210, 50, 100, 30); + btnBuscaItem = CriarBotaoLupa(315, 66, OnBuscaItem); + + txtBarcode = AddInput(content, "BARCODE", 355, 50, 160, 30); + txtDescricao = AddInput(content, "DESCRIÇÃO DO ITEM", 20, 105, 495, 30); + txtUn = AddInput(content, "UN", 525, 105, 60, 30); + txtServico = AddInput(content, "S/P", 595, 105, 60, 30); // Serviço ou Produto + + // --- SEÇÃO 2: Financeiro e Precificação --- + content.Controls.Add(CreateSectionHeader("VALORES E NEGOCIAÇÃO", 175)); + + txtCusto = AddInput(content, "CUSTO UNIT. (REF)", 20, 205, 130, 30, true); + txtVendaTabela = AddInput(content, "PREÇO TABELA", 160, 205, 130, 30, true); + + txtQtd = AddInput(content, "QUANTIDADE", 300, 205, 100, 30); + txtVlrUn = AddInput(content, "PREÇO PRATICADO", 410, 205, 130, 30); + txtVlrUn.BackColor = Color.LightCyan; + + txtDesconto = AddInput(content, "DESCONTO UNIT.", 550, 205, 105, 30); + + txtVlrTotal = AddInput(content, "TOTAL LÍQUIDO", 665, 205, 170, 30, true); + txtVlrTotal.BackColor = Color.FromArgb(235, 255, 235); + txtVlrTotal.Font = new Font("Segoe UI", 11, FontStyle.Bold); + + // --- SEÇÃO 3: Rastreabilidade (Seriais e Lotes) --- + content.Controls.Add(CreateSectionHeader("CONTROLE DE ESTOQUE ESPECÍFICO", 275)); + + txtSeriais = AddInput(content, "NÚMEROS DE SÉRIE (GARANTIA)", 20, 305, 400, 40); + txtLotes = AddInput(content, "IDENTIFICAÇÃO DE LOTES", 430, 305, 405, 40); + + // --- SEÇÃO 4: Dados Fiscais e Pedido Externo --- + content.Controls.Add(CreateSectionHeader("REFERÊNCIAS FISCAIS (NF-e)", 375)); + + txtXped = AddInput(content, "PEDIDO COMPRA CLIENTE (xPed)", 20, 405, 200, 30); + txtNitemped = AddInput(content, "ITEM DO PEDIDO (nItemPed)", 230, 405, 150, 30); + txtDia = AddInput(content, "DIA", 390, 405, 60, 30); + + txtInfAdic = AddInput(content, "INFORMAÇÕES ADICIONAIS DO ITEM", 460, 405, 375, 40); + + content.Height = 480; + } + + private Button CriarBotaoLupa(int x, int y, EventHandler clickEvent) + { + var btn = new Button + { + Text = "🔍", + Location = new Point(x, y), + Size = new Size(32, 30), + BackColor = AccentBlue, + ForeColor = Color.White, + FlatStyle = FlatStyle.Flat, + Cursor = Cursors.Hand + }; + btn.FlatAppearance.BorderSize = 0; + btn.Click += clickEvent; + content.Controls.Add(btn); + return btn; + } + + private void OnBuscaItem(object sender, EventArgs e) => MessageBox.Show("Selecionar Item para Venda"); + + private void PreencherModel() + { + _itemVenda.CODIGO = txtCodigo.Text; + _itemVenda.ITEM_CODIGO = txtItemCodigo.Text; + _itemVenda.BARCODE = txtBarcode.Text; + _itemVenda.DESCRICAO = txtDescricao.Text; + _itemVenda.SERVICO = txtServico.Text; + _itemVenda.QTD = txtQtd.Text; + _itemVenda.VRL_UN = txtVlrUn.Text; + _itemVenda.DESCONTO = txtDesconto.Text; + _itemVenda.VLR_TOTAL = txtVlrTotal.Text; + _itemVenda.UN = txtUn.Text; + _itemVenda.VENDA = txtVendaTabela.Text; + _itemVenda.DIA = txtDia.Text; + _itemVenda.SERIAIS_IN = txtSeriais.Text; + _itemVenda.XPED = txtXped.Text; + _itemVenda.NITEMPED = txtNitemped.Text; + _itemVenda.CUSTO = txtCusto.Text; + _itemVenda.VINF_ADIC = txtInfAdic.Text; + _itemVenda.LOTES = txtLotes.Text; + } + + protected override void OnNovo() + { + _itemVenda = new ModeloItensVenda(); + txtBarcode.Focus(); + } + + protected override void OnSalvar() + { + try + { + PreencherModel(); + MessageBox.Show("Item adicionado à venda!", "LevelOS PDV", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show("Erro: " + ex.Message); + } + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { OnNovo(); } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/LCP116CadastroPanel.cs b/UI/Dashboards/Cadastros/LCP116CadastroPanel.cs new file mode 100644 index 0000000..d2f3fdd --- /dev/null +++ b/UI/Dashboards/Cadastros/LCP116CadastroPanel.cs @@ -0,0 +1,93 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class LCP116CadastroPanel : FormularioModelo + { + private ModeloLCP116 _lcp = new ModeloLCP116(); + + // Controles - Identificação + private LV_TEXTBOX1 txtId, txtCodigo, txtDataCadastro; + + // Controles - Hierarquia e Descrição + private LV_TEXTBOX1 txtCodigoPai, txtCodigoFilho, txtDescricao; + + public LCP116CadastroPanel() + { + this.Titulo = "Lista de Serviços LC 116/03 (ISS)"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Identificação do Registro --- + content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO FISCAL", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtCodigo = AddInput(content, "CÓD. INTERNO", 100, 50, 110, 30); + txtDataCadastro = AddInput(content, "DATA CADASTRO", 220, 50, 150, 30, true); + + // --- SEÇÃO 2: Estrutura do Código de Serviço --- + content.Controls.Add(CreateSectionHeader("HIERARQUIA DO SERVIÇO", 115)); + + txtCodigoPai = AddInput(content, "GRUPO (PAI)", 20, 145, 120, 30); + txtCodigoFilho = AddInput(content, "SUB-ITEM (FILHO)", 150, 145, 120, 30); + + // Exemplo visual: 14.02 (Assistência Técnica) + Label lblExemplo = new Label + { + Text = "Ex: Pai [14] - Filho [02] = 14.02", + Location = new Point(280, 161), + AutoSize = true, + ForeColor = Color.Gray, + Font = new Font("Segoe UI", 8, FontStyle.Italic) + }; + content.Controls.Add(lblExemplo); + + // --- SEÇÃO 3: Descrição Oficial --- + content.Controls.Add(CreateSectionHeader("DESCRIÇÃO DA ATIVIDADE", 210)); + txtDescricao = AddInput(content, "TEXTO CONFORME LEI COMPLEMENTAR", 20, 240, 815, 60); + + content.Height = 330; + } + + private void PreencherModel() + { + _lcp.CODIGO = txtCodigo.Text; + _lcp.CODIGO_PAI = txtCodigoPai.Text; + _lcp.CODIGO_FILHO = txtCodigoFilho.Text; + _lcp.DESCRICAO = txtDescricao.Text; + _lcp.DATA_CADASTRO = txtDataCadastro.Text; + } + + protected override void OnNovo() + { + _lcp = new ModeloLCP116(); + txtDataCadastro.Text = DateTime.Now.ToString("dd/MM/yyyy"); + txtCodigoPai.Focus(); + } + + protected override void OnSalvar() + { + try + { + PreencherModel(); + MessageBox.Show("Código de serviço LC116 registrado!", "LevelOS Fiscal", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show("Erro: " + ex.Message); + } + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { OnNovo(); } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Configurações/Servicos/FtpClienteCadastroPanel.cs b/UI/Dashboards/Configurações/Servicos/FtpClienteCadastroPanel.cs new file mode 100644 index 0000000..06364c2 --- /dev/null +++ b/UI/Dashboards/Configurações/Servicos/FtpClienteCadastroPanel.cs @@ -0,0 +1,111 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class FtpClienteCadastroPanel : FormularioModelo + { + private ModeloFtpCliente _ftp = new ModeloFtpCliente(); + + // Controles - Conexão + private LV_TEXTBOX1 txtId, txtNome, txtHost, txtPorta, txtDiretorio; + + // Controles - Autenticação + private LV_TEXTBOX1 txtUsuario, txtSenha; + private CheckBox chkSsl, chkPassivo, chkAtivo; + + // Controles - Info e Ação + private LV_TEXTBOX1 txtCriadoEm, txtAtualizadoEm; + private Button btnTestarFtp; + + public FtpClienteCadastroPanel() + { + this.Titulo = "Configuração de Cliente FTP / Storage"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Endereçamento --- + content.Controls.Add(CreateSectionHeader("SERVIDOR DE ARQUIVOS", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtNome = AddInput(content, "NOME DA CONEXÃO (EX: BACKUP CLOUD)", 100, 50, 350, 30); + + txtHost = AddInput(content, "HOST / IP (EX: ftp.meusite.com)", 20, 105, 330, 30); + txtPorta = AddInput(content, "PORTA", 360, 105, 90, 30); + + chkSsl = new CheckBox { Text = "USAR SSL/TLS", Location = new Point(470, 121), AutoSize = true }; + chkPassivo = new CheckBox { Text = "MODO PASSIVO", Location = new Point(580, 121), AutoSize = true, Checked = true }; + chkAtivo = new CheckBox { Text = "ATIVO", Location = new Point(700, 121), AutoSize = true, Checked = true }; + + content.Controls.Add(chkSsl); + content.Controls.Add(chkPassivo); + content.Controls.Add(chkAtivo); + + // --- SEÇÃO 2: Credenciais e Caminhos --- + content.Controls.Add(CreateSectionHeader("AUTENTICAÇÃO E DIRETÓRIO", 165)); + + txtUsuario = AddInput(content, "USUÁRIO", 20, 195, 250, 30); + txtSenha = AddInput(content, "SENHA", 280, 195, 200, 30); + txtSenha.PasswordChar = '●'; + + txtDiretorio = AddInput(content, "DIRETÓRIO RAIZ (EX: /public_html/backups)", 20, 250, 460, 30); + + btnTestarFtp = new Button + { + Text = "📁 Testar Acesso", + Location = new Point(500, 266), + Size = new Size(150, 30), + BackColor = Color.FromArgb(0, 122, 204), + ForeColor = Color.White, + FlatStyle = FlatStyle.Flat, + Font = new Font("Segoe UI", 9, FontStyle.Bold) + }; + btnTestarFtp.Click += (s, e) => MessageBox.Show("Tentando conectar ao servidor FTP..."); + content.Controls.Add(btnTestarFtp); + + // --- SEÇÃO 3: Datas --- + content.Controls.Add(CreateSectionHeader("LOG DE REGISTRO", 310)); + txtCriadoEm = AddInput(content, "CRIADO EM", 20, 340, 185, 30, true); + txtAtualizadoEm = AddInput(content, "ÚLT. ATUALIZAÇÃO", 215, 340, 185, 30, true); + + content.Height = 400; + } + + private void PreencherModel() + { + _ftp.Nome = txtNome.Text; + _ftp.Host = txtHost.Text; + _ftp.Porta = int.TryParse(txtPorta.Text, out int p) ? p : 21; + _ftp.Usuario = txtUsuario.Text; + _ftp.Senha = txtSenha.Text; + _ftp.UsarSsl = chkSsl.Checked; + _ftp.ModoPassivo = chkPassivo.Checked; + _ftp.DiretorioRaiz = txtDiretorio.Text; + _ftp.Ativo = chkAtivo.Checked; + } + + protected override void OnNovo() + { + _ftp = new ModeloFtpCliente(); + txtPorta.Text = "21"; + txtNome.Focus(); + } + + protected override void OnSalvar() + { + PreencherModel(); + MessageBox.Show("Configuração FTP salva com sucesso!", "LevelOS Storage", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Configurações/Servicos/SmtpClienteCadastroPanel.cs b/UI/Dashboards/Configurações/Servicos/SmtpClienteCadastroPanel.cs new file mode 100644 index 0000000..af93f7b --- /dev/null +++ b/UI/Dashboards/Configurações/Servicos/SmtpClienteCadastroPanel.cs @@ -0,0 +1,116 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class SmtpClienteCadastroPanel : FormularioModelo + { + private ModeloSmtpCliente _smtp = new ModeloSmtpCliente(); + + // Controles - Servidor + private LV_TEXTBOX1 txtId, txtNome, txtServidor, txtPorta; + + // Controles - Autenticação + private LV_TEXTBOX1 txtUsuario, txtSenha; + private CheckBox chkSsl, chkTls, chkAtivo; + + // Controles - Remetente + private LV_TEXTBOX1 txtEmailRemetente, txtNomeRemetente; + + // Controles - Info e Ações + private LV_TEXTBOX1 txtCriadoEm, txtAtualizadoEm; + private Button btnTestarSmtp; + + public SmtpClienteCadastroPanel() + { + this.Titulo = "Configuração de Servidor de E-mail (SMTP)"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Servidor --- + content.Controls.Add(CreateSectionHeader("SERVIDOR DE SAÍDA", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtNome = AddInput(content, "NOME DA CONFIG. (EX: GMAIL OFICIAL)", 100, 50, 350, 30); + + txtServidor = AddInput(content, "HOST SMTP (EX: smtp.gmail.com)", 20, 105, 330, 30); + txtPorta = AddInput(content, "PORTA", 360, 105, 90, 30); + + chkSsl = new CheckBox { Text = "USAR SSL", Location = new Point(470, 121), AutoSize = true }; + chkTls = new CheckBox { Text = "USAR TLS", Location = new Point(560, 121), AutoSize = true }; + chkAtivo = new CheckBox { Text = "ATIVO", Location = new Point(650, 121), AutoSize = true, Checked = true }; + + content.Controls.Add(chkSsl); + content.Controls.Add(chkTls); + content.Controls.Add(chkAtivo); + + // --- SEÇÃO 2: Autenticação e Remetente --- + content.Controls.Add(CreateSectionHeader("CONTA E IDENTIFICAÇÃO", 165)); + + txtUsuario = AddInput(content, "USUÁRIO / LOGIN", 20, 195, 250, 30); + txtSenha = AddInput(content, "SENHA / APP PASSWORD", 280, 195, 200, 30); + txtSenha.PasswordChar = '●'; + + txtEmailRemetente = AddInput(content, "E-MAIL DO REMETENTE", 20, 250, 250, 30); + txtNomeRemetente = AddInput(content, "NOME EXIBIDO NO ENVIO", 280, 250, 200, 30); + + btnTestarSmtp = new Button + { + Text = "⚡ Testar Conexão", + Location = new Point(500, 266), + Size = new Size(150, 30), + BackColor = Color.FromArgb(40, 167, 69), + ForeColor = Color.White, + FlatStyle = FlatStyle.Flat, + Font = new Font("Segoe UI", 9, FontStyle.Bold) + }; + btnTestarSmtp.Click += (s, e) => MessageBox.Show("Enviando e-mail de teste..."); + content.Controls.Add(btnTestarSmtp); + + // --- SEÇÃO 3: Datas --- + content.Controls.Add(CreateSectionHeader("HISTÓRICO", 310)); + txtCriadoEm = AddInput(content, "CRIADO EM", 20, 340, 185, 30, true); + txtAtualizadoEm = AddInput(content, "ÚLT. ATUALIZAÇÃO", 215, 340, 185, 30, true); + + content.Height = 400; + } + + private void PreencherModel() + { + _smtp.Nome = txtNome.Text; + _smtp.ServidorSmtp = txtServidor.Text; + _smtp.Porta = int.TryParse(txtPorta.Text, out int p) ? p : 587; + _smtp.Usuario = txtUsuario.Text; + _smtp.Senha = txtSenha.Text; + _smtp.UsarSsl = chkSsl.Checked; + _smtp.UsarTls = chkTls.Checked; + _smtp.EmailRemetente = txtEmailRemetente.Text; + _smtp.NomeRemetente = txtNomeRemetente.Text; + _smtp.Ativo = chkAtivo.Checked; + } + + protected override void OnNovo() + { + _smtp = new ModeloSmtpCliente(); + txtPorta.Text = "587"; + txtNome.Focus(); + } + + protected override void OnSalvar() + { + PreencherModel(); + MessageBox.Show("Configuração SMTP salva com sucesso!", "LevelOS Mail", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Configurações/Servicos/SshClienteCadastroPanel.cs b/UI/Dashboards/Configurações/Servicos/SshClienteCadastroPanel.cs new file mode 100644 index 0000000..bcf4e50 --- /dev/null +++ b/UI/Dashboards/Configurações/Servicos/SshClienteCadastroPanel.cs @@ -0,0 +1,133 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class SshClienteCadastroPanel : FormularioModelo + { + private ModeloSshCliente _ssh = new ModeloSshCliente(); + + // Controles - Identificação e Conexão + private LV_TEXTBOX1 txtId, txtNome, txtHost, txtPorta, txtUsuario; + + // Controles - Autenticação + private LV_TEXTBOX1 txtSenha, txtPassphrase, txtCaminhoChave; + private ComboBox cbTipoAutenticacao; + private CheckBox chkUsarChave, chkAtivo; + private Button btnSelecionarChave; + + // Controles - Informações Técnicas + private LV_TEXTBOX1 txtFingerprint, txtCriadoEm, txtAtualizadoEm; + + public SshClienteCadastroPanel() + { + this.Titulo = "Configuração de Conexão SSH"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Endereçamento --- + content.Controls.Add(CreateSectionHeader("SERVIDOR DESTINO", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtNome = AddInput(content, "NOME DA CONEXÃO (EX: SERVER CLOUD)", 100, 50, 350, 30); + txtHost = AddInput(content, "HOST / IP", 20, 105, 330, 30); + txtPorta = AddInput(content, "PORTA", 360, 105, 90, 30); + txtUsuario = AddInput(content, "USUÁRIO SSH", 460, 105, 180, 30); + + chkAtivo = new CheckBox { Text = "ATIVO", Location = new Point(660, 121), AutoSize = true, Checked = true }; + content.Controls.Add(chkAtivo); + + // --- SEÇÃO 2: Autenticação --- + content.Controls.Add(CreateSectionHeader("SEGURANÇA E ACESSO", 165)); + + // ✅ Usando AddComboBox — label e input no mesmo padrão do AddInput + cbTipoAutenticacao = AddComboBox(content, "MÉTODO", 20, 195, 150); + cbTipoAutenticacao.Items.AddRange(new object[] { "Senha", "Chave Privada" }); + cbTipoAutenticacao.SelectedIndex = 0; + + // ✅ Y=195 no AddInput → label em 195, input em 211 — alinhado com o ComboBox + txtSenha = AddInput(content, "SENHA", 180, 195, 200, 30); + txtSenha.PasswordChar = '●'; + + chkUsarChave = new CheckBox + { + Text = "USAR CHAVE (.PEM / .PPK)", + Location = new Point(400, 213), + AutoSize = true + }; + content.Controls.Add(chkUsarChave); + + txtCaminhoChave = AddInput(content, "CAMINHO DA CHAVE PRIVADA", 20, 260, 580, 30); + + btnSelecionarChave = new Button + { + Text = "...", + Location = new Point(610, 276), + Size = new Size(40, 30), + BackColor = Color.Gainsboro, + FlatStyle = FlatStyle.Flat + }; + new ToolTip().SetToolTip(btnSelecionarChave, "Selecionar arquivo de chave (.PEM / .PPK)"); + btnSelecionarChave.Click += (s, e) => + { + using var ofd = new OpenFileDialog + { + Filter = "Arquivos de Chave (*.pem;*.ppk)|*.pem;*.ppk|Todos (*.*)|*.*" + }; + if (ofd.ShowDialog() == DialogResult.OK) + txtCaminhoChave.Text = ofd.FileName; + }; + content.Controls.Add(btnSelecionarChave); + + txtPassphrase = AddInput(content, "PASSPHRASE DA CHAVE", 660, 260, 175, 30); + txtPassphrase.PasswordChar = '●'; + + // --- SEÇÃO 3: Metadados --- + content.Controls.Add(CreateSectionHeader("DADOS TÉCNICOS", 330)); + txtFingerprint = AddInput(content, "SSH FINGERPRINT (AUTOMÁTICO)", 20, 360, 430, 30, true); + txtCriadoEm = AddInput(content, "CRIADO EM", 460, 360, 185, 30, true); + txtAtualizadoEm = AddInput(content, "ÚLT. ATUALIZAÇÃO", 655, 360, 185, 30, true); + + content.Height = 420; + } + + private void PreencherModel() + { + _ssh.Nome = txtNome.Text; + _ssh.Host = txtHost.Text; + _ssh.Porta = int.TryParse(txtPorta.Text, out int p) ? p : 22; + _ssh.Usuario = txtUsuario.Text; + _ssh.TipoAutenticacao = cbTipoAutenticacao.Text; + _ssh.Senha = txtSenha.Text; + _ssh.CaminhoChave = txtCaminhoChave.Text; + _ssh.Passphrase = txtPassphrase.Text; + _ssh.UsarChave = chkUsarChave.Checked; + _ssh.Ativo = chkAtivo.Checked; + } + + protected override void OnNovo() + { + _ssh = new ModeloSshCliente(); + txtPorta.Text = "22"; + cbTipoAutenticacao.SelectedIndex = 0; + txtNome.Focus(); + } + + protected override void OnSalvar() + { + PreencherModel(); + MessageBox.Show("Configuração de conexão SSH salva!", "LevelOS Network", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Configurações/Servicos/SshClienteCadastroPanel.resx b/UI/Dashboards/Configurações/Servicos/SshClienteCadastroPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/Dashboards/Configurações/Servicos/SshClienteCadastroPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UI/Dashboards/Configurações/Servicos/TelegramClienteCadastroPanel.cs b/UI/Dashboards/Configurações/Servicos/TelegramClienteCadastroPanel.cs new file mode 100644 index 0000000..8e2e84d --- /dev/null +++ b/UI/Dashboards/Configurações/Servicos/TelegramClienteCadastroPanel.cs @@ -0,0 +1,134 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class TelegramClienteCadastroPanel : FormularioModelo + { + private ModeloTelegramCliente _tg = new ModeloTelegramCliente(); + + // Controles - Básicos + private LV_TEXTBOX1 txtId, txtNome, txtChatId; + private ComboBox cbTipo; + private CheckBox chkAtivo; + + // Controles - Bot API (Simples) + private LV_TEXTBOX1 txtBotToken; + + // Controles - User API (Avançado) + private LV_TEXTBOX1 txtApiId, txtApiHash, txtTelefone, txtSession; + + // Controles - Info + private LV_TEXTBOX1 txtCriadoEm, txtAtualizadoEm; + private Button btnTestarBot; + + public TelegramClienteCadastroPanel() + { + this.Titulo = "Integração com Telegram (Bot & User API)"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Identificação --- + content.Controls.Add(CreateSectionHeader("CONFIGURAÇÃO GERAL", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtNome = AddInput(content, "NOME DA INTEGRAÇÃO", 100, 50, 320, 30); + + Label lblTipo = new Label { Text = "TIPO DE CONTA", Location = new Point(435, 33), AutoSize = true }; + cbTipo = new ComboBox + { + Location = new Point(435, 50), + Size = new Size(150, 30), + DropDownStyle = ComboBoxStyle.DropDownList, + FlatStyle = FlatStyle.Flat + }; + cbTipo.Items.AddRange(new object[] { "BOT (API)", "USER (SESSION)" }); + cbTipo.SelectedIndex = 0; + content.Controls.Add(lblTipo); + content.Controls.Add(cbTipo); + + txtChatId = AddInput(content, "ID DO CHAT DESTINO (CHAT_ID)", 600, 50, 160, 30); + chkAtivo = new CheckBox { Text = "ATIVO", Location = new Point(770, 66), AutoSize = true, Checked = true }; + content.Controls.Add(chkAtivo); + + // --- SEÇÃO 2: Bot API --- + content.Controls.Add(CreateSectionHeader("BOT API (SIMPLES)", 115)); + txtBotToken = AddInput(content, "BOT TOKEN (FORNECIDO PELO @BOTFATHER)", 20, 145, 565, 30); + + btnTestarBot = new Button + { + Text = "🔔 Testar Envio", + Location = new Point(600, 161), + Size = new Size(160, 30), + BackColor = Color.FromArgb(0, 136, 204), // Azul Telegram + ForeColor = Color.White, + FlatStyle = FlatStyle.Flat, + Font = new Font("Segoe UI", 9, FontStyle.Bold) + }; + btnTestarBot.Click += (s, e) => MessageBox.Show("Enviando mensagem de teste via Telegram..."); + content.Controls.Add(btnTestarBot); + + // --- SEÇÃO 3: User API / MTProto (Avançado) --- + content.Controls.Add(CreateSectionHeader("USER API / MTPROTO (AVANÇADO)", 210)); + txtApiId = AddInput(content, "API ID", 20, 240, 120, 30); + txtApiHash = AddInput(content, "API HASH", 150, 240, 300, 30); + txtTelefone = AddInput(content, "TELEFONE (+55...)", 460, 240, 180, 30); + + txtSession = AddInput(content, "SESSION STRING (PARA CONEXÕES PERSISTENTES)", 20, 295, 815, 30); + txtSession.PasswordChar = '●'; + + // --- SEÇÃO 4: Rodapé --- + content.Controls.Add(CreateSectionHeader("HISTÓRICO", 360)); + txtCriadoEm = AddInput(content, "CRIADO EM", 20, 390, 185, 30, true); + txtAtualizadoEm = AddInput(content, "ÚLT. ATUALIZAÇÃO", 215, 390, 185, 30, true); + + content.Height = 450; + + // Logica visual para alternar campos + cbTipo.SelectedIndexChanged += (s, e) => { + bool isBot = cbTipo.SelectedIndex == 0; + txtBotToken.Enabled = isBot; + txtApiId.Enabled = !isBot; + txtApiHash.Enabled = !isBot; + txtTelefone.Enabled = !isBot; + txtSession.Enabled = !isBot; + }; + } + + private void PreencherModel() + { + _tg.Nome = txtNome.Text; + _tg.Tipo = cbTipo.Text; + _tg.BotToken = txtBotToken.Text; + _tg.ApiId = int.TryParse(txtApiId.Text, out int aid) ? aid : 0; + _tg.ApiHash = txtApiHash.Text; + _tg.Telefone = txtTelefone.Text; + _tg.SessionString = txtSession.Text; + _tg.ChatId = txtChatId.Text; + _tg.Ativo = chkAtivo.Checked; + } + + protected override void OnNovo() + { + _tg = new ModeloTelegramCliente(); + txtNome.Focus(); + } + + protected override void OnSalvar() + { + PreencherModel(); + MessageBox.Show("Configuração de Telegram salva com sucesso!", "LevelOS Messenger", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Consultas/BackupExecucaoDetalhePanel.cs b/UI/Dashboards/Consultas/BackupExecucaoDetalhePanel.cs new file mode 100644 index 0000000..7821f23 --- /dev/null +++ b/UI/Dashboards/Consultas/BackupExecucaoDetalhePanel.cs @@ -0,0 +1,92 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class BackupExecucaoDetalhePanel : FormularioModelo + { + private ModeloBackupExecucao _exec = new ModeloBackupExecucao(); + + // Controles - Identificação + private LV_TEXTBOX1 txtId, txtIdBackup, txtStatus, txtData; + + // Controles - Métricas de Performance + private LV_TEXTBOX1 txtTamanho, txtDuracao; + + // Controles - Resultado + private LV_TEXTBOX1 txtMensagem; + + public BackupExecucaoDetalhePanel() + { + this.Titulo = "Detalhes da Execução de Backup"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Identificação do Evento --- + content.Controls.Add(CreateSectionHeader("INFORMAÇÕES DA EXECUÇÃO", 20)); + + txtId = AddInput(content, "ID LOG", 20, 50, 80, 30, true); + txtIdBackup = AddInput(content, "ID CONFIG. ORIGEM", 110, 50, 120, 30, true); + txtData = AddInput(content, "DATA/HORA EXECUÇÃO", 240, 50, 200, 30, true); + + txtStatus = AddInput(content, "STATUS FINAL", 450, 50, 150, 30, true); + txtStatus.Font = new Font("Segoe UI", 10, FontStyle.Bold); + + // --- SEÇÃO 2: Métricas --- + content.Controls.Add(CreateSectionHeader("MÉTRICAS E DESEMPENHO", 115)); + + txtTamanho = AddInput(content, "TAMANHO DO ARQUIVO (BYTES)", 20, 145, 230, 30, true); + txtDuracao = AddInput(content, "DURAÇÃO (SEGUNDOS)", 260, 145, 180, 30, true); + + // --- SEÇÃO 3: Log Completo --- + content.Controls.Add(CreateSectionHeader("MENSAGEM DO SISTEMA / ERRO", 210)); + txtMensagem = AddInput(content, "DETALHAMENTO DO PROCESSO", 20, 240, 815, 80, true); + txtMensagem.Multiline = true; + + content.Height = 350; + } + + // Método para carregar os dados (usado pela tela de listagem/grid) + public void CarregarDados(ModeloBackupExecucao execucao) + { + _exec = execucao; + txtId.Text = _exec.Id.ToString(); + txtIdBackup.Text = _exec.IdBackup.ToString(); + txtData.Text = _exec.DataExecucao.ToString("dd/MM/yyyy HH:mm:ss"); + txtStatus.Text = _exec.Status.ToUpper(); + txtTamanho.Text = _exec.TamanhoArquivo?.ToString("N0") ?? "0"; + txtDuracao.Text = _exec.DuracaoSegundos?.ToString() + "s"; + txtMensagem.Text = _exec.Mensagem; + + // Alerta visual para falhas + if (_exec.Status.ToLower() == "erro" || _exec.Status.ToLower() == "falha") + { + txtStatus.BackColor = Color.FromArgb(255, 230, 230); + txtStatus.ForeColor = Color.Red; + } + else + { + txtStatus.BackColor = Color.FromArgb(230, 255, 230); + txtStatus.ForeColor = Color.DarkGreen; + } + } + + protected override void OnNovo() { } // Bloqueado para logs + protected override void OnSalvar() { } // Bloqueado para logs + protected override void OnAlterar() + { + + } + protected override void OnCancelar() { } + + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + + } +} \ No newline at end of file diff --git a/UI/Dashboards/Consultas/LogUserConsultaPanel.cs b/UI/Dashboards/Consultas/LogUserConsultaPanel.cs new file mode 100644 index 0000000..c116cca --- /dev/null +++ b/UI/Dashboards/Consultas/LogUserConsultaPanel.cs @@ -0,0 +1,94 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class LogUserConsultaPanel : FormularioModelo + { + private ModeloLogUser _log = new ModeloLogUser(); + + // Controles - Quem e Quando + private LV_TEXTBOX1 txtId, txtCodigo, txtUsuario, txtMicro, txtDiaLog; + + // Controles - O Quê e Onde + private LV_TEXTBOX1 txtAcao, txtEnderCli; + + // Controles - Nível de Severidade + private ComboBox cbRisco; + + public LogUserConsultaPanel() + { + this.Titulo = "Auditoria de Eventos e Logs de Usuário"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Identificação do Evento --- + content.Controls.Add(CreateSectionHeader("DETALHES DA OCORRÊNCIA", 20)); + + txtId = AddInput(content, "ID LOG", 20, 50, 70, 30, true); + txtCodigo = AddInput(content, "CÓD. REF", 100, 50, 110, 30, true); + txtDiaLog = AddInput(content, "DATA/HORA DO EVENTO", 220, 50, 200, 30, true); + + // --- SEÇÃO 2: Rastreabilidade de Origem --- + content.Controls.Add(CreateSectionHeader("ORIGEM E USUÁRIO", 115)); + + txtUsuario = AddInput(content, "OPERADOR", 20, 145, 250, 30, true); + txtMicro = AddInput(content, "NOME DA MÁQUINA (HOSTNAME)", 280, 145, 250, 30, true); + txtEnderCli = AddInput(content, "IP / ENDEREÇO CLIENTE", 540, 145, 295, 30, true); + + // --- SEÇÃO 3: Ação e Impacto --- + content.Controls.Add(CreateSectionHeader("DESCRIÇÃO DA ATIVIDADE E RISCO", 210)); + + txtAcao = AddInput(content, "AÇÃO EXECUTADA", 20, 240, 500, 30, true); + + Label lblRisco = new Label { Text = "NÍVEL DE RISCO", Location = new Point(530, 223), AutoSize = true }; + cbRisco = new ComboBox + { + Location = new Point(530, 240), + Size = new Size(150, 30), + DropDownStyle = ComboBoxStyle.DropDownList, + Enabled = false // Logs geralmente são imutáveis + }; + cbRisco.Items.AddRange(new object[] { "BAIXO", "MÉDIO", "ALTO", "CRÍTICO" }); + content.Controls.Add(lblRisco); + content.Controls.Add(cbRisco); + + // Destaque visual para o risco se necessário + cbRisco.SelectedIndexChanged += (s, e) => { + if (cbRisco.Text == "CRÍTICO" || cbRisco.Text == "ALTO") + cbRisco.BackColor = Color.LightCoral; + }; + + content.Height = 320; + } + + private void PreencherModel() + { + _log.CODIGO = txtCodigo.Text; + _log.USUARIO = txtUsuario.Text; + _log.MICRO = txtMicro.Text; + _log.ACAO = txtAcao.Text; + _log.RISCO = cbRisco.Text; + _log.DIA_LOG = txtDiaLog.Text; + _log.ENDER_CLI = txtEnderCli.Text; + } + + protected override void OnNovo() { /* Logs não são criados manualmente */ } + + protected override void OnSalvar() + { + MessageBox.Show("Registros de auditoria são protegidos e não podem ser alterados.", "LevelOS Security", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { /* Implementar busca por data ou usuário */ } + protected override void OnCancelar() { } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Dashmain/MainForm.cs b/UI/Dashboards/Dashmain/MainForm.cs index dd5a958..11bb69c 100644 --- a/UI/Dashboards/Dashmain/MainForm.cs +++ b/UI/Dashboards/Dashmain/MainForm.cs @@ -30,9 +30,14 @@ namespace UI private readonly ChamadoCadastroPanel _pChamadoCadastroPanel; - //Sistma + //Sistema private readonly ConfigCadastroPanel _pconfigCadastroPanel; - + private readonly SshClienteCadastroPanel _psshClienteCadastroPanel; + private readonly SmtpClienteCadastroPanel _psmtpClienteCadastroPanel; + private readonly FtpClienteCadastroPanel _pftpClienteCadastroPanel; + private readonly TelegramClienteCadastroPanel _ptelegramClienteCadastroPanel; + private readonly BackupAutomaticoCadastroPanel _pBackupAutomaticoCadastroPanel; + private readonly CloudStorageCadastroPanel _pCloudStorageCadastroPanel; //Painel financeiro private readonly BoletoCadastroPanel _pboletoCadastroPanel; private readonly ContaPagarCadastroPanel _pcontaPagarCadastroPanel; @@ -73,6 +78,12 @@ namespace UI _pcontaPagarCadastroPanel = new ContaPagarCadastroPanel { Dock = DockStyle.Fill, Visible = false }; _pcontaReceberCadastroPanel = new ContaReceberCadastroPanel { Dock = DockStyle.Fill, Visible = false }; _pcontasCadastroPanel = new ContasCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + _psshClienteCadastroPanel = new SshClienteCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + _psmtpClienteCadastroPanel = new SmtpClienteCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + _pftpClienteCadastroPanel = new FtpClienteCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + _ptelegramClienteCadastroPanel = new TelegramClienteCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + _pBackupAutomaticoCadastroPanel = new BackupAutomaticoCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + _pCloudStorageCadastroPanel = new CloudStorageCadastroPanel { Dock = DockStyle.Fill, Visible = false }; _pOrdens = PlaceholderPanel("Ordens de Serviço", Color.FromArgb(22, 163, 74)); _pProdutos = PlaceholderPanel("Catálogo de Produtos", Color.FromArgb(217, 119, 6)); _pEstoque = PlaceholderPanel("Controle de Estoque", Color.FromArgb(234, 88, 12)); @@ -102,6 +113,12 @@ namespace UI mainContainer.Controls.Add(_pfuncionariosCadastro); mainContainer.Controls.Add(_pcontaPagarCadastroPanel); mainContainer.Controls.Add(_pcontasCadastroPanel); + mainContainer.Controls.Add(_psshClienteCadastroPanel); + mainContainer.Controls.Add(_psmtpClienteCadastroPanel); + mainContainer.Controls.Add(_pftpClienteCadastroPanel); + mainContainer.Controls.Add(_ptelegramClienteCadastroPanel); + mainContainer.Controls.Add(_pBackupAutomaticoCadastroPanel); + mainContainer.Controls.Add(_pCloudStorageCadastroPanel); Controls.Add(mainContainer); Controls.Add(_sidebar); @@ -139,7 +156,13 @@ namespace UI case 201: ShowPanel(_pconfigCadastroPanel); break; case 202: ShowPanel(_pEmpresaConfig); break; - + case 203: ShowPanel(_pftpClienteCadastroPanel); break; + case 204: ShowPanel(_ptelegramClienteCadastroPanel); break; + case 205: ShowPanel(_psmtpClienteCadastroPanel); break; + case 206: ShowPanel(_psshClienteCadastroPanel); break; + case 207: ShowPanel(_pBackupAutomaticoCadastroPanel); break; + case 208: ShowPanel(_pCloudStorageCadastroPanel); break; + case 300: ShowPanel(_pAgendaCadastro); break; case 301: ShowPanel(_pAgendaConsulta); break; case 309: ShowPanel(_pChamadoCadastroPanel); break; @@ -178,6 +201,12 @@ namespace UI _pcontaPagarCadastroPanel.Visible = (panelToShow == _pcontaPagarCadastroPanel); _pcontaReceberCadastroPanel.Visible = (panelToShow == _pcontaReceberCadastroPanel); _pcontasCadastroPanel.Visible = (panelToShow == _pcontasCadastroPanel); + _psshClienteCadastroPanel.Visible = (panelToShow == _psshClienteCadastroPanel); + _psmtpClienteCadastroPanel.Visible = (panelToShow == _psmtpClienteCadastroPanel); + _pftpClienteCadastroPanel.Visible = (panelToShow == _pftpClienteCadastroPanel); + _ptelegramClienteCadastroPanel.Visible = (panelToShow == _ptelegramClienteCadastroPanel); + _pBackupAutomaticoCadastroPanel.Visible = (panelToShow == _pBackupAutomaticoCadastroPanel); + _pCloudStorageCadastroPanel.Visible = (panelToShow == _pCloudStorageCadastroPanel); if (panelToShow.Visible) { panelToShow.BringToFront(); diff --git a/UI/Dashboards/Dashmain/SidebarControl.cs b/UI/Dashboards/Dashmain/SidebarControl.cs index 00131de..58e0c9b 100644 --- a/UI/Dashboards/Dashmain/SidebarControl.cs +++ b/UI/Dashboards/Dashmain/SidebarControl.cs @@ -141,9 +141,11 @@ namespace UI _subMenuConfiguracao.Items.Add(CreateItem("📂 FTP-Cliente", (s, e) => NavItemClicked?.Invoke(this, 203))); _subMenuConfiguracao.Items.Add(CreateItem("💬 Telegram-Cliente", (s, e) => NavItemClicked?.Invoke(this, 204))); _subMenuConfiguracao.Items.Add(CreateItem("📩 SMTP-Cliente", (s, e) => NavItemClicked?.Invoke(this, 205))); + // Adicionando ao sub-menu de configurações + _subMenuConfiguracao.Items.Add(CreateItem(">_ SSH-Cliente", (s, e) => NavItemClicked?.Invoke(this, 206))); _subMenuConfiguracao.Items.Add(new ToolStripSeparator()); - _subMenuConfiguracao.Items.Add(CreateItem("⏰ Backups Automáticos", (s, e) => NavItemClicked?.Invoke(this, 206))); - _subMenuConfiguracao.Items.Add(CreateItem("☁️ Backup em Nuvem", (s, e) => NavItemClicked?.Invoke(this, 207))); + _subMenuConfiguracao.Items.Add(CreateItem("⏰ Backups Automáticos", (s, e) => NavItemClicked?.Invoke(this, 207))); + _subMenuConfiguracao.Items.Add(CreateItem("☁️ Backup em Nuvem", (s, e) => NavItemClicked?.Invoke(this, 208))); // ── AJUDA ───────────────────────────────────────────────────────── _subMenuAjuda = CreateStyledMenu(); _subMenuAjuda.Items.Add(CreateItem("💬 Atendimento Online")); diff --git a/UI/ModeloPanel/Formulariomodelo.cs b/UI/ModeloPanel/Formulariomodelo.cs index 43e5bb9..5d27fb6 100644 --- a/UI/ModeloPanel/Formulariomodelo.cs +++ b/UI/ModeloPanel/Formulariomodelo.cs @@ -6,16 +6,10 @@ using System.Windows.Forms; namespace UI { - /// - /// Modelo base para todos os formulários do sistema. - /// Herde esta classe e implemente os membros abstratos. - /// public abstract class FormularioModelo : UserControl { - // ── CONEXÃO ─────────────────────────────────────────────────────────── protected string _cx = DadosDaConexao.ObterConexao(); - // ── CORES DO SISTEMA ────────────────────────────────────────────────── protected readonly Color AccentBlue = Color.FromArgb(37, 99, 235); protected readonly Color TextDark = Color.FromArgb(30, 41, 59); protected readonly Color BorderColor = Color.FromArgb(226, 232, 240); @@ -23,31 +17,27 @@ namespace UI protected readonly Color ReadOnlyBg = Color.FromArgb(241, 245, 249); protected readonly Color ReadOnlyBorder = Color.FromArgb(203, 213, 225); - // ── PAINÉIS ESTRUTURAIS ─────────────────────────────────────────────── protected Panel pnlToolbar = null!; protected Panel pnlTitulo = null!; protected Panel mainScroll = null!; protected Panel content = null!; - // ── BOTÕES DA TOOLBAR ───────────────────────────────────────────────── protected Button btnNovo = null!; protected Button btnAlterar = null!; protected Button btnExcluir = null!; protected Button btnLocalizar = null!; protected Button btnSalvar = null!; protected Button btnCancelar = null!; + protected Button btnFechar = null!; // ✅ NOVO - // ── TÍTULO ──────────────────────────────────────────────────────────── private Label lblTitulo = null!; - /// Título exibido no cabeçalho do formulário. public string Titulo { get => lblTitulo.Text; set => lblTitulo.Text = value; } - // ── CONSTRUTOR ──────────────────────────────────────────────────────── protected FormularioModelo() { Dock = DockStyle.Fill; @@ -58,16 +48,24 @@ namespace UI BuildTitulo(); BuildScrollArea(); - // Liga os eventos abstratos btnNovo.Click += (s, e) => OnNovo(); btnAlterar.Click += (s, e) => OnAlterar(); btnExcluir.Click += (s, e) => OnExcluir(); btnLocalizar.Click += (s, e) => OnLocalizar(); btnSalvar.Click += (s, e) => OnSalvar(); btnCancelar.Click += (s, e) => OnCancelar(); - } - // ── CONSTRUÇÃO DA INTERFACE ─────────────────────────────────────────── + // ✅ Fechar: remove o UserControl do pai + btnFechar.Click += (s, e) => + { + var pai = this.Parent; + if (pai != null) + { + pai.Controls.Remove(this); + this.Dispose(); + } + }; + } private void BuildToolbar() { @@ -91,9 +89,10 @@ namespace UI btnLocalizar = CreateToolbarButton("Localizar", AccentBlue); btnSalvar = CreateToolbarButton("Salvar", AccentBlue); btnCancelar = CreateToolbarButton("Cancelar", Color.FromArgb(148, 163, 184)); + btnFechar = CreateToolbarButton("Fechar", Color.FromArgb(100, 116, 139)); // ✅ NOVO flow.Controls.AddRange(new Control[] - { btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar, btnCancelar }); + { btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar, btnCancelar, btnFechar }); pnlToolbar.Controls.Add(flow); this.Controls.Add(pnlToolbar); @@ -108,7 +107,6 @@ namespace UI BackColor = Color.White }; - // Linha separadora no topo do título var linha = new Panel { Dock = DockStyle.Top, @@ -153,9 +151,6 @@ namespace UI mainScroll.BringToFront(); } - // ── HELPERS DISPONÍVEIS PARA AS SUBCLASSES ──────────────────────────── - - /// Cria um cabeçalho de seção com linha separadora. protected Panel CreateSectionHeader(string title, int y) { var pnl = new Panel { Location = new Point(20, y), Width = 1000, Height = 26 }; @@ -182,7 +177,6 @@ namespace UI return pnl; } - /// Cria um campo LV_TEXTBOX1 com label acima. protected LV_TEXTBOX1 AddInput(Control parent, string label, int x, int y, int width, int height, bool readOnly = false) @@ -198,7 +192,7 @@ namespace UI var txt = new LV_TEXTBOX1 { - Location = new Point(x, y + 16), + Location = new Point(x, y + 16), // ← input sempre 16px abaixo do label Size = new Size(width, height), BorderColor = readOnly ? ReadOnlyBorder : BorderColor, BorderFocusColor = AccentBlue, @@ -211,7 +205,36 @@ namespace UI return txt; } - /// Cria um CheckBox padrão do sistema. + /// + /// Cria um label + ComboBox seguindo o mesmo padrão visual do AddInput. + /// ✅ Resolve o bug do label sendo coberto pelo ComboBox. + /// + protected ComboBox AddComboBox(Control parent, string label, + int x, int y, int width) + { + var lbl = new Label + { + Text = label, + Location = new Point(x, y), + Font = new Font("Segoe UI", 7.5f, FontStyle.Bold), + ForeColor = TextDark, + AutoSize = true + }; + + var cb = new ComboBox + { + Location = new Point(x, y + 16), // ← mesmo padrão do AddInput + Size = new Size(width, 26), + DropDownStyle = ComboBoxStyle.DropDownList, + FlatStyle = FlatStyle.Flat, + Font = new Font("Segoe UI", 9f) + }; + + parent.Controls.Add(lbl); + parent.Controls.Add(cb); + return cb; + } + protected CheckBox CreateCheckBox(string text, int x, int y) => new CheckBox { Text = text, @@ -221,7 +244,6 @@ namespace UI AutoSize = true }; - /// Cria um botão extra para a toolbar (ex: Ficha PDF, Certificado). protected Button CreateToolbarButton(string text, Color color) => new Button { Text = text, @@ -235,15 +257,12 @@ namespace UI FlatAppearance = { BorderSize = 0 } }; - /// Adiciona um botão extra na toolbar (após os padrões). protected void AddToolbarButton(Button btn) { var flow = pnlToolbar.Controls[0] as FlowLayoutPanel; flow?.Controls.Add(btn); } - // ── EVENTOS ABSTRATOS (cada formulário implementa o seu) ────────────── - protected abstract void OnNovo(); protected abstract void OnAlterar(); protected abstract void OnExcluir();