-
-
-
Hello, {{ title }}
-
Congratulations! Your app is running. 🎉
-
-
-
-
- @for (item of [
- { title: 'Explore the Docs', link: 'https://angular.dev' },
- { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' },
- { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' },
- { title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' },
- { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' },
- ]; track item.title) {
-
- {{ item.title }}
-
-
- }
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/source/ticketUI/src/app/app.component.spec.ts b/source/ticketUI/src/app/app.component.spec.ts
deleted file mode 100644
index ec9b684..0000000
--- a/source/ticketUI/src/app/app.component.spec.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { TestBed } from '@angular/core/testing';
-import { AppComponent } from './app.component';
-
-describe('AppComponent', () => {
- beforeEach(async () => {
- await TestBed.configureTestingModule({
- imports: [AppComponent],
- }).compileComponents();
- });
-
- it('should create the app', () => {
- const fixture = TestBed.createComponent(AppComponent);
- const app = fixture.componentInstance;
- expect(app).toBeTruthy();
- });
-
- it(`should have the 'ticketUI' title`, () => {
- const fixture = TestBed.createComponent(AppComponent);
- const app = fixture.componentInstance;
- expect(app.title).toEqual('ticketUI');
- });
-
- it('should render title', () => {
- const fixture = TestBed.createComponent(AppComponent);
- fixture.detectChanges();
- const compiled = fixture.nativeElement as HTMLElement;
- expect(compiled.querySelector('h1')?.textContent).toContain('Hello, ticketUI');
- });
-});
diff --git a/source/ticketUI/src/app/app.component.ts b/source/ticketUI/src/app/app.component.ts
index b8abe42..77c8f56 100644
--- a/source/ticketUI/src/app/app.component.ts
+++ b/source/ticketUI/src/app/app.component.ts
@@ -1,12 +1,16 @@
-import { Component } from '@angular/core';
-import { RouterOutlet } from '@angular/router';
+import {Component} from '@angular/core';
+import {SidebarComponent} from './sidebar/sidebar.component';
+import {RouterOutlet} from '@angular/router';
@Component({
selector: 'app-root',
- imports: [RouterOutlet],
+ imports: [
+ SidebarComponent,
+ RouterOutlet
+ ],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
- title = 'ticketUI';
+
}
diff --git a/source/ticketUI/src/app/app.config.ts b/source/ticketUI/src/app/app.config.ts
index a1e7d6f..f0ce9be 100644
--- a/source/ticketUI/src/app/app.config.ts
+++ b/source/ticketUI/src/app/app.config.ts
@@ -2,7 +2,12 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
+import {provideHttpClient} from '@angular/common/http';
export const appConfig: ApplicationConfig = {
- providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]
+ providers: [
+ provideZoneChangeDetection({ eventCoalescing: true }),
+ provideRouter(routes),
+ provideHttpClient()
+ ]
};
diff --git a/source/ticketUI/src/app/app.routes.ts b/source/ticketUI/src/app/app.routes.ts
index dc39edb..fa11451 100644
--- a/source/ticketUI/src/app/app.routes.ts
+++ b/source/ticketUI/src/app/app.routes.ts
@@ -1,3 +1,9 @@
import { Routes } from '@angular/router';
+import {DebugComponent} from './page/debug/debug.component';
-export const routes: Routes = [];
+export const routes: Routes = [
+ {
+ path: 'debug',
+ component: DebugComponent
+ }
+];
diff --git a/source/ticketUI/src/app/page/debug/debug.component.html b/source/ticketUI/src/app/page/debug/debug.component.html
new file mode 100644
index 0000000..fe87625
--- /dev/null
+++ b/source/ticketUI/src/app/page/debug/debug.component.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/source/ticketUI/src/app/page/debug/debug.component.scss b/source/ticketUI/src/app/page/debug/debug.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/source/ticketUI/src/app/page/debug/debug.component.spec.ts b/source/ticketUI/src/app/page/debug/debug.component.spec.ts
new file mode 100644
index 0000000..38528ea
--- /dev/null
+++ b/source/ticketUI/src/app/page/debug/debug.component.spec.ts
@@ -0,0 +1,23 @@
+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
new file mode 100644
index 0000000..af85c93
--- /dev/null
+++ b/source/ticketUI/src/app/page/debug/debug.component.ts
@@ -0,0 +1,25 @@
+import {Component, inject} from '@angular/core';
+import {TicketComponent} from "../../ticket/ticket.component";
+import {TicketService} from '../../services/ticket.service';
+import {MintRequest} from '../../../models/request/mint-request';
+import {TicketTypeEnum} from '../../../models/enums/ticket-type.enum';
+
+@Component({
+ selector: 'app-debug',
+ imports: [
+ TicketComponent
+ ],
+ templateUrl: './debug.component.html',
+ styleUrl: './debug.component.scss'
+})
+export class DebugComponent {
+ private ticketMinter = inject(TicketService);
+
+ public getQrCode(): void {
+ const mintRequest: MintRequest = {
+ ticketType: TicketTypeEnum.Single
+ };
+
+ this.ticketMinter.mintTicket(mintRequest);
+ }
+}
diff --git a/source/ticketUI/src/app/services/ticket.service.ts b/source/ticketUI/src/app/services/ticket.service.ts
new file mode 100644
index 0000000..fdeb062
--- /dev/null
+++ b/source/ticketUI/src/app/services/ticket.service.ts
@@ -0,0 +1,64 @@
+import {Injectable} from '@angular/core';
+import {HttpClient, HttpHeaders, HttpParams} 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';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TicketService {
+ public dataSignal = signal('');
+
+ constructor(public httpClient: HttpClient) {
+ }
+
+ public mintTicket(request: MintRequest): void {
+ const options = this.setHttpRequestOptions();
+ const url = environment.apiBase + Endpoints.MINT_TICKETS;
+
+ this.httpClient.post(url, JSON.stringify(request), options)
+ .pipe(
+ map((response: any) => response.body),
+ catchError(error => {
+ console.log(error);
+ return of(undefined);
+ })
+ ).subscribe((res: MintResponse) => {
+ 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
new file mode 100644
index 0000000..9e99c43
--- /dev/null
+++ b/source/ticketUI/src/app/sidebar/sidebar.component.html
@@ -0,0 +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
new file mode 100644
index 0000000..e69de29
diff --git a/source/ticketUI/src/app/sidebar/sidebar.component.spec.ts b/source/ticketUI/src/app/sidebar/sidebar.component.spec.ts
new file mode 100644
index 0000000..5445f3c
--- /dev/null
+++ b/source/ticketUI/src/app/sidebar/sidebar.component.spec.ts
@@ -0,0 +1,23 @@
+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/app/sidebar/sidebar.component.ts b/source/ticketUI/src/app/sidebar/sidebar.component.ts
new file mode 100644
index 0000000..83e9e99
--- /dev/null
+++ b/source/ticketUI/src/app/sidebar/sidebar.component.ts
@@ -0,0 +1,15 @@
+import { Component } from '@angular/core';
+import {environment} from '../../environments/environment';
+import {RouterModule} from '@angular/router';
+
+@Component({
+ selector: 'app-sidebar',
+ imports: [RouterModule],
+ templateUrl: './sidebar.component.html',
+ styleUrl: './sidebar.component.scss'
+})
+export class SidebarComponent {
+ //TODO: Make sidebar stick to the left side of the screen
+ //TODO: Make sidebar collapsable
+ protected readonly environment = environment;
+}
diff --git a/source/ticketUI/src/app/ticket/ticket.component.html b/source/ticketUI/src/app/ticket/ticket.component.html
new file mode 100644
index 0000000..b147f07
--- /dev/null
+++ b/source/ticketUI/src/app/ticket/ticket.component.html
@@ -0,0 +1,10 @@
+@if(qrCode().length > 0) {
+
+
+
.toString()}})
+
+
+ test
+
+
+}
diff --git a/source/ticketUI/src/app/ticket/ticket.component.scss b/source/ticketUI/src/app/ticket/ticket.component.scss
new file mode 100644
index 0000000..a08fedc
--- /dev/null
+++ b/source/ticketUI/src/app/ticket/ticket.component.scss
@@ -0,0 +1,5 @@
+.qrcode {
+ height: 150px;
+ width: 150px;
+ padding: 10px;
+}
diff --git a/source/ticketUI/src/app/ticket/ticket.component.ts b/source/ticketUI/src/app/ticket/ticket.component.ts
new file mode 100644
index 0000000..6a523cd
--- /dev/null
+++ b/source/ticketUI/src/app/ticket/ticket.component.ts
@@ -0,0 +1,13 @@
+import {Component, inject} from '@angular/core';
+import {TicketService} from '../services/ticket.service';
+
+@Component({
+ selector: 'app-ticket',
+ imports: [],
+ templateUrl: './ticket.component.html',
+ styleUrl: './ticket.component.scss'
+})
+export class TicketComponent {
+ private ticketMinter = inject(TicketService);
+ public qrCode = this.ticketMinter.dataSignal;
+}
diff --git a/source/ticketUI/src/environments/environment.development.ts b/source/ticketUI/src/environments/environment.development.ts
new file mode 100644
index 0000000..4aaafd8
--- /dev/null
+++ b/source/ticketUI/src/environments/environment.development.ts
@@ -0,0 +1,4 @@
+export const environment = {
+ production: false,
+ apiBase: 'http://localhost:5168/',
+};
diff --git a/source/ticketUI/src/environments/environment.ts b/source/ticketUI/src/environments/environment.ts
new file mode 100644
index 0000000..64346b2
--- /dev/null
+++ b/source/ticketUI/src/environments/environment.ts
@@ -0,0 +1,4 @@
+export const environment = {
+ production: true,
+ apiBase: 'http://localhost:5168/',
+};
diff --git a/source/ticketUI/src/models/endpoints.ts b/source/ticketUI/src/models/endpoints.ts
new file mode 100644
index 0000000..56d6f00
--- /dev/null
+++ b/source/ticketUI/src/models/endpoints.ts
@@ -0,0 +1,4 @@
+export class Endpoints {
+ public static readonly TICKET = 'ticket';
+ public static readonly MINT_TICKETS = Endpoints.TICKET + '/mint'
+}
diff --git a/source/ticketUI/src/models/enums/ticket-type.enum.ts b/source/ticketUI/src/models/enums/ticket-type.enum.ts
new file mode 100644
index 0000000..4ae4212
--- /dev/null
+++ b/source/ticketUI/src/models/enums/ticket-type.enum.ts
@@ -0,0 +1,8 @@
+export enum TicketTypeEnum {
+ Single,
+ SingleSeason,
+ Family,
+ FamilySeason,
+ Senior,
+ SeniorSeason
+}
diff --git a/source/ticketUI/src/models/request/mint-request.ts b/source/ticketUI/src/models/request/mint-request.ts
new file mode 100644
index 0000000..2a7ea8f
--- /dev/null
+++ b/source/ticketUI/src/models/request/mint-request.ts
@@ -0,0 +1,5 @@
+import {TicketTypeEnum} from '../enums/ticket-type.enum';
+
+export interface MintRequest {
+ ticketType: TicketTypeEnum
+}
diff --git a/source/ticketUI/src/models/response/mint-response.ts b/source/ticketUI/src/models/response/mint-response.ts
new file mode 100644
index 0000000..8a9aefe
--- /dev/null
+++ b/source/ticketUI/src/models/response/mint-response.ts
@@ -0,0 +1,3 @@
+export interface MintResponse {
+ qrCode: string,
+}
diff --git a/source/ticketUI/src/styles.scss b/source/ticketUI/src/styles.scss
index 90d4ee0..07b5789 100644
--- a/source/ticketUI/src/styles.scss
+++ b/source/ticketUI/src/styles.scss
@@ -1 +1,52 @@
-/* You can add global styles to this file, and also import other style files */
+/* Background styles */
+body {
+ background-image: url('https://images.unsplash.com/photo-1648461513491-c8dc79739211?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D');
+ background-size: auto;
+}
+
+/* Glassmorphism card effect */
+.card {
+ margin: 15px;
+ padding: 5px;
+ backdrop-filter: blur(25px) saturate(112%);
+ -webkit-backdrop-filter: blur(25px) saturate(112%);
+ background-color: rgba(255, 255, 255, 0.11);
+ border-radius: 12px;
+ border: 1px solid rgba(255, 255, 255, 0.125);
+ width: fit-content;
+
+ &-large {
+ width: 250px;
+ }
+}
+
+.button {
+ margin: 15px;
+ padding: 5px;
+ backdrop-filter: blur(25px) saturate(112%);
+ -webkit-backdrop-filter: blur(25px) saturate(112%);
+ background-color: rgba(255, 255, 255, 0.11);
+ border-radius: 8px;
+ border: 1px solid rgba(255, 255, 255, 0.125);
+ width: auto;
+
+ &:hover {
+ background-color: rgba(255, 255, 255, 0.0);
+ }
+
+ &:active {
+ background-color: rgba(255, 255, 255, 0.25);
+ }
+}
+
+.row {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+}
+
+.column {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}