From 643545a18a6e929bd30f51b5cd30b4f016004dcb Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Sat, 26 Apr 2025 20:58:47 +0200 Subject: [PATCH] Add appeal and login functionality structure Introduces initial structure for appeal and login forms in both the frontend and backend. New controllers, APIs, and components were created, but functionality has not been fully implemented yet. This serves as a foundation for future development of these features. --- .../application/AppealController.java | 28 ++++++ .../controllers/login/LoginController.java | 22 +++++ .../app/forms/appeal/appeal.component.html | 5 + .../app/forms/appeal/appeal.component.scss | 0 .../app/forms/appeal/appeal.component.spec.ts | 23 +++++ .../src/app/forms/appeal/appeal.component.ts | 63 ++++++++++++ frontend/src/app/forms/forms.component.html | 12 +++ frontend/src/app/forms/forms.component.scss | 0 .../src/app/forms/forms.component.spec.ts | 23 +++++ frontend/src/app/forms/forms.component.ts | 15 +++ open_api/src/main/resources/api.yml | 4 + .../main/resources/schemas/login/login.yml | 97 +++++++++++++++++++ 12 files changed, 292 insertions(+) create mode 100644 backend/src/main/java/com/alttd/altitudeweb/controllers/application/AppealController.java create mode 100644 backend/src/main/java/com/alttd/altitudeweb/controllers/login/LoginController.java create mode 100644 frontend/src/app/forms/appeal/appeal.component.html create mode 100644 frontend/src/app/forms/appeal/appeal.component.scss create mode 100644 frontend/src/app/forms/appeal/appeal.component.spec.ts create mode 100644 frontend/src/app/forms/appeal/appeal.component.ts create mode 100644 frontend/src/app/forms/forms.component.html create mode 100644 frontend/src/app/forms/forms.component.scss create mode 100644 frontend/src/app/forms/forms.component.spec.ts create mode 100644 frontend/src/app/forms/forms.component.ts create mode 100644 open_api/src/main/resources/schemas/login/login.yml diff --git a/backend/src/main/java/com/alttd/altitudeweb/controllers/application/AppealController.java b/backend/src/main/java/com/alttd/altitudeweb/controllers/application/AppealController.java new file mode 100644 index 0000000..e8b8ee7 --- /dev/null +++ b/backend/src/main/java/com/alttd/altitudeweb/controllers/application/AppealController.java @@ -0,0 +1,28 @@ +package com.alttd.altitudeweb.controllers.application; + +import com.alttd.altitudeweb.api.AppealsApi; +import com.alttd.altitudeweb.model.AppealResponseDto; +import com.alttd.altitudeweb.model.DiscordAppealDto; +import com.alttd.altitudeweb.model.MinecraftAppealDto; +import com.alttd.altitudeweb.model.UpdateMailDto; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.web.server.ResponseStatusException; + +public class AppealController implements AppealsApi { + + @Override + public ResponseEntity submitDiscordAppeal(DiscordAppealDto discordAppealDto) { + throw new ResponseStatusException(HttpStatusCode.valueOf(501), "Discord appeals are not yet supported"); + } + + @Override + public ResponseEntity submitMinecraftAppeal(MinecraftAppealDto minecraftAppealDto) { + throw new ResponseStatusException(HttpStatusCode.valueOf(501), "Minecraft appeals are not yet supported"); + } + + @Override + public ResponseEntity updateMail(UpdateMailDto updateMailDto) { + throw new ResponseStatusException(HttpStatusCode.valueOf(501), "Updating mail is not yet supported"); + } +} diff --git a/backend/src/main/java/com/alttd/altitudeweb/controllers/login/LoginController.java b/backend/src/main/java/com/alttd/altitudeweb/controllers/login/LoginController.java new file mode 100644 index 0000000..8b81255 --- /dev/null +++ b/backend/src/main/java/com/alttd/altitudeweb/controllers/login/LoginController.java @@ -0,0 +1,22 @@ +package com.alttd.altitudeweb.controllers.login; + +import com.alttd.altitudeweb.api.LoginApi; +import com.alttd.altitudeweb.model.AddLoginDto; +import com.alttd.altitudeweb.model.LoginDataDto; +import com.alttd.altitudeweb.model.LoginResultDto; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.web.server.ResponseStatusException; + +public class LoginController implements LoginApi { + + @Override + public ResponseEntity addLogin(AddLoginDto addLoginDto) { + throw new ResponseStatusException(HttpStatusCode.valueOf(501), "Adding login is not yet supported"); + } + + @Override + public ResponseEntity login(LoginDataDto loginDataDto) { + throw new ResponseStatusException(HttpStatusCode.valueOf(501), "Logging in is not yet supported"); + } +} diff --git a/frontend/src/app/forms/appeal/appeal.component.html b/frontend/src/app/forms/appeal/appeal.component.html new file mode 100644 index 0000000..6ca9adc --- /dev/null +++ b/frontend/src/app/forms/appeal/appeal.component.html @@ -0,0 +1,5 @@ + +
+ +
+
diff --git a/frontend/src/app/forms/appeal/appeal.component.scss b/frontend/src/app/forms/appeal/appeal.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/app/forms/appeal/appeal.component.spec.ts b/frontend/src/app/forms/appeal/appeal.component.spec.ts new file mode 100644 index 0000000..9af6eed --- /dev/null +++ b/frontend/src/app/forms/appeal/appeal.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AppealComponent } from './appeal.component'; + +describe('AppealComponent', () => { + let component: AppealComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AppealComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AppealComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/forms/appeal/appeal.component.ts b/frontend/src/app/forms/appeal/appeal.component.ts new file mode 100644 index 0000000..e51191f --- /dev/null +++ b/frontend/src/app/forms/appeal/appeal.component.ts @@ -0,0 +1,63 @@ +import {Component, OnInit} from '@angular/core'; +import {FormsComponent} from '../forms.component'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; +import {AppealsService} from '../../../api'; + +@Component({ + selector: 'app-appeal', + imports: [ + FormsComponent + ], + templateUrl: './appeal.component.html', + styleUrl: './appeal.component.scss' +}) +export class AppealComponent implements OnInit { + + public form: FormGroup | undefined; + + constructor(private fb: FormBuilder, private appealApi: AppealsService) { + } + + ngOnInit() { + this.initForm() + } + + private initForm() { + this.form = this.fb.group({ + name: ['', [Validators.required]], + punishmentId: ['', [Validators.required]], + email: ['', [Validators.required, Validators.email]], + message: ['', [Validators.required, Validators.minLength(10)]] + }); + } + + public onSubmit() { + if (this.form === undefined) { + console.error('Form is undefined'); + return + } + if (this.form.valid) { + console.log('Form submitted:', this.form.value); + // Process form submission here + } else { + // Mark all fields as touched to trigger validation display + Object.keys(this.form.controls).forEach(field => { + const control = this.form!.get(field); + if (!(control instanceof FormGroup)) { + console.error('Control [' + control + '] is not a FormGroup'); + return; + } + control.markAsTouched({onlySelf: true}); + }); + } + } + + private sendForm(validForm: FormGroup) { + // const appeal: MinecraftAppeal = { + // + // } + // this.appealApi.submitMinecraftAppeal() + } + + +} diff --git a/frontend/src/app/forms/forms.component.html b/frontend/src/app/forms/forms.component.html new file mode 100644 index 0000000..9f04ed1 --- /dev/null +++ b/frontend/src/app/forms/forms.component.html @@ -0,0 +1,12 @@ + + +
+

{{ formTitle }}

+
+
+ +
+ +
+
diff --git a/frontend/src/app/forms/forms.component.scss b/frontend/src/app/forms/forms.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/app/forms/forms.component.spec.ts b/frontend/src/app/forms/forms.component.spec.ts new file mode 100644 index 0000000..84fe7b1 --- /dev/null +++ b/frontend/src/app/forms/forms.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FormsComponent } from './forms.component'; + +describe('FormsComponent', () => { + let component: FormsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FormsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FormsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/forms/forms.component.ts b/frontend/src/app/forms/forms.component.ts new file mode 100644 index 0000000..fffed0e --- /dev/null +++ b/frontend/src/app/forms/forms.component.ts @@ -0,0 +1,15 @@ +import {Component, Input} from '@angular/core'; +import {HeaderComponent} from '../header/header.component'; + +@Component({ + selector: 'app-forms', + imports: [ + HeaderComponent + ], + templateUrl: './forms.component.html', + styleUrl: './forms.component.scss' +}) +export class FormsComponent { + @Input() formTitle: string = 'Form'; + @Input() currentPage: string = 'forms'; +} diff --git a/open_api/src/main/resources/api.yml b/open_api/src/main/resources/api.yml index 7102696..6428127 100644 --- a/open_api/src/main/resources/api.yml +++ b/open_api/src/main/resources/api.yml @@ -36,3 +36,7 @@ paths: $ref: './schemas/forms/appeal/appeal.yml#/MinecraftAppeal' /appeal/discord-appeal: $ref: './schemas/forms/appeal/appeal.yml#/DiscordAppeal' + /login/addUserLogin: + $ref: './schemas/login/login.yml#/AddUserLogin' + /login/userLogin: + $ref: './schemas/login/login.yml#/UserLogin' diff --git a/open_api/src/main/resources/schemas/login/login.yml b/open_api/src/main/resources/schemas/login/login.yml new file mode 100644 index 0000000..05cf30e --- /dev/null +++ b/open_api/src/main/resources/schemas/login/login.yml @@ -0,0 +1,97 @@ +UserLogin: + post: + tags: + - login + summary: Log in to the site + description: Log in to the site through a code from the server + operationId: login + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LoginData' + responses: + '200': + description: Logged in + content: + application/json: + schema: + $ref: '#/components/schemas/LoginResult' + '401': + description: Login failed - Invalid credentials + content: + application/json: + schema: + $ref: '../generic/errors.yml#/components/schemas/ApiError' + default: + description: Unexpected error + content: + application/json: + schema: + $ref: '../generic/errors.yml#/components/schemas/ApiError' +AddUserLogin: + post: + tags: + - login + summary: Add a login + description: Add a code, user combination that can be used to log in + operationId: addLogin + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AddLogin' + responses: + '200': + description: Success + default: + description: Unexpected error + content: + application/json: + schema: + $ref: '../generic/errors.yml#/components/schemas/ApiError' +components: + schemas: + LoginData: + type: object + required: + - loginCode + properties: + loginCode: + type: string + description: The code to log in + LoginResult: + type: object + required: + - uuid + - userName + - auth + properties: + uuid: + type: string + format: uuid + description: UUID of logged in user + userName: + type: string + description: Name of the logged in user + auth: + type: string + description: Token to use along side requests + AddLogin: + type: object + required: + - loginCode + - uuid + properties: + auth: + type: string + description: Token to verify the sender is allowed to add logins + loginCode: + type: string + description: The code that can be logged in with + uuid: + type: string + format: uuid + description: UUID of the user that will get logged in