From 3a8f2949b27da1fb9170939086a771a7fee6982e Mon Sep 17 00:00:00 2001 From: Tara Wilson Date: Mon, 2 Dec 2024 20:21:55 -0500 Subject: [PATCH] Adding Event Management Fixing Bugs Building out UI --- .../api/Controllers/EventController.cs | 59 +++++++++++++++++++ .../api/Controllers/TicketController.cs | 51 +++++++++------- .../api/IServiceCollectionExtensions.cs | 1 + .../ticketAPI/api/Interfaces/IEventManager.cs | 11 ++++ source/ticketAPI/api/Program.cs | 5 ++ source/ticketAPI/api/RestFiles/event.http | 50 ++++++++++++++++ source/ticketAPI/api/RestFiles/ticket.http | 3 +- source/ticketAPI/api/Services/EventManager.cs | 34 +++++++++++ .../ticketAPI/api/Services/TicketManager.cs | 5 +- source/ticketAPI/data/Events/GetInDates.cs | 19 ++++++ source/ticketAPI/data/Events/Save.cs | 14 +++++ source/ticketAPI/data/Events/Update.cs | 28 +++++++++ source/ticketAPI/data/MongoFactory.cs | 40 +++++++++++++ source/ticketAPI/data/Tickets/Save.cs | 14 +++++ source/ticketAPI/data/Tickets/SaveTicket.cs | 22 ------- source/ticketAPI/models/Core/Talent.cs | 2 - source/ticketAPI/models/Core/Venue.cs | 8 +-- source/ticketAPI/models/Request/AddEvent.cs | 12 ++++ .../ticketAPI/models/Request/EventSearch.cs | 7 +++ source/ticketAPI/models/Request/PatchEvent.cs | 13 ++++ source/ticketUI/src/app/app.component.html | 13 ++-- source/ticketUI/src/app/app.component.scss | 25 ++++++++ source/ticketUI/src/app/app.routes.ts | 17 +++++- .../app/page/debug/debug.component.spec.ts | 23 -------- .../src/app/page/debug/debug.component.ts | 2 +- .../src/app/page/event/event.component.html | 1 + .../src/app/page/event/event.component.scss | 0 .../src/app/page/event/event.component.ts | 11 ++++ .../src/app/page/scan/scan.component.html | 1 + .../src/app/page/scan/scan.component.scss | 0 .../src/app/page/scan/scan.component.ts | 11 ++++ .../src/app/page/ticket/ticket.component.html | 1 + .../src/app/page/ticket/ticket.component.scss | 0 .../src/app/page/ticket/ticket.component.ts | 11 ++++ source/ticketUI/src/app/services/api-utils.ts | 31 ++++++++++ .../src/app/services/event.service.ts | 48 +++++++++++++++ .../src/app/services/ticket.service.ts | 47 ++++----------- .../src/app/sidebar/sidebar.component.html | 8 +-- .../src/app/sidebar/sidebar.component.scss | 17 ++++++ .../src/app/sidebar/sidebar.component.spec.ts | 23 -------- source/ticketUI/src/models/core/talent.ts | 4 ++ source/ticketUI/src/models/core/venue.ts | 9 +++ source/ticketUI/src/models/endpoints.ts | 3 +- .../src/models/request/add-event-request.ts | 10 ++++ 44 files changed, 562 insertions(+), 152 deletions(-) create mode 100644 source/ticketAPI/api/Controllers/EventController.cs create mode 100644 source/ticketAPI/api/Interfaces/IEventManager.cs create mode 100644 source/ticketAPI/api/RestFiles/event.http create mode 100644 source/ticketAPI/api/Services/EventManager.cs create mode 100644 source/ticketAPI/data/Events/GetInDates.cs create mode 100644 source/ticketAPI/data/Events/Save.cs create mode 100644 source/ticketAPI/data/Events/Update.cs create mode 100644 source/ticketAPI/data/MongoFactory.cs create mode 100644 source/ticketAPI/data/Tickets/Save.cs delete mode 100644 source/ticketAPI/data/Tickets/SaveTicket.cs create mode 100644 source/ticketAPI/models/Request/AddEvent.cs create mode 100644 source/ticketAPI/models/Request/EventSearch.cs create mode 100644 source/ticketAPI/models/Request/PatchEvent.cs delete mode 100644 source/ticketUI/src/app/page/debug/debug.component.spec.ts create mode 100644 source/ticketUI/src/app/page/event/event.component.html create mode 100644 source/ticketUI/src/app/page/event/event.component.scss create mode 100644 source/ticketUI/src/app/page/event/event.component.ts create mode 100644 source/ticketUI/src/app/page/scan/scan.component.html create mode 100644 source/ticketUI/src/app/page/scan/scan.component.scss create mode 100644 source/ticketUI/src/app/page/scan/scan.component.ts create mode 100644 source/ticketUI/src/app/page/ticket/ticket.component.html create mode 100644 source/ticketUI/src/app/page/ticket/ticket.component.scss create mode 100644 source/ticketUI/src/app/page/ticket/ticket.component.ts create mode 100644 source/ticketUI/src/app/services/api-utils.ts create mode 100644 source/ticketUI/src/app/services/event.service.ts delete mode 100644 source/ticketUI/src/app/sidebar/sidebar.component.spec.ts create mode 100644 source/ticketUI/src/models/core/talent.ts create mode 100644 source/ticketUI/src/models/core/venue.ts create mode 100644 source/ticketUI/src/models/request/add-event-request.ts diff --git a/source/ticketAPI/api/Controllers/EventController.cs b/source/ticketAPI/api/Controllers/EventController.cs new file mode 100644 index 0000000..6f01234 --- /dev/null +++ b/source/ticketAPI/api/Controllers/EventController.cs @@ -0,0 +1,59 @@ +using api.Interfaces; +using Microsoft.AspNetCore.Mvc; +using models.Request; + +namespace api.Controllers; + +/// +/// Endpoints for Event Management +/// +/// +[ApiController] +[Route("[controller]")] +public class EventController(IEventManager eventManager) : ControllerBase +{ + [HttpPost] + public ActionResult Post([FromBody] AddEvent request) + { + //TODO: Protect Endpoint + + try + { + eventManager.AddEvent(request); + return Ok(); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + [HttpPatch] + public ActionResult Patch([FromBody] PatchEvent request) + { + //TODO: Protect Endpoint + + try + { + eventManager.PatchEvent(request); + return Ok(); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + [HttpGet("{startDate}/{endDate}")] + public ActionResult Get([FromRoute] DateTime startDate, DateTime endDate) + { + try + { + return Ok(eventManager.GetEvents(startDate, endDate)); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } +} \ No newline at end of file diff --git a/source/ticketAPI/api/Controllers/TicketController.cs b/source/ticketAPI/api/Controllers/TicketController.cs index 00e1a27..5c1249c 100644 --- a/source/ticketAPI/api/Controllers/TicketController.cs +++ b/source/ticketAPI/api/Controllers/TicketController.cs @@ -7,7 +7,7 @@ using models.Response; namespace api.Controllers; /// -/// Endpoints for Qr Code Generation +/// Endpoints for Ticket Management /// /// Injected QR Code Service /// Injected Ticket Manager Service @@ -18,38 +18,45 @@ public class TicketController( ITicketManager ticketManager) : ControllerBase { /// - /// Generates a Base64 String Qr Code + /// Generates a Base64 String Qr Code and Saves Qr Code and Ticket to DB /// /// Base64 String Qr Code - [HttpPost("mint")] - public ActionResult MintTicket([FromBody] MintTickets mintRequest) + [HttpPost] + public ActionResult AddTicket([FromBody] MintTickets mintRequest) { //TODO: Protect Endpoint //generate ticket id var ticketId = Guid.NewGuid(); - //generate the qr code - var qrCode = qr.GenerateQrCode(ticketId.ToString()); - - //build the ticket - var ticket = new Ticket + try { - Id = Guid.NewGuid(), - QrCode = qrCode, - Type = mintRequest.Type, - }; + //generate the qr code + var qrCode = qr.GenerateQrCode(ticketId.ToString()); - //save the minted ticket - ticketManager.SaveMintedTicket(ticket); + //build the ticket + var ticket = new Ticket + { + Id = ticketId, + QrCode = qrCode, + Type = mintRequest.Type, + }; - //return - var response = new MintResponse + //save the minted ticket + ticketManager.SaveMintedTicket(ticket); + + //return + var response = new MintResponse + { + QrCode = ticket.QrCode, + Type = ticket.Type + }; + + return Ok(response); + } + catch (Exception e) { - QrCode = ticket.QrCode, - Type = ticket.Type - }; - - return Ok(response); + return BadRequest(e.Message); + } } } \ No newline at end of file diff --git a/source/ticketAPI/api/IServiceCollectionExtensions.cs b/source/ticketAPI/api/IServiceCollectionExtensions.cs index 1d5c6d0..8d0f5f1 100644 --- a/source/ticketAPI/api/IServiceCollectionExtensions.cs +++ b/source/ticketAPI/api/IServiceCollectionExtensions.cs @@ -9,5 +9,6 @@ public static class ServiceCollectionExtensions { services.AddScoped(); services.AddScoped(); + services.AddScoped(); } } \ No newline at end of file diff --git a/source/ticketAPI/api/Interfaces/IEventManager.cs b/source/ticketAPI/api/Interfaces/IEventManager.cs new file mode 100644 index 0000000..87b130b --- /dev/null +++ b/source/ticketAPI/api/Interfaces/IEventManager.cs @@ -0,0 +1,11 @@ +using models.Core; +using models.Request; + +namespace api.Interfaces; + +public interface IEventManager +{ + void AddEvent(AddEvent request); + void PatchEvent(PatchEvent request); + List GetEvents(DateTime startDate, DateTime endDate); +} \ No newline at end of file diff --git a/source/ticketAPI/api/Program.cs b/source/ticketAPI/api/Program.cs index e3f5a1c..85c13be 100644 --- a/source/ticketAPI/api/Program.cs +++ b/source/ticketAPI/api/Program.cs @@ -1,4 +1,5 @@ using api; +using data; var builder = WebApplication.CreateBuilder(args); @@ -23,4 +24,8 @@ app.UseHttpsRedirection(); app.UseCors("AllowOrigin"); app.UseAuthorization(); app.MapControllers(); + +//Inject config into Mongo DB Factory +MongoFactory.InitConfig(app.Configuration); + app.Run(); \ No newline at end of file diff --git a/source/ticketAPI/api/RestFiles/event.http b/source/ticketAPI/api/RestFiles/event.http new file mode 100644 index 0000000..cadb4ba --- /dev/null +++ b/source/ticketAPI/api/RestFiles/event.http @@ -0,0 +1,50 @@ +@api_HostAddress = http://localhost:5168 + +POST {{api_HostAddress}}/event +Accept: application/json +Content-Type: application/json + +{ + "Date": "2024-12-02T15:00:00.991Z", + "EventName": "Winter Concert", + "EventDescription": "A wintery journey of classical music", + "Venue": { + "Name": "Valley Forge High School", + "Description": "Auditorium", + "AddressOne": "9999 Independence Blvd", + "AddressTwo": null, + "City": "Parma", + "State": "Ohio", + "Zip": "44130" + }, + "Talent": { + "Name": "Parma Symphony Orchestra", + "Description": "Parma Symphony Orchestra is a Northeast Ohio community orchestra with over 50 years of history bringing classical music to people of all ages, with opportunities for local students and professional guests to perform a wide ranging repertoire." + } +} + +### + +PATCH {{api_HostAddress}}/Event +Accept: application/json +Content-Type: application/json + +{ + "Id": "1a06c032-b073-4715-9b95-9f3410e7abd9", + "Date": "2024-12-03T15:00:00.991Z", + "EventName": "Winter Concert", + "EventDescription": "A wintery journey of classical music", + "Venue": { + "Name": "Valley Forge High School", + "Description": "Auditorium", + "AddressOne": "9999 Independence Blvd", + "AddressTwo": null, + "City": "Parma", + "State": "Ohio", + "Zip": "44130" + }, + "Talent": { + "Name": "Parma Symphony Orchestra", + "Description": "Parma Symphony Orchestra is a Northeast Ohio community orchestra with over 50 years of history bringing classical music to people of all ages, with opportunities for local students and professional guests to perform a wide ranging repertoire." + } +} \ No newline at end of file diff --git a/source/ticketAPI/api/RestFiles/ticket.http b/source/ticketAPI/api/RestFiles/ticket.http index edcd880..4510c18 100644 --- a/source/ticketAPI/api/RestFiles/ticket.http +++ b/source/ticketAPI/api/RestFiles/ticket.http @@ -1,7 +1,8 @@ @api_HostAddress = http://localhost:5168 -POST {{api_HostAddress}}/ticket/mint +POST {{api_HostAddress}}/ticket Accept: application/json +Content-Type: application/json { "ticketType": "Single" diff --git a/source/ticketAPI/api/Services/EventManager.cs b/source/ticketAPI/api/Services/EventManager.cs new file mode 100644 index 0000000..017c917 --- /dev/null +++ b/source/ticketAPI/api/Services/EventManager.cs @@ -0,0 +1,34 @@ +using api.Interfaces; +using data.Events; +using models.Core; +using models.Request; + +namespace api.Services; + +public class EventManager : IEventManager +{ + public void AddEvent(AddEvent request) + { + var @event = new Event + { + Id = Guid.NewGuid(), + EventDescription = request.EventDescription, + EventName = request.EventName, + Date = request.Date, + Talent = request.Talent, + Venue = request.Venue + }; + + new Save().Execute(@event); + } + + public void PatchEvent(PatchEvent request) + { + new Update().Execute(request); + } + + public List GetEvents(DateTime startDate, DateTime endDate) + { + return new GetInDates().Execute(startDate, endDate); + } +} \ No newline at end of file diff --git a/source/ticketAPI/api/Services/TicketManager.cs b/source/ticketAPI/api/Services/TicketManager.cs index 0325c91..3e8036e 100644 --- a/source/ticketAPI/api/Services/TicketManager.cs +++ b/source/ticketAPI/api/Services/TicketManager.cs @@ -4,11 +4,10 @@ using models.Core; namespace api.Services; -public class TicketManager(IConfiguration config) : ITicketManager +public class TicketManager : ITicketManager { public void SaveMintedTicket(Ticket ticket) { - var db = new Save(config); - db.Execute(ticket); + new Save().Execute(ticket); } } \ No newline at end of file diff --git a/source/ticketAPI/data/Events/GetInDates.cs b/source/ticketAPI/data/Events/GetInDates.cs new file mode 100644 index 0000000..1840046 --- /dev/null +++ b/source/ticketAPI/data/Events/GetInDates.cs @@ -0,0 +1,19 @@ +using models.Core; +using models.Request; +using MongoDB.Driver; + +namespace data.Events; + +public class GetInDates +{ + public List Execute(DateTime startDate, DateTime endDate) + { + var database = MongoFactory.GetDatabase(); + var collection = database.GetCollection("events"); + + return collection.Find(x => + startDate <= x.Date + && x.Date <= endDate + ).ToList(); + } +} \ No newline at end of file diff --git a/source/ticketAPI/data/Events/Save.cs b/source/ticketAPI/data/Events/Save.cs new file mode 100644 index 0000000..01dbf2f --- /dev/null +++ b/source/ticketAPI/data/Events/Save.cs @@ -0,0 +1,14 @@ +using models.Core; + +namespace data.Events; + +public class Save +{ + public void Execute(Event @event) + { + var database = MongoFactory.GetDatabase(); + var collection = database.GetCollection("events"); + + collection.InsertOne(@event); + } +} \ No newline at end of file diff --git a/source/ticketAPI/data/Events/Update.cs b/source/ticketAPI/data/Events/Update.cs new file mode 100644 index 0000000..3e5c2d4 --- /dev/null +++ b/source/ticketAPI/data/Events/Update.cs @@ -0,0 +1,28 @@ +using models.Core; +using models.Request; +using MongoDB.Driver; + +namespace data.Events; + +public class Update +{ + public bool Execute(PatchEvent request) + { + var database = MongoFactory.GetDatabase(); + var collection = database.GetCollection("events"); + + var filter = Builders.Filter.Eq(e => e.Id, request.Id); + + var newEvent = new Event + { + Id = request.Id, + Date = request.Date, + EventName = request.EventName, + EventDescription = request.EventDescription, + Venue = request.Venue, + Talent = request.Talent, + }; + + return collection.ReplaceOne(filter, newEvent).IsAcknowledged; + } +} \ No newline at end of file diff --git a/source/ticketAPI/data/MongoFactory.cs b/source/ticketAPI/data/MongoFactory.cs new file mode 100644 index 0000000..2e6ab44 --- /dev/null +++ b/source/ticketAPI/data/MongoFactory.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.Configuration; +using MongoDB.Driver; + +namespace data; + +public static class MongoFactory +{ + private static IConfiguration? _config; + + /// + /// Sets up the configuration, must be called before using GetDatabase() + /// + /// + public static void InitConfig(IConfiguration config) + { + _config = config; + } + + /// + /// Sets up the connection to Mongo and returns the database from Configuration + /// + /// + /// + /// + public static IMongoDatabase GetDatabase() + { + if (_config == null) + { + throw new NullReferenceException("Configuration is not set"); + } + + if (String.IsNullOrEmpty(_config.GetSection("Mongo:ConnectionString").Value)) + { + throw new Exception("No MongoDB connection string"); + } + + var client = new MongoClient(_config.GetSection("Mongo:ConnectionString").Value); + return client.GetDatabase(_config.GetSection("Mongo:Database").Value); + } +} \ No newline at end of file diff --git a/source/ticketAPI/data/Tickets/Save.cs b/source/ticketAPI/data/Tickets/Save.cs new file mode 100644 index 0000000..2ab14a1 --- /dev/null +++ b/source/ticketAPI/data/Tickets/Save.cs @@ -0,0 +1,14 @@ +using models.Core; + +namespace data.Tickets; + +public class Save +{ + public void Execute(Ticket ticket) + { + var database = MongoFactory.GetDatabase(); + var collection = database.GetCollection("tickets"); + + collection.InsertOne(ticket); + } +} \ No newline at end of file diff --git a/source/ticketAPI/data/Tickets/SaveTicket.cs b/source/ticketAPI/data/Tickets/SaveTicket.cs deleted file mode 100644 index 9e92eaf..0000000 --- a/source/ticketAPI/data/Tickets/SaveTicket.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.Extensions.Configuration; -using models.Core; -using MongoDB.Driver; - -namespace data.Tickets; - -public class Save(IConfiguration config) -{ - public void Execute(Ticket ticket) - { - if (String.IsNullOrEmpty(config.GetSection("Mongo:ConnectionString").Value)) - { - throw new Exception("No MongoDB connection string"); - } - - var client = new MongoClient(config.GetSection("Mongo:ConnectionString").Value); - var database = client.GetDatabase(config.GetSection("Mongo:Database").Value); - var collection = database.GetCollection("tickets"); - - collection.InsertOne(ticket); - } -} \ No newline at end of file diff --git a/source/ticketAPI/models/Core/Talent.cs b/source/ticketAPI/models/Core/Talent.cs index 1bf1337..4403510 100644 --- a/source/ticketAPI/models/Core/Talent.cs +++ b/source/ticketAPI/models/Core/Talent.cs @@ -5,8 +5,6 @@ namespace models.Core; public class Talent { - [BsonGuidRepresentation(GuidRepresentation.Standard)] - public Guid Id { get; set; } public required string Name { get; set; } public string? Description { get; set; } } \ No newline at end of file diff --git a/source/ticketAPI/models/Core/Venue.cs b/source/ticketAPI/models/Core/Venue.cs index e391fa4..e250d95 100644 --- a/source/ticketAPI/models/Core/Venue.cs +++ b/source/ticketAPI/models/Core/Venue.cs @@ -1,15 +1,11 @@ -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; - namespace models.Core; public class Venue { - [BsonGuidRepresentation(GuidRepresentation.Standard)] - public Guid Id { get; set; } public required string Name { get; set; } public string? Description { get; set; } - public List Address { get; set; } = []; + public required string AddressOne { get; set; } + public string? AddressTwo { get; set; } public required string City { get; set; } public required string State { get; set; } public required string Zip { get; set; } diff --git a/source/ticketAPI/models/Request/AddEvent.cs b/source/ticketAPI/models/Request/AddEvent.cs new file mode 100644 index 0000000..7910e06 --- /dev/null +++ b/source/ticketAPI/models/Request/AddEvent.cs @@ -0,0 +1,12 @@ +using models.Core; + +namespace models.Request; + +public class AddEvent +{ + public DateTime Date { get; set; } + public required string EventName { get; set; } + public string? EventDescription { get; set; } + public required Venue Venue { get; set; } + public required Talent Talent { get; set; } +} \ No newline at end of file diff --git a/source/ticketAPI/models/Request/EventSearch.cs b/source/ticketAPI/models/Request/EventSearch.cs new file mode 100644 index 0000000..2fbb12d --- /dev/null +++ b/source/ticketAPI/models/Request/EventSearch.cs @@ -0,0 +1,7 @@ +namespace models.Request; + +public class EventSearch +{ + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } +} \ No newline at end of file diff --git a/source/ticketAPI/models/Request/PatchEvent.cs b/source/ticketAPI/models/Request/PatchEvent.cs new file mode 100644 index 0000000..aa446f3 --- /dev/null +++ b/source/ticketAPI/models/Request/PatchEvent.cs @@ -0,0 +1,13 @@ +using models.Core; + +namespace models.Request; + +public class PatchEvent +{ + public Guid Id { get; set; } + public DateTime Date { get; set; } + public required string EventName { get; set; } + public string? EventDescription { get; set; } + public required Venue Venue { get; set; } + public required Talent Talent { get; set; } +} \ No newline at end of file diff --git a/source/ticketUI/src/app/app.component.html b/source/ticketUI/src/app/app.component.html index 0694ce4..4ead765 100644 --- a/source/ticketUI/src/app/app.component.html +++ b/source/ticketUI/src/app/app.component.html @@ -1,8 +1,7 @@ -
-
- -
-
- -
+
+
+
+ +
+ diff --git a/source/ticketUI/src/app/app.component.scss b/source/ticketUI/src/app/app.component.scss index e69de29..586e9a8 100644 --- a/source/ticketUI/src/app/app.component.scss +++ b/source/ticketUI/src/app/app.component.scss @@ -0,0 +1,25 @@ +/* The sidebar menu */ +.sidenav { + height: 100%; /* Full-height: remove this if you want "auto" height */ + width: 120px; /* Set the width of the sidebar */ + position: fixed; /* Fixed Sidebar (stay in place on scroll) */ + z-index: 1; /* Stay on top */ + top: 0; /* Stay at the top */ + left: 0; + backdrop-filter: blur(25px) saturate(112%); + -webkit-backdrop-filter: blur(25px) saturate(112%); + background-color: rgba(255, 255, 255, 0.11); + overflow-x: hidden; /* Disable horizontal scroll */ +} + +/* Style page content */ +.main { + margin-left: 120px; /* Same as the width of the sidebar */ + padding: 0px 10px; +} + +/* On smaller screens, where height is less than 450px, change the style of the sidebar (less padding and a smaller font size) */ +@media screen and (max-height: 450px) { + .sidenav {} + .sidenav a {font-size: 18px;} +} diff --git a/source/ticketUI/src/app/app.routes.ts b/source/ticketUI/src/app/app.routes.ts index fa11451..c549f80 100644 --- a/source/ticketUI/src/app/app.routes.ts +++ b/source/ticketUI/src/app/app.routes.ts @@ -1,9 +1,24 @@ -import { Routes } from '@angular/router'; +import {Routes} from '@angular/router'; import {DebugComponent} from './page/debug/debug.component'; +import {EventComponent} from './page/event/event.component'; +import {TicketComponent} from './page/ticket/ticket.component'; +import {ScanComponent} from './page/scan/scan.component'; export const routes: Routes = [ { path: 'debug', component: DebugComponent + }, + { + path: 'event', + component: EventComponent + }, + { + path: 'ticket', + component: TicketComponent + }, + { + path: 'scan', + component: ScanComponent } ]; diff --git a/source/ticketUI/src/app/page/debug/debug.component.spec.ts b/source/ticketUI/src/app/page/debug/debug.component.spec.ts deleted file mode 100644 index 38528ea..0000000 --- a/source/ticketUI/src/app/page/debug/debug.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { DebugComponent } from './debug.component'; - -describe('DebugComponent', () => { - let component: DebugComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [DebugComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(DebugComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/source/ticketUI/src/app/page/debug/debug.component.ts b/source/ticketUI/src/app/page/debug/debug.component.ts index af85c93..d0b5515 100644 --- a/source/ticketUI/src/app/page/debug/debug.component.ts +++ b/source/ticketUI/src/app/page/debug/debug.component.ts @@ -20,6 +20,6 @@ export class DebugComponent { ticketType: TicketTypeEnum.Single }; - this.ticketMinter.mintTicket(mintRequest); + this.ticketMinter.addTicket(mintRequest); } } diff --git a/source/ticketUI/src/app/page/event/event.component.html b/source/ticketUI/src/app/page/event/event.component.html new file mode 100644 index 0000000..8a7c90c --- /dev/null +++ b/source/ticketUI/src/app/page/event/event.component.html @@ -0,0 +1 @@ +

event works!

diff --git a/source/ticketUI/src/app/page/event/event.component.scss b/source/ticketUI/src/app/page/event/event.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/source/ticketUI/src/app/page/event/event.component.ts b/source/ticketUI/src/app/page/event/event.component.ts new file mode 100644 index 0000000..ee6181f --- /dev/null +++ b/source/ticketUI/src/app/page/event/event.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-event', + imports: [], + templateUrl: './event.component.html', + styleUrl: './event.component.scss' +}) +export class EventComponent { + +} diff --git a/source/ticketUI/src/app/page/scan/scan.component.html b/source/ticketUI/src/app/page/scan/scan.component.html new file mode 100644 index 0000000..c706b4d --- /dev/null +++ b/source/ticketUI/src/app/page/scan/scan.component.html @@ -0,0 +1 @@ +

scan works!

diff --git a/source/ticketUI/src/app/page/scan/scan.component.scss b/source/ticketUI/src/app/page/scan/scan.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/source/ticketUI/src/app/page/scan/scan.component.ts b/source/ticketUI/src/app/page/scan/scan.component.ts new file mode 100644 index 0000000..c92f5c0 --- /dev/null +++ b/source/ticketUI/src/app/page/scan/scan.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-scan', + imports: [], + templateUrl: './scan.component.html', + styleUrl: './scan.component.scss' +}) +export class ScanComponent { + +} diff --git a/source/ticketUI/src/app/page/ticket/ticket.component.html b/source/ticketUI/src/app/page/ticket/ticket.component.html new file mode 100644 index 0000000..9d31e5c --- /dev/null +++ b/source/ticketUI/src/app/page/ticket/ticket.component.html @@ -0,0 +1 @@ +

ticket works!

diff --git a/source/ticketUI/src/app/page/ticket/ticket.component.scss b/source/ticketUI/src/app/page/ticket/ticket.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/source/ticketUI/src/app/page/ticket/ticket.component.ts b/source/ticketUI/src/app/page/ticket/ticket.component.ts new file mode 100644 index 0000000..9a2e826 --- /dev/null +++ b/source/ticketUI/src/app/page/ticket/ticket.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-ticket', + imports: [], + templateUrl: './ticket.component.html', + styleUrl: './ticket.component.scss' +}) +export class TicketComponent { + +} diff --git a/source/ticketUI/src/app/services/api-utils.ts b/source/ticketUI/src/app/services/api-utils.ts new file mode 100644 index 0000000..6599bde --- /dev/null +++ b/source/ticketUI/src/app/services/api-utils.ts @@ -0,0 +1,31 @@ +import {HttpHeaders, HttpParams} from '@angular/common/http'; + +export class ApiUtils { + public setHttpRequestOptions(params?: any): any { + let headers: HttpHeaders = new HttpHeaders(); + headers = headers.set('Content-Type', 'application/json'); + + const options: any = { + headers, + observe: 'response' + }; + + if (params) { + options.params = this.setHttpParams(params); + } + + return options; + } + + private setHttpParams(query: object): HttpParams { + const params = new HttpParams(); + for (const key in query) { + // @ts-ignore + if (query[key] && query.hasOwnProperty(key)) { + // @ts-ignore + params.append(key, query[key]); + } + } + return params; + } +} diff --git a/source/ticketUI/src/app/services/event.service.ts b/source/ticketUI/src/app/services/event.service.ts new file mode 100644 index 0000000..1cbc82b --- /dev/null +++ b/source/ticketUI/src/app/services/event.service.ts @@ -0,0 +1,48 @@ +import {inject, Injectable} from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {AddEventRequest} from '../../models/request/add-event-request'; +import {ApiUtils} from './api-utils'; +import {environment} from '../../environments/environment'; +import {Endpoints} from '../../models/endpoints'; +import {catchError, of} from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class EventService extends ApiUtils { + private httpClient = inject(HttpClient); + + constructor() { + super(); + } + + public addEvent(request: AddEventRequest): void { + //TODO: Remove hard coded venue and talent information + + request.talent = { + name: 'Parma Symphony Orchestra', + description: 'Parma Symphony Orchestra is a Northeast Ohio community orchestra with over 50 years of history bringing classical music to people of all ages, with opportunities for local students and professional guests to perform a wide ranging repertoire.', + }; + + request.venue = { + name: 'Valley Forge High School', + description: 'Auditorium', + addressOne: '9999 Independence Blvd', + addressTwo: null, + city: 'Parma', + state: 'Ohio', + zip: '44130' + }; + + const options = this.setHttpRequestOptions(); + const url = environment.apiBase + Endpoints.EVENT; + + this.httpClient.post(url, JSON.stringify(request), options) + .pipe( + catchError(error => { + console.log(error); + return of(undefined); + }) + ).subscribe(); + } +} diff --git a/source/ticketUI/src/app/services/ticket.service.ts b/source/ticketUI/src/app/services/ticket.service.ts index fdeb062..841e9b3 100644 --- a/source/ticketUI/src/app/services/ticket.service.ts +++ b/source/ticketUI/src/app/services/ticket.service.ts @@ -1,24 +1,27 @@ -import {Injectable} from '@angular/core'; -import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; +import {inject, Injectable} from '@angular/core'; +import {HttpClient} from '@angular/common/http'; import {signal} from '@angular/core'; import {catchError, map, of} from 'rxjs'; import {environment} from '../../environments/environment'; import {MintResponse} from '../../models/response/mint-response'; import {Endpoints} from '../../models/endpoints'; import {MintRequest} from '../../models/request/mint-request'; +import {ApiUtils} from './api-utils'; @Injectable({ providedIn: 'root' }) -export class TicketService { +export class TicketService extends ApiUtils { public dataSignal = signal(''); + private httpClient = inject(HttpClient); - constructor(public httpClient: HttpClient) { + constructor() { + super(); } - public mintTicket(request: MintRequest): void { - const options = this.setHttpRequestOptions(); - const url = environment.apiBase + Endpoints.MINT_TICKETS; + public addTicket(request: MintRequest): void { + const options = this.setHttpRequestOptions(); + const url = environment.apiBase + Endpoints.TICKET; this.httpClient.post(url, JSON.stringify(request), options) .pipe( @@ -31,34 +34,6 @@ export class TicketService { if (res !== undefined) { this.dataSignal.set(res.qrCode); } - }) - } - - private setHttpRequestOptions(params?: any): any { - let headers: HttpHeaders = new HttpHeaders(); - headers = headers.set('Content-Type', 'application/json'); - - const options: any = { - headers, - observe: 'response' - }; - - if (params) { - options.params = this.setHttpParams(params); - } - - return options; - } - - private setHttpParams(query: object): HttpParams { - const params = new HttpParams(); - for (const key in query) { - // @ts-ignore - if (query[key] && query.hasOwnProperty(key)) { - // @ts-ignore - params.append(key, query[key]); - } - } - return params; + }); } } diff --git a/source/ticketUI/src/app/sidebar/sidebar.component.html b/source/ticketUI/src/app/sidebar/sidebar.component.html index 9e99c43..73f7142 100644 --- a/source/ticketUI/src/app/sidebar/sidebar.component.html +++ b/source/ticketUI/src/app/sidebar/sidebar.component.html @@ -1,8 +1,8 @@
- - - + + + @if(!environment.production) { - + }
diff --git a/source/ticketUI/src/app/sidebar/sidebar.component.scss b/source/ticketUI/src/app/sidebar/sidebar.component.scss index e69de29..3ca0c17 100644 --- a/source/ticketUI/src/app/sidebar/sidebar.component.scss +++ b/source/ticketUI/src/app/sidebar/sidebar.component.scss @@ -0,0 +1,17 @@ +.sidebar-button { + margin: 5px; + padding: 5px; + backdrop-filter: blur(25px) saturate(112%); + -webkit-backdrop-filter: blur(25px) saturate(112%); + background-color: rgba(255, 255, 255, 0.11); + border: 1px solid rgba(255, 255, 255, 0.125); + border-radius: 8px; + + &:hover { + background-color: rgba(255, 255, 255, 0.0); + } + + &:active { + background-color: rgba(255, 255, 255, 0.25); + } +} diff --git a/source/ticketUI/src/app/sidebar/sidebar.component.spec.ts b/source/ticketUI/src/app/sidebar/sidebar.component.spec.ts deleted file mode 100644 index 5445f3c..0000000 --- a/source/ticketUI/src/app/sidebar/sidebar.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { SidebarComponent } from './sidebar.component'; - -describe('SidebarComponent', () => { - let component: SidebarComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [SidebarComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(SidebarComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/source/ticketUI/src/models/core/talent.ts b/source/ticketUI/src/models/core/talent.ts new file mode 100644 index 0000000..b843a8e --- /dev/null +++ b/source/ticketUI/src/models/core/talent.ts @@ -0,0 +1,4 @@ +export interface Talent { + name: string; + description: string; +} diff --git a/source/ticketUI/src/models/core/venue.ts b/source/ticketUI/src/models/core/venue.ts new file mode 100644 index 0000000..bf9cfff --- /dev/null +++ b/source/ticketUI/src/models/core/venue.ts @@ -0,0 +1,9 @@ +export interface Venue { + name: string, + description: string, + addressOne: string, + addressTwo: string | null, + city: string, + state: string, + zip: string, +} diff --git a/source/ticketUI/src/models/endpoints.ts b/source/ticketUI/src/models/endpoints.ts index 56d6f00..a315e8e 100644 --- a/source/ticketUI/src/models/endpoints.ts +++ b/source/ticketUI/src/models/endpoints.ts @@ -1,4 +1,5 @@ export class Endpoints { public static readonly TICKET = 'ticket'; - public static readonly MINT_TICKETS = Endpoints.TICKET + '/mint' + + public static readonly EVENT = 'events'; } diff --git a/source/ticketUI/src/models/request/add-event-request.ts b/source/ticketUI/src/models/request/add-event-request.ts new file mode 100644 index 0000000..65a5410 --- /dev/null +++ b/source/ticketUI/src/models/request/add-event-request.ts @@ -0,0 +1,10 @@ +import {Venue} from '../core/venue'; +import {Talent} from '../core/talent'; + +export interface AddEventRequest { + date: Date, + eventName: string, + eventDescription: string, + venue: Venue, + talent: Talent, +}