Adding Event Management
Fixing Bugs Building out UI
This commit is contained in:
parent
3bb86da5c0
commit
3a8f2949b2
59
source/ticketAPI/api/Controllers/EventController.cs
Normal file
59
source/ticketAPI/api/Controllers/EventController.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
using api.Interfaces;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using models.Request;
|
||||
|
||||
namespace api.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoints for Event Management
|
||||
/// </summary>
|
||||
/// <param name="eventManager"></param>
|
||||
[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ using models.Response;
|
|||
namespace api.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoints for Qr Code Generation
|
||||
/// Endpoints for Ticket Management
|
||||
/// </summary>
|
||||
/// <param name="qr">Injected QR Code Service</param>
|
||||
/// <param name="ticketManager">Injected Ticket Manager Service</param>
|
||||
|
|
@ -18,24 +18,26 @@ public class TicketController(
|
|||
ITicketManager ticketManager) : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a Base64 String Qr Code
|
||||
/// Generates a Base64 String Qr Code and Saves Qr Code and Ticket to DB
|
||||
/// </summary>
|
||||
/// <returns>Base64 String Qr Code</returns>
|
||||
[HttpPost("mint")]
|
||||
public ActionResult<MintResponse> MintTicket([FromBody] MintTickets mintRequest)
|
||||
[HttpPost]
|
||||
public ActionResult<MintResponse> AddTicket([FromBody] MintTickets mintRequest)
|
||||
{
|
||||
//TODO: Protect Endpoint
|
||||
|
||||
//generate ticket id
|
||||
var ticketId = Guid.NewGuid();
|
||||
|
||||
try
|
||||
{
|
||||
//generate the qr code
|
||||
var qrCode = qr.GenerateQrCode(ticketId.ToString());
|
||||
|
||||
//build the ticket
|
||||
var ticket = new Ticket
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Id = ticketId,
|
||||
QrCode = qrCode,
|
||||
Type = mintRequest.Type,
|
||||
};
|
||||
|
|
@ -52,4 +54,9 @@ public class TicketController(
|
|||
|
||||
return Ok(response);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return BadRequest(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,5 +9,6 @@ public static class ServiceCollectionExtensions
|
|||
{
|
||||
services.AddScoped<IQrCodeGenerator, QrCodeGenerator>();
|
||||
services.AddScoped<ITicketManager, TicketManager>();
|
||||
services.AddScoped<IEventManager, EventManager>();
|
||||
}
|
||||
}
|
||||
11
source/ticketAPI/api/Interfaces/IEventManager.cs
Normal file
11
source/ticketAPI/api/Interfaces/IEventManager.cs
Normal file
|
|
@ -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<Event> GetEvents(DateTime startDate, DateTime endDate);
|
||||
}
|
||||
|
|
@ -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();
|
||||
50
source/ticketAPI/api/RestFiles/event.http
Normal file
50
source/ticketAPI/api/RestFiles/event.http
Normal file
|
|
@ -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."
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
34
source/ticketAPI/api/Services/EventManager.cs
Normal file
34
source/ticketAPI/api/Services/EventManager.cs
Normal file
|
|
@ -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<Event> GetEvents(DateTime startDate, DateTime endDate)
|
||||
{
|
||||
return new GetInDates().Execute(startDate, endDate);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
19
source/ticketAPI/data/Events/GetInDates.cs
Normal file
19
source/ticketAPI/data/Events/GetInDates.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using models.Core;
|
||||
using models.Request;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace data.Events;
|
||||
|
||||
public class GetInDates
|
||||
{
|
||||
public List<Event> Execute(DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var database = MongoFactory.GetDatabase();
|
||||
var collection = database.GetCollection<Event>("events");
|
||||
|
||||
return collection.Find(x =>
|
||||
startDate <= x.Date
|
||||
&& x.Date <= endDate
|
||||
).ToList();
|
||||
}
|
||||
}
|
||||
14
source/ticketAPI/data/Events/Save.cs
Normal file
14
source/ticketAPI/data/Events/Save.cs
Normal file
|
|
@ -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<Event>("events");
|
||||
|
||||
collection.InsertOne(@event);
|
||||
}
|
||||
}
|
||||
28
source/ticketAPI/data/Events/Update.cs
Normal file
28
source/ticketAPI/data/Events/Update.cs
Normal file
|
|
@ -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<Event>("events");
|
||||
|
||||
var filter = Builders<Event>.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;
|
||||
}
|
||||
}
|
||||
40
source/ticketAPI/data/MongoFactory.cs
Normal file
40
source/ticketAPI/data/MongoFactory.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace data;
|
||||
|
||||
public static class MongoFactory
|
||||
{
|
||||
private static IConfiguration? _config;
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the configuration, must be called before using GetDatabase()
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public static void InitConfig(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the connection to Mongo and returns the database from Configuration
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NullReferenceException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
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);
|
||||
}
|
||||
}
|
||||
14
source/ticketAPI/data/Tickets/Save.cs
Normal file
14
source/ticketAPI/data/Tickets/Save.cs
Normal file
|
|
@ -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<Ticket>("tickets");
|
||||
|
||||
collection.InsertOne(ticket);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Ticket>("tickets");
|
||||
|
||||
collection.InsertOne(ticket);
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
|
@ -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<string> 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; }
|
||||
|
|
|
|||
12
source/ticketAPI/models/Request/AddEvent.cs
Normal file
12
source/ticketAPI/models/Request/AddEvent.cs
Normal file
|
|
@ -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; }
|
||||
}
|
||||
7
source/ticketAPI/models/Request/EventSearch.cs
Normal file
7
source/ticketAPI/models/Request/EventSearch.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace models.Request;
|
||||
|
||||
public class EventSearch
|
||||
{
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
}
|
||||
13
source/ticketAPI/models/Request/PatchEvent.cs
Normal file
13
source/ticketAPI/models/Request/PatchEvent.cs
Normal file
|
|
@ -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; }
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
<div class="row">
|
||||
<div class="card">
|
||||
<div class="sidenav">
|
||||
<app-sidebar/>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="main">
|
||||
<router-outlet/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;}
|
||||
}
|
||||
|
|
@ -1,9 +1,24 @@
|
|||
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
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DebugComponent } from './debug.component';
|
||||
|
||||
describe('DebugComponent', () => {
|
||||
let component: DebugComponent;
|
||||
let fixture: ComponentFixture<DebugComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [DebugComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DebugComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -20,6 +20,6 @@ export class DebugComponent {
|
|||
ticketType: TicketTypeEnum.Single
|
||||
};
|
||||
|
||||
this.ticketMinter.mintTicket(mintRequest);
|
||||
this.ticketMinter.addTicket(mintRequest);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
source/ticketUI/src/app/page/event/event.component.html
Normal file
1
source/ticketUI/src/app/page/event/event.component.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<p>event works!</p>
|
||||
11
source/ticketUI/src/app/page/event/event.component.ts
Normal file
11
source/ticketUI/src/app/page/event/event.component.ts
Normal file
|
|
@ -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 {
|
||||
|
||||
}
|
||||
1
source/ticketUI/src/app/page/scan/scan.component.html
Normal file
1
source/ticketUI/src/app/page/scan/scan.component.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<p>scan works!</p>
|
||||
11
source/ticketUI/src/app/page/scan/scan.component.ts
Normal file
11
source/ticketUI/src/app/page/scan/scan.component.ts
Normal file
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<p>ticket works!</p>
|
||||
11
source/ticketUI/src/app/page/ticket/ticket.component.ts
Normal file
11
source/ticketUI/src/app/page/ticket/ticket.component.ts
Normal file
|
|
@ -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 {
|
||||
|
||||
}
|
||||
31
source/ticketUI/src/app/services/api-utils.ts
Normal file
31
source/ticketUI/src/app/services/api-utils.ts
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
48
source/ticketUI/src/app/services/event.service.ts
Normal file
48
source/ticketUI/src/app/services/event.service.ts
Normal file
|
|
@ -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<AddEventRequest>(url, JSON.stringify(request), options)
|
||||
.pipe(
|
||||
catchError(error => {
|
||||
console.log(error);
|
||||
return of(undefined);
|
||||
})
|
||||
).subscribe();
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
public addTicket(request: MintRequest): void {
|
||||
const options = this.setHttpRequestOptions();
|
||||
const url = environment.apiBase + Endpoints.MINT_TICKETS;
|
||||
const url = environment.apiBase + Endpoints.TICKET;
|
||||
|
||||
this.httpClient.post<MintResponse>(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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<div class="column">
|
||||
<button class="button">Generate Tickets</button>
|
||||
<button class="button">Scan Tickets</button>
|
||||
<button class="button">Manage Events</button>
|
||||
<button class="sidebar-button" [routerLink]="['/ticket']">Generate Tickets</button>
|
||||
<button class="sidebar-button" [routerLink]="['/scan']">Scan Tickets</button>
|
||||
<button class="sidebar-button" [routerLink]="['/event']">Manage Events</button>
|
||||
@if(!environment.production) {
|
||||
<button class="button" [routerLink]="['/debug']">Debug</button>
|
||||
<button class="sidebar-button" [routerLink]="['/debug']">Debug</button>
|
||||
}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SidebarComponent } from './sidebar.component';
|
||||
|
||||
describe('SidebarComponent', () => {
|
||||
let component: SidebarComponent;
|
||||
let fixture: ComponentFixture<SidebarComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SidebarComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SidebarComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
4
source/ticketUI/src/models/core/talent.ts
Normal file
4
source/ticketUI/src/models/core/talent.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export interface Talent {
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
9
source/ticketUI/src/models/core/venue.ts
Normal file
9
source/ticketUI/src/models/core/venue.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export interface Venue {
|
||||
name: string,
|
||||
description: string,
|
||||
addressOne: string,
|
||||
addressTwo: string | null,
|
||||
city: string,
|
||||
state: string,
|
||||
zip: string,
|
||||
}
|
||||
|
|
@ -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';
|
||||
}
|
||||
|
|
|
|||
10
source/ticketUI/src/models/request/add-event-request.ts
Normal file
10
source/ticketUI/src/models/request/add-event-request.ts
Normal file
|
|
@ -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,
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user