From 9f0303fbef518230a4494dbe9677abdbb57b1b9b Mon Sep 17 00:00:00 2001 From: "c0d3.m0nk3y" Date: Mon, 4 May 2026 19:11:25 -0400 Subject: [PATCH] Created ClientForm UI --- DBVERSION | 1 + Forms/ClientForm.Designer.cs | 337 +++++++++++++++++++++++++++++++++++ Forms/ClientForm.cs | 20 +++ Forms/ClientForm.resx | 120 +++++++++++++ Forms/MainForm.Designer.cs | 149 ++++++++++++++++ Forms/MainForm.cs | 34 ++++ Forms/MainForm.resx | 129 ++++++++++++++ Models/Client.cs | 44 +++++ Models/Project.cs | 57 ++++++ Models/TimeEntry.cs | 55 ++++++ Program.cs | 17 ++ commit.sh | 7 + deploy.sh | 21 +++ refresh.sh | 17 ++ trakker.csproj | 16 ++ trakker.slnx | 3 + 16 files changed, 1027 insertions(+) create mode 100644 DBVERSION create mode 100644 Forms/ClientForm.Designer.cs create mode 100644 Forms/ClientForm.cs create mode 100644 Forms/ClientForm.resx create mode 100644 Forms/MainForm.Designer.cs create mode 100644 Forms/MainForm.cs create mode 100644 Forms/MainForm.resx create mode 100644 Models/Client.cs create mode 100644 Models/Project.cs create mode 100644 Models/TimeEntry.cs create mode 100644 Program.cs create mode 100644 commit.sh create mode 100644 deploy.sh create mode 100644 refresh.sh create mode 100644 trakker.csproj create mode 100644 trakker.slnx diff --git a/DBVERSION b/DBVERSION new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/DBVERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/Forms/ClientForm.Designer.cs b/Forms/ClientForm.Designer.cs new file mode 100644 index 0000000..f53af72 --- /dev/null +++ b/Forms/ClientForm.Designer.cs @@ -0,0 +1,337 @@ +namespace trakker.Forms +{ + partial class ClientForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + groupBoxNewClient = new GroupBox(); + tableLayoutPanel1 = new TableLayoutPanel(); + tableLayoutPanel2 = new TableLayoutPanel(); + labelName = new Label(); + labelCompany = new Label(); + labelEmail = new Label(); + labelPhone = new Label(); + labelAddress = new Label(); + labelIsActive = new Label(); + textBoxName = new TextBox(); + textBoxCompany = new TextBox(); + textBoxEmail = new TextBox(); + textBoxPhone = new TextBox(); + richTextBoxAddress = new RichTextBox(); + comboBoxIsActive = new ComboBox(); + groupBoxNotes = new GroupBox(); + richTextBoxNotes = new RichTextBox(); + tableLayoutPanel3 = new TableLayoutPanel(); + buttonOkay = new Button(); + buttonCancel = new Button(); + labelCreatedUpdatedDT = new Label(); + groupBoxNewClient.SuspendLayout(); + tableLayoutPanel1.SuspendLayout(); + tableLayoutPanel2.SuspendLayout(); + groupBoxNotes.SuspendLayout(); + tableLayoutPanel3.SuspendLayout(); + SuspendLayout(); + // + // groupBoxNewClient + // + groupBoxNewClient.Controls.Add(tableLayoutPanel1); + groupBoxNewClient.Dock = DockStyle.Fill; + groupBoxNewClient.Location = new Point(0, 0); + groupBoxNewClient.Name = "groupBoxNewClient"; + groupBoxNewClient.Size = new Size(1128, 665); + groupBoxNewClient.TabIndex = 0; + groupBoxNewClient.TabStop = false; + groupBoxNewClient.Text = "New Client"; + // + // tableLayoutPanel1 + // + tableLayoutPanel1.ColumnCount = 1; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); + tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 0); + tableLayoutPanel1.Controls.Add(groupBoxNotes, 0, 1); + tableLayoutPanel1.Controls.Add(tableLayoutPanel3, 0, 2); + tableLayoutPanel1.Dock = DockStyle.Fill; + tableLayoutPanel1.Location = new Point(3, 35); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 3; + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 200F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 75F)); + tableLayoutPanel1.Size = new Size(1122, 627); + tableLayoutPanel1.TabIndex = 0; + // + // tableLayoutPanel2 + // + tableLayoutPanel2.ColumnCount = 2; + tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 150F)); + tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); + tableLayoutPanel2.Controls.Add(labelName, 0, 0); + tableLayoutPanel2.Controls.Add(labelCompany, 0, 1); + tableLayoutPanel2.Controls.Add(labelEmail, 0, 2); + tableLayoutPanel2.Controls.Add(labelPhone, 0, 3); + tableLayoutPanel2.Controls.Add(labelAddress, 0, 4); + tableLayoutPanel2.Controls.Add(labelIsActive, 0, 5); + tableLayoutPanel2.Controls.Add(textBoxName, 1, 0); + tableLayoutPanel2.Controls.Add(textBoxCompany, 1, 1); + tableLayoutPanel2.Controls.Add(textBoxEmail, 1, 2); + tableLayoutPanel2.Controls.Add(textBoxPhone, 1, 3); + tableLayoutPanel2.Controls.Add(richTextBoxAddress, 1, 4); + tableLayoutPanel2.Controls.Add(comboBoxIsActive, 1, 5); + tableLayoutPanel2.Dock = DockStyle.Fill; + tableLayoutPanel2.Location = new Point(3, 3); + tableLayoutPanel2.Name = "tableLayoutPanel2"; + tableLayoutPanel2.RowCount = 6; + tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F)); + tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F)); + tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F)); + tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F)); + tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 100F)); + tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F)); + tableLayoutPanel2.Size = new Size(1116, 346); + tableLayoutPanel2.TabIndex = 0; + // + // labelName + // + labelName.AutoSize = true; + labelName.Dock = DockStyle.Fill; + labelName.Location = new Point(3, 0); + labelName.Name = "labelName"; + labelName.Size = new Size(144, 50); + labelName.TabIndex = 0; + labelName.Text = "Name *"; + // + // labelCompany + // + labelCompany.AutoSize = true; + labelCompany.Dock = DockStyle.Fill; + labelCompany.Location = new Point(3, 50); + labelCompany.Name = "labelCompany"; + labelCompany.Size = new Size(144, 50); + labelCompany.TabIndex = 1; + labelCompany.Text = "Company"; + // + // labelEmail + // + labelEmail.AutoSize = true; + labelEmail.Dock = DockStyle.Fill; + labelEmail.Location = new Point(3, 100); + labelEmail.Name = "labelEmail"; + labelEmail.Size = new Size(144, 50); + labelEmail.TabIndex = 2; + labelEmail.Text = "Email *"; + // + // labelPhone + // + labelPhone.AutoSize = true; + labelPhone.Dock = DockStyle.Fill; + labelPhone.Location = new Point(3, 150); + labelPhone.Name = "labelPhone"; + labelPhone.Size = new Size(144, 50); + labelPhone.TabIndex = 3; + labelPhone.Text = "Phone"; + // + // labelAddress + // + labelAddress.AutoSize = true; + labelAddress.Dock = DockStyle.Fill; + labelAddress.Location = new Point(3, 200); + labelAddress.Name = "labelAddress"; + labelAddress.Size = new Size(144, 100); + labelAddress.TabIndex = 4; + labelAddress.Text = "Address"; + // + // labelIsActive + // + labelIsActive.AutoSize = true; + labelIsActive.Dock = DockStyle.Fill; + labelIsActive.Location = new Point(3, 300); + labelIsActive.Name = "labelIsActive"; + labelIsActive.Size = new Size(144, 50); + labelIsActive.TabIndex = 5; + labelIsActive.Text = "Is Active?"; + // + // textBoxName + // + textBoxName.Dock = DockStyle.Fill; + textBoxName.Location = new Point(153, 3); + textBoxName.Name = "textBoxName"; + textBoxName.Size = new Size(960, 39); + textBoxName.TabIndex = 6; + // + // textBoxCompany + // + textBoxCompany.Dock = DockStyle.Fill; + textBoxCompany.Location = new Point(153, 53); + textBoxCompany.Name = "textBoxCompany"; + textBoxCompany.Size = new Size(960, 39); + textBoxCompany.TabIndex = 7; + // + // textBoxEmail + // + textBoxEmail.Dock = DockStyle.Fill; + textBoxEmail.Location = new Point(153, 103); + textBoxEmail.Name = "textBoxEmail"; + textBoxEmail.Size = new Size(960, 39); + textBoxEmail.TabIndex = 8; + // + // textBoxPhone + // + textBoxPhone.Dock = DockStyle.Fill; + textBoxPhone.Location = new Point(153, 153); + textBoxPhone.Name = "textBoxPhone"; + textBoxPhone.Size = new Size(960, 39); + textBoxPhone.TabIndex = 9; + // + // richTextBoxAddress + // + richTextBoxAddress.Dock = DockStyle.Fill; + richTextBoxAddress.Location = new Point(153, 203); + richTextBoxAddress.Name = "richTextBoxAddress"; + richTextBoxAddress.Size = new Size(960, 94); + richTextBoxAddress.TabIndex = 10; + richTextBoxAddress.Text = ""; + // + // comboBoxIsActive + // + comboBoxIsActive.FormattingEnabled = true; + comboBoxIsActive.Location = new Point(153, 303); + comboBoxIsActive.Name = "comboBoxIsActive"; + comboBoxIsActive.Size = new Size(147, 40); + comboBoxIsActive.TabIndex = 11; + // + // groupBoxNotes + // + groupBoxNotes.Controls.Add(richTextBoxNotes); + groupBoxNotes.Dock = DockStyle.Fill; + groupBoxNotes.Location = new Point(3, 355); + groupBoxNotes.Name = "groupBoxNotes"; + groupBoxNotes.Size = new Size(1116, 194); + groupBoxNotes.TabIndex = 1; + groupBoxNotes.TabStop = false; + groupBoxNotes.Text = "Notes"; + // + // richTextBoxNotes + // + richTextBoxNotes.Dock = DockStyle.Fill; + richTextBoxNotes.Location = new Point(3, 35); + richTextBoxNotes.Name = "richTextBoxNotes"; + richTextBoxNotes.Size = new Size(1110, 156); + richTextBoxNotes.TabIndex = 0; + richTextBoxNotes.Text = ""; + // + // tableLayoutPanel3 + // + tableLayoutPanel3.ColumnCount = 3; + tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); + tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 200F)); + tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 200F)); + tableLayoutPanel3.Controls.Add(buttonOkay, 1, 0); + tableLayoutPanel3.Controls.Add(buttonCancel, 2, 0); + tableLayoutPanel3.Controls.Add(labelCreatedUpdatedDT, 0, 0); + tableLayoutPanel3.Dock = DockStyle.Fill; + tableLayoutPanel3.Location = new Point(3, 555); + tableLayoutPanel3.Name = "tableLayoutPanel3"; + tableLayoutPanel3.RowCount = 1; + tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Absolute, 75F)); + tableLayoutPanel3.Size = new Size(1116, 69); + tableLayoutPanel3.TabIndex = 2; + // + // buttonOkay + // + buttonOkay.Dock = DockStyle.Fill; + buttonOkay.Location = new Point(719, 3); + buttonOkay.Margin = new Padding(3, 3, 3, 15); + buttonOkay.Name = "buttonOkay"; + buttonOkay.Size = new Size(194, 57); + buttonOkay.TabIndex = 0; + buttonOkay.Text = "Okay"; + buttonOkay.UseVisualStyleBackColor = true; + // + // buttonCancel + // + buttonCancel.Dock = DockStyle.Fill; + buttonCancel.Location = new Point(919, 3); + buttonCancel.Margin = new Padding(3, 3, 3, 15); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(194, 57); + buttonCancel.TabIndex = 1; + buttonCancel.Text = "Cancel"; + buttonCancel.UseVisualStyleBackColor = true; + // + // labelCreatedUpdatedDT + // + labelCreatedUpdatedDT.AutoSize = true; + labelCreatedUpdatedDT.Dock = DockStyle.Fill; + labelCreatedUpdatedDT.Location = new Point(3, 0); + labelCreatedUpdatedDT.Name = "labelCreatedUpdatedDT"; + labelCreatedUpdatedDT.Size = new Size(710, 75); + labelCreatedUpdatedDT.TabIndex = 2; + labelCreatedUpdatedDT.Text = "Created: yyyy-mm-dd, Updated: yyyy-mm-dd"; + // + // ClientForm + // + AutoScaleDimensions = new SizeF(13F, 32F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1128, 665); + Controls.Add(groupBoxNewClient); + Name = "ClientForm"; + Text = "Client"; + groupBoxNewClient.ResumeLayout(false); + tableLayoutPanel1.ResumeLayout(false); + tableLayoutPanel2.ResumeLayout(false); + tableLayoutPanel2.PerformLayout(); + groupBoxNotes.ResumeLayout(false); + tableLayoutPanel3.ResumeLayout(false); + tableLayoutPanel3.PerformLayout(); + ResumeLayout(false); + } + + #endregion + + private GroupBox groupBoxNewClient; + private TableLayoutPanel tableLayoutPanel1; + private TableLayoutPanel tableLayoutPanel2; + private Label labelName; + private Label labelCompany; + private Label labelEmail; + private Label labelPhone; + private Label labelAddress; + private Label labelIsActive; + private GroupBox groupBoxNotes; + private TextBox textBoxName; + private TextBox textBoxCompany; + private TextBox textBoxEmail; + private TextBox textBoxPhone; + private RichTextBox richTextBoxAddress; + private ComboBox comboBoxIsActive; + private RichTextBox richTextBoxNotes; + private TableLayoutPanel tableLayoutPanel3; + private Button buttonOkay; + private Button buttonCancel; + private Label labelCreatedUpdatedDT; + } +} \ No newline at end of file diff --git a/Forms/ClientForm.cs b/Forms/ClientForm.cs new file mode 100644 index 0000000..e62e556 --- /dev/null +++ b/Forms/ClientForm.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace trakker.Forms +{ + public partial class ClientForm : Form + { + public ClientForm() + { + InitializeComponent(); + } + } +} diff --git a/Forms/ClientForm.resx b/Forms/ClientForm.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/Forms/ClientForm.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/Forms/MainForm.Designer.cs b/Forms/MainForm.Designer.cs new file mode 100644 index 0000000..1c59763 --- /dev/null +++ b/Forms/MainForm.Designer.cs @@ -0,0 +1,149 @@ +namespace trakker +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + MainForm_MenuStrip = new MenuStrip(); + fileToolStripMenuItem = new ToolStripMenuItem(); + MainForm_Exit_MenuItem = new ToolStripMenuItem(); + MainForm_StatusStrip = new StatusStrip(); + MainForm_TabControl = new TabControl(); + MainForm_TabPage1 = new TabPage(); + MainForm_TabPage2 = new TabPage(); + button1 = new Button(); + MainForm_MenuStrip.SuspendLayout(); + MainForm_TabControl.SuspendLayout(); + MainForm_TabPage1.SuspendLayout(); + SuspendLayout(); + // + // MainForm_MenuStrip + // + MainForm_MenuStrip.ImageScalingSize = new Size(32, 32); + MainForm_MenuStrip.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem }); + MainForm_MenuStrip.Location = new Point(0, 0); + MainForm_MenuStrip.Name = "MainForm_MenuStrip"; + MainForm_MenuStrip.Size = new Size(1696, 40); + MainForm_MenuStrip.TabIndex = 0; + MainForm_MenuStrip.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { MainForm_Exit_MenuItem }); + fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + fileToolStripMenuItem.Size = new Size(71, 36); + fileToolStripMenuItem.Text = "File"; + // + // MainForm_Exit_MenuItem + // + MainForm_Exit_MenuItem.Name = "MainForm_Exit_MenuItem"; + MainForm_Exit_MenuItem.Size = new Size(184, 44); + MainForm_Exit_MenuItem.Text = "Exit"; + MainForm_Exit_MenuItem.Click += MainForm_Exit_MenuItem_Click; + // + // MainForm_StatusStrip + // + MainForm_StatusStrip.ImageScalingSize = new Size(32, 32); + MainForm_StatusStrip.Location = new Point(0, 1074); + MainForm_StatusStrip.Name = "MainForm_StatusStrip"; + MainForm_StatusStrip.Size = new Size(1696, 22); + MainForm_StatusStrip.TabIndex = 1; + MainForm_StatusStrip.Text = "MainForm_StatusStrip"; + // + // MainForm_TabControl + // + MainForm_TabControl.Controls.Add(MainForm_TabPage1); + MainForm_TabControl.Controls.Add(MainForm_TabPage2); + MainForm_TabControl.Dock = DockStyle.Fill; + MainForm_TabControl.Location = new Point(0, 40); + MainForm_TabControl.Name = "MainForm_TabControl"; + MainForm_TabControl.SelectedIndex = 0; + MainForm_TabControl.Size = new Size(1696, 1034); + MainForm_TabControl.TabIndex = 2; + // + // MainForm_TabPage1 + // + MainForm_TabPage1.Controls.Add(button1); + MainForm_TabPage1.Location = new Point(8, 46); + MainForm_TabPage1.Name = "MainForm_TabPage1"; + MainForm_TabPage1.Padding = new Padding(3); + MainForm_TabPage1.Size = new Size(1680, 980); + MainForm_TabPage1.TabIndex = 0; + MainForm_TabPage1.Text = "Tab 1"; + MainForm_TabPage1.UseVisualStyleBackColor = true; + // + // MainForm_TabPage2 + // + MainForm_TabPage2.Location = new Point(8, 46); + MainForm_TabPage2.Name = "MainForm_TabPage2"; + MainForm_TabPage2.Padding = new Padding(3); + MainForm_TabPage2.Size = new Size(1680, 1015); + MainForm_TabPage2.TabIndex = 1; + MainForm_TabPage2.Text = "Tab 2"; + MainForm_TabPage2.UseVisualStyleBackColor = true; + // + // button1 + // + button1.Location = new Point(39, 47); + button1.Name = "button1"; + button1.Size = new Size(150, 46); + button1.TabIndex = 0; + button1.Text = "button1"; + button1.UseVisualStyleBackColor = true; + button1.Click += button1_Click; + // + // MainForm + // + AutoScaleDimensions = new SizeF(13F, 32F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1696, 1096); + Controls.Add(MainForm_TabControl); + Controls.Add(MainForm_StatusStrip); + Controls.Add(MainForm_MenuStrip); + MainMenuStrip = MainForm_MenuStrip; + Name = "MainForm"; + Text = "MainForm"; + MainForm_MenuStrip.ResumeLayout(false); + MainForm_MenuStrip.PerformLayout(); + MainForm_TabControl.ResumeLayout(false); + MainForm_TabPage1.ResumeLayout(false); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private MenuStrip MainForm_MenuStrip; + private StatusStrip MainForm_StatusStrip; + private TabControl MainForm_TabControl; + private TabPage MainForm_TabPage1; + private TabPage MainForm_TabPage2; + private ToolStripMenuItem fileToolStripMenuItem; + private ToolStripMenuItem MainForm_Exit_MenuItem; + private Button button1; + } +} diff --git a/Forms/MainForm.cs b/Forms/MainForm.cs new file mode 100644 index 0000000..048cd20 --- /dev/null +++ b/Forms/MainForm.cs @@ -0,0 +1,34 @@ +using trakker.Forms; + +namespace trakker +{ + public partial class MainForm : Form + { + /// + /// Initializes a new instance of the class. + /// Sets up the form's controls and event handlers by calling + /// which is generated by the designer. + /// + public MainForm() + { + InitializeComponent(); + } + + /// + /// Handles the Click event of the Exit menu item. When invoked, this + /// method terminates the application. + /// + /// The source of the event. + /// Event data associated with the click event. + private void MainForm_Exit_MenuItem_Click(object sender, EventArgs e) + { + Application.Exit(); + } + + private void button1_Click(object sender, EventArgs e) + { + var dialog = new ClientForm(); + dialog.ShowDialog(); + } + } +} diff --git a/Forms/MainForm.resx b/Forms/MainForm.resx new file mode 100644 index 0000000..9603b8d --- /dev/null +++ b/Forms/MainForm.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 16, 12 + + + 16, 55 + + + 162 + + \ No newline at end of file diff --git a/Models/Client.cs b/Models/Client.cs new file mode 100644 index 0000000..a221a40 --- /dev/null +++ b/Models/Client.cs @@ -0,0 +1,44 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace YourProject.Models +{ + public class Client + { + [Key] + public string ClientId { get; set; } = string.Empty; + + [Required] + [MaxLength(200)] + public string Name { get; set; } = string.Empty; + + [MaxLength(200)] + public string? Company { get; set; } + + [EmailAddress] + [MaxLength(255)] + public string? Email { get; set; } + + [Phone] + [MaxLength(50)] + public string? Phone { get; set; } + + [MaxLength(500)] + public string? Address { get; set; } + + [MaxLength(2000)] + public string? Notes { get; set; } + + public bool IsActive { get; set; } = true; + + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; + + // Optional: Helper method for updating timestamp + public void UpdateTimestamp() + { + UpdatedAt = DateTime.UtcNow; + } + } +} diff --git a/Models/Project.cs b/Models/Project.cs new file mode 100644 index 0000000..cc4f92e --- /dev/null +++ b/Models/Project.cs @@ -0,0 +1,57 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace YourProject.Models +{ + public class Project + { + [Key] + public string ProjectId { get; set; } = string.Empty; + + [Required] + public string ClientId { get; set; } = string.Empty; + + [Required] + [MaxLength(200)] + public string Name { get; set; } = string.Empty; + + [MaxLength(1000)] + public string? Description { get; set; } + + public DateOnly? StartDate { get; set; } + + public DateOnly? EndDate { get; set; } + + [Range(0, double.MaxValue)] + public decimal Budget { get; set; } = 0; + + public ProjectStatus Status { get; set; } = ProjectStatus.Active; + + [Range(0, double.MaxValue)] + public decimal? HourlyRate { get; set; } + + [MaxLength(2000)] + public string? Notes { get; set; } + + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; + + // Optional navigation property (for Entity Framework Core) + public Client? Client { get; set; } + + // Helper method + public void UpdateTimestamp() + { + UpdatedAt = DateTime.UtcNow; + } + } + + public enum ProjectStatus + { + Active = 0, + OnHold = 1, + Completed = 2, + Cancelled = 3 + } +} diff --git a/Models/TimeEntry.cs b/Models/TimeEntry.cs new file mode 100644 index 0000000..31ca3e1 --- /dev/null +++ b/Models/TimeEntry.cs @@ -0,0 +1,55 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace YourProject.Models +{ + public class TimeEntry + { + [Key] + public string EntryId { get; set; } = string.Empty; + + [Required] + public string ProjectId { get; set; } = string.Empty; + + [Required] + public string ClientId { get; set; } = string.Empty; + + [Required] + public DateOnly WorkDate { get; set; } + + public TimeOnly? StartTime { get; set; } + + public TimeOnly? EndTime { get; set; } + + [Required] + [Range(0.01, double.MaxValue)] + public decimal Hours { get; set; } + + [MaxLength(1000)] + public string? Description { get; set; } + + [Range(0, double.MaxValue)] + public decimal? Rate { get; set; } + + // Computed column (mirrors the GENERATED ALWAYS AS clause) + public decimal Amount => (Rate ?? 0) * Hours; + + public bool Billed { get; set; } = false; + + public DateOnly? BilledDate { get; set; } + + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; + + // Optional navigation properties (great for EF Core) + public Project? Project { get; set; } + public Client? Client { get; set; } + + // Helper method + public void UpdateTimestamp() + { + UpdatedAt = DateTime.UtcNow; + } + } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..8e4fbbb --- /dev/null +++ b/Program.cs @@ -0,0 +1,17 @@ +namespace trakker +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new MainForm()); + } + } +} \ No newline at end of file diff --git a/commit.sh b/commit.sh new file mode 100644 index 0000000..847658b --- /dev/null +++ b/commit.sh @@ -0,0 +1,7 @@ +#!/bin/bash +MSG="$1" +if [[ $MSG == "" ]]; then + MSG="Continued development" +fi + +git add . && git commit -m "$MSG" && git push diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 0000000..610d639 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,21 @@ +#!/bin/bash +BIN="../../utils/io.cdmnky.utils.replace.exe" +TS=$(date '+%Y.%m.%d.%H%M%S'); +DBVERSION=`cat DBVERSION` +TRGT="./Forms/MainForm.cs" + +cp $TRGT ./backup.txt +cp $TRGT ./wrk.txt + +$BIN ./wrk.txt --search "[YYYY.MM.DD]" --replace $TS +$BIN ./wrk.txt --search "[N.N.N]" --replace $DBVERSION + +# backup original exe before replacing... +EXEC="/c/Users/xboxo/Documents/Shared/Bin/newcle.us/newcle.us.exe" +BACK="/c/Users/xboxo/Documents/Shared/Bin/newcle.us/newcle.us-$TS.exe" +mv $EXEC $BACK + +mv ./wrk.txt $TRGT +dotnet.exe build -c Release && cp ./bin/Release/net8.0-windows/newcle.us.* ~/Documents/Shared/Bin/newcle.us/ +cp ./backup.txt $TRGT + diff --git a/refresh.sh b/refresh.sh new file mode 100644 index 0000000..f85736f --- /dev/null +++ b/refresh.sh @@ -0,0 +1,17 @@ +#!/bin/bash +TS=$(date '+%Y.%m.%d.%H%M%S'); +PROD="/c/Users/xboxo/Documents/Shared/Bin/newcle.us/core.db" +DVLP="/c/Users/xboxo/source/repos/newcle.us/win/bin/Debug/net8.0-windows/core.db" +BKUP="/c/Users/xboxo/source/repos/newcle.us/win/bin/Debug/net8.0-windows/core-$TS.db" + +echo "Prod... $PROD" +echo "Dvlp... $DVLP" +echo "Bkup... $BKUP" + +echo "Backup current DVLP database..." +mv $DVLP $BKUP + +echo "Copy PROD database to DVLP" +cp $PROD $DVLP + +echo "Done" diff --git a/trakker.csproj b/trakker.csproj new file mode 100644 index 0000000..f718f2e --- /dev/null +++ b/trakker.csproj @@ -0,0 +1,16 @@ + + + + WinExe + net8.0-windows + enable + true + enable + + + + + + + + \ No newline at end of file diff --git a/trakker.slnx b/trakker.slnx new file mode 100644 index 0000000..6a0b70e --- /dev/null +++ b/trakker.slnx @@ -0,0 +1,3 @@ + + +