From 76691ea4b301f303a572d5a4670666f437df4db2 Mon Sep 17 00:00:00 2001 From: Blake Ridgway Date: Wed, 18 Jun 2025 20:09:47 -0500 Subject: [PATCH 1/6] feat: Ability to add Scripts and Styles to other pages --- Views/Shared/_Layout.cshtml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Views/Shared/_Layout.cshtml b/Views/Shared/_Layout.cshtml index f73bc46..c27a958 100644 --- a/Views/Shared/_Layout.cshtml +++ b/Views/Shared/_Layout.cshtml @@ -5,6 +5,8 @@ @ViewData["Title"] - MowLog + @await RenderSectionAsync("Scripts", required: false) + @await RenderSectionAsync("Styles", required: false) @@ -46,6 +48,5 @@ - @await RenderSectionAsync("Scripts", required: false) \ No newline at end of file -- 2.47.3 From c914649a8bb5ea00ebc74d2ad9dc43a55a2fe453 Mon Sep 17 00:00:00 2001 From: Blake Ridgway Date: Wed, 18 Jun 2025 20:10:07 -0500 Subject: [PATCH 2/6] styles: Calendar stylesheet --- wwwroot/css/calendar.css | 95 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 wwwroot/css/calendar.css diff --git a/wwwroot/css/calendar.css b/wwwroot/css/calendar.css new file mode 100644 index 0000000..88e010f --- /dev/null +++ b/wwwroot/css/calendar.css @@ -0,0 +1,95 @@ +.calendar-container { + max-width: 900px; + margin: 20px auto; + font-family: Arial, sans-serif; + border: 1px solid #ddd; + border-radius: 5px; + overflow: hidden; + background-color: #fff; + box-shadow: 0 2px 5px rgba(0,0,0,0.1); +} + +.calendar-header { + display: flex; + justify-content: space-between; + align-items: center; + background-color: #f8f9fa; + padding: 15px; + border-bottom: 1px solid #ddd; +} + +.calendar-header h2 { + margin: 0; + font-size: 1.5em; + color: #333; +} + +.calendar-grid { + display: grid; + grid-template-columns: repeat(7, 1fr); + gap: 1px; + background-color: #ddd; + border-bottom: 1px solid #ddd; +} + +.day-name { + background-color: #e9ecef; + padding: 10px 5px; + text-align: center; + font-weight: bold; + color: #555; + font-size: 0.9em; +} + +.calendar-day { + background-color: #fff; + padding: 10px 5px; + min-height: 100px; + text-align: right; + position: relative; + cursor: pointer; + transition: background-color 0.2s ease; + box-sizing: border-box; + border: 1px solid #eee; +} + +.calendar-day:hover { + background-color: #f0f0f0; +} + +.calendar-day.other-month { + background-color: #f9f9f9; + color: #ccc; +} + +.calendar-day .day-number { + font-weight: bold; + font-size: 1.2em; + color: #333; + position: absolute; + top: 5px; + right: 5px; +} + +.calendar-day .event-indicator { + background-color: #28a745; + color: white; + font-size: 0.75em; + padding: 2px 5px; + border-radius: 3px; + margin-top: 25px; + display: inline-block; + margin-left: 5px; + margin-right: 5px; +} + +.event-indicator.mowing { background-color: #28a745; } +.event-indicator.watering { background-color: #007bff; } +.event-indicator.fertilizing { background-color: #ffc107; } +.event-indicator.aeration { background-color: #6f42c1; } +.event-indicator.weedcontrol { background-color: #dc3545; } +.event-indicator.other { background-color: #6c757d; } + +.card.h-100 { + height: 100% !important; +} \ No newline at end of file -- 2.47.3 From f282b39d576605af2189c270232061e586b1cce4 Mon Sep 17 00:00:00 2001 From: Blake Ridgway Date: Wed, 18 Jun 2025 20:10:24 -0500 Subject: [PATCH 3/6] feat: Working on implementing calendar. Javascript work left --- Controllers/LawnCareEventsContoller.cs | 51 +++++++++++++++++--------- Views/LawnCareEvents/Calendar.cshtml | 37 +++++++++++++++++++ 2 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 Views/LawnCareEvents/Calendar.cshtml diff --git a/Controllers/LawnCareEventsContoller.cs b/Controllers/LawnCareEventsContoller.cs index de6e138..ab9fd2d 100644 --- a/Controllers/LawnCareEventsContoller.cs +++ b/Controllers/LawnCareEventsContoller.cs @@ -14,19 +14,15 @@ namespace turf_tasker.Controllers _context = context; } - // GET: LawnCareEvents public async Task Index(string sortOrder, string searchString) { - // Use ViewData to pass sort order info to the view ViewData["DateSortParm"] = String.IsNullOrEmpty(sortOrder) ? "date_desc" : ""; ViewData["TypeSortParm"] = sortOrder == "Type" ? "type_desc" : "Type"; ViewData["CurrentFilter"] = searchString; - // Start with a base query that can be modified var events = from e in _context.LawnCareEvents select e; - // Apply the filter if a search string is provided if (!String.IsNullOrEmpty(searchString)) { events = events.Where(e => @@ -35,7 +31,6 @@ namespace turf_tasker.Controllers ); } - // Apply the sorting based on the sortOrder parameter switch (sortOrder) { case "date_desc": @@ -51,12 +46,9 @@ namespace turf_tasker.Controllers events = events.OrderBy(e => e.EventDate); break; } - - // Execute the query and return the view with the filtered/sorted list return View(await events.AsNoTracking().ToListAsync()); } - // GET: LawnCareEvents/Details/5 public async Task Details(int? id) { if (id == null) @@ -74,15 +66,13 @@ namespace turf_tasker.Controllers return View(lawnCareEvent); } - // GET: LawnCareEvents/Create - // MODIFIED: We now create a model with a default date. + public IActionResult Create() { var model = new LawnCareEvent { EventDate = DateTime.Now }; return View(model); } - // POST: LawnCareEvents/Create [HttpPost] [ValidateAntiForgeryToken] public async Task Create([Bind("Id,EventType,EventDate,MowingPattern,Notes")] LawnCareEvent lawnCareEvent) @@ -95,8 +85,7 @@ namespace turf_tasker.Controllers } return View(lawnCareEvent); } - - // GET: LawnCareEvents/Edit/5 + public async Task Edit(int? id) { if (id == null) @@ -112,7 +101,6 @@ namespace turf_tasker.Controllers return View(lawnCareEvent); } - // POST: LawnCareEvents/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public async Task Edit(int id, [Bind("Id,EventType,EventDate,MowingPattern,Notes")] LawnCareEvent lawnCareEvent) @@ -131,7 +119,7 @@ namespace turf_tasker.Controllers } catch (DbUpdateConcurrencyException) { - if (!LawnCareEventExists(lawnCareEvent.Id)) + if (!LawnCareEventExists(lawnCareEvent.Id)) // This uses the private method below { return NotFound(); } @@ -145,7 +133,6 @@ namespace turf_tasker.Controllers return View(lawnCareEvent); } - // GET: LawnCareEvents/Delete/5 public async Task Delete(int? id) { if (id == null) @@ -163,7 +150,6 @@ namespace turf_tasker.Controllers return View(lawnCareEvent); } - // POST: LawnCareEvents/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task DeleteConfirmed(int id) @@ -182,5 +168,36 @@ namespace turf_tasker.Controllers { return _context.LawnCareEvents.Any(e => e.Id == id); } + + public IActionResult Calendar() + { + return View(); + } + + [HttpGet] + public async Task GetEventsJson() + { + var events = await _context.LawnCareEvents.AsNoTracking().ToListAsync(); + + var calendarEvents = events.Select(e => new + { + id = e.Id, + title = $"{e.EventType} {((e.EventType == LawnCareEventType.Mowing && e.MowingPattern.HasValue) ? $"({e.MowingPattern})" : "")}", + start = e.EventDate.ToString("yyyy-MM-dd"), + allDay = true, + url = $"/LawnCareEvents/Details/{e.Id}", + color = e.EventType switch + { + LawnCareEventType.Mowing => "#28a745", + LawnCareEventType.Watering => "#007bff", + LawnCareEventType.Fertilizing => "#ffc107", + LawnCareEventType.Aeration => "#6f42c1", + LawnCareEventType.WeedControl => "#dc3545", + _ => "#6c757d" + } + }).ToList(); + + return Json(calendarEvents); + } } } \ No newline at end of file diff --git a/Views/LawnCareEvents/Calendar.cshtml b/Views/LawnCareEvents/Calendar.cshtml new file mode 100644 index 0000000..c5f0a96 --- /dev/null +++ b/Views/LawnCareEvents/Calendar.cshtml @@ -0,0 +1,37 @@ +@{ + ViewData["Title"] = "Lawn Care Calendar"; +} + +

@ViewData["Title"]

+ +
+
+ +

+ +
+
+
Sun
+
Mon
+
Tue
+
Wed
+
Thu
+
Fri
+
Sat
+
+
+ +
+
+ +@section Scripts { + + +} + +@section Styles { + + +} \ No newline at end of file -- 2.47.3 From 557fb720819daeb1969d157ab51d6a0729ff8fdf Mon Sep 17 00:00:00 2001 From: Blake Ridgway Date: Wed, 18 Jun 2025 21:32:44 -0500 Subject: [PATCH 4/6] feat: Enhance UI/UX across multiple views with consistent styling and improved layout This commit introduces significant user interface and experience improvements across the Lawn Care Log, Calendar, and Lawn Tips sections, focusing on consistent button styling, improved layout, and clearer navigation. **Key Changes:** * **Lawn Care Event Models:** * Added `NotApplicable` to `MowingPattern` enum with `[Display(Name = "N/A")]` for better logging flexibility. * **Lawn Care Log (`Views/LawnCareEvents/Index.cshtml`):** * **Centered Page Title & Actions:** Wrapped `

` and primary action buttons (`Create New Event`, `View Calendar`) in a `div` with `text-center` for better alignment. * **Improved Search Bar Layout:** Encapsulated the search input and buttons in an `input-group` within a flex container (`d-flex justify-content-end`) with fixed width and auto margins, ensuring it's centered as a block but right-aligned internally. * **Convert Table Actions to Buttons:** Replaced "Edit | Details | Delete" links in the main log table with `btn-sm btn-outline-primary/info/danger` styled buttons, wrapped in `d-flex flex-wrap gap-2` for consistent spacing and responsive behavior. * Renamed "Back to Full List" to "Reset Filter" for clarity and changed its style to `btn-primary`. * **Lawn Care Calendar (`Views/LawnCareEvents/Calendar.cshtml`):** * **Centralized Title & Button:** Implemented a flexbox container (`d-flex justify-content-between align-items-center`) for the calendar's page title and the "Create New Event" button, ensuring they are on the same line and properly spaced. * **Restored JavaScript Integrity:** Re-structured the top-level HTML to ensure the calendar's internal JavaScript (`#prevMonth`, `#nextMonth`, `#currentMonthYear`) remains unaffected by the page title/button layout changes. * **Lawn Care Tips (`Views/LawnCareTip/Index.cshtml`):** * **Consolidated Actions:** Converted "Edit | Details | Delete" links in the tips table into Bootstrap buttons (`btn-sm btn-outline-primary/info/danger`). * **Improved Action Column Layout:** Applied new `.col-actions` CSS to the action column (`` and ``) to give it a fixed width and use `white-space: nowrap` to prevent action buttons from wrapping. * **Content Column Wrapping:** Added `.col-content` CSS to the content column to limit its max-width and allow `word-wrap`. * Changed "Create New" to "Create New Tip" with `btn-primary` styling for consistency. * **Removed Details Link from Tips:** (Implied by diff) The Details link for `LawnCareTip` was removed from the table view, aligning with a common pattern where simple tip content might be fully displayed or only Edit/Delete actions are prioritized in the index. * **Global Styling (`wwwroot/css/site.css`):** * Added `col-content` and `col-actions` CSS classes to manage table column widths and wrapping behavior for cleaner table layouts. These changes significantly improve the aesthetic consistency and usability of the application's main views. --- ..._AddNotApplicableMowingPattern.Designer.cs | 72 ++++++++++++ ...619022142_AddNotApplicableMowingPattern.cs | 22 ++++ Models/LawnCareEvent.cs | 2 + Views/LawnCareEvents/Calendar.cshtml | 106 +++++++++++++++++- Views/LawnCareEvents/Delete.cshtml | 8 +- Views/LawnCareEvents/Details.cshtml | 1 + Views/LawnCareEvents/Edit.cshtml | 46 ++++---- Views/LawnCareEvents/Index.cshtml | 23 ++-- Views/LawnCareTip/Index.cshtml | 11 +- wwwroot/css/site.css | 13 +++ 10 files changed, 263 insertions(+), 41 deletions(-) create mode 100644 Migrations/20250619022142_AddNotApplicableMowingPattern.Designer.cs create mode 100644 Migrations/20250619022142_AddNotApplicableMowingPattern.cs diff --git a/Migrations/20250619022142_AddNotApplicableMowingPattern.Designer.cs b/Migrations/20250619022142_AddNotApplicableMowingPattern.Designer.cs new file mode 100644 index 0000000..1952d3d --- /dev/null +++ b/Migrations/20250619022142_AddNotApplicableMowingPattern.Designer.cs @@ -0,0 +1,72 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using turf_tasker.Data; + +#nullable disable + +namespace turf_tasker.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250619022142_AddNotApplicableMowingPattern")] + partial class AddNotApplicableMowingPattern + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.6"); + + modelBuilder.Entity("turf_tasker.Models.LawnCareEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EventDate") + .HasColumnType("TEXT"); + + b.Property("EventType") + .HasColumnType("INTEGER"); + + b.Property("MowingPattern") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("LawnCareEvents"); + }); + + modelBuilder.Entity("turf_tasker.Models.LawnCareTip", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Category") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("LawnCareTips"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20250619022142_AddNotApplicableMowingPattern.cs b/Migrations/20250619022142_AddNotApplicableMowingPattern.cs new file mode 100644 index 0000000..a94da34 --- /dev/null +++ b/Migrations/20250619022142_AddNotApplicableMowingPattern.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace turf_tasker.Migrations +{ + /// + public partial class AddNotApplicableMowingPattern : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/Models/LawnCareEvent.cs b/Models/LawnCareEvent.cs index 604d8de..d5e4c36 100644 --- a/Models/LawnCareEvent.cs +++ b/Models/LawnCareEvent.cs @@ -14,6 +14,8 @@ public enum LawnCareEventType public enum MowingPattern { + [Display(Name = "N/A")] + NotApplicable, Vertical, Horizontal, Diagonal, diff --git a/Views/LawnCareEvents/Calendar.cshtml b/Views/LawnCareEvents/Calendar.cshtml index c5f0a96..0db49ff 100644 --- a/Views/LawnCareEvents/Calendar.cshtml +++ b/Views/LawnCareEvents/Calendar.cshtml @@ -2,7 +2,12 @@ ViewData["Title"] = "Lawn Care Calendar"; } -

@ViewData["Title"]

+
+

@ViewData["Title"]

+ + Create New Event + +
@@ -27,11 +32,106 @@ @section Scripts { } @section Styles { - } \ No newline at end of file diff --git a/Views/LawnCareEvents/Delete.cshtml b/Views/LawnCareEvents/Delete.cshtml index 101b2f0..42b8768 100644 --- a/Views/LawnCareEvents/Delete.cshtml +++ b/Views/LawnCareEvents/Delete.cshtml @@ -39,7 +39,11 @@
- | - Back to List + +
+ +
\ No newline at end of file diff --git a/Views/LawnCareEvents/Details.cshtml b/Views/LawnCareEvents/Details.cshtml index d76c146..08013e6 100644 --- a/Views/LawnCareEvents/Details.cshtml +++ b/Views/LawnCareEvents/Details.cshtml @@ -43,6 +43,7 @@
+ Delete
diff --git a/Views/LawnCareEvents/Edit.cshtml b/Views/LawnCareEvents/Edit.cshtml index 47642ec..0be630c 100644 --- a/Views/LawnCareEvents/Edit.cshtml +++ b/Views/LawnCareEvents/Edit.cshtml @@ -1,72 +1,74 @@ @model turf_tasker.Models.LawnCareEvent @{ - ViewData["Title"] = "Edit"; +ViewData["Title"] = "Edit"; }

Edit

-

LawnCareEvent

+

Lawn Care Event


-
+
-
+
-
+
-
+
+ + Delete
-
+ @section Scripts { - @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} +@{await Html.RenderPartialAsync("_ValidationScriptsPartial");} - + }); + } \ No newline at end of file diff --git a/Views/LawnCareEvents/Index.cshtml b/Views/LawnCareEvents/Index.cshtml index 55439ca..5c79329 100644 --- a/Views/LawnCareEvents/Index.cshtml +++ b/Views/LawnCareEvents/Index.cshtml @@ -4,11 +4,14 @@ ViewData["Title"] = "Lawn Care Log"; } -

@ViewData["Title"]

+
+

@ViewData["Title"]

-

- Create New Event -

+

+ Create New Event + View Calendar +

+
@@ -16,8 +19,8 @@

Find by type or note: - | - Back to Full List + + Reset Filter

@@ -63,9 +66,11 @@ @Html.DisplayFor(modelItem => item.Notes) - Edit | - Details | - Delete +
+ Edit + Details + Delete +
} diff --git a/Views/LawnCareTip/Index.cshtml b/Views/LawnCareTip/Index.cshtml index 694efe3..edd49e9 100644 --- a/Views/LawnCareTip/Index.cshtml +++ b/Views/LawnCareTip/Index.cshtml @@ -7,7 +7,7 @@

Index

- Create New + Create New Tip

@@ -36,10 +36,11 @@ - } diff --git a/wwwroot/css/site.css b/wwwroot/css/site.css index efacf73..c019ffe 100644 --- a/wwwroot/css/site.css +++ b/wwwroot/css/site.css @@ -33,4 +33,17 @@ body { .navbar-custom .nav-link:hover { color: #d4d4d4; /* A light gray for hover effect */ +} + +/* For tables, to control column widths */ +.table .col-content { + max-width: 400px; /* Adjust as needed */ + word-wrap: break-word; /* Break long words */ + white-space: normal; /* Allow text to wrap normally */ +} + +.table .col-actions { + width: 150px; /* Fixed width for action buttons, adjust as needed */ + min-width: 120px; /* Ensure minimum space */ + white-space: nowrap; /* Keep buttons on one line, prevent wrapping */ } \ No newline at end of file -- 2.47.3 From 9ecaf8350b1d1ea59a82507f103644b4edc0acfd Mon Sep 17 00:00:00 2001 From: Blake Ridgway Date: Wed, 18 Jun 2025 21:35:39 -0500 Subject: [PATCH 5/6] chore: clean up unneeded comment now that it works --- Models/LawnCareEvent.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Models/LawnCareEvent.cs b/Models/LawnCareEvent.cs index d5e4c36..e43d501 100644 --- a/Models/LawnCareEvent.cs +++ b/Models/LawnCareEvent.cs @@ -31,14 +31,11 @@ public class LawnCareEvent [Required] [Display(Name = "Activity Type")] public LawnCareEventType EventType { get; set; } - - // --- THIS IS THE LINE TO CHECK --- - // Make sure this property exists and is spelled correctly. + [Required] [DataType(DataType.Date)] [Display(Name = "Date")] public DateTime EventDate { get; set; } - // --------------------------------- [Display(Name = "Mowing Pattern")] public MowingPattern? MowingPattern { get; set; } -- 2.47.3 From 5c81fb70fd1e1fc8cb54334284d5e0782b0eb2b7 Mon Sep 17 00:00:00 2001 From: Blake Ridgway Date: Sat, 21 Jun 2025 16:30:12 -0500 Subject: [PATCH 6/6] feat: added new event details --- ...20250621212709_AddEventDetails.Designer.cs | 86 +++++++++++++++++++ Migrations/20250621212709_AddEventDetails.cs | 60 +++++++++++++ .../ApplicationDbContextModelSnapshot.cs | 14 +++ Models/LawnCareEvent.cs | 20 +++++ 4 files changed, 180 insertions(+) create mode 100644 Migrations/20250621212709_AddEventDetails.Designer.cs create mode 100644 Migrations/20250621212709_AddEventDetails.cs diff --git a/Migrations/20250621212709_AddEventDetails.Designer.cs b/Migrations/20250621212709_AddEventDetails.Designer.cs new file mode 100644 index 0000000..0eb8d9c --- /dev/null +++ b/Migrations/20250621212709_AddEventDetails.Designer.cs @@ -0,0 +1,86 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using turf_tasker.Data; + +#nullable disable + +namespace turf_tasker.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250621212709_AddEventDetails")] + partial class AddEventDetails + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.6"); + + modelBuilder.Entity("turf_tasker.Models.LawnCareEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AppliedAmount") + .HasColumnType("TEXT"); + + b.Property("EventDate") + .HasColumnType("TEXT"); + + b.Property("EventType") + .HasColumnType("INTEGER"); + + b.Property("MowerHeightInches") + .HasColumnType("TEXT"); + + b.Property("MowingPattern") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("ProblemObserved") + .HasMaxLength(250) + .HasColumnType("TEXT"); + + b.Property("ProductUsed") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("LawnCareEvents"); + }); + + modelBuilder.Entity("turf_tasker.Models.LawnCareTip", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Category") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("LawnCareTips"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20250621212709_AddEventDetails.cs b/Migrations/20250621212709_AddEventDetails.cs new file mode 100644 index 0000000..97662ed --- /dev/null +++ b/Migrations/20250621212709_AddEventDetails.cs @@ -0,0 +1,60 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace turf_tasker.Migrations +{ + /// + public partial class AddEventDetails : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "AppliedAmount", + table: "LawnCareEvents", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "MowerHeightInches", + table: "LawnCareEvents", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "ProblemObserved", + table: "LawnCareEvents", + type: "TEXT", + maxLength: 250, + nullable: true); + + migrationBuilder.AddColumn( + name: "ProductUsed", + table: "LawnCareEvents", + type: "TEXT", + maxLength: 200, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "AppliedAmount", + table: "LawnCareEvents"); + + migrationBuilder.DropColumn( + name: "MowerHeightInches", + table: "LawnCareEvents"); + + migrationBuilder.DropColumn( + name: "ProblemObserved", + table: "LawnCareEvents"); + + migrationBuilder.DropColumn( + name: "ProductUsed", + table: "LawnCareEvents"); + } + } +} diff --git a/Migrations/ApplicationDbContextModelSnapshot.cs b/Migrations/ApplicationDbContextModelSnapshot.cs index f6d0c56..320c9f9 100644 --- a/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Migrations/ApplicationDbContextModelSnapshot.cs @@ -23,12 +23,18 @@ namespace turf_tasker.Migrations .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); + b.Property("AppliedAmount") + .HasColumnType("TEXT"); + b.Property("EventDate") .HasColumnType("TEXT"); b.Property("EventType") .HasColumnType("INTEGER"); + b.Property("MowerHeightInches") + .HasColumnType("TEXT"); + b.Property("MowingPattern") .HasColumnType("INTEGER"); @@ -36,6 +42,14 @@ namespace turf_tasker.Migrations .HasMaxLength(500) .HasColumnType("TEXT"); + b.Property("ProblemObserved") + .HasMaxLength(250) + .HasColumnType("TEXT"); + + b.Property("ProductUsed") + .HasMaxLength(200) + .HasColumnType("TEXT"); + b.HasKey("Id"); b.ToTable("LawnCareEvents"); diff --git a/Models/LawnCareEvent.cs b/Models/LawnCareEvent.cs index e43d501..4b8d9c3 100644 --- a/Models/LawnCareEvent.cs +++ b/Models/LawnCareEvent.cs @@ -9,6 +9,10 @@ public enum LawnCareEventType Fertilizing, Aeration, WeedControl, + PestControl, + DiseaseControl, + Topdressing, + Overseeding, Other } @@ -39,6 +43,22 @@ public class LawnCareEvent [Display(Name = "Mowing Pattern")] public MowingPattern? MowingPattern { get; set; } + + [Display(Name = "Product Used")] + [StringLength(200)] + public string? ProductUsed { get; set; } + + [Display(Name = "Applied Amount")] + [Range(0.01, 1000.0, ErrorMessage = "Amount must be positive.")] // Example range + public decimal? AppliedAmount { get; set; } + + [Display(Name = "Mower Height (inches)")] + [Range(0.5, 6.0, ErrorMessage = "Height must be between 0.5 and 6 inches.")] + public decimal? MowerHeightInches { get; set; } + + [Display(Name = "Problem Observed")] + [StringLength(250)] + public string? ProblemObserved { get; set; } [StringLength(500)] public string? Notes { get; set; } -- 2.47.3
@Html.DisplayFor(modelItem => item.Content) - Edit | - Details | - Delete + +
+ Edit + Delete +