From 00076bced6d679094dee43d90bb188d83f8f208b Mon Sep 17 00:00:00 2001 From: Jorge Luis Censi Date: Tue, 14 Jan 2025 16:41:45 +1000 Subject: [PATCH 1/4] Add venue address to Gig model PR generated by AI --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/jorgecensi/GigHub?shareId=XXXX-XXXX-XXXX-XXXX). --- .../GigHub/Controllers/API/GigsController.cs | 199 +++++------ GigHub/GigHub/Controllers/GigsController.cs | 336 +++++++++--------- GigHub/GigHub/Core/DTOs/GigDto.cs | 33 +- GigHub/GigHub/Core/Models/Gig.cs | 131 +++---- .../Core/ViewModels/GigDetailsViewModel.cs | 23 +- .../Core/ViewModels/GigFormViewModel.cs | 57 +++ .../EntityConfigurations/GigConfiguration.cs | 60 ++-- GigHub/GigHub/Views/Gigs/Details.cshtml | 71 ++-- GigHub/GigHub/Views/Gigs/GigForm.cshtml | 81 +++-- GigHub/GigHub/Views/Gigs/Mine.cshtml | 2 +- 10 files changed, 528 insertions(+), 465 deletions(-) create mode 100644 GigHub/GigHub/Core/ViewModels/GigFormViewModel.cs diff --git a/GigHub/GigHub/Controllers/API/GigsController.cs b/GigHub/GigHub/Controllers/API/GigsController.cs index bde0b81..680c011 100644 --- a/GigHub/GigHub/Controllers/API/GigsController.cs +++ b/GigHub/GigHub/Controllers/API/GigsController.cs @@ -1,99 +1,100 @@ -using AutoMapper; -using GigHub.Core; -using GigHub.Core.DTOs; -using GigHub.Core.Models; -using Microsoft.AspNet.Identity; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Web.Http; - -namespace GigHub.Controllers.API -{ - [Authorize] - public class GigsController : ApiController - { - private readonly IUnitOfWork _unitOfWork; - - public GigsController(IUnitOfWork unitOfWork) - { - _unitOfWork = unitOfWork; - } - - - [HttpDelete] - public IHttpActionResult Cancel(int id) - { - var userId = User.Identity.GetUserId(); - var gig = _unitOfWork.Gigs.GetGigWithAttendees(id); - - if (gig == null || gig.IsCanceled) - return NotFound(); - - if (gig.ArtistId != userId) - return Unauthorized(); - - gig.Cancel(); - - _unitOfWork.Complete(); - - return Ok(); - - } - - [HttpGet] - public IEnumerable Gigs() - { - var gigs = _unitOfWork.Gigs.GetUpcomingGigs(); - return gigs.ToList().Select(Mapper.Map); - } - - [HttpPost] - public IHttpActionResult PostGig(Gig gigViewModel) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - var gig = new Gig - { - ArtistId = User.Identity.GetUserId(), - DateTime = gigViewModel.DateTime, - GenreId = gigViewModel.GenreId, - Venue = gigViewModel.Venue - }; - - _unitOfWork.Gigs.Add(gig); - _unitOfWork.Complete(); - - return CreatedAtRoute("DefaultApi", new { id = gig.Id }, gig); - } - - [HttpPut] - public IHttpActionResult UpdateGig(int id, Gig gigViewModel) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - if (id != gigViewModel.Id) - { - return BadRequest(); - } - var userId = User.Identity.GetUserId(); - if (userId != gigViewModel.ArtistId) - { - return StatusCode(HttpStatusCode.Conflict); - } - - var gig = _unitOfWork.Gigs.GetGigWithAttendees(gigViewModel.Id); - if (gig == null) - return NotFound(); - if (gig.ArtistId != User.Identity.GetUserId()) - return BadRequest(); - gig.Modify(gigViewModel.DateTime, gigViewModel.Genre.Id, gigViewModel.Venue); - _unitOfWork.Complete(); - return StatusCode(HttpStatusCode.NoContent); - } - } -} +using AutoMapper; +using GigHub.Core; +using GigHub.Core.DTOs; +using GigHub.Core.Models; +using Microsoft.AspNet.Identity; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Web.Http; + +namespace GigHub.Controllers.API +{ + [Authorize] + public class GigsController : ApiController + { + private readonly IUnitOfWork _unitOfWork; + + public GigsController(IUnitOfWork unitOfWork) + { + _unitOfWork = unitOfWork; + } + + + [HttpDelete] + public IHttpActionResult Cancel(int id) + { + var userId = User.Identity.GetUserId(); + var gig = _unitOfWork.Gigs.GetGigWithAttendees(id); + + if (gig == null || gig.IsCanceled) + return NotFound(); + + if (gig.ArtistId != userId) + return Unauthorized(); + + gig.Cancel(); + + _unitOfWork.Complete(); + + return Ok(); + + } + + [HttpGet] + public IEnumerable Gigs() + { + var gigs = _unitOfWork.Gigs.GetUpcomingGigs(); + return gigs.ToList().Select(Mapper.Map); + } + + [HttpPost] + public IHttpActionResult PostGig(Gig gigViewModel) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + var gig = new Gig + { + ArtistId = User.Identity.GetUserId(), + DateTime = gigViewModel.DateTime, + GenreId = gigViewModel.GenreId, + Venue = gigViewModel.Venue, + VenueAddress = gigViewModel.VenueAddress + }; + + _unitOfWork.Gigs.Add(gig); + _unitOfWork.Complete(); + + return CreatedAtRoute("DefaultApi", new { id = gig.Id }, gig); + } + + [HttpPut] + public IHttpActionResult UpdateGig(int id, Gig gigViewModel) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + if (id != gigViewModel.Id) + { + return BadRequest(); + } + var userId = User.Identity.GetUserId(); + if (userId != gigViewModel.ArtistId) + { + return StatusCode(HttpStatusCode.Conflict); + } + + var gig = _unitOfWork.Gigs.GetGigWithAttendees(gigViewModel.Id); + if (gig == null) + return NotFound(); + if (gig.ArtistId != User.Identity.GetUserId()) + return BadRequest(); + gig.Modify(gigViewModel.DateTime, gigViewModel.Genre.Id, gigViewModel.Venue, gigViewModel.VenueAddress); + _unitOfWork.Complete(); + return StatusCode(HttpStatusCode.NoContent); + } + } +} diff --git a/GigHub/GigHub/Controllers/GigsController.cs b/GigHub/GigHub/Controllers/GigsController.cs index e992ae9..2b77e6d 100644 --- a/GigHub/GigHub/Controllers/GigsController.cs +++ b/GigHub/GigHub/Controllers/GigsController.cs @@ -1,174 +1,162 @@ - -using GigHub.Core; -using GigHub.Core.Models; -using GigHub.Core.ViewModels; -using Microsoft.AspNet.Identity; -using System.Linq; -using System.Web.Mvc; - -namespace GigHub.Controllers -{ - public class GigsController : Controller - { - private readonly IUnitOfWork _unitOfWork; - - - public GigsController(IUnitOfWork unitOfWork) - { - _unitOfWork = unitOfWork; - } - - [Authorize] - public ViewResult Mine() - { - return View(_unitOfWork.Gigs.GetFutureUserGigs(User.Identity.GetUserId())); - } - - - - [Authorize] - public ActionResult Attending() - { - var userId = User.Identity.GetUserId(); - - var viewModel = new GigsViewModel() - { - UpcommingGigs = _unitOfWork.Gigs.GetGigsUserAttending(userId), - ShowActions = User.Identity.IsAuthenticated, - Heading = "Gigs I'm Attending", - Attendances = _unitOfWork.Attendances.GetFutureAttendances(userId).ToLookup(a => a.GigId) - }; - - return View("Gigs", viewModel); - - } - - - - - - [HttpPost] - public ActionResult Search(GigsViewModel viewModel) - { - return RedirectToAction("Index", "Home", new { query = viewModel.SearchTerm }); - } - - // GET: Gigs - [Authorize] - public ActionResult Create() - { - var viewModel = new GigFormViewModel - { - Genres = _unitOfWork.Genres.GetAllGenres(), - Heading = "Add a Gig" - - }; - return View("GigForm", viewModel); - } - - [Authorize] - public ActionResult Edit(int id) - { - - var gig = _unitOfWork.Gigs.GetGig(id); - if (gig == null) - return HttpNotFound(); - - if (gig.ArtistId != User.Identity.GetUserId()) - return new HttpUnauthorizedResult(); - - var viewModel = new GigFormViewModel - { - Heading = "Edit a Gig", - Id = gig.Id, - Genres = _unitOfWork.Genres.GetAllGenres(), - Date = gig.DateTime.ToString("dd/MM/yyyy"), - Time = gig.DateTime.ToString("HH:mm"), - Venue = gig.Venue, - Genre = gig.GenreId - - }; - return View("GigForm", viewModel); - } - - [Authorize] - public ActionResult Details(int id) - { - var gig = _unitOfWork.Gigs.GetGig(id); - - if (gig == null) - return HttpNotFound(); - - var viewModel = new GigDetailsViewModel { Gig = gig }; - - if (User.Identity.IsAuthenticated) - { - var userId = User.Identity.GetUserId(); - - viewModel.IsAttending = _unitOfWork.Attendances.GetAttendance(gig.Id, userId) != null; - - viewModel.IsFollowing = _unitOfWork.Followings.GetFollowing(gig.ArtistId, userId) != null; - } - - - - return View("Details", viewModel); - - } - - [Authorize] - [HttpPost] - [ValidateAntiForgeryToken] - public ActionResult Create(GigFormViewModel viewModel) - { - if (!ModelState.IsValid) - { - viewModel.Genres = _unitOfWork.Genres.GetAllGenres(); - return View("GigForm", viewModel); - } - - var gig = new Gig - { - ArtistId = User.Identity.GetUserId(), - DateTime = viewModel.GetDateTime(), - GenreId = viewModel.Genre, - Venue = viewModel.Venue - }; - - _unitOfWork.Gigs.Add(gig); - _unitOfWork.Complete(); - - - - return RedirectToAction("Mine", "Gigs"); - - } - - [Authorize] - [HttpPost] - [ValidateAntiForgeryToken] - public ActionResult Update(GigFormViewModel viewModel) - { - if (!ModelState.IsValid) - { - viewModel.Genres = _unitOfWork.Genres.GetAllGenres(); - return View("GigForm", viewModel); - } - - var gig = _unitOfWork.Gigs.GetGigWithAttendees(viewModel.Id); - - if (gig == null) - return HttpNotFound(); - if (gig.ArtistId != User.Identity.GetUserId()) - return new HttpUnauthorizedResult(); - - - gig.Modify(viewModel.GetDateTime(), viewModel.Genre, viewModel.Venue); - - _unitOfWork.Complete(); - - return RedirectToAction("Mine", "Gigs"); - - } - } -} +using GigHub.Core; +using GigHub.Core.Models; +using GigHub.Core.ViewModels; +using Microsoft.AspNet.Identity; +using System.Linq; +using System.Web.Mvc; + +namespace GigHub.Controllers +{ + public class GigsController : Controller + { + private readonly IUnitOfWork _unitOfWork; + + public GigsController(IUnitOfWork unitOfWork) + { + _unitOfWork = unitOfWork; + } + + [Authorize] + public ViewResult Mine() + { + return View(_unitOfWork.Gigs.GetFutureUserGigs(User.Identity.GetUserId())); + } + + [Authorize] + public ActionResult Attending() + { + var userId = User.Identity.GetUserId(); + + var viewModel = new GigsViewModel() + { + UpcommingGigs = _unitOfWork.Gigs.GetGigsUserAttending(userId), + ShowActions = User.Identity.IsAuthenticated, + Heading = "Gigs I'm Attending", + Attendances = _unitOfWork.Attendances.GetFutureAttendances(userId).ToLookup(a => a.GigId) + }; + + return View("Gigs", viewModel); + } + + [HttpPost] + public ActionResult Search(GigsViewModel viewModel) + { + return RedirectToAction("Index", "Home", new { query = viewModel.SearchTerm }); + } + + // GET: Gigs + [Authorize] + public ActionResult Create() + { + var viewModel = new GigFormViewModel + { + Genres = _unitOfWork.Genres.GetAllGenres(), + Heading = "Add a Gig", + Venue = string.Empty, + VenueAddress = string.Empty + }; + return View("GigForm", viewModel); + } + + [Authorize] + public ActionResult Edit(int id) + { + var gig = _unitOfWork.Gigs.GetGig(id); + if (gig == null) + return HttpNotFound(); + + if (gig.ArtistId != User.Identity.GetUserId()) + return new HttpUnauthorizedResult(); + + var viewModel = new GigFormViewModel + { + Heading = "Edit a Gig", + Id = gig.Id, + Genres = _unitOfWork.Genres.GetAllGenres(), + Date = gig.DateTime.ToString("dd/MM/yyyy"), + Time = gig.DateTime.ToString("HH:mm"), + Venue = gig.Venue, + VenueAddress = gig.VenueAddress, + Genre = gig.GenreId + }; + return View("GigForm", viewModel); + } + + [Authorize] + public ActionResult Details(int id) + { + var gig = _unitOfWork.Gigs.GetGig(id); + + if (gig == null) + return HttpNotFound(); + + var viewModel = new GigDetailsViewModel + { + Gig = gig, + VenueAddress = gig.VenueAddress + }; + + if (User.Identity.IsAuthenticated) + { + var userId = User.Identity.GetUserId(); + + viewModel.IsAttending = _unitOfWork.Attendances.GetAttendance(gig.Id, userId) != null; + + viewModel.IsFollowing = _unitOfWork.Followings.GetFollowing(gig.ArtistId, userId) != null; + } + + return View("Details", viewModel); + } + + [Authorize] + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Create(GigFormViewModel viewModel) + { + if (!ModelState.IsValid) + { + viewModel.Genres = _unitOfWork.Genres.GetAllGenres(); + return View("GigForm", viewModel); + } + + var gig = new Gig + { + ArtistId = User.Identity.GetUserId(), + DateTime = viewModel.GetDateTime(), + GenreId = viewModel.Genre, + Venue = viewModel.Venue, + VenueAddress = viewModel.VenueAddress + }; + + _unitOfWork.Gigs.Add(gig); + _unitOfWork.Complete(); + + return RedirectToAction("Mine", "Gigs"); + } + + [Authorize] + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Update(GigFormViewModel viewModel) + { + if (!ModelState.IsValid) + { + viewModel.Genres = _unitOfWork.Genres.GetAllGenres(); + return View("GigForm", viewModel); + } + + var gig = _unitOfWork.Gigs.GetGigWithAttendees(viewModel.Id); + + if (gig == null) + return HttpNotFound(); + if (gig.ArtistId != User.Identity.GetUserId()) + return new HttpUnauthorizedResult(); + + gig.Modify(viewModel.GetDateTime(), viewModel.Genre, viewModel.Venue, viewModel.VenueAddress); + + _unitOfWork.Complete(); + + return RedirectToAction("Mine", "Gigs"); + } + } +} diff --git a/GigHub/GigHub/Core/DTOs/GigDto.cs b/GigHub/GigHub/Core/DTOs/GigDto.cs index dd9d92a..9b924be 100644 --- a/GigHub/GigHub/Core/DTOs/GigDto.cs +++ b/GigHub/GigHub/Core/DTOs/GigDto.cs @@ -1,16 +1,17 @@ -using System; - -namespace GigHub.Core.DTOs -{ - public class GigDto - { - public int Id { get; set; } - public bool IsCanceled { get; set; } - public UserDto Artist { get; set; } - public DateTime DateTime { get; set; } - public string Venue { get; set; } - public GenreDto Genre { get; set; } - public byte GenreId { get; set; } - - } -} \ No newline at end of file +using System; + +namespace GigHub.Core.DTOs +{ + public class GigDto + { + public int Id { get; set; } + public bool IsCanceled { get; set; } + public UserDto Artist { get; set; } + public DateTime DateTime { get; set; } + public string Venue { get; set; } + public string VenueAddress { get; set; } + public GenreDto Genre { get; set; } + public byte GenreId { get; set; } + + } +} diff --git a/GigHub/GigHub/Core/Models/Gig.cs b/GigHub/GigHub/Core/Models/Gig.cs index c5b5318..0ab379c 100644 --- a/GigHub/GigHub/Core/Models/Gig.cs +++ b/GigHub/GigHub/Core/Models/Gig.cs @@ -1,64 +1,67 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; - -namespace GigHub.Core.Models -{ - public class Gig - { - public int Id { get; private set; } - - public bool IsCanceled { get; private set; } - - public ApplicationUser Artist { get; set; } - - public string ArtistId { get; set; } - - public DateTime DateTime { get; set; } - - public string Venue { get; set; } - - public Genre Genre { get; set; } - - public byte GenreId { get; set; } - - public ICollection Attendances { get; private set; } - - public Gig() - { - Attendances = new Collection(); - } - - public void Cancel() - { - IsCanceled = true; - - var notification = Notification.GigCanceled(this); - - foreach (var attendee in Attendances.Select(a => a.Attendee)) - { - attendee.Notify(notification); - } - } - - public void Modify(DateTime dateTime, byte genreId, string venue) - { - - var notification = Notification.GigUpdated(this, DateTime, Venue); - - DateTime = dateTime; - GenreId = genreId; - Venue = venue; - - foreach (var attendee in Attendances.Select(a => a.Attendee)) - { - attendee.Notify(notification); - } - - - } - } - - -} \ No newline at end of file +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace GigHub.Core.Models +{ + public class Gig + { + public int Id { get; private set; } + + public bool IsCanceled { get; private set; } + + public ApplicationUser Artist { get; set; } + + public string ArtistId { get; set; } + + public DateTime DateTime { get; set; } + + public string Venue { get; set; } + + public string VenueAddress { get; set; } + + public Genre Genre { get; set; } + + public byte GenreId { get; set; } + + public ICollection Attendances { get; private set; } + + public Gig() + { + Attendances = new Collection(); + } + + public void Cancel() + { + IsCanceled = true; + + var notification = Notification.GigCanceled(this); + + foreach (var attendee in Attendances.Select(a => a.Attendee)) + { + attendee.Notify(notification); + } + } + + public void Modify(DateTime dateTime, byte genreId, string venue, string venueAddress) + { + + var notification = Notification.GigUpdated(this, DateTime, Venue); + + DateTime = dateTime; + GenreId = genreId; + Venue = venue; + VenueAddress = venueAddress; + + foreach (var attendee in Attendances.Select(a => a.Attendee)) + { + attendee.Notify(notification); + } + + + } + } + + +} diff --git a/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs b/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs index b4ee93a..f0a25ef 100644 --- a/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs +++ b/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs @@ -1,11 +1,12 @@ -using GigHub.Core.Models; - -namespace GigHub.Core.ViewModels -{ - public class GigDetailsViewModel - { - public Gig Gig { get; set; } - public bool IsAttending { get; set; } - public bool IsFollowing { get; set; } - } -} \ No newline at end of file +using GigHub.Core.Models; + +namespace GigHub.Core.ViewModels +{ + public class GigDetailsViewModel + { + public Gig Gig { get; set; } + public bool IsAttending { get; set; } + public bool IsFollowing { get; set; } + public string VenueAddress { get; set; } + } +} diff --git a/GigHub/GigHub/Core/ViewModels/GigFormViewModel.cs b/GigHub/GigHub/Core/ViewModels/GigFormViewModel.cs new file mode 100644 index 0000000..2a9b99d --- /dev/null +++ b/GigHub/GigHub/Core/ViewModels/GigFormViewModel.cs @@ -0,0 +1,57 @@ +using GigHub.Controllers; +using GigHub.Core.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq.Expressions; +using System.Web.Mvc; + +namespace GigHub.Core.ViewModels +{ + public class GigFormViewModel + { + public int Id { get; set; } + + [Required] + public string Venue { get; set; } + + [Required] + public string VenueAddress { get; set; } + + [Required] + [FutureDate] + public string Date { get; set; } + + [Required] + [ValidTime] + public string Time { get; set; } + + [Required] + public byte Genre { get; set; } + + public IEnumerable Genres { get; set; } + + public DateTime GetDateTime() + { + return DateTime.Parse(string.Format("{0} {1}", Date, Time)); + } + + public string Heading { get; set; } + + public string Action + { + get + { + Expression> update = + (c => c.Update(this)); + + Expression> create = + (c => c.Create(this)); + + var action = (Id != 0) ? update : create; + + return (action.Body as MethodCallExpression).Method.Name; + } + } + } +} diff --git a/GigHub/GigHub/Persistence/EntityConfigurations/GigConfiguration.cs b/GigHub/GigHub/Persistence/EntityConfigurations/GigConfiguration.cs index 7e6fa78..e31af5c 100644 --- a/GigHub/GigHub/Persistence/EntityConfigurations/GigConfiguration.cs +++ b/GigHub/GigHub/Persistence/EntityConfigurations/GigConfiguration.cs @@ -1,28 +1,32 @@ -using GigHub.Core.Models; -using System.Data.Entity.ModelConfiguration; - -namespace GigHub.Persistence.EntityConfigurations -{ - public class GigConfiguration : EntityTypeConfiguration - { - public GigConfiguration() - { - Property(g => g.ArtistId) - .IsRequired(); - - Property(g => g.Venue) - .IsRequired() - .HasMaxLength(255); - - Property(g => g.GenreId) - .IsRequired(); - - //Create a relationship between Gig and Attendance - //turn off cascade delete - HasMany(g => g.Attendances) - .WithRequired(a => a.Gig) - .WillCascadeOnDelete(false); - - } - } -} \ No newline at end of file +using GigHub.Core.Models; +using System.Data.Entity.ModelConfiguration; + +namespace GigHub.Persistence.EntityConfigurations +{ + public class GigConfiguration : EntityTypeConfiguration + { + public GigConfiguration() + { + Property(g => g.ArtistId) + .IsRequired(); + + Property(g => g.Venue) + .IsRequired() + .HasMaxLength(255); + + Property(g => g.VenueAddress) + .IsRequired() + .HasMaxLength(255); + + Property(g => g.GenreId) + .IsRequired(); + + //Create a relationship between Gig and Attendance + //turn off cascade delete + HasMany(g => g.Attendances) + .WithRequired(a => a.Gig) + .WillCascadeOnDelete(false); + + } + } +} diff --git a/GigHub/GigHub/Views/Gigs/Details.cshtml b/GigHub/GigHub/Views/Gigs/Details.cshtml index f49d0f9..9ac7821 100644 --- a/GigHub/GigHub/Views/Gigs/Details.cshtml +++ b/GigHub/GigHub/Views/Gigs/Details.cshtml @@ -1,34 +1,37 @@ -@model GigHub.Core.ViewModels.GigDetailsViewModel -@{ - ViewBag.Title = "Details"; -} - -

- @Model.Gig.Artist.Name - @if (User.Identity.IsAuthenticated) - { - - } -

-

- Performing at @Model.Gig.Venue on @Model.Gig.DateTime.ToString("dd/MM/yyyy") at @Model.Gig.DateTime.ToString("HH:mm") -

- -@if (User.Identity.IsAuthenticated && Model.IsAttending) -{ -

You are going to this event.

-} -@section scripts -{ - -} \ No newline at end of file +@model GigHub.Core.ViewModels.GigDetailsViewModel +@{ + ViewBag.Title = "Details"; +} + +

+ @Model.Gig.Artist.Name + @if (User.Identity.IsAuthenticated) + { + + } +

+

+ Performing at @Model.Gig.Venue on @Model.Gig.DateTime.ToString("dd/MM/yyyy") at @Model.Gig.DateTime.ToString("HH:mm") +

+

+ Address: @Model.VenueAddress +

+ +@if (User.Identity.IsAuthenticated && Model.IsAttending) +{ +

You are going to this event.

+} +@section scripts +{ + +} diff --git a/GigHub/GigHub/Views/Gigs/GigForm.cshtml b/GigHub/GigHub/Views/Gigs/GigForm.cshtml index f416edb..b3ae317 100644 --- a/GigHub/GigHub/Views/Gigs/GigForm.cshtml +++ b/GigHub/GigHub/Views/Gigs/GigForm.cshtml @@ -1,38 +1,43 @@ -@model GigHub.Core.ViewModels.GigFormViewModel -@{ - ViewBag.Title = Model.Heading; -} - -

@Model.Heading

- -@using (Html.BeginForm(Model.Action, "Gigs")) -{ -

All fields are required.

- @Html.AntiForgeryToken() - @Html.HiddenFor(m => m.Id) -
- @Html.LabelFor(m => m.Venue) - @Html.TextBoxFor(m => m.Venue, new { @class = "form-control", autofocus = "autofocus" }) - @Html.ValidationMessageFor(m => m.Venue) -
-
- @Html.LabelFor(m => m.Date) - @Html.TextBoxFor(m => m.Date, new { @class = "form-control", placeholder = "eg 1 Jan 2017" }) - @Html.ValidationMessageFor(m => m.Date) -
-
- @Html.LabelFor(m => m.Time) - @Html.TextBoxFor(m => m.Time, new { @class = "form-control", placeholder = "eg 20:00" }) - @Html.ValidationMessageFor(m => m.Time) -
-
- @Html.LabelFor(m => m.Genre) - @Html.DropDownListFor(m => m.Genre, new SelectList(Model.Genres, "Id", "Name"), "", new { @class = "form-control" }) - @Html.ValidationMessageFor(m => m.Genre) -
- -} -@section scripts -{ - @Scripts.Render("~/bundles/jqueryval") -} \ No newline at end of file +@model GigHub.Core.ViewModels.GigFormViewModel +@{ + ViewBag.Title = Model.Heading; +} + +

@Model.Heading

+ +@using (Html.BeginForm(Model.Action, "Gigs")) +{ +

All fields are required.

+ @Html.AntiForgeryToken() + @Html.HiddenFor(m => m.Id) +
+ @Html.LabelFor(m => m.Venue) + @Html.TextBoxFor(m => m.Venue, new { @class = "form-control", autofocus = "autofocus" }) + @Html.ValidationMessageFor(m => m.Venue) +
+
+ @Html.LabelFor(m => m.VenueAddress) + @Html.TextBoxFor(m => m.VenueAddress, new { @class = "form-control" }) + @Html.ValidationMessageFor(m => m.VenueAddress) +
+
+ @Html.LabelFor(m => m.Date) + @Html.TextBoxFor(m => m.Date, new { @class = "form-control", placeholder = "eg 1 Jan 2017" }) + @Html.ValidationMessageFor(m => m.Date) +
+
+ @Html.LabelFor(m => m.Time) + @Html.TextBoxFor(m => m.Time, new { @class = "form-control", placeholder = "eg 20:00" }) + @Html.ValidationMessageFor(m => m.Time) +
+
+ @Html.LabelFor(m => m.Genre) + @Html.DropDownListFor(m => m.Genre, new SelectList(Model.Genres, "Id", "Name"), "", new { @class = "form-control" }) + @Html.ValidationMessageFor(m => m.Genre) +
+ +} +@section scripts +{ + @Scripts.Render("~/bundles/jqueryval") +} diff --git a/GigHub/GigHub/Views/Gigs/Mine.cshtml b/GigHub/GigHub/Views/Gigs/Mine.cshtml index b25cc7a..e11746c 100644 --- a/GigHub/GigHub/Views/Gigs/Mine.cshtml +++ b/GigHub/GigHub/Views/Gigs/Mine.cshtml @@ -78,4 +78,4 @@ }); }); -} \ No newline at end of file +} From bec7f00cbbec4a273388d7cd30d1cebea1c8d6e0 Mon Sep 17 00:00:00 2001 From: Jorge Luis Censi Date: Tue, 14 Jan 2025 17:26:19 +1000 Subject: [PATCH 2/4] add city entity --- .../GigHub/Controllers/API/GigsController.cs | 5 +- GigHub/GigHub/Controllers/CitiesController.cs | 93 ++++++++++++++ GigHub/GigHub/Controllers/GigsController.cs | 12 +- GigHub/GigHub/Core/IUnitOfWork.cs | 33 ++--- GigHub/GigHub/Core/Models/City.cs | 9 ++ GigHub/GigHub/Core/Models/Gig.cs | 5 +- GigHub/GigHub/Core/UnitOfWork.cs | 36 ++++++ .../Core/ViewModels/GigDetailsViewModel.cs | 1 + .../Core/ViewModels/GigFormVielModel.cs | 118 +++++++++--------- .../EntityConfigurations/CityConfiguration.cs | 18 +++ .../EntityConfigurations/GigConfiguration.cs | 4 + .../Repositories/CityRepository.cs | 37 ++++++ GigHub/GigHub/Views/Cities/Index.cshtml | 40 ++++++ GigHub/GigHub/Views/Gigs/Details.cshtml | 7 ++ GigHub/GigHub/Views/Gigs/GigForm.cshtml | 7 +- 15 files changed, 343 insertions(+), 82 deletions(-) create mode 100644 GigHub/GigHub/Controllers/CitiesController.cs create mode 100644 GigHub/GigHub/Core/Models/City.cs create mode 100644 GigHub/GigHub/Core/UnitOfWork.cs create mode 100644 GigHub/GigHub/Persistence/EntityConfigurations/CityConfiguration.cs create mode 100644 GigHub/GigHub/Persistence/Repositories/CityRepository.cs create mode 100644 GigHub/GigHub/Views/Cities/Index.cshtml diff --git a/GigHub/GigHub/Controllers/API/GigsController.cs b/GigHub/GigHub/Controllers/API/GigsController.cs index 680c011..3bf9515 100644 --- a/GigHub/GigHub/Controllers/API/GigsController.cs +++ b/GigHub/GigHub/Controllers/API/GigsController.cs @@ -61,7 +61,8 @@ public IHttpActionResult PostGig(Gig gigViewModel) DateTime = gigViewModel.DateTime, GenreId = gigViewModel.GenreId, Venue = gigViewModel.Venue, - VenueAddress = gigViewModel.VenueAddress + VenueAddress = gigViewModel.VenueAddress, + City = gigViewModel.City }; _unitOfWork.Gigs.Add(gig); @@ -92,7 +93,7 @@ public IHttpActionResult UpdateGig(int id, Gig gigViewModel) return NotFound(); if (gig.ArtistId != User.Identity.GetUserId()) return BadRequest(); - gig.Modify(gigViewModel.DateTime, gigViewModel.Genre.Id, gigViewModel.Venue, gigViewModel.VenueAddress); + gig.Modify(gigViewModel.DateTime, gigViewModel.Genre.Id, gigViewModel.Venue, gigViewModel.VenueAddress, gigViewModel.City); _unitOfWork.Complete(); return StatusCode(HttpStatusCode.NoContent); } diff --git a/GigHub/GigHub/Controllers/CitiesController.cs b/GigHub/GigHub/Controllers/CitiesController.cs new file mode 100644 index 0000000..8e9a330 --- /dev/null +++ b/GigHub/GigHub/Controllers/CitiesController.cs @@ -0,0 +1,93 @@ +using GigHub.Core; +using GigHub.Core.Models; +using System.Linq; +using System.Web.Mvc; + +namespace GigHub.Controllers +{ + [Authorize(Roles = "Admin")] + public class CitiesController : Controller + { + private readonly IUnitOfWork _unitOfWork; + + public CitiesController(IUnitOfWork unitOfWork) + { + _unitOfWork = unitOfWork; + } + + public ActionResult Index() + { + var cities = _unitOfWork.Cities.GetAllCities(); + return View(cities); + } + + public ActionResult Edit(int id) + { + var city = _unitOfWork.Cities.GetCity(id); + if (city == null) + return HttpNotFound(); + + return View(city); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Edit(City city) + { + if (!ModelState.IsValid) + return View(city); + + var cityInDb = _unitOfWork.Cities.GetCity(city.Id); + if (cityInDb == null) + return HttpNotFound(); + + cityInDb.Name = city.Name; + cityInDb.IsPartner = city.IsPartner; + + _unitOfWork.Complete(); + + return RedirectToAction("Index"); + } + + public ActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Create(City city) + { + if (!ModelState.IsValid) + return View(city); + + _unitOfWork.Cities.Add(city); + _unitOfWork.Complete(); + + return RedirectToAction("Index"); + } + + public ActionResult Delete(int id) + { + var city = _unitOfWork.Cities.GetCity(id); + if (city == null) + return HttpNotFound(); + + return View(city); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public ActionResult DeleteConfirmed(int id) + { + var city = _unitOfWork.Cities.GetCity(id); + if (city == null) + return HttpNotFound(); + + _unitOfWork.Cities.Remove(city); + _unitOfWork.Complete(); + + return RedirectToAction("Index"); + } + } +} diff --git a/GigHub/GigHub/Controllers/GigsController.cs b/GigHub/GigHub/Controllers/GigsController.cs index 2b77e6d..7aac195 100644 --- a/GigHub/GigHub/Controllers/GigsController.cs +++ b/GigHub/GigHub/Controllers/GigsController.cs @@ -53,7 +53,8 @@ public ActionResult Create() Genres = _unitOfWork.Genres.GetAllGenres(), Heading = "Add a Gig", Venue = string.Empty, - VenueAddress = string.Empty + VenueAddress = string.Empty, + City = string.Empty }; return View("GigForm", viewModel); } @@ -77,6 +78,7 @@ public ActionResult Edit(int id) Time = gig.DateTime.ToString("HH:mm"), Venue = gig.Venue, VenueAddress = gig.VenueAddress, + City = gig.City, Genre = gig.GenreId }; return View("GigForm", viewModel); @@ -93,7 +95,8 @@ public ActionResult Details(int id) var viewModel = new GigDetailsViewModel { Gig = gig, - VenueAddress = gig.VenueAddress + VenueAddress = gig.VenueAddress, + City = gig.City }; if (User.Identity.IsAuthenticated) @@ -125,7 +128,8 @@ public ActionResult Create(GigFormViewModel viewModel) DateTime = viewModel.GetDateTime(), GenreId = viewModel.Genre, Venue = viewModel.Venue, - VenueAddress = viewModel.VenueAddress + VenueAddress = viewModel.VenueAddress, + City = viewModel.City }; _unitOfWork.Gigs.Add(gig); @@ -152,7 +156,7 @@ public ActionResult Update(GigFormViewModel viewModel) if (gig.ArtistId != User.Identity.GetUserId()) return new HttpUnauthorizedResult(); - gig.Modify(viewModel.GetDateTime(), viewModel.Genre, viewModel.Venue, viewModel.VenueAddress); + gig.Modify(viewModel.GetDateTime(), viewModel.Genre, viewModel.Venue, viewModel.VenueAddress, viewModel.City); _unitOfWork.Complete(); diff --git a/GigHub/GigHub/Core/IUnitOfWork.cs b/GigHub/GigHub/Core/IUnitOfWork.cs index 05f9ec9..1a750f3 100644 --- a/GigHub/GigHub/Core/IUnitOfWork.cs +++ b/GigHub/GigHub/Core/IUnitOfWork.cs @@ -1,16 +1,17 @@ -using GigHub.Core.Repositories; - -namespace GigHub.Core -{ - public interface IUnitOfWork - { - IAttendanceRepository Attendances { get; } - IFollowingRepository Followings { get; } - IGenreRepository Genres { get; } - IGigRepository Gigs { get; } - IUserNotificationRepository UserNotifications { get; } - INotificationRepository Notifications { get; } - - void Complete(); - } -} \ No newline at end of file +using GigHub.Core.Repositories; + +namespace GigHub.Core +{ + public interface IUnitOfWork + { + IAttendanceRepository Attendances { get; } + IFollowingRepository Followings { get; } + IGenreRepository Genres { get; } + IGigRepository Gigs { get; } + IUserNotificationRepository UserNotifications { get; } + INotificationRepository Notifications { get; } + ICityRepository Cities { get; } + + void Complete(); + } +} diff --git a/GigHub/GigHub/Core/Models/City.cs b/GigHub/GigHub/Core/Models/City.cs new file mode 100644 index 0000000..81a9f95 --- /dev/null +++ b/GigHub/GigHub/Core/Models/City.cs @@ -0,0 +1,9 @@ +namespace GigHub.Core.Models +{ + public class City + { + public int Id { get; set; } + public string Name { get; set; } + public bool IsPartner { get; set; } + } +} diff --git a/GigHub/GigHub/Core/Models/Gig.cs b/GigHub/GigHub/Core/Models/Gig.cs index 0ab379c..a716e98 100644 --- a/GigHub/GigHub/Core/Models/Gig.cs +++ b/GigHub/GigHub/Core/Models/Gig.cs @@ -21,6 +21,8 @@ public class Gig public string VenueAddress { get; set; } + public string City { get; set; } + public Genre Genre { get; set; } public byte GenreId { get; set; } @@ -44,7 +46,7 @@ public void Cancel() } } - public void Modify(DateTime dateTime, byte genreId, string venue, string venueAddress) + public void Modify(DateTime dateTime, byte genreId, string venue, string venueAddress, string city) { var notification = Notification.GigUpdated(this, DateTime, Venue); @@ -53,6 +55,7 @@ public void Modify(DateTime dateTime, byte genreId, string venue, string venueAd GenreId = genreId; Venue = venue; VenueAddress = venueAddress; + City = city; foreach (var attendee in Attendances.Select(a => a.Attendee)) { diff --git a/GigHub/GigHub/Core/UnitOfWork.cs b/GigHub/GigHub/Core/UnitOfWork.cs new file mode 100644 index 0000000..9a878dd --- /dev/null +++ b/GigHub/GigHub/Core/UnitOfWork.cs @@ -0,0 +1,36 @@ +using GigHub.Core.Repositories; +using GigHub.Persistence; +using GigHub.Persistence.Repositories; + +namespace GigHub.Core +{ + public class UnitOfWork : IUnitOfWork + { + private readonly ApplicationDbContext _context; + + public IGigRepository Gigs { get; private set; } + public IAttendanceRepository Attendances { get; private set; } + public IGenreRepository Genres { get; private set; } + public IFollowingRepository Followings { get; private set; } + public INotificationRepository Notifications { get; private set; } + public IUserNotificationRepository UserNotifications { get; private set; } + public ICityRepository Cities { get; private set; } + + public UnitOfWork(ApplicationDbContext context) + { + _context = context; + Gigs = new GigRepository(context); + Attendances = new AttendanceRepository(context); + Genres = new GenreRepository(context); + Followings = new FollowingRepository(context); + Notifications = new NotificationRepository(context); + UserNotifications = new UserNotificationRepository(context); + Cities = new CityRepository(context); + } + + public void Complete() + { + _context.SaveChanges(); + } + } +} diff --git a/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs b/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs index f0a25ef..f67f6a5 100644 --- a/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs +++ b/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs @@ -8,5 +8,6 @@ public class GigDetailsViewModel public bool IsAttending { get; set; } public bool IsFollowing { get; set; } public string VenueAddress { get; set; } + public string City { get; set; } } } diff --git a/GigHub/GigHub/Core/ViewModels/GigFormVielModel.cs b/GigHub/GigHub/Core/ViewModels/GigFormVielModel.cs index 039c0e8..abb0ab5 100644 --- a/GigHub/GigHub/Core/ViewModels/GigFormVielModel.cs +++ b/GigHub/GigHub/Core/ViewModels/GigFormVielModel.cs @@ -1,58 +1,60 @@ -using GigHub.Controllers; -using GigHub.Core.Models; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq.Expressions; -using System.Web.Mvc; - -namespace GigHub.Core.ViewModels -{ - public class GigFormViewModel - { - public int Id { get; set; } - - - [Required] - public string Venue { get; set; } - - [Required] - [FutureDate] - public string Date { get; set; } - - [Required] - [ValidTime] - public string Time { get; set; } - - [Required] - public byte Genre { get; set; } - - public IEnumerable Genres { get; set; } - - - public DateTime GetDateTime() - { - - return DateTime.Parse(string.Format("{0} {1}", Date, Time)); - - } - - public string Heading { get; set; } - - public string Action - { - get - { - Expression> update = - (c => c.Update(this)); - - Expression> create = - (c => c.Create(this)); - - var action = (Id != 0) ? update : create; - - return (action.Body as MethodCallExpression).Method.Name; - } - } - } -} \ No newline at end of file +using GigHub.Controllers; +using GigHub.Core.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq.Expressions; +using System.Web.Mvc; + +namespace GigHub.Core.ViewModels +{ + public class GigFormViewModel + { + public int Id { get; set; } + + [Required] + public string Venue { get; set; } + + [Required] + public string VenueAddress { get; set; } + + [Required] + public string City { get; set; } + + [Required] + [FutureDate] + public string Date { get; set; } + + [Required] + [ValidTime] + public string Time { get; set; } + + [Required] + public byte Genre { get; set; } + + public IEnumerable Genres { get; set; } + + public DateTime GetDateTime() + { + return DateTime.Parse(string.Format("{0} {1}", Date, Time)); + } + + public string Heading { get; set; } + + public string Action + { + get + { + Expression> update = + (c => c.Update(this)); + + Expression> create = + (c => c.Create(this)); + + var action = (Id != 0) ? update : create; + + return (action.Body as MethodCallExpression).Method.Name; + } + } + } +} diff --git a/GigHub/GigHub/Persistence/EntityConfigurations/CityConfiguration.cs b/GigHub/GigHub/Persistence/EntityConfigurations/CityConfiguration.cs new file mode 100644 index 0000000..011ff98 --- /dev/null +++ b/GigHub/GigHub/Persistence/EntityConfigurations/CityConfiguration.cs @@ -0,0 +1,18 @@ +using GigHub.Core.Models; +using System.Data.Entity.ModelConfiguration; + +namespace GigHub.Persistence.EntityConfigurations +{ + public class CityConfiguration : EntityTypeConfiguration + { + public CityConfiguration() + { + Property(c => c.Name) + .IsRequired() + .HasMaxLength(255); + + Property(c => c.IsPartner) + .IsRequired(); + } + } +} diff --git a/GigHub/GigHub/Persistence/EntityConfigurations/GigConfiguration.cs b/GigHub/GigHub/Persistence/EntityConfigurations/GigConfiguration.cs index e31af5c..22147a1 100644 --- a/GigHub/GigHub/Persistence/EntityConfigurations/GigConfiguration.cs +++ b/GigHub/GigHub/Persistence/EntityConfigurations/GigConfiguration.cs @@ -18,6 +18,10 @@ public GigConfiguration() .IsRequired() .HasMaxLength(255); + Property(g => g.City) + .IsRequired() + .HasMaxLength(255); + Property(g => g.GenreId) .IsRequired(); diff --git a/GigHub/GigHub/Persistence/Repositories/CityRepository.cs b/GigHub/GigHub/Persistence/Repositories/CityRepository.cs new file mode 100644 index 0000000..a6e6e95 --- /dev/null +++ b/GigHub/GigHub/Persistence/Repositories/CityRepository.cs @@ -0,0 +1,37 @@ +using GigHub.Core.Models; +using System.Collections.Generic; +using System.Data.Entity; +using System.Linq; + +namespace GigHub.Persistence.Repositories +{ + public class CityRepository + { + private readonly IApplicationDbContext _context; + + public CityRepository(IApplicationDbContext context) + { + _context = context; + } + + public IEnumerable GetAllCities() + { + return _context.Cities.ToList(); + } + + public City GetCity(int id) + { + return _context.Cities.SingleOrDefault(c => c.Id == id); + } + + public void Add(City city) + { + _context.Cities.Add(city); + } + + public void Remove(City city) + { + _context.Cities.Remove(city); + } + } +} diff --git a/GigHub/GigHub/Views/Cities/Index.cshtml b/GigHub/GigHub/Views/Cities/Index.cshtml new file mode 100644 index 0000000..542a5cf --- /dev/null +++ b/GigHub/GigHub/Views/Cities/Index.cshtml @@ -0,0 +1,40 @@ +@model IEnumerable + +@{ + ViewBag.Title = "Cities"; +} + +

Cities

+ +

+ @Html.ActionLink("Create New", "Create") +

+ + + + + + + + +@foreach (var item in Model) { + + + + + +} + +
+ @Html.DisplayNameFor(model => model.Name) + + @Html.DisplayNameFor(model => model.IsPartner) +
+ @Html.DisplayFor(modelItem => item.Name) + + @Html.DisplayFor(modelItem => item.IsPartner) + + @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | + @Html.ActionLink("Details", "Details", new { id=item.Id }) | + @Html.ActionLink("Delete", "Delete", new { id=item.Id }) +
diff --git a/GigHub/GigHub/Views/Gigs/Details.cshtml b/GigHub/GigHub/Views/Gigs/Details.cshtml index 9ac7821..5d703a8 100644 --- a/GigHub/GigHub/Views/Gigs/Details.cshtml +++ b/GigHub/GigHub/Views/Gigs/Details.cshtml @@ -22,6 +22,13 @@

Address: @Model.VenueAddress

+

+ City: @Model.City +

+@if (Model.City == "PartnerCity1" || Model.City == "PartnerCity2") +{ + Partner +} @if (User.Identity.IsAuthenticated && Model.IsAttending) { diff --git a/GigHub/GigHub/Views/Gigs/GigForm.cshtml b/GigHub/GigHub/Views/Gigs/GigForm.cshtml index b3ae317..da67c01 100644 --- a/GigHub/GigHub/Views/Gigs/GigForm.cshtml +++ b/GigHub/GigHub/Views/Gigs/GigForm.cshtml @@ -1,4 +1,4 @@ -@model GigHub.Core.ViewModels.GigFormViewModel +@model GigHub.Core.ViewModels.GigFormViewModel @{ ViewBag.Title = Model.Heading; } @@ -20,6 +20,11 @@ @Html.TextBoxFor(m => m.VenueAddress, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.VenueAddress) +
+ @Html.LabelFor(m => m.City) + @Html.TextBoxFor(m => m.City, new { @class = "form-control" }) + @Html.ValidationMessageFor(m => m.City) +
@Html.LabelFor(m => m.Date) @Html.TextBoxFor(m => m.Date, new { @class = "form-control", placeholder = "eg 1 Jan 2017" }) From a22a8599f4b8af15dd85a07b8824d057818be481 Mon Sep 17 00:00:00 2001 From: Jorge Luis Censi Date: Tue, 14 Jan 2025 17:34:33 +1000 Subject: [PATCH 3/4] --- GigHub/GigHub/Controllers/API/GigsController.cs | 3 +-- GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/GigHub/GigHub/Controllers/API/GigsController.cs b/GigHub/GigHub/Controllers/API/GigsController.cs index 3bf9515..e3c7697 100644 --- a/GigHub/GigHub/Controllers/API/GigsController.cs +++ b/GigHub/GigHub/Controllers/API/GigsController.cs @@ -61,8 +61,7 @@ public IHttpActionResult PostGig(Gig gigViewModel) DateTime = gigViewModel.DateTime, GenreId = gigViewModel.GenreId, Venue = gigViewModel.Venue, - VenueAddress = gigViewModel.VenueAddress, - City = gigViewModel.City + VenueAddress = gigViewModel.VenueAddress }; _unitOfWork.Gigs.Add(gig); diff --git a/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs b/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs index f67f6a5..f0a25ef 100644 --- a/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs +++ b/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs @@ -8,6 +8,5 @@ public class GigDetailsViewModel public bool IsAttending { get; set; } public bool IsFollowing { get; set; } public string VenueAddress { get; set; } - public string City { get; set; } } } From 8f824fc61863b34fb3cd6dcdeb063e67f178fe8e Mon Sep 17 00:00:00 2001 From: Jorge Luis Censi Date: Tue, 14 Jan 2025 17:46:28 +1000 Subject: [PATCH 4/4] Add new properties and update methods to handle VenueAddress and City * **GigDetailsViewModel.cs** - Add new property `City` of type `string`. * **API/GigsController.cs** - Update `PostGig` method to handle `City` property. * **Details.cshtml** - Update logic to check if the gig is happening in a partner city and display the "Partner" badge accordingly. * **PartnerCity.cs** - Create a new class `PartnerCity` with properties `Id` and `Name`. * **PartnerCityConfiguration.cs** - Create a new configuration class `PartnerCityConfiguration` to configure the `PartnerCity` model. * **PartnerCitiesController.cs** - Create a new controller `PartnerCitiesController` to handle the `PartnerCity` model. * **Index.cshtml** - Create a new view `PartnerCities` to allow an admin to mark cities as partner. * **20230801000000_AddVenueAddressAndCityToGig.cs** - Create a new migration to update the database schema to include the `VenueAddress` and `City` properties in the `Gig` model and the `PartnerCity` model. --- .../GigHub/Controllers/API/GigsController.cs | 3 +- .../Controllers/PartnerCitiesController.cs | 93 +++++++++++++++++++ GigHub/GigHub/Core/Models/PartnerCity.cs | 8 ++ .../Core/ViewModels/GigDetailsViewModel.cs | 1 + .../PartnerCityConfiguration.cs | 15 +++ ...30801000000_AddVenueAddressAndCityToGig.cs | 29 ++++++ GigHub/GigHub/Views/Gigs/Details.cshtml | 2 +- .../GigHub/Views/PartnerCities/Index.cshtml | 33 +++++++ 8 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 GigHub/GigHub/Controllers/PartnerCitiesController.cs create mode 100644 GigHub/GigHub/Core/Models/PartnerCity.cs create mode 100644 GigHub/GigHub/Persistence/EntityConfigurations/PartnerCityConfiguration.cs create mode 100644 GigHub/GigHub/Persistence/Migrations/20230801000000_AddVenueAddressAndCityToGig.cs create mode 100644 GigHub/GigHub/Views/PartnerCities/Index.cshtml diff --git a/GigHub/GigHub/Controllers/API/GigsController.cs b/GigHub/GigHub/Controllers/API/GigsController.cs index e3c7697..3bf9515 100644 --- a/GigHub/GigHub/Controllers/API/GigsController.cs +++ b/GigHub/GigHub/Controllers/API/GigsController.cs @@ -61,7 +61,8 @@ public IHttpActionResult PostGig(Gig gigViewModel) DateTime = gigViewModel.DateTime, GenreId = gigViewModel.GenreId, Venue = gigViewModel.Venue, - VenueAddress = gigViewModel.VenueAddress + VenueAddress = gigViewModel.VenueAddress, + City = gigViewModel.City }; _unitOfWork.Gigs.Add(gig); diff --git a/GigHub/GigHub/Controllers/PartnerCitiesController.cs b/GigHub/GigHub/Controllers/PartnerCitiesController.cs new file mode 100644 index 0000000..6f09366 --- /dev/null +++ b/GigHub/GigHub/Controllers/PartnerCitiesController.cs @@ -0,0 +1,93 @@ +using GigHub.Core; +using GigHub.Core.Models; +using System.Linq; +using System.Web.Mvc; + +namespace GigHub.Controllers +{ + [Authorize(Roles = "Admin")] + public class PartnerCitiesController : Controller + { + private readonly IUnitOfWork _unitOfWork; + + public PartnerCitiesController(IUnitOfWork unitOfWork) + { + _unitOfWork = unitOfWork; + } + + public ActionResult Index() + { + var partnerCities = _unitOfWork.Cities.GetAllCities().Where(c => c.IsPartner).ToList(); + return View(partnerCities); + } + + public ActionResult Edit(int id) + { + var city = _unitOfWork.Cities.GetCity(id); + if (city == null) + return HttpNotFound(); + + return View(city); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Edit(City city) + { + if (!ModelState.IsValid) + return View(city); + + var cityInDb = _unitOfWork.Cities.GetCity(city.Id); + if (cityInDb == null) + return HttpNotFound(); + + cityInDb.Name = city.Name; + cityInDb.IsPartner = city.IsPartner; + + _unitOfWork.Complete(); + + return RedirectToAction("Index"); + } + + public ActionResult Create() + { + return View(); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Create(City city) + { + if (!ModelState.IsValid) + return View(city); + + _unitOfWork.Cities.Add(city); + _unitOfWork.Complete(); + + return RedirectToAction("Index"); + } + + public ActionResult Delete(int id) + { + var city = _unitOfWork.Cities.GetCity(id); + if (city == null) + return HttpNotFound(); + + return View(city); + } + + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public ActionResult DeleteConfirmed(int id) + { + var city = _unitOfWork.Cities.GetCity(id); + if (city == null) + return HttpNotFound(); + + _unitOfWork.Cities.Remove(city); + _unitOfWork.Complete(); + + return RedirectToAction("Index"); + } + } +} diff --git a/GigHub/GigHub/Core/Models/PartnerCity.cs b/GigHub/GigHub/Core/Models/PartnerCity.cs new file mode 100644 index 0000000..5917d07 --- /dev/null +++ b/GigHub/GigHub/Core/Models/PartnerCity.cs @@ -0,0 +1,8 @@ +namespace GigHub.Core.Models +{ + public class PartnerCity + { + public int Id { get; set; } + public string Name { get; set; } + } +} diff --git a/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs b/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs index f0a25ef..f67f6a5 100644 --- a/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs +++ b/GigHub/GigHub/Core/ViewModels/GigDetailsViewModel.cs @@ -8,5 +8,6 @@ public class GigDetailsViewModel public bool IsAttending { get; set; } public bool IsFollowing { get; set; } public string VenueAddress { get; set; } + public string City { get; set; } } } diff --git a/GigHub/GigHub/Persistence/EntityConfigurations/PartnerCityConfiguration.cs b/GigHub/GigHub/Persistence/EntityConfigurations/PartnerCityConfiguration.cs new file mode 100644 index 0000000..0f35ff8 --- /dev/null +++ b/GigHub/GigHub/Persistence/EntityConfigurations/PartnerCityConfiguration.cs @@ -0,0 +1,15 @@ +using GigHub.Core.Models; +using System.Data.Entity.ModelConfiguration; + +namespace GigHub.Persistence.EntityConfigurations +{ + public class PartnerCityConfiguration : EntityTypeConfiguration + { + public PartnerCityConfiguration() + { + Property(pc => pc.Name) + .IsRequired() + .HasMaxLength(255); + } + } +} diff --git a/GigHub/GigHub/Persistence/Migrations/20230801000000_AddVenueAddressAndCityToGig.cs b/GigHub/GigHub/Persistence/Migrations/20230801000000_AddVenueAddressAndCityToGig.cs new file mode 100644 index 0000000..e483fdf --- /dev/null +++ b/GigHub/GigHub/Persistence/Migrations/20230801000000_AddVenueAddressAndCityToGig.cs @@ -0,0 +1,29 @@ +using System; +using System.Data.Entity.Migrations; + +namespace GigHub.Persistence.Migrations +{ + public partial class AddVenueAddressAndCityToGig : DbMigration + { + public override void Up() + { + AddColumn("dbo.Gigs", "VenueAddress", c => c.String(nullable: false, maxLength: 255)); + AddColumn("dbo.Gigs", "City", c => c.String(nullable: false, maxLength: 255)); + CreateTable( + "dbo.PartnerCities", + c => new + { + Id = c.Int(nullable: false, identity: true), + Name = c.String(nullable: false, maxLength: 255), + }) + .PrimaryKey(t => t.Id); + } + + public override void Down() + { + DropTable("dbo.PartnerCities"); + DropColumn("dbo.Gigs", "City"); + DropColumn("dbo.Gigs", "VenueAddress"); + } + } +} diff --git a/GigHub/GigHub/Views/Gigs/Details.cshtml b/GigHub/GigHub/Views/Gigs/Details.cshtml index 5d703a8..1c5fec5 100644 --- a/GigHub/GigHub/Views/Gigs/Details.cshtml +++ b/GigHub/GigHub/Views/Gigs/Details.cshtml @@ -25,7 +25,7 @@

City: @Model.City

-@if (Model.City == "PartnerCity1" || Model.City == "PartnerCity2") +@if (Model.Gig.IsPartnerCity) { Partner } diff --git a/GigHub/GigHub/Views/PartnerCities/Index.cshtml b/GigHub/GigHub/Views/PartnerCities/Index.cshtml new file mode 100644 index 0000000..ee82628 --- /dev/null +++ b/GigHub/GigHub/Views/PartnerCities/Index.cshtml @@ -0,0 +1,33 @@ +@model IEnumerable + +@{ + ViewBag.Title = "Partner Cities"; +} + +

Partner Cities

+ +

+ @Html.ActionLink("Create New", "Create") +

+ + + + + + + +@foreach (var item in Model) { + + + + +} + +
+ @Html.DisplayNameFor(model => model.Name) +
+ @Html.DisplayFor(modelItem => item.Name) + + @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | + @Html.ActionLink("Delete", "Delete", new { id=item.Id }) +