Add Event Application Form handling

Introduced `EventAppController` and `EventAppFormData` classes to handle event application form submissions. Updated `FormQuery` to support the new form type. This enhancement allows users to submit event-related applications via the API while ensuring data validation and proper email communication.
This commit is contained in:
Teriuihi 2024-09-20 18:02:24 +02:00
parent 3eb4970407
commit 36c736f8d3
5 changed files with 165 additions and 10 deletions

View File

@ -4,9 +4,10 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="ce59df2a-8d56-446a-867b-80e627daf479" name="Changes" comment="Add IP address tracking for form submissions&#10;&#10;Included IP and timestamp columns in the database schema to track form submissions. Updated methods to handle and store the IP information upon form submission. Adjusted related test cases to validate the new implementation.">
<list default="true" id="ce59df2a-8d56-446a-867b-80e627daf479" name="Changes" comment="Refactor `toHtml()` method in `Form.java`&#10;&#10;Enhanced `toHtml()` to split multiline values into paragraphs using streams and filters. This improves HTML output readability by ensuring each line is wrapped in `&lt;p&gt;` tags. Also updated workspace.xml with the correct description for the recent changes.">
<change afterPath="$PROJECT_DIR$/src/main/java/com/alttd/forms/controlers/event_apply/EventAppController.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/com/alttd/forms/controlers/event_apply/EventAppFormData.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/alttd/forms/form/Form.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/alttd/forms/form/Form.java" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -132,7 +133,7 @@
"git-widget-placeholder": "master",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "P:/Code/Plugins/forms",
"last_opened_file_path": "P:/Code/Plugins/forms/src/main/java/com/alttd/forms/controlers/event_apply",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
@ -156,6 +157,9 @@
<key name="CreateClassDialog.RecentsKey">
<recent name="com.alttd.forms.apply" />
</key>
<key name="CopyFile.RECENT_KEYS">
<recent name="P:\Code\Plugins\forms\src\main\java\com\alttd\forms\controlers\event_apply" />
</key>
<key name="CopyClassDialog.RECENTS_KEY">
<recent name="com.alttd.forms.controlers.form_active" />
<recent name="com.alttd.forms.form" />
@ -346,8 +350,8 @@
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-jdk-9823dce3aa75-b114ca120d71-intellij.indexing.shared.core-IU-242.20224.300" />
<option value="bundled-js-predefined-d6986cc7102b-410509235cf1-JavaScript-IU-242.20224.300" />
<option value="bundled-jdk-9823dce3aa75-b114ca120d71-intellij.indexing.shared.core-IU-242.20224.419" />
<option value="bundled-js-predefined-d6986cc7102b-410509235cf1-JavaScript-IU-242.20224.419" />
</set>
</attachedChunks>
</component>
@ -393,7 +397,8 @@
<workItem from="1723242314809" duration="9799000" />
<workItem from="1723307861750" duration="2179000" />
<workItem from="1723392202182" duration="258000" />
<workItem from="1723392471077" duration="2183000" />
<workItem from="1723392471077" duration="3893000" />
<workItem from="1726847432584" duration="446000" />
</task>
<task id="LOCAL-00001" summary="Initial commit for site for forms">
<option name="closed" value="true" />
@ -691,7 +696,15 @@
<option name="project" value="LOCAL" />
<updated>1723393877624</updated>
</task>
<option name="localTasksCounter" value="38" />
<task id="LOCAL-00038" summary="Refactor `toHtml()` method in `Form.java`&#10;&#10;Enhanced `toHtml()` to split multiline values into paragraphs using streams and filters. This improves HTML output readability by ensuring each line is wrapped in `&lt;p&gt;` tags. Also updated workspace.xml with the correct description for the recent changes.">
<option name="closed" value="true" />
<created>1723394857549</created>
<option name="number" value="00038" />
<option name="presentableId" value="LOCAL-00038" />
<option name="project" value="LOCAL" />
<updated>1723394857549</updated>
</task>
<option name="localTasksCounter" value="39" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@ -709,7 +722,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="Rename StoreFormQuery package to forms.form&#10;&#10;Updated the package name for consistency and better categorization. Adjusted imports in related test files to reflect the new package structure." />
<MESSAGE value="Refactor HTML generation in ContactFormData&#10;&#10;Extract the HTML generation logic to a reusable method in the Form class. This change reduces code duplication and enhances maintainability by centralizing the table generation functionality." />
<MESSAGE value="Add Staff Application Form handling&#10;&#10;Introduced `StaffAppController` and `StaffAppFormData` to handle staff application form submissions. The controller now stores user data, initiates email verification, and provides appropriate responses based on the verification outcome. Additionally, updated `application.properties` and cleaned up IntelliJ workspace.xml." />
<MESSAGE value="Add REST annotations to StaffAppController&#10;&#10;Introduce `@RestController` and `@RequestMapping` annotations to the `StaffAppController` class. This change standardizes the API endpoint and ensures all methods within this class are mapped correctly under `/api/apply`." />
@ -734,7 +746,8 @@
<MESSAGE value="Improve email handling with Mailable interface&#10;&#10;Added a new Mailable interface for extracting email-related data like receiver and subject. Updated StaffAppFormData and ContactFormData to implement this interface, and refactored MailForm to utilize these details. This enhances flexibility and decouples email details from form classes." />
<MESSAGE value="Update `toHtml()` method in `Form.java`&#10;&#10;Simplified the HTML structure for the `toHtml` method by switching from a table layout to paragraph tags. This removes unnecessary table formatting for improved readability and maintainability. Also updated workspace.xml with task tracking and removed outdated comments." />
<MESSAGE value="Add IP address tracking for form submissions&#10;&#10;Included IP and timestamp columns in the database schema to track form submissions. Updated methods to handle and store the IP information upon form submission. Adjusted related test cases to validate the new implementation." />
<option name="LAST_COMMIT_MESSAGE" value="Add IP address tracking for form submissions&#10;&#10;Included IP and timestamp columns in the database schema to track form submissions. Updated methods to handle and store the IP information upon form submission. Adjusted related test cases to validate the new implementation." />
<MESSAGE value="Refactor `toHtml()` method in `Form.java`&#10;&#10;Enhanced `toHtml()` to split multiline values into paragraphs using streams and filters. This improves HTML output readability by ensuring each line is wrapped in `&lt;p&gt;` tags. Also updated workspace.xml with the correct description for the recent changes." />
<option name="LAST_COMMIT_MESSAGE" value="Refactor `toHtml()` method in `Form.java`&#10;&#10;Enhanced `toHtml()` to split multiline values into paragraphs using streams and filters. This improves HTML output readability by ensuring each line is wrapped in `&lt;p&gt;` tags. Also updated workspace.xml with the correct description for the recent changes." />
</component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />

View File

@ -0,0 +1,26 @@
package com.alttd.forms.controlers.event_apply;
import com.alttd.forms.controlers.FormRequestHandler;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.CompletableFuture;
@RestController
@RequestMapping("/api/event-apply")
public class EventAppController {
private static final Logger logger = LoggerFactory.getLogger(EventAppController.class);
@PostMapping("/eventApplication")
public CompletableFuture<ResponseEntity<String>> submitForm(@Valid @RequestBody EventAppFormData formData, HttpServletRequest request) {
logger.debug("submitForm");
logger.trace(formData.toString());
return FormRequestHandler.handleRequestWithVerifyMail(formData, request.getRemoteAddr());
}
}

View File

@ -0,0 +1,113 @@
package com.alttd.forms.controlers.event_apply;
import com.alttd.forms.form.Form;
import com.alttd.forms.mail.mail_forms.Mailable;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.*;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import java.util.Optional;
public class EventAppFormData extends Form implements Mailable {
public EventAppFormData() {}
public EventAppFormData(String username, String email, String discord, int age, String pronoun, int avg_time, String event_experience, String discord_vc, String other) {
this.username = username;
this.email = email;
this.discord = discord;
this.age = age;
this.pronoun = pronoun;
this.avg_time = avg_time;
this.event_experience = event_experience;
this.discord_vc = discord_vc;
this.other = other;
}
@NotEmpty(message = "Username is required")
@Length(min = 3, max = 16, message = "Username should be between 3 and 16 characters")
@Pattern(regexp = "^[a-zA-Z0-9_]*$", message = "Username should only include alphanumeric characters and underscore")
public String username;
@NotEmpty(message = "E-mail address is required")
@Email(message = "Invalid email")
@Length(min = 3, max = 254, message = "Email should be between 3 and 254 characters")
public String email;
@NotEmpty(message = "Discord name is required")
@Length(min = 2, max = 32, message = "Discord name should be between 2 and 32 characters")
@Pattern(regexp = "^([a-z0-9._]{2,32})$", message = "Please enter a valid Discord name")
public String discord;
@Min(value = 0, message = "Please enter a valid age")
@Max(value = 999, message = "We do not accept players older than 999 years old sorry!")
public int age;
@Length(max = 16, message = "Pronouns can't be longer than 16 characters")
public String pronoun;
@Range(min = 0, max = 168, message = "The only valid values are 0-168")
public int avg_time;
@NotEmpty(message = "Event experience is required")
@Length(min = 2, max = 2000, message = "Experience should be between 2 and 2000 characters")
public String event_experience;
@NotEmpty(message = "An answer is required")
@Length(min = 2, max = 3, message = "Please answer yes or no")
@Pattern(regexp = "(?i)^(yes|no)$", message = "Yes or no")
public String discord_vc;
@Length(max = 2000, message = "Text can't be longer than 2000 characters")
public String other;
@JsonIgnore
@Override
public String toString() {
return "EventAppFormData{" +
"username='" + username + '\'' +
", email='" + email + '\'' +
", discord='" + discord + '\'' +
", age=" + age +
", pronoun='" + pronoun + '\'' +
", avg_time=" + avg_time +
", event_experience='" + event_experience + '\'' +
", discord_vc='" + discord_vc + '\'' +
", other='" + other + '\'' +
'}';
}
@JsonIgnore
@Override
public Optional<String> getDiscordBotUrl() {
return Optional.empty();
}
@JsonIgnore
@Override
public String getReceiver() {
return "events@alttd.com";
}
@JsonIgnore
@Override
public String getSubject() {
return "Event Application: " + username;
}
@JsonIgnore
@Override
public String getSender() {
return email;
}
@JsonIgnore
@Override
public String toHtml() {
String[] fields = {"Username", "Email", "Discord", "Age", "Pronoun", "Avg time", "Event experience", "Discord VC", "Other"};
String[] values = {username, email, discord, String.valueOf(age), pronoun, String.valueOf(avg_time), event_experience, discord_vc, other};
return toHtml(fields, values);
}
}

View File

@ -2,6 +2,7 @@ package com.alttd.forms.verify_mail;
import com.alttd.forms.controlers.apply.StaffAppFormData;
import com.alttd.forms.controlers.contact.ContactFormData;
import com.alttd.forms.controlers.event_apply.EventAppFormData;
import com.alttd.forms.database.DatabaseConnection;
import com.alttd.forms.form.Form;
import com.fasterxml.jackson.core.JsonProcessingException;
@ -76,6 +77,9 @@ public class FormQuery {
case "StaffAppFormData" -> {
return objectMapper.readValue(json, StaffAppFormData.class);
}
case "EventAppFormData" -> {
return objectMapper.readValue(json, EventAppFormData.class);
}
default -> throw new IllegalArgumentException("Invalid form class name: " + className);
}
}

View File

@ -1,6 +1,5 @@
package com.alttd.forms.verify_mail;
import com.alttd.forms.controlers.apply.StaffAppFormData;
import com.alttd.forms.form.Form;
import com.alttd.forms.mail.mail_forms.MailForm;
import com.alttd.forms.mail.mail_forms.Mailable;