30 Commits
Author SHA1 Message Date
auto 8fda5d9fb9 Initial appeal commit 2024-10-06 00:27:29 +02:00
auto ee54e91051 Add event application form
Implemented a new event application form with validations and necessary fields such as username, email, and event experience. Incorporated the form into the home page with a navigation link and updated form interfaces and data configurations.
2024-09-20 18:01:38 +02:00
auto 1c4f4b154b Enhance email verification layout styling
Added CSS styles for the fields and field containers to improve the layout and alignment of the email verification page. This change ensures a more structured and visually appealing presentation of the form data.
2024-08-11 19:13:49 +02:00
auto 30720d0738 Refactor type and string handling in ThankYou component
Changed the `DynamicFormData` type to accept any data type, enhancing flexibility. Updated string handling to be more explicit with type checks, ensuring newline handling works correctly for strings only.
2024-08-11 19:09:31 +02:00
auto 25c6a15413 Handle single-line and multi-line email verification messages
Previously, multi-line messages were parsed for line breaks while single-line messages were not appropriately handled. This update checks if the value contains line breaks and processes it accordingly, ensuring both single-line and multi-line messages are displayed correctly.
2024-08-11 19:01:00 +02:00
auto 821e63953b Refactor email verification UI to enhance data display
Replaced table with div and paragraph elements to improve readability of user-submitted data. Added logic to handle multiline form data and remove empty lines, ensuring cleaner and more user-friendly presentation.
2024-08-11 18:47:19 +02:00
auto ceaca60ece Add additional_info field to form requirements
Include extra guidance for the user to specify their timezone. This aims to reduce ambiguity and ensure better form submissions. The change is minimal but improves overall user experience.
2024-08-11 18:41:56 +02:00
auto b00b857f29 Add "Apply for staff" link to homepage
This commit enhances the homepage by adding a new link to the "Apply for staff" page, making it easier for visitors to find and access staff application information directly from the main page. The new link is placed alongside the existing "Contact us" link for better visibility.
2024-08-11 18:32:57 +02:00
auto cf7bdeb481 Enforce integer validation on age and average time fields
Added integer validation messages to the age and avg_time fields to ensure users enter whole numbers. This enhances the form's data integrity by preventing input errors.
2024-08-10 04:35:54 +02:00
auto afb833bd19 Add useCallback to optimize handleCheckForm
Refactored handleCheckForm using useCallback to prevent unnecessary re-renders. This ensures the function is only re-created when formData.backendFormName changes, improving performance. Updated useEffect dependencies to include handleCheckForm for proper effect cleanup.
2024-08-10 03:27:28 +02:00
auto 6215944972 Fix missing promise handling in formActiveRedirect
Added a then() clause to handle the resolved promise after calling handleCheckForm in the useEffect. This ensures any asynchronous operations complete as expected and avoids potential unhandled promise rejections.
2024-08-10 03:24:46 +02:00
auto a08c55ec41 Remove GenericForm import from App.tsx
GenericForm was imported but never used in App.tsx. This clean-up helps in maintaining the codebase by removing unnecessary imports, thus enhancing readability and reducing potential confusion.
2024-08-10 03:24:07 +02:00
auto 2a56144bbc Enhance npm cache clean error handling in Jenkinsfile
Wrapped npm cache clean command in a try-catch block to improve error handling. This ensures that the build process can proceed even if the npm cache clean step fails. Added an informational echo message for better diagnostics in case of failure.
2024-08-10 03:21:16 +02:00
auto 98b86363f5 Add npm install fallback and remove unused variable
Added a fallback npm install command in the Jenkinsfile to handle legacy peer dependencies. Also removed an unused variable from genericForm.tsx to improve code clarity and performance.
2024-08-10 03:19:26 +02:00
auto 75559af7c8 Add form active status check and redirection
Introduced `FormActiveRedirect` component to check if forms are active before rendering. Updated form data to include `backendFormName` and adjusted routes in `App.tsx` to use the new component. This ensures that inactive forms redirect users with a relevant message.
2024-08-10 03:10:25 +02:00
auto 21e23b98ad Remove unused Field import from GenericForm
This commit eliminates the unused Field import from Formik in the genericForm.tsx file. Removing unused imports helps maintain cleaner and more efficient code.
2024-08-10 00:27:24 +02:00
auto 67eddc0394 Merge branch 'refs/heads/dev' 2024-08-10 00:26:46 +02:00
auto d005b72634 Add react-select component and integrate into FormHTML
Added `react-select` library dependency to `package.json` and lock file. Created a new `FormHTML` component in `formHTML.tsx` to handle form field rendering, including support for `select` fields using `react-select` for multi-select functionality.
2024-08-10 00:25:44 +02:00
Peter 51642612ec More style changes 2024-08-09 23:16:41 +02:00
auto cde2a01dd9 Refactor form to use useFormik and FormikProvider
Replaced Formik component with useFormik hook and FormikProvider. This change simplifies the form implementation and separates the form's logic and presentation. The form now benefits from more direct access to formik methods and state.
2024-08-08 21:37:09 +02:00
Peter 4dda70effc Styling for forms 2024-08-08 21:32:37 +02:00
auto 960fc1707b Refactor conditional stage in Jenkinsfile
Updated the 'discord' stage condition to use 'anyOf' for more readable and maintainable branch checks. This change enhances the clarity of branch conditions, ensuring it triggers on either the 'main' or 'master' branches.
2024-08-08 20:38:05 +02:00
auto 94c336fb74 Add dropdown and additional info fields to form steps
Updated form interfaces to include optional dropdown and additional info properties. Adjusted form rendering logic to handle these new fields, providing clearer instructions and choices for users. Refined validation messages for consistency and clarity.
2024-08-08 20:33:15 +02:00
auto 7407372b03 Add branch condition to Discord notification stage
Previously, the Discord notification was sent for all branches. Now, the notification will only be sent for builds on the 'main' or 'master' branches, reducing unnecessary notifications.
2024-08-08 20:32:43 +02:00
auto 973b6b5e7d Add titles to form data and display them dynamically
Incorporated 'title' property into form data objects for dynamic rendering in the GenericForm component. This enhancement facilitates the use of specific titles for different forms, improving readability and user experience.
2024-08-07 00:41:11 +02:00
auto f52201b683 Rename variables for clarity and adjust download filename and contents
Renamed the parameter 'e' to 'formikValues' for better clarity in the handleSubmit function. Now load formikValues into the file that get's uploaded so it has the up to date form data. Changed the downloaded JSON filename from 'form_data.json' to 'your_form_data.json' to be more user-friendly.
2024-08-06 23:21:53 +02:00
auto 9a281ed76c Update backend URLs to use environment variables
Replaced hardcoded backend URLs with environment variables in contact, apply, and verify_email components. Added .env.development and .env.production files to define the base URLs for different environments. This improves flexibility and allows easier configuration changes.
2024-08-06 23:17:37 +02:00
auto 997baae4d3 Fix JSON serialization in error handling
Replaced steps variable with userInput for JSON serialization in error handling. This ensures that the correct data is saved as a JSON blob when a network error occurs.
2024-08-06 22:28:41 +02:00
auto 857d61e09d Add staff application form
Introduced a new form for staff applications based on the old staff application form.
2024-08-06 22:23:35 +02:00
auto d2f15d2627 Refactor forms to use a generic form component
Replaced the contact form with a generic form component to support multiple form configurations. Moved validation schema and form data to a new structure, allowing dynamic form rendering. Updated the App component to utilize this generic approach for handling different forms.
2024-08-06 21:07:20 +02:00
36 changed files with 2083 additions and 6477 deletions
+1
View File
@@ -0,0 +1 @@
REACT_APP_BACKEND_BASE_URL=http://localhost:8002
+1
View File
@@ -0,0 +1 @@
REACT_APP_BACKEND_BASE_URL=https://forms-backend.alttd.com
Vendored
+17 -1
View File
@@ -11,7 +11,11 @@ pipeline {
def success = false
// Clean npm cache and try normal install and npm ci once
sh 'npm cache clean --force'
try {
sh 'npm cache clean --force'
} catch (Exception e0) {
echo 'npm cache clean --force failed trying more things'
}
try {
sh 'npm install'
success = true
@@ -39,6 +43,12 @@ pipeline {
echo "Retry ${retryCount}/${MAX_RETRIES} failed"
}
}
try {
sh 'npm install --legacy-peer-deps --force'
success = true
} catch (Exception e4) {
echo "npm install --legacy-peer-deps --force failed"
}
}
if (!success) {
@@ -55,6 +65,12 @@ pipeline {
}
}
stage('discord') {
when {
anyOf {
branch 'main'
branch 'master'
}
}
steps {
discordSend description: "Build: ${BUILD_NUMBER}", showChangeset: true, result: currentBuild.currentResult, title: currentBuild.fullProjectName, webhookURL: env.discordwebhook
}
+427 -6220
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -16,6 +16,7 @@
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
"react-scripts": "^5.0.1",
"react-select": "^5.8.0",
"typescript": "^5.3.3",
"web-vitals": "^3.5.1",
"yup": "^1.3.3"
Binary file not shown.
+361
View File
@@ -0,0 +1,361 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20161116 at Wed Feb 29 18:13:36 2012
By Jimmy Wärting
Copyright qrelly 2011
</metadata>
<defs>
<font id="Minecraft" horiz-adv-x="768" >
<font-face
font-family="Minecraft"
font-weight="400"
font-stretch="normal"
units-per-em="1024"
panose-1="0 0 4 0 0 0 0 0 0 0"
ascent="896"
descent="-128"
x-height="640"
cap-height="896"
bbox="0 -128 896 896"
underline-thickness="51"
underline-position="77"
unicode-range="U+0020-201D"
/>
<missing-glyph horiz-adv-x="0"
d="M448 127v142h-143v-142h143zM590 293v143h-285v-143h285zM448 459v143h-143v-143h143zM590 626v141h-142q-60 0 -101 -41q-42 -42 -42 -100h285zM0 0v896h896v-896h-896z" />
<glyph glyph-name=".notdef" horiz-adv-x="0"
d="M448 127v142h-143v-142h143zM590 293v143h-285v-143h285zM448 459v143h-143v-143h143zM590 626v141h-142q-60 0 -101 -41q-42 -42 -42 -100h285zM0 0v896h896v-896h-896z" />
<glyph glyph-name="glyph1" horiz-adv-x="0"
/>
<glyph glyph-name="glyph2" horiz-adv-x="256"
/>
<glyph glyph-name="space" unicode=" " horiz-adv-x="384"
/>
<glyph glyph-name="exclam" unicode="!" horiz-adv-x="256"
d="M0 0v128h128v-128h-128zM0 256v640h128v-640h-128z" />
<glyph glyph-name="quotedbl" unicode="&#x22;" horiz-adv-x="512"
d="M0 512v384h128v-384h-128zM256 512v384h128v-384h-128z" />
<glyph glyph-name="numbersign" unicode="#"
d="M384 384v128h-128v-128h128zM128 0v256h-128v128h128v128h-128v128h128v256h128v-256h128v256h128v-256h128v-128h-128v-128h128v-128h-128v-256h-128v256h-128v-256h-128z" />
<glyph glyph-name="dollar" unicode="$"
d="M256 0v128h-256v128h512v-128h-128v-128h-128zM512 256v128h128v-128h-128zM128 384v128h384v-128h-384zM0 512v128h128v-128h-128zM128 640v128h128v128h128v-128h256v-128h-512z" />
<glyph glyph-name="percent" unicode="%"
d="M0 0v128h128v-128h-128zM512 0v256h128v-256h-128zM128 128v256h128v-256h-128zM256 384v128h128v-128h-128zM384 512v256h128v-256h-128zM0 640v256h128v-256h-128zM512 768v128h128v-128h-128z" />
<glyph glyph-name="ampersand" unicode="&#x26;"
d="M128 0v128h256v-128h-256zM512 0v128h128v-128h-128zM0 128v256h128v-256h-128zM512 384v128h128v-128h-128zM384 128v128h-128v128h-128v128h128v128h128v-256h128v-256h-128zM128 640v128h128v-128h-128zM384 640v128h128v-128h-128zM256 768v128h128v-128h-128z" />
<glyph glyph-name="quotesingle" unicode="'" horiz-adv-x="256"
d="M0 512v384h128v-384h-128z" />
<glyph glyph-name="parenleft" unicode="(" horiz-adv-x="640"
d="M256 0v128h256v-128h-256zM128 128v128h128v-128h-128zM0 256v384h128v-384h-128zM128 640v128h128v-128h-128zM256 768v128h256v-128h-256z" />
<glyph glyph-name="parenright" unicode=")" horiz-adv-x="640"
d="M0 0v128h256v-128h-256zM256 128v128h128v-128h-128zM384 256v384h128v-384h-128zM256 640v128h128v-128h-128zM0 768v128h256v-128h-256z" />
<glyph glyph-name="asterisk" unicode="*" horiz-adv-x="640"
d="M128 512v128h128v-128h-128zM384 512v128h128v-128h-128zM256 640v128h128v-128h-128zM128 768v128h128v-128h-128zM384 768v128h128v-128h-128z" />
<glyph glyph-name="plus" unicode="+"
d="M256 128v256h-256v128h256v256h128v-256h256v-128h-256v-256h-128z" />
<glyph glyph-name="comma" unicode="," horiz-adv-x="384"
d="M0 -128v128h128v-128h-128zM128 0v128h128v-128h-128z" />
<glyph glyph-name="hyphen" unicode="-"
d="M0 384v128h640v-128h-640z" />
<glyph glyph-name="period" unicode="." horiz-adv-x="256"
d="M0 0v128h128v-128h-128z" />
<glyph glyph-name="slash" unicode="/"
d="M0 0v128h128v-128h-128zM128 128v256h128v-256h-128zM256 384v128h128v-128h-128zM384 512v256h128v-256h-128zM512 768v128h128v-128h-128z" />
<glyph glyph-name="zero" unicode="0"
d="M128 0v128h384v-128h-384zM256 384v128h128v-128h-128zM0 128v640h128v-384h128v-128h-128v-128h-128zM512 128v384h-128v128h128v128h128v-640h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="one" unicode="1"
d="M0 0v128h256v512h-128v128h128v128h128v-768h256v-128h-640z" />
<glyph glyph-name="two" unicode="2"
d="M0 0v256h128v-128h384v128h128v-256h-640zM128 256v128h128v-128h-128zM256 384v128h256v-128h-256zM0 640v128h128v-128h-128zM512 512v256h128v-256h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="three" unicode="3"
d="M128 0v128h384v-128h-384zM0 128v128h128v-128h-128zM512 128v256h128v-256h-128zM256 384v128h256v-128h-256zM0 640v128h128v-128h-128zM512 512v256h128v-256h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="four" unicode="4"
d="M128 512v128h128v-128h-128zM256 640v128h128v-128h-128zM512 0v256h-512v256h128v-128h384v384h-128v128h256v-896h-128z" />
<glyph glyph-name="five" unicode="5"
d="M128 0v128h384v-128h-384zM0 128v128h128v-128h-128zM512 128v384h128v-384h-128zM0 512v384h640v-128h-512v-128h384v-128h-512z" />
<glyph glyph-name="six" unicode="6"
d="M128 0v128h384v-128h-384zM512 128v256h128v-256h-128zM0 128v512h128v-128h384v-128h-384v-256h-128zM128 640v128h128v-128h-128zM256 768v128h256v-128h-256z" />
<glyph glyph-name="seven" unicode="7"
d="M256 0v384h128v-384h-128zM384 384v128h128v-128h-128zM512 512v256h-384v-128h-128v256h640v-384h-128z" />
<glyph glyph-name="eight" unicode="8"
d="M128 0v128h384v-128h-384zM0 128v256h128v-256h-128zM512 128v256h128v-256h-128zM128 384v128h384v-128h-384zM0 512v256h128v-256h-128zM512 512v256h128v-256h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="nine" unicode="9"
d="M128 0v128h256v-128h-256zM384 128v128h128v-128h-128zM0 512v256h128v-256h-128zM512 256v128h-384v128h384v256h128v-512h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="colon" unicode=":" horiz-adv-x="256"
d="M0 128v256h128v-256h-128zM0 512v256h128v-256h-128z" />
<glyph glyph-name="semicolon" unicode=";" horiz-adv-x="512"
d="M128 128v128h128v-128h-128zM256 256v128h128v-128h-128zM256 512v256h128v-256h-128z" />
<glyph glyph-name="less" unicode="&#x3c;" horiz-adv-x="640"
d="M384 0v128h128v-128h-128zM256 128v128h128v-128h-128zM128 256v128h128v-128h-128zM0 384v128h128v-128h-128zM128 512v128h128v-128h-128zM256 640v128h128v-128h-128zM384 768v128h128v-128h-128z" />
<glyph glyph-name="equal" unicode="="
d="M0 128v128h640v-128h-640zM0 512v128h640v-128h-640z" />
<glyph glyph-name="greater" unicode="&#x3e;" horiz-adv-x="640"
d="M0 0v128h128v-128h-128zM128 128v128h128v-128h-128zM256 256v128h128v-128h-128zM384 384v128h128v-128h-128zM256 512v128h128v-128h-128zM128 640v128h128v-128h-128zM0 768v128h128v-128h-128z" />
<glyph glyph-name="question" unicode="?"
d="M256 0v128h128v-128h-128zM256 256v128h128v-128h-128zM384 384v128h128v-128h-128zM0 640v128h128v-128h-128zM512 512v256h128v-256h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="at" unicode="@" horiz-adv-x="896"
d="M128 0v128h512v-128h-512zM0 128v640h128v-640h-128zM256 256v384h256v-256h128v384h128v-512h-512zM128 768v128h512v-128h-512z" />
<glyph glyph-name="A" unicode="A"
d="M0 0v768h128v-128h384v128h128v-768h-128v512h-384v-512h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="B" unicode="B"
d="M512 128v384h128v-384h-128zM512 640v128h128v-128h-128zM0 0v896h512v-128h-384v-128h384v-128h-384v-384h384v-128h-512z" />
<glyph glyph-name="C" unicode="C"
d="M128 0v128h384v-128h-384zM512 128v128h128v-128h-128zM0 128v640h128v-640h-128zM512 640v128h128v-128h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="D" unicode="D"
d="M512 128v640h128v-640h-128zM0 0v896h512v-128h-384v-640h384v-128h-512z" />
<glyph glyph-name="E" unicode="E"
d="M0 0v896h640v-128h-512v-128h256v-128h-256v-384h512v-128h-640z" />
<glyph glyph-name="F" unicode="F"
d="M0 0v896h640v-128h-512v-128h256v-128h-256v-512h-128z" />
<glyph glyph-name="G" unicode="G"
d="M128 0v128h384v-128h-384zM512 128v384h-128v128h256v-512h-128zM0 128v640h128v-640h-128zM128 768v128h512v-128h-512z" />
<glyph glyph-name="H" unicode="H"
d="M0 0v896h128v-256h384v256h128v-896h-128v512h-384v-512h-128z" />
<glyph glyph-name="I" unicode="I" horiz-adv-x="512"
d="M0 0v128h128v640h-128v128h384v-128h-128v-640h128v-128h-384z" />
<glyph glyph-name="J" unicode="J"
d="M128 0v128h384v-128h-384zM0 128v128h128v-128h-128zM512 128v768h128v-768h-128z" />
<glyph glyph-name="K" unicode="K"
d="M512 0v384h128v-384h-128zM384 384v128h128v-128h-128zM384 640v128h128v-128h-128zM0 0v896h128v-256h256v-128h-256v-512h-128zM512 768v128h128v-128h-128z" />
<glyph glyph-name="L" unicode="L"
d="M0 0v896h128v-768h512v-128h-640z" />
<glyph glyph-name="M" unicode="M"
d="M256 512v128h128v-128h-128zM0 0v896h128v-128h128v-128h-128v-640h-128zM512 0v640h-128v128h128v128h128v-896h-128z" />
<glyph glyph-name="N" unicode="N"
d="M256 512v128h128v-128h-128zM0 0v896h128v-128h128v-128h-128v-640h-128zM512 0v384h-128v128h128v384h128v-896h-128z" />
<glyph glyph-name="O" unicode="O"
d="M128 0v128h384v-128h-384zM0 128v640h128v-640h-128zM512 128v640h128v-640h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="P" unicode="P"
d="M512 640v128h128v-128h-128zM0 0v896h512v-128h-384v-128h384v-128h-384v-512h-128z" />
<glyph glyph-name="Q" unicode="Q"
d="M128 0v128h256v-128h-256zM512 0v128h128v-128h-128zM384 128v128h128v-128h-128zM0 128v640h128v-640h-128zM512 256v512h128v-512h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="R" unicode="R"
d="M512 0v512h128v-512h-128zM512 640v128h128v-128h-128zM0 0v896h512v-128h-384v-128h384v-128h-384v-512h-128z" />
<glyph glyph-name="S" unicode="S"
d="M128 0v128h384v-128h-384zM0 128v128h128v-128h-128zM512 128v384h128v-384h-128zM128 512v128h384v-128h-384zM0 640v128h128v-128h-128zM128 768v128h512v-128h-512z" />
<glyph glyph-name="T" unicode="T"
d="M256 0v768h-256v128h640v-128h-256v-768h-128z" />
<glyph glyph-name="U" unicode="U"
d="M128 0v128h384v-128h-384zM0 128v768h128v-768h-128zM512 128v768h128v-768h-128z" />
<glyph glyph-name="V" unicode="V"
d="M256 0v128h128v-128h-128zM128 128v256h128v-256h-128zM384 128v256h128v-256h-128zM0 384v512h128v-512h-128zM512 384v512h128v-512h-128z" />
<glyph glyph-name="W" unicode="W"
d="M256 256v128h128v-128h-128zM0 0v896h128v-640h128v-128h-128v-128h-128zM512 0v128h-128v128h128v640h128v-896h-128z" />
<glyph glyph-name="X" unicode="X"
d="M0 0v384h128v-384h-128zM512 0v384h128v-384h-128zM128 384v128h128v-128h-128zM384 384v128h128v-128h-128zM256 512v128h128v-128h-128zM128 640v128h128v-128h-128zM384 640v128h128v-128h-128zM0 768v128h128v-128h-128zM512 768v128h128v-128h-128z" />
<glyph glyph-name="Y" unicode="Y"
d="M256 0v640h128v-640h-128zM128 640v128h128v-128h-128zM384 640v128h128v-128h-128zM0 768v128h128v-128h-128zM512 768v128h128v-128h-128z" />
<glyph glyph-name="Z" unicode="Z"
d="M0 0v256h128v-128h512v-128h-640zM128 256v128h128v-128h-128zM256 384v128h128v-128h-128zM384 512v128h128v-128h-128zM512 640v128h-512v128h640v-256h-128z" />
<glyph glyph-name="bracketleft" unicode="[" horiz-adv-x="640"
d="M128 0v896h384v-128h-256v-640h256v-128h-384z" />
<glyph glyph-name="backslash" unicode="\"
d="M512 0v128h128v-128h-128zM384 128v256h128v-256h-128zM256 384v128h128v-128h-128zM128 512v256h128v-256h-128zM0 768v128h128v-128h-128z" />
<glyph glyph-name="bracketright" unicode="]" horiz-adv-x="640"
d="M128 0v128h256v640h-256v128h384v-896h-384z" />
<glyph glyph-name="asciicircum" unicode="^"
d="M0 512v128h128v-128h-128zM512 512v128h128v-128h-128zM128 640v128h128v-128h-128zM384 640v128h128v-128h-128zM256 768v128h128v-128h-128z" />
<glyph glyph-name="underscore" unicode="_"
d="M0 0v128h640v-128h-640z" />
<glyph glyph-name="grave" unicode="`" horiz-adv-x="384"
d="M128 512v128h128v-128h-128zM0 640v256h128v-256h-128z" />
<glyph glyph-name="a" unicode="a"
d="M0 128v128h128v-128h-128zM128 0v128h384v128h-384v128h384v128h128v-512h-512zM128 512v128h384v-128h-384z" />
<glyph glyph-name="b" unicode="b"
d="M512 128v384h128v-384h-128zM256 512v128h256v-128h-256zM0 0v896h128v-384h128v-128h-128v-256h384v-128h-512z" />
<glyph glyph-name="c" unicode="c"
d="M128 0v128h384v-128h-384zM512 128v128h128v-128h-128zM0 128v384h128v-384h-128zM512 384v128h128v-128h-128zM128 512v128h384v-128h-384z" />
<glyph glyph-name="d" unicode="d"
d="M0 128v384h128v-384h-128zM128 512v128h256v-128h-256zM128 0v128h384v256h-128v128h128v384h128v-896h-512z" />
<glyph glyph-name="e" unicode="e"
d="M128 0v128h512v-128h-512zM0 128v384h128v-128h384v128h128v-256h-512v-128h-128zM128 512v128h384v-128h-384z" />
<glyph glyph-name="f" unicode="f" horiz-adv-x="640"
d="M128 0v512h-128v128h128v128h128v-128h256v-128h-256v-512h-128zM256 768v128h256v-128h-256z" />
<glyph glyph-name="g" unicode="g"
d="M0 -128v128h512v-128h-512zM0 256v256h128v-256h-128zM512 0v128h-384v128h384v256h-384v128h512v-640h-128z" />
<glyph glyph-name="h" unicode="h"
d="M512 0v512h128v-512h-128zM256 512v128h256v-128h-256zM0 0v896h128v-384h128v-128h-128v-384h-128z" />
<glyph glyph-name="i" unicode="i" horiz-adv-x="256"
d="M0 0v640h128v-640h-128zM0 768v128h128v-128h-128z" />
<glyph glyph-name="j" unicode="j"
d="M128 -128v128h384v-128h-384zM0 0v128h128v-128h-128zM512 0v640h128v-640h-128zM512 768v128h128v-128h-128z" />
<glyph glyph-name="k" unicode="k" horiz-adv-x="640"
d="M384 0v128h128v-128h-128zM256 128v128h128v-128h-128zM256 384v128h128v-128h-128zM384 512v128h128v-128h-128zM0 0v896h128v-512h128v-128h-128v-256h-128z" />
<glyph glyph-name="l" unicode="l" horiz-adv-x="384"
d="M128 0v128h128v-128h-128zM0 128v768h128v-768h-128z" />
<glyph glyph-name="m" unicode="m"
d="M256 256v256h128v-256h-128zM512 0v512h128v-512h-128zM0 0v640h256v-128h-128v-512h-128zM384 512v128h128v-128h-128z" />
<glyph glyph-name="n" unicode="n"
d="M512 0v512h128v-512h-128zM0 0v640h512v-128h-384v-512h-128z" />
<glyph glyph-name="o" unicode="o"
d="M128 0v128h384v-128h-384zM0 128v384h128v-384h-128zM512 128v384h128v-384h-128zM128 512v128h384v-128h-384z" />
<glyph glyph-name="p" unicode="p"
d="M512 256v256h128v-256h-128zM0 -128v768h128v-128h128v-128h-128v-128h384v-128h-384v-256h-128zM256 512v128h256v-128h-256z" />
<glyph glyph-name="q" unicode="q"
d="M0 256v256h128v-256h-128zM128 512v128h256v-128h-256zM512 -128v256h-384v128h384v128h-128v128h128v128h128v-768h-128z" />
<glyph glyph-name="r" unicode="r"
d="M512 384v128h128v-128h-128zM0 0v640h128v-128h128v-128h-128v-384h-128zM256 512v128h256v-128h-256z" />
<glyph glyph-name="s" unicode="s"
d="M0 0v128h512v-128h-512zM512 128v128h128v-128h-128zM128 256v128h384v-128h-384zM0 384v128h128v-128h-128zM128 512v128h512v-128h-512z" />
<glyph glyph-name="t" unicode="t" horiz-adv-x="512"
d="M256 0v128h128v-128h-128zM128 128v384h-128v128h128v256h128v-256h128v-128h-128v-384h-128z" />
<glyph glyph-name="u" unicode="u"
d="M0 128v512h128v-512h-128zM128 0v128h384v512h128v-640h-512z" />
<glyph glyph-name="v" unicode="v"
d="M256 0v128h128v-128h-128zM128 128v128h128v-128h-128zM384 128v128h128v-128h-128zM0 256v384h128v-384h-128zM512 256v384h128v-384h-128z" />
<glyph glyph-name="w" unicode="w"
d="M0 128v512h128v-512h-128zM128 0v128h128v256h128v-256h128v512h128v-640h-512z" />
<glyph glyph-name="x" unicode="x"
d="M0 0v128h128v-128h-128zM512 0v128h128v-128h-128zM128 128v128h128v-128h-128zM384 128v128h128v-128h-128zM256 256v128h128v-128h-128zM128 384v128h128v-128h-128zM384 384v128h128v-128h-128zM0 512v128h128v-128h-128zM512 512v128h128v-128h-128z" />
<glyph glyph-name="y" unicode="y"
d="M0 -128v128h512v-128h-512zM0 256v384h128v-384h-128zM512 0v128h-384v128h384v384h128v-640h-128z" />
<glyph glyph-name="z" unicode="z"
d="M0 0v128h128v128h128v-128h384v-128h-640zM256 256v128h128v-128h-128zM384 384v128h-384v128h640v-128h-128v-128h-128z" />
<glyph glyph-name="braceleft" unicode="{" horiz-adv-x="640"
d="M256 0v128h256v-128h-256zM128 128v256h128v-256h-128zM0 384v128h128v-128h-128zM128 512v256h128v-256h-128zM256 768v128h256v-128h-256z" />
<glyph glyph-name="bar" unicode="|" horiz-adv-x="256"
d="M0 0v896h128v-896h-128z" />
<glyph glyph-name="braceright" unicode="}" horiz-adv-x="640"
d="M0 0v128h256v-128h-256zM256 128v256h128v-256h-128zM384 384v128h128v-128h-128zM256 512v256h128v-256h-128zM0 768v128h256v-128h-256z" />
<glyph glyph-name="asciitilde" unicode="~" horiz-adv-x="896"
d="M0 640v128h128v-128h-128zM384 640v128h256v-128h-256zM128 768v128h256v-128h-256zM640 768v128h128v-128h-128z" />
<glyph glyph-name="uni0410" unicode="&#x410;"
d="M0 0v768h128v-128h384v128h128v-768h-128v512h-384v-512h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="uni0411" unicode="&#x411;"
d="M512 128v384h128v-384h-128zM0 0v896h640v-128h-512v-128h384v-128h-384v-384h384v-128h-512z" />
<glyph glyph-name="uni0412" unicode="&#x412;"
d="M512 128v384h128v-384h-128zM512 640v128h128v-128h-128zM0 0v896h512v-128h-384v-128h384v-128h-384v-384h384v-128h-512z" />
<glyph glyph-name="uni0413" unicode="&#x413;"
d="M0 0v896h640v-128h-512v-768h-128z" />
<glyph glyph-name="uni0414" unicode="&#x414;"
d="M0 -128v256h128v640h128v-640h128v640h-128v128h256v-768h128v-256h-128v128h-384v-128h-128z" />
<glyph glyph-name="uni0415" unicode="&#x415;"
d="M0 0v896h640v-128h-512v-128h256v-128h-256v-384h512v-128h-640z" />
<glyph glyph-name="uni0416" unicode="&#x416;"
d="M0 0v512h128v-512h-128zM512 0v512h128v-512h-128zM0 640v256h128v-256h-128zM256 0v512h-128v128h128v256h128v-256h128v-128h-128v-512h-128zM512 640v256h128v-256h-128z" />
<glyph glyph-name="uni0417" unicode="&#x417;"
d="M128 0v128h384v-128h-384zM0 128v128h128v-128h-128zM512 128v384h128v-384h-128zM256 512v128h256v-128h-256zM0 640v128h128v-128h-128zM512 640v128h128v-128h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="uni0418" unicode="&#x418;"
d="M256 256v128h128v-128h-128zM0 0v896h128v-640h128v-128h-128v-128h-128zM512 0v384h-128v128h128v384h128v-896h-128z" />
<glyph glyph-name="uni0419" unicode="&#x419;"
d="M256 256v128h128v-128h-128zM0 0v896h128v-640h128v-128h-128v-128h-128zM256 768v128h128v-128h-128zM512 0v384h-128v128h128v384h128v-896h-128z" />
<glyph glyph-name="uni041A" unicode="&#x41a;"
d="M512 0v384h128v-384h-128zM384 384v128h128v-128h-128zM384 640v128h128v-128h-128zM0 0v896h128v-256h256v-128h-256v-512h-128zM512 768v128h128v-128h-128z" />
<glyph glyph-name="uni041B" unicode="&#x41b;"
d="M0 0v640h128v-640h-128zM128 640v128h128v-128h-128zM512 0v768h-256v128h384v-896h-128z" />
<glyph glyph-name="uni041C" unicode="&#x41c;"
d="M256 512v128h128v-128h-128zM0 0v896h128v-128h128v-128h-128v-640h-128zM512 0v640h-128v128h128v128h128v-896h-128z" />
<glyph glyph-name="uni041D" unicode="&#x41d;"
d="M0 0v896h128v-256h384v256h128v-896h-128v512h-384v-512h-128z" />
<glyph glyph-name="uni041E" unicode="&#x41e;"
d="M128 0v128h384v-128h-384zM0 128v640h128v-640h-128zM512 128v640h128v-640h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="uni041F" unicode="&#x41f;"
d="M0 0v896h640v-896h-128v768h-384v-768h-128z" />
<glyph glyph-name="uni0420" unicode="&#x420;"
d="M512 640v128h128v-128h-128zM0 0v896h512v-128h-384v-128h384v-128h-384v-512h-128z" />
<glyph glyph-name="uni0421" unicode="&#x421;"
d="M128 0v128h384v-128h-384zM512 128v128h128v-128h-128zM0 128v640h128v-640h-128zM512 640v128h128v-128h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="uni0422" unicode="&#x422;"
d="M256 0v768h-256v128h640v-128h-256v-768h-128z" />
<glyph glyph-name="uni0423" unicode="&#x423;"
d="M128 0v128h384v-128h-384zM0 128v128h128v-128h-128zM0 640v256h128v-256h-128zM512 128v384h-384v128h384v256h128v-768h-128z" />
<glyph glyph-name="uni0424" unicode="&#x424;"
d="M0 512v256h128v-256h-128zM512 512v256h128v-256h-128zM256 0v384h-128v128h128v256h-128v128h384v-128h-128v-256h128v-128h-128v-384h-128z" />
<glyph glyph-name="uni0425" unicode="&#x425;"
d="M0 0v384h128v-384h-128zM512 0v384h128v-384h-128zM128 384v128h128v-128h-128zM384 384v128h128v-128h-128zM256 512v128h128v-128h-128zM128 640v128h128v-128h-128zM384 640v128h128v-128h-128zM0 768v128h128v-128h-128zM512 768v128h128v-128h-128z" />
<glyph glyph-name="uni0426" unicode="&#x426;" horiz-adv-x="896"
d="M640 -128v128h-640v896h128v-768h384v768h128v-768h128v-256h-128z" />
<glyph glyph-name="uni0427" unicode="&#x427;"
d="M0 640v256h128v-256h-128zM512 0v512h-384v128h384v256h128v-896h-128z" />
<glyph glyph-name="uni0428" unicode="&#x428;"
d="M0 0v896h128v-768h128v768h128v-768h128v768h128v-896h-640z" />
<glyph glyph-name="uni0429" unicode="&#x429;" horiz-adv-x="896"
d="M640 -128v128h-640v896h128v-768h128v768h128v-768h128v768h128v-768h128v-256h-128z" />
<glyph glyph-name="uni042A" unicode="&#x42a;" horiz-adv-x="896"
d="M640 128v384h128v-384h-128zM128 0v768h-128v128h256v-256h384v-128h-384v-384h384v-128h-512z" />
<glyph glyph-name="uni042B" unicode="&#x42b;" horiz-adv-x="1024"
d="M512 128v384h128v-384h-128zM0 0v896h128v-256h384v-128h-384v-384h384v-128h-512zM768 0v896h128v-896h-128z" />
<glyph glyph-name="uni042C" unicode="&#x42c;"
d="M512 128v384h128v-384h-128zM0 0v896h128v-256h384v-128h-384v-384h384v-128h-512z" />
<glyph glyph-name="uni042D" unicode="&#x42d;"
d="M128 0v128h384v-128h-384zM0 128v128h128v-128h-128zM0 640v128h128v-128h-128zM512 128v384h-256v128h256v128h128v-640h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="uni042E" unicode="&#x42e;" horiz-adv-x="896"
d="M384 0v128h256v-128h-256zM640 128v640h128v-640h-128zM0 0v896h128v-256h128v128h128v-640h-128v384h-128v-512h-128zM384 768v128h256v-128h-256z" />
<glyph glyph-name="uni042F" unicode="&#x42f;"
d="M0 0v512h128v-512h-128zM0 640v128h128v-128h-128zM512 0v512h-384v128h384v128h-384v128h512v-896h-128z" />
<glyph glyph-name="uni0430" unicode="&#x430;"
d="M0 128v128h128v-128h-128zM128 0v128h384v128h-384v128h384v128h128v-512h-512zM128 512v128h384v-128h-384z" />
<glyph glyph-name="uni0431" unicode="&#x431;"
d="M128 0v128h384v-128h-384zM512 128v384h128v-384h-128zM0 128v640h128v-128h384v-128h-384v-384h-128zM128 768v128h384v-128h-384z" />
<glyph glyph-name="uni0432" unicode="&#x432;"
d="M512 128v128h128v-128h-128zM512 384v128h128v-128h-128zM0 0v640h512v-128h-384v-128h384v-128h-384v-128h384v-128h-512z" />
<glyph glyph-name="uni0433" unicode="&#x433;"
d="M0 0v640h640v-128h-512v-512h-128z" />
<glyph glyph-name="uni0434" unicode="&#x434;"
d="M0 -128v256h128v384h128v-384h128v384h-128v128h256v-512h128v-256h-128v128h-384v-128h-128z" />
<glyph glyph-name="uni0435" unicode="&#x435;"
d="M128 0v128h512v-128h-512zM0 128v384h128v-128h384v128h128v-256h-512v-128h-128zM128 512v128h384v-128h-384z" />
<glyph glyph-name="uni0436" unicode="&#x436;"
d="M0 0v256h128v-256h-128zM512 0v256h128v-256h-128zM0 384v256h128v-256h-128zM256 0v256h-128v128h128v256h128v-256h128v-128h-128v-256h-128zM512 384v256h128v-256h-128z" />
<glyph glyph-name="uni0437" unicode="&#x437;"
d="M0 0v128h512v-128h-512zM512 128v128h128v-128h-128zM128 256v128h384v-128h-384zM512 384v128h128v-128h-128zM0 512v128h512v-128h-512z" />
<glyph glyph-name="uni0438" unicode="&#x438;"
d="M0 128v512h128v-512h-128zM128 0v128h384v512h128v-640h-512z" />
<glyph glyph-name="uni0439" unicode="&#x439;"
d="M0 128v512h128v-512h-128zM128 0v128h384v512h128v-640h-512zM256 640v128h128v-128h-128z" />
<glyph glyph-name="uni043A" unicode="&#x43a;"
d="M512 0v128h128v-128h-128zM384 128v128h128v-128h-128zM384 384v128h128v-128h-128zM0 0v640h128v-256h256v-128h-256v-256h-128zM512 512v128h128v-128h-128z" />
<glyph glyph-name="uni043B" unicode="&#x43b;"
d="M0 0v384h128v-384h-128zM128 384v128h128v-128h-128zM512 0v512h-256v128h384v-640h-128z" />
<glyph glyph-name="uni043C" unicode="&#x43c;"
d="M256 256v128h128v-128h-128zM0 0v640h128v-128h128v-128h-128v-384h-128zM512 0v384h-128v128h128v128h128v-640h-128z" />
<glyph glyph-name="uni043D" unicode="&#x43d;"
d="M0 0v640h128v-256h384v256h128v-640h-128v256h-384v-256h-128z" />
<glyph glyph-name="uni043E" unicode="&#x43e;"
d="M128 0v128h384v-128h-384zM0 128v384h128v-384h-128zM512 128v384h128v-384h-128zM128 512v128h384v-128h-384z" />
<glyph glyph-name="uni043F" unicode="&#x43f;"
d="M0 0v640h640v-640h-128v512h-384v-512h-128z" />
<glyph glyph-name="uni0440" unicode="&#x440;"
d="M512 128v384h128v-384h-128zM0 -128v768h512v-128h-384v-384h384v-128h-384v-128h-128z" />
<glyph glyph-name="uni0441" unicode="&#x441;"
d="M128 0v128h384v-128h-384zM512 128v128h128v-128h-128zM0 128v384h128v-384h-128zM512 384v128h128v-128h-128zM128 512v128h384v-128h-384z" />
<glyph glyph-name="uni0442" unicode="&#x442;"
d="M256 0v512h-256v128h640v-128h-256v-512h-128z" />
<glyph glyph-name="uni0443" unicode="&#x443;"
d="M0 -128v128h512v-128h-512zM0 256v384h128v-384h-128zM512 0v128h-384v128h384v384h128v-640h-128z" />
<glyph glyph-name="uni0444" unicode="&#x444;"
d="M0 256v256h128v-256h-128zM512 256v256h128v-256h-128zM256 0v128h-128v128h128v256h-128v128h384v-128h-128v-256h128v-128h-128v-128h-128z" />
<glyph glyph-name="uni0445" unicode="&#x445;"
d="M0 0v128h128v-128h-128zM512 0v128h128v-128h-128zM128 128v128h128v-128h-128zM384 128v128h128v-128h-128zM256 256v128h128v-128h-128zM128 384v128h128v-128h-128zM384 384v128h128v-128h-128zM0 512v128h128v-128h-128zM512 512v128h128v-128h-128z" />
<glyph glyph-name="uni0446" unicode="&#x446;"
d="M512 -128v128h-512v640h128v-512h256v512h128v-512h128v-256h-128z" />
<glyph glyph-name="uni0447" unicode="&#x447;"
d="M0 384v256h128v-256h-128zM512 0v256h-384v128h384v256h128v-640h-128z" />
<glyph glyph-name="uni0448" unicode="&#x448;"
d="M0 0v640h128v-512h128v384h128v-384h128v512h128v-640h-640z" />
<glyph glyph-name="uni0449" unicode="&#x449;" horiz-adv-x="896"
d="M640 -128v128h-640v640h128v-512h128v384h128v-384h128v512h128v-512h128v-256h-128z" />
<glyph glyph-name="uni044A" unicode="&#x44a;" horiz-adv-x="896"
d="M640 128v256h128v-256h-128zM128 0v512h-128v128h256v-128h384v-128h-384v-256h384v-128h-512z" />
<glyph glyph-name="uni044B" unicode="&#x44b;" horiz-adv-x="1024"
d="M512 128v256h128v-256h-128zM0 0v640h128v-128h384v-128h-384v-256h384v-128h-512zM768 0v640h128v-640h-128z" />
<glyph glyph-name="uni044C" unicode="&#x44c;"
d="M512 128v256h128v-256h-128zM0 0v640h128v-128h384v-128h-384v-256h384v-128h-512z" />
<glyph glyph-name="uni044D" unicode="&#x44d;"
d="M128 0v128h384v-128h-384zM0 128v128h128v-128h-128zM0 384v128h128v-128h-128zM512 128v128h-256v128h256v128h128v-384h-128zM128 512v128h384v-128h-384z" />
<glyph glyph-name="uni044E" unicode="&#x44e;" horiz-adv-x="896"
d="M384 0v128h256v-128h-256zM640 128v384h128v-384h-128zM0 0v640h128v-256h128v128h128v-384h-128v128h-128v-256h-128zM384 512v128h256v-128h-256z" />
<glyph glyph-name="uni044F" unicode="&#x44f;"
d="M0 0v256h128v-256h-128zM0 384v128h128v-128h-128zM512 0v256h-384v128h384v128h-384v128h512v-640h-128z" />
<glyph glyph-name="quoteleft" unicode="&#x2018;" horiz-adv-x="384"
d="M0 512v256h128v-256h-128zM128 768v128h128v-128h-128z" />
<glyph glyph-name="quoteright" unicode="&#x2019;" horiz-adv-x="384"
d="M0 512v128h128v-128h-128zM128 640v256h128v-256h-128z" />
<glyph glyph-name="quotedblleft" unicode="&#x201c;" horiz-adv-x="640"
d="M0 512v256h128v-256h-128zM256 512v256h128v-256h-128zM128 768v128h128v-128h-128zM384 768v128h128v-128h-128z" />
<glyph glyph-name="quotedblright" unicode="&#x201d;" horiz-adv-x="640"
d="M0 512v128h128v-128h-128zM256 512v128h128v-128h-128zM128 640v256h128v-256h-128zM384 640v256h128v-256h-128z" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
+167
View File
@@ -0,0 +1,167 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20161116 at Mon May 26 10:12:18 2014
By Jimmy Wärting
</metadata>
<defs>
<font id="Minecrafter" horiz-adv-x="679" >
<font-face
font-family="Minecrafter"
font-weight="400"
font-stretch="normal"
units-per-em="1000"
panose-1="0 0 0 0 0 0 0 0 0 0"
ascent="750"
descent="-250"
x-height="784"
cap-height="784"
bbox="19 -68 1247 790"
underline-thickness="0"
underline-position="0"
unicode-range="U+0020-007A"
/>
<missing-glyph horiz-adv-x="500"
/>
<glyph glyph-name=".notdef" horiz-adv-x="500"
/>
<glyph glyph-name=".null" horiz-adv-x="0"
/>
<glyph glyph-name="nonmarkingreturn" horiz-adv-x="1284"
d="M315 130l12 -13v-105l-12 -12h-86v130h86zM438 130v-34h-49v-13h49v-37h-49v-12h49v-34h-92v130h92zM519 34v12h-56v84h99v-34h-62v-13h62v-83h-99v34h56zM611 130v-130h-31v130h31zM636 117l12 13h93v-34h-68v-59h34q0 1 2 3t1 3q-2 2 -9 4t-10 2v31h50v-80h-93l-12 12
v105zM796 130q1 -2 3 -6.5t4 -6.5q1 -2 8.5 -9t9.5 -9t5 -6.5t4 -6.5v44h41v-130h-38q0 2 -2 6t-4 6t-9 9.5t-9 9.5t-5 6t-4 6v-43h-41v130h37zM945 34v12h-56v84h99v-34h-56v-13h56v-83h-99v34h56zM272 37h12v56h-12v-56zM80 340q0 -3 2.5 -10t4.5 -9q1 -1 9 -3t9 -3t3 -9
t3 -10q2 -1 3 -1h3h4q1 0 3 1q1 2 3 10t3 9t9 3t9 3q2 2 4.5 9t1.5 10h50v-180h-53v71q-1 0 -4.5 2.5t-4.5 1.5q-2 -2 -4 -6.5t-2 -6.5h-37q0 2 -2 6.5t-4 6.5q-2 1 -5 -1.5t-5 -2.5v-71h-52v180h49zM358 340v-180h-52v44h-25v-44h-52v180h129zM506 340q1 -2 3 -6.5t3 -6.5
l3 -3t4 -3v-142q-2 -1 -4 -3l-3 -3q-1 -2 -3 -6.5t-3 -6.5h-123v180h123zM673 340v-115h-77v-65h-53v180h130zM747 340v-180h-49v180h49zM784 222l6 6t6 7q2 0 7 2.5t6 3.5v4q0 2 0.5 3t0.5 2t-0.5 2t-0.5 3v4q-1 1 -6 3.5t-7 2.5q-1 2 -6 7l-6 6l-12 6v56h49q1 -2 3 -6.5
t3 -6.5l25 -25h3h3l25 25q1 2 3 6.5t3 6.5h49v-56q-1 -1 -5.5 -3t-6.5 -3q-3 -3 -10.5 -10t-7.5 -9q-1 0 -1.5 -3.5t-0.5 -5.5t0.5 -5.5t1.5 -3.5q0 -2 7.5 -9t10.5 -10q2 -1 6.5 -3t5.5 -3v-56h-49q-1 2 -3 6.5t-3 6.5l-25 25h-3h-3l-25 -25q-1 -2 -3 -6.5t-3 -6.5h-49v56z
M1093 340v-47h-74v-18h74v-50h-74v-18h74v-47h-130v180h130zM1170 340v-133h77v-47h-130v180h53zM438 210h25v80h-25v-80zM284 253h19v43h-19v-43zM599 278h18v12h-18v-12z" />
<glyph glyph-name="space" unicode=" " horiz-adv-x="500"
/>
<glyph glyph-name="space" unicode="&#xa0;" horiz-adv-x="500"
/>
<glyph glyph-name="Y" unicode="Y" horiz-adv-x="802"
d="M195 281v74h-74v74h-90v349h256v-188h74v-71h80v71h75v188h256v-349h-90v-74h-74v-74h-74v-287h-265v287h-74z" />
<glyph glyph-name="A" unicode="A"
d="M636 784v-784h-256v210h-87v-210h-256v784h599zM296 401h81v198h-81v-198z" />
<glyph glyph-name="B" unicode="b"
d="M636 784v-374h-68v-37h68v-373h-599v784h599zM296 210h81v74h-81v-74zM296 500h81v74h-81v-74z" />
<glyph glyph-name="c" unicode="c" horiz-adv-x="710"
d="M679 784v-207h-383v-370h383v-207h-642v784h642z" />
<glyph glyph-name="D" unicode="d" horiz-adv-x="704"
d="M589 784v-71h71v-642h-71v-71h-552v784h552zM296 210h105v364h-105v-364z" />
<glyph glyph-name="E" unicode="e" horiz-adv-x="667"
d="M630 784v-207h-334v-80h334v-210h-334v-80h334v-207h-593v784h593z" />
<glyph glyph-name="F" unicode="f" horiz-adv-x="660"
d="M630 784v-207h-334v-80h334v-210h-337v-287h-256v784h593z" />
<glyph glyph-name="g" unicode="g" horiz-adv-x="735"
d="M704 784v-207h-408v-367h201v142h207v-352h-667v784h667z" />
<glyph glyph-name="H" unicode="h" horiz-adv-x="716"
d="M287 784v-284h136v284h250v-784h-250v284h-136v-284h-250v784h250z" />
<glyph glyph-name="I" unicode="i" horiz-adv-x="327"
d="M284 784v-784h-247v784h247z" />
<glyph glyph-name="J" unicode="j" horiz-adv-x="648"
d="M355 207v577h250v-784h-586v207h336z" />
<glyph glyph-name="K" unicode="k" horiz-adv-x="685"
d="M287 784v-204h37v108h74v96h250v-275h-83v-74h-77v-86h77v-74h83v-275h-250v96h-74v108h-37v-204h-250v784h250z" />
<glyph glyph-name="L" unicode="l" horiz-adv-x="648"
d="M287 784v-577h336v-207h-586v784h250z" />
<glyph glyph-name="m" unicode="m" horiz-adv-x="864"
d="M287 784v-96h74v-108h136v108h74v96h250v-784h-250v333h-49v-92h-186v92h-49v-333h-250v784h250z" />
<glyph glyph-name="n" unicode="n" horiz-adv-x="741"
d="M287 784v-127h99v-132h61v259h250v-784h-250v127h-98v132h-62v-259h-250v784h250z" />
<glyph glyph-name="o" unicode="o" horiz-adv-x="759"
d="M716 784v-784h-679v784h679zM290 210h173v364h-173v-364z" />
<glyph glyph-name="P" unicode="p" horiz-adv-x="667"
d="M636 784v-559h-343v-225h-256v784h599zM296 414h81v185h-81v-185z" />
<glyph glyph-name="q" unicode="q" horiz-adv-x="759"
d="M37 -3v787h679v-846h-250v59h-429zM290 210h173v364h-173v-364z" />
<glyph glyph-name="R" unicode="r"
d="M636 784v-448h-68v-37h68v-299h-256v284h-87v-284h-256v784h599zM296 500h81v74h-81v-74z" />
<glyph glyph-name="S" unicode="s" horiz-adv-x="691"
d="M401 207v80h-364v497h617v-207h-364v-80h364v-497h-617v207h364z" />
<glyph glyph-name="T" unicode="t" horiz-adv-x="660"
d="M31 577v207h599v-207h-170v-577h-259v577h-170z" />
<glyph glyph-name="u" unicode="u" horiz-adv-x="716"
d="M287 784v-574h136v574h250v-784h-636v784h250z" />
<glyph glyph-name="V" unicode="v"
d="M90 120v142h-59v522h250v-574h111v574h250v-522h-59v-142h-86v-120h-321v120h-86z" />
<glyph glyph-name="w" unicode="w" horiz-adv-x="864"
d="M287 784v-377h49v93h186v-93h49v377h250v-784h-250v71h-74v89h-136v-89h-74v-71h-250v784h250z" />
<glyph glyph-name="x" unicode="x"
d="M117 355v74h-80v355h256v-241h87v241h256v-355h-80v-74h80v-355h-256v241h-87v-241h-256v355h80z" />
<glyph glyph-name="y" unicode="y" horiz-adv-x="660"
d="M114 355v74h-83v355h256v-284h87v284h256v-355h-84v-74h-80v-355h-259v355h-93z" />
<glyph glyph-name="z" unicode="z" horiz-adv-x="698"
d="M120 349v74h87v74h194v80h-364v207h617v-349h-83v-74h-86v-74h-195v-80h364v-207h-617v349h83z" />
<glyph glyph-name="one" unicode="1" horiz-adv-x="420"
d="M25 485v203h46v50h50v46h256v-784h-256v485h-96z" />
<glyph glyph-name="two" unicode="2" horiz-adv-x="704"
d="M108 423v74h287v80h-358v207h552v-71h71v-352h-71v-74h-293v-80h364v-207h-623v423h71z" />
<glyph glyph-name="three" unicode="3" horiz-adv-x="673"
d="M370 207v80h-333v210h333v80h-333v213h528v-77h71v-303h-43v-37h43v-302h-71v-71h-528v207h333z" />
<glyph glyph-name="four" unicode="4" horiz-adv-x="667"
d="M25 287v497h262v-284h74v284h263v-784h-263v287h-336z" />
<glyph glyph-name="five" unicode="5" horiz-adv-x="704"
d="M389 207v80h-281v74h-71v423h623v-207h-358v-80h287v-74h71v-352h-71v-71h-552v207h352z" />
<glyph glyph-name="six" unicode="6" horiz-adv-x="673"
d="M636 784v-207h-334v-80h334v-497h-599v784h599zM302 210h68v74h-68v-74z" />
<glyph glyph-name="seven" unicode="7" horiz-adv-x="660"
d="M19 577v207h599v-784h-263v577h-336z" />
<glyph glyph-name="eight" unicode="8"
d="M80 373v37h-43v374h599v-374h-43v-37h43v-373h-599v373h43zM302 210h68v74h-68v-74zM302 500h68v74h-68v-74z" />
<glyph glyph-name="nine" unicode="9"
d="M370 207v80h-333v497h599v-784h-599v207h333zM302 500h68v74h-68v-74z" />
<glyph glyph-name="zero" unicode="0"
d="M636 784v-784h-599v784h599zM302 210h68v364h-68v-364z" />
<glyph glyph-name="U" unicode="U" horiz-adv-x="710"
d="M37 77v688h250v-574h136v574h250v-688h-96v-96h-444v96h-96z" />
<glyph glyph-name="Q" unicode="Q" horiz-adv-x="809"
d="M133 -9v98h-96v593h96v96h487v-96h99v-500h53v-250h-306v59h-333zM290 204h173v364h-173v-364z" />
<glyph glyph-name="G" unicode="G" horiz-adv-x="735"
d="M37 90v592h96v96h571v-207h-408v-367h201v142h207v-352h-571v96h-96z" />
<glyph glyph-name="C" unicode="C" horiz-adv-x="704"
d="M37 96v592h96v96h540v-207h-383v-370h383v-207h-540v96h-96z" />
<glyph glyph-name="M" unicode="M" horiz-adv-x="809"
d="M287 784v-96h99v-89h37v89h99v96h243v-784h-243v333h-44v-86h-154v86h-37v-333h-250v784h250z" />
<glyph glyph-name="N" unicode="N" horiz-adv-x="809"
d="M293 784v-96h93v-92h99v-96h37v284h243v-784h-243v96h-99v92h-99v96h-37v-284h-250v784h256z" />
<glyph glyph-name="O" unicode="O" horiz-adv-x="802"
d="M37 96v592h90v96h543v-96h95v-592h-95v-96h-543v96h-90zM284 204h228v370h-228v-370z" />
<glyph glyph-name="Z" unicode="Z" horiz-adv-x="698"
d="M120 349v74h87v74h194v80h-364v207h617v-349h-83v-74h-86v-74h-195v-80h364v-207h-617v349h83z" />
<glyph glyph-name="b" unicode="B"
d="M636 784v-374h-68v-37h68v-373h-599v784h599zM296 210h81v74h-81v-74zM296 500h81v74h-81v-74z" />
<glyph glyph-name="d" unicode="D" horiz-adv-x="704"
d="M589 784v-71h71v-642h-71v-71h-552v784h552zM296 210h105v364h-105v-364z" />
<glyph glyph-name="e" unicode="E" horiz-adv-x="667"
d="M630 784v-207h-334v-80h334v-210h-334v-80h334v-207h-593v784h593z" />
<glyph glyph-name="f" unicode="F" horiz-adv-x="660"
d="M630 784v-207h-334v-80h334v-210h-337v-287h-256v784h593z" />
<glyph glyph-name="h" unicode="H" horiz-adv-x="716"
d="M287 784v-284h136v284h250v-784h-250v284h-136v-284h-250v784h250z" />
<glyph glyph-name="i" unicode="I" horiz-adv-x="327"
d="M284 784v-784h-247v784h247z" />
<glyph glyph-name="j" unicode="J" horiz-adv-x="648"
d="M355 207v577h250v-784h-586v207h336z" />
<glyph glyph-name="k" unicode="K" horiz-adv-x="685"
d="M287 784v-204h37v108h74v96h250v-275h-83v-74h-77v-86h77v-74h83v-275h-250v96h-74v108h-37v-204h-250v784h250z" />
<glyph glyph-name="l" unicode="L" horiz-adv-x="648"
d="M287 784v-577h336v-207h-586v784h250z" />
<glyph glyph-name="p" unicode="P" horiz-adv-x="667"
d="M636 784v-559h-343v-225h-256v784h599zM296 414h81v185h-81v-185z" />
<glyph glyph-name="r" unicode="R"
d="M636 784v-448h-68v-37h68v-299h-256v284h-87v-284h-256v784h599zM296 500h81v74h-81v-74z" />
<glyph glyph-name="s" unicode="S" horiz-adv-x="691"
d="M401 207v80h-364v497h617v-207h-364v-80h364v-497h-617v207h364z" />
<glyph glyph-name="t" unicode="T" horiz-adv-x="660"
d="M31 577v207h599v-207h-170v-577h-259v577h-170z" />
<glyph glyph-name="v" unicode="V"
d="M90 120v142h-59v522h250v-574h111v574h250v-522h-59v-142h-86v-120h-321v120h-86z" />
<glyph glyph-name="a" unicode="a"
d="M636 784v-784h-256v210h-87v-210h-256v784h599zM247 377h34v43h111v-43h34v132h-46v47h-87v-47h-46v-132zM197 574h81v74h-81v-74zM395 574h80v74h-80v-74z" />
<glyph glyph-name="X" unicode="X" horiz-adv-x="815"
d="M133 275v74h71v86h-71v74h-96v275h256v-96h74v-71h80v71h75v96h256v-275h-96v-74h-71v-86h71v-74h96v-275h-256v96h-75v71h-80v-71h-74v-96h-256v275h96z" />
<glyph glyph-name="W" unicode="W" horiz-adv-x="809"
d="M287 784v-333h37v86h154v-86h44v333h243v-784h-243v96h-99v89h-37v-89h-99v-96h-250v784h250z" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.
Binary file not shown.
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 512 512" xml:space="preserve">
<g>
<g>
<g>
<path d="M256,0C114.618,0,0,114.618,0,256s114.618,256,256,256s256-114.618,256-256S397.382,0,256,0z M256,469.333
c-117.818,0-213.333-95.515-213.333-213.333S138.182,42.667,256,42.667S469.333,138.182,469.333,256S373.818,469.333,256,469.333
z"/>
<path d="M347.582,198.248L256,289.83l-91.582-91.582c-8.331-8.331-21.839-8.331-30.17,0c-8.331,8.331-8.331,21.839,0,30.17
l106.667,106.667c8.331,8.331,21.839,8.331,30.17,0l106.667-106.667c8.331-8.331,8.331-21.839,0-30.17
C369.42,189.917,355.913,189.917,347.582,198.248z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 900 B

+3 -3
View File
@@ -2,14 +2,14 @@
--white: #FFFFFF;
--black: #282828;
--pureblack: #000000;
--font-color: #272727;
--grey: #A3A3A3;
--font-color: #272727;
--grey: #706F6F;
--link-color: #1f9bde;
--linkhover: #00d9ff;
--navlink: #4b4b4b;
--switch: #FBFBFE;
--error: #c23c3c;
--footer-color: #e9e9e9;
--footer-color: #e9e9e9;
}
@font-face {
+12 -2
View File
@@ -1,4 +1,3 @@
import ContactForm from "./components/contact_form/contact";
import './App.css';
import Home from "./components/home/home";
import {BrowserRouter, Route, Routes} from 'react-router-dom';
@@ -7,6 +6,10 @@ import Footer from "./components/footer/footer";
import VerifyMail from "./components/verify_email/verify_mail";
import ThankYou from "./components/verify_email/thank_you";
import DEBUG from "./components/DEBUG/DEBUG";
import {getFormProperties} from "./components/form/formData";
import {FormProperties} from "./components/form/formInterfaces";
import FormActiveRedirect from "./components/form/formActiveRedirect";
import Appeal from "./components/appeal";
function App() {
return (
@@ -15,9 +18,16 @@ function App() {
<BrowserRouter basename="/">
<Routes>
<Route path="/" element={<Home/>}/>
<Route path="/contact" element={<ContactForm/>}/>
{getFormProperties().map((property: FormProperties) => (
<Route
key={property.path}
path={property.path}
element={<FormActiveRedirect {...property.formData} />}
/>
))}
<Route path="/verify-email" element={<VerifyMail/>}/>
<Route path="/thank-you" element={<ThankYou/>}/>
<Route path="/appeal" element={<Appeal/>}/>
{process.env.NODE_ENV === 'development' && <Route path="/debug" element={<DEBUG/>}/>}
</Routes>
</BrowserRouter>
-11
View File
@@ -1,11 +0,0 @@
.container {
display: flex;
align-items: center;
justify-content: center;
height: 300px;
}
button {
margin: 10px;
cursor: pointer;
}
+21
View File
@@ -0,0 +1,21 @@
// you might need to adjust imports according to your project structure
import React, { FunctionComponent } from 'react';
import { Helmet } from 'react-helmet';
const Appeal: FunctionComponent = () => {
return (
<div>
<Helmet>
<title>Appeals Selection</title>
<meta name="Appeals selection page" content="Choose the type of appeal"/>
</Helmet>
<header className="App-header">
<h1>Welcome to the Appeals page</h1>
<h2><a href="/appeal/minecraft">Appeal a Minecraft punishment.</a></h2>
<h2><a href="/appeal/discord">Appeal a Discord punishment.</a></h2>
</header>
</div>
);
}
export default Appeal;
-49
View File
@@ -1,49 +0,0 @@
.container {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
form {
max-width: 600px;
margin: auto;
padding: 20px;
}
h1 {
text-align: center;
color: #333;
}
label {
display: block;
margin-bottom: 20px;
}
input[type="text"],
input[type="email"],
textarea {
width: 100%;
padding: 10px;
font-size: 1em;
border-radius: 5px;
border: 1px solid #ccc;
}
button,
input[type="submit"] {
padding: 10px 20px;
font-size: 1em;
border-radius: 5px;
border: none;
color: #fff;
background-color: #007BFF;
cursor: pointer;
}
button[disabled],
input[type="submit"][disabled] {
background-color: #ccc;
}
-152
View File
@@ -1,152 +0,0 @@
import React, {useState} from "react";
import './Contact.css';
import {useNavigate} from 'react-router-dom'
import {validationSchema} from "./validationSchema";
import {ErrorMessage, Field, Form, Formik, FormikValues} from "formik";
type InputNames = "username" | "email" | "question";
interface Step {
label: string;
name: InputNames;
type: "text" | "email" | "textarea";
min_length: number;
max_length: number;
required: boolean;
pattern: string;
}
const ContactForm = () => {
const navigate = useNavigate();
const [currentStep, setCurrentStep] = useState<number>(0);
const steps: Step[] = [
{
label: "Username",
name: "username",
type: "text",
min_length: 3,
max_length: 16,
required: true,
pattern: ""
},
{
label: "Email",
name: "email",
type: "email",
min_length: 3,
max_length: 254,
required: true,
pattern: ""
},
{
label: "Question",
name: "question",
type: "textarea",
min_length: 10,
max_length: 2000,
required: true,
pattern: ""
},
]
const handleSubmit = async (e: FormikValues) => {
try {
const response = await fetch('https://forms-backend.alttd.com/api/contact/submitContactForm', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(e)
})
if (!response.ok) {
alert("Your form submission was denied by the server, or the server was unable to process it, if you didn't mess with the data please contact the administrator at [email protected]");
} else {
navigate('/verify-email', {
state: {
email: e['email']
}
});
}
} catch (e) {
alert("Your form submission was denied by the server, if you didn't mess with the data please contact the administrator at [email protected]")
}
};
const next = () => {
setCurrentStep(current => current + 1)
}
const prev = () => {
setCurrentStep(current => Math.max(current - 1, 0))
}
const [prevLength, setPrevLength] = useState(0);
return (
<div className="container">
<div>
<h1>Contact Form</h1>
</div>
<div>
<Formik
initialValues={{username: '', email: '', question: ''}}
validationSchema={validationSchema}
onSubmit={(values: FormikValues) => {
handleSubmit(values);
}}
>
{({
touched,
errors,
isValid,
handleChange,
values,
setFieldTouched
}) => (
<Form>
<div>
<label>
{steps[currentStep].label}
<Field
type={steps[currentStep].type}
name={steps[currentStep].name}
required={steps[currentStep].required}
min={steps[currentStep].min_length}
max={steps[currentStep].max_length}
as={(steps[currentStep].type === "textarea") ? "textarea" : "input"}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
handleChange(e);
if (prevLength !== values[steps[currentStep].name].length) {
setFieldTouched(steps[currentStep].name);
setPrevLength(values[steps[currentStep].name].length);
}
}}
/>
<ErrorMessage name={steps[currentStep].name} component="div"/>
</label>
</div>
<button type="button" onClick={prev} disabled={currentStep === 0}>
Previous
</button>
<button type="button" onClick={next}
hidden={currentStep === (steps.length - 1)}
disabled={(!touched[steps[currentStep].name] || !!errors[steps[currentStep].name]) || currentStep === (steps.length - 1)}>
Next
</button>
<input type="submit" value="Submit"
hidden={currentStep !== (steps.length - 1)}
disabled={!isValid || currentStep !== (steps.length - 1)}
/>
</Form>
)}
</Formik>
</div>
</div>
);
};
export default ContactForm;
@@ -1,20 +0,0 @@
import * as Yup from 'yup';
export const validationSchema = Yup.object().shape({
username: Yup.string()
.min(3, 'Username should be at least 3 characters')
.max(16, 'Username should not exceed 16 characters')
.matches(/^[a-zA-Z0-9_]*$/, 'Username should only include alphanumeric characters and underscore')
.required('Username is required'),
email: Yup.string()
.email('Invalid email')
.min(3, 'Email should be at least 3 characters')
.max(254, 'Email should not exceed 254 characters')
.required(),
question: Yup.string()
.min(10, 'Question should be at least 10 characters')
.max(2000, 'Question should not exceed 2000 characters')
.required('Question is required')
});
+137
View File
@@ -0,0 +1,137 @@
@font-face {
font-family: 'opensans';
src:url('/public/fonts/opensans.ttf') format('truetype'),
url('/public/fonts/opensans.eot') format('embedded-opentype'),
url('/public/fonts/opensans.svg') format('svg'),
url('/public/fonts/opensans.woff') format('woff');
}
@font-face {
font-family: 'opensans-bold';
src:url('/public/fonts/opensans-bold.ttf') format('truetype'),
url('/public/fonts/opensans-bold.eot') format('embedded-opentype'),
url('/public/fonts/opensans-bold.svg') format('svg'),
url('/public/fonts/opensans-bold.woff') format('woff');
}
@font-face {
font-family: 'minecraft-title';
src:url('/public/fonts/minecraft-title.ttf') format('truetype'),
url('/public/fonts/minecraft-title.eot') format('embedded-opentype'),
url('/public/fonts/minecraft-title.svg') format('svg'),
url('/public/fonts/minecraft-title.woff') format('woff');
}
@font-face {
font-family: 'minecraft-text';
src:url('/public/fonts/minecraft-text.ttf') format('truetype'),
url('/public/fonts/minecraft-text.eot') format('embedded-opentype'),
url('/public/fonts/minecraft-text.svg') format('svg'),
url('/public/fonts/minecraft-text.woff') format('woff');
}
.container {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
form {
max-width: 600px;
margin: auto;
padding: 20px;
margin-bottom: 90px;
}
h1 {
text-align: center;
color: #333;
margin-top: 100px;
}
.headline {
margin-bottom: 20px;
}
.description {
font-size: 0.85rem;
color: var(--grey);
}
label {
display: block;
}
input[type="text"],
input[type="email"],
textarea {
width: 100%;
padding: 10px;
font-size: 1em;
border-radius: 5px;
border: 1px solid #ccc;
}
input[type="date"] {
width: 150px;
padding: 5px 5px 5px 5px;
font-size: 16px;
border: 1px solid #CCC;
height: 34px;
border-radius: 5px;
}
button[disabled],
input[type="submit"][disabled] {
background-color: #ccc;
}
.button-outer {
display: inline-block;
font-family: 'minecraft-text', sans-serif;
font-size: 0.8em;
padding: 15px 35px;
background: var(--link-color);
color: #ffffff;
letter-spacing: 1px;
border: none;
border-radius: 5px;
height: auto;
transition: all 100ms cubic-bezier(0.55, 0.085, 0.68, 0.53), 0.5s background ease;
cursor: pointer;
text-shadow: 1px 1px 0px black;
margin: 10px;
}
.button-outer:hover {
color: var(--pureblack);
text-shadow: 1px 1px 0px white;
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.5);
transform: scale(1.1);
}
.button-outer:focus, .button-outer:active {
color: var(--white);
background: #8b8a8f;
}
select {
width: 150px;
padding: 5px 35px 5px 5px;
font-size: 16px;
border: 1px solid #CCC;
height: 34px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: url(../../../public/img/down-arrow.svg) 96% / 15% no-repeat #EEE;
border-radius: 5px;
}
.error-message {
color: var(--error);
margin: 5px 0 15px 0;
font-size: 0.8rem;
}
+104
View File
@@ -0,0 +1,104 @@
import {FormData} from "../formInterfaces";
import * as Yup from "yup";
type PunishmentsForUser = {
punishments: string[]
};
type UserForPunishments = {
username: string
};
export const minecraft_appeal: FormData = {
steps: [
{
label: "What is your Minecraft username?",
additional_info: "Use the username you had when you last tried to join the server.",
name: "username",
type: "text",
min_length: 3,
max_length: 16,
required: true,
},
{
label: "What is your email?",
additional_info: "It does not have to be your minecraft email.",
name: "email",
type: "email",
min_length: 3,
max_length: 254,
required: true,
},
{
label: "What punishment would you like to appeal?",
additional_info: "Please select it below.",
name: "punishment",
type: "dropdown",
min_length: 10,
max_length: 2000,
required: true,
drop_down: [],
processInput: (input: string): Promise<string[]> => {
return new Promise((resolve, reject) => {
const userForPunishments: UserForPunishments = {
username: input,
}
fetch(`${process.env.REACT_APP_BACKEND_BASE_URL}/api/appeal/retrieve-minecraft-punishments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userForPunishments)
})
.then(response => {
if (!response.ok) {
console.log(response)
reject(new Error('Invalid username'));
}
return response.json()
})
.then((punishmentsForUser: PunishmentsForUser) => {
resolve(punishmentsForUser.punishments);
})
.catch(error => {
console.error('Received an unexpected error: ' + error);
reject(error);
})
});
}
},
{
label: "Why should your punishment be reduced or removed?",
additional_info: "Please take your time writing this, we're more likely to accept an appeal if effort was put into it.",
name: "appeal",
type: "textarea",
min_length: 2,
max_length: 2000,
required: true,
},
],
//TODO warning if no punishments
backend: `${process.env.REACT_APP_BACKEND_BASE_URL}/api/appeal/minecraft`,
userInput: {username: '', email: '', punishment: '', appeal: ''},
spec: Yup.object().shape({
username: Yup.string()
.min(3, 'Username should be at least 3 characters')
.max(16, 'Username should not exceed 16 characters')
.matches(/^[a-zA-Z0-9_]*$/, 'Username should only include alphanumeric characters and underscore')
.required('Username is required'),
email: Yup.string()
.email('Invalid email')
.min(3, 'Email should be at least 3 characters')
.max(254, 'Email should not exceed 254 characters')
.required('Email is required'),
punishment: Yup.string()
.required('You are required to select a punishment'),
appeal: Yup.string()
.min(3, 'Your appeal needs to be at least 100 characters')
.max(2000, 'Your appeal can not be longer than 2000 characters')
.required()
}),
title: "Minecraft Appeal",
backendFormName: "MinecraftAppeal",
};
+221
View File
@@ -0,0 +1,221 @@
import {FormData} from "../formInterfaces";
import * as Yup from "yup";
export const apply: FormData = {
steps: [
{
label: "What is your Minecraft username?",
name: "username",
type: "text",
min_length: 3,
max_length: 16,
required: true,
},
{
label: "What is your email?",
name: "email",
type: "email",
min_length: 3,
max_length: 254,
required: true,
},
{
label: "What is your Discord username?",
name: "discord",
type: "text",
min_length: 2,
max_length: 32,
required: true,
},
{
label: "Do you meet the minimum pc requirements?",
name: "pc_requirements",
type: "dropdown",
min_length: 2,
max_length: 3,
required: true,
additional_info: "Use voice chat in Discord with reasonable audio quality\n" +
"Take screenshots through your pc (normally f2 in minecraft)\n" +
"Record your screen through your pc at 20fps+ and 720p+ at normal Minecraft settings (with free programs like OBS)\n",
drop_down: ["Yes", "No", ""],
},
{
label: "What is your age?",
name: "age",
type: "text",
min_length: 1,
max_length: 3,
required: true,
},
{
label: "What is your preferred pronoun?",
name: "pronoun",
type: "dropdown",
min_length: 0,
max_length: 16,
required: true,
drop_down: ["They/them", "She/her", "He/him", ""],
},
{
label: "When did you join Altitude?",
name: "join_date",
type: "date",
min_length: 4,
max_length: 32,
required: true,
},
{
label: "On average, how many hours per week are you available to moderate Altitude?",
name: "avg_time",
type: "text",
min_length: 1,
max_length: 2,
required: true,
},
{
label: "Which days are you normally able to come on?",
name: "available_days",
type: "select",
min_length: 6,
max_length: 128,
required: true,
drop_down: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
multiple: true
},
{
label: "What time of the day are you normally online?",
name: "available_time",
type: "textarea",
min_length: 3,
max_length: 256,
required: true,
additional_info: "Please include your timezone."
},
{
label: "Do you have any previous experience being staff?",
name: "staff_experience",
type: "textarea",
min_length: 2,
max_length: 2000,
required: true,
},
{
label: "Which server plugins do you have experience with?",
name: "plugin_experience",
type: "textarea",
min_length: 2,
max_length: 2000,
required: true,
},
{
label: "Why are you interested in being a moderator on Altitude?",
name: "why_staff",
type: "textarea",
min_length: 2,
max_length: 2000,
required: true,
},
{
label: "What do you believe are the expectations of a moderator?",
name: "expectations_mod",
type: "textarea",
min_length: 2,
max_length: 2000,
required: true,
},
{
label: "You may share anything else you wish here.",
name: "other",
type: "textarea",
min_length: 2,
max_length: 2000,
required: false,
},
],
backend: `${process.env.REACT_APP_BACKEND_BASE_URL}/api/apply/staffApplication`,
userInput: {username: '', email: '', discord: '', pc_requirements: ''
, age: '', pronoun: '', join_date: '', avg_time: '', available_days: '', available_time: '', staff_experience: ''
, plugin_experience: '', why_staff: '', expectations_mod: '', other: ''
},
spec: Yup.object().shape({
username: Yup.string()
.min(3, 'Username should be at least 3 characters')
.max(16, 'Username should not exceed 16 characters')
.matches(/^[a-zA-Z0-9_]*$/, 'Username should only include alphanumeric characters and underscore')
.required('Please enter your username'),
email: Yup.string()
.email('Invalid email')
.min(3, 'Email should be at least 3 characters')
.max(254, 'Email should not exceed 254 characters')
.required('Please enter your email'),
discord: Yup.string()
.min(2, 'Discord name should be at least 2 characters')
.max(32, 'Discord name should be at most 32 characters')
.matches(/^(?!.*\.\.)([a-z0-9._]{2,32})$/, 'Please enter a valid Discord name')
.required('Please enter your Discord name'),
pc_requirements: Yup.string()
// .min(2, "Please answer yes or no")
// .max(3, "Please answer yes or no")
.matches(/(yes|no)$/i, 'Yes or no')
.required('An answer is required'),
age: Yup.number()
.typeError('Input must be a number')
.integer('Please enter a whole number')
.min(0, 'Please enter a valid age')
.max(999, 'We do not accept players older than 999 years old sorry!')
.required('You are required to fill out your age'),
pronoun: Yup.string()
.max(16, 'Pronouns can\'t be longer than 16 characters'),
join_date: Yup.date()
.required('Your join date is required, if you\'re not sure enter an estimated date'),
avg_time: Yup.number()
.typeError('Please enter a number')
.integer('Please enter a whole number')
.min(0, 'Please enter a positive number')
.max(168, 'There are only 168 hours in a week')
.required('Please enter the average time you will be available each week'),
available_days: Yup.lazy(value =>
Array.isArray(value)
? Yup.array().of(Yup.string()).min(1).max(7).required('Please select the days you will be available on')
: Yup.string().required('Please select the days you will be available on')
),
available_time: Yup.string()
.min(3, 'Please provide at least 3 characters')
.max(256, 'Please provide at most 256 characters')
.required('Please enter your available time'),
staff_experience: Yup.string()
.min(2, 'Please provide your experience as staff, if you don\'t have any you can say that instead')
.max(2000, 'Please provide at most 2000 characters')
.required('Please enter your staff experience or simply say you don\'t have any'),
plugin_experience: Yup.string()
.min(2, 'Please provide your experience with moderation plugins, if you don\'t have any you can say that instead')
.max(2000, 'Please provide at most 2000 characters')
.required('Please enter your plugin experience or simply say you don\'t have any'),
why_staff: Yup.string()
.min(2, 'Please provide your reason for wanting to be a moderator')
.max(2000, 'Please provide at most 2000 characters')
.required('Please enter your reason for wanting to be a moderator on Altitude'),
expectations_mod: Yup.string()
.min(2, 'Please provide your expectations of a moderator')
.max(2000, 'Please provide at most 2000 characters')
.required('Please enter your expectations of what a moderator does'),
other: Yup.string()
.max(2000, 'Please provide at most 2000 characters')
}),
title: "Staff Application",
backendFormName: "StaffApplication",
};
+53
View File
@@ -0,0 +1,53 @@
import {FormData} from "../formInterfaces";
import * as Yup from "yup";
export const contact: FormData = {
steps: [
{
label: "What is your Minecraft username?",
name: "username",
type: "text",
min_length: 3,
max_length: 16,
required: true,
},
{
label: "What is your email?",
name: "email",
type: "email",
min_length: 3,
max_length: 254,
required: true,
},
{
label: "What is your question?",
name: "question",
type: "textarea",
min_length: 10,
max_length: 2000,
required: true,
},
],
backend: `${process.env.REACT_APP_BACKEND_BASE_URL}/api/contact/submitContactForm`,
userInput: {username: '', email: '', question: ''},
spec: Yup.object().shape({
username: Yup.string()
.min(3, 'Username should be at least 3 characters')
.max(16, 'Username should not exceed 16 characters')
.matches(/^[a-zA-Z0-9_]*$/, 'Username should only include alphanumeric characters and underscore')
.required('Username is required'),
email: Yup.string()
.email('Invalid email')
.min(3, 'Email should be at least 3 characters')
.max(254, 'Email should not exceed 254 characters')
.required(),
question: Yup.string()
.min(10, 'Question should be at least 10 characters')
.max(2000, 'Question should not exceed 2000 characters')
.required('Question is required')
}),
title: "Contact Form",
backendFormName: "ContactForm",
};
+140
View File
@@ -0,0 +1,140 @@
import {FormData} from "../formInterfaces";
import * as Yup from "yup";
export const event_apply: FormData = {
steps: [
{
label: "What is your Minecraft username?",
name: "username",
type: "text",
min_length: 3,
max_length: 16,
required: true,
},
{
label: "What is your email?",
name: "email",
type: "email",
min_length: 3,
max_length: 254,
required: true,
},
{
label: "What is your Discord username?",
name: "discord",
type: "text",
min_length: 2,
max_length: 32,
required: true,
},
{
label: "What is your age?",
name: "age",
type: "text",
min_length: 1,
max_length: 3,
required: true,
},
{
label: "What is your preferred pronoun?",
name: "pronoun",
type: "dropdown",
min_length: 0,
max_length: 16,
required: true,
drop_down: ["They/them", "She/her", "He/him", ""],
},
{
label: "On average, how many hours per week are you available to help with events?",
name: "avg_time",
type: "text",
min_length: 1,
max_length: 2,
required: true,
},
{
label: "Do you have any previous experience running events of any kind?",
name: "event_experience",
type: "textarea",
min_length: 2,
max_length: 2000,
required: true,
},
{
label: "Are you able to use voice chat on Discord",
name: "discord_vc",
type: "dropdown",
min_length: 2,
max_length: 3,
required: true,
additional_info: "Use voice chat in Discord with reasonable audio quality\n" +
"Take screenshots through your pc (normally f2 in minecraft)\n" +
"Record your screen through your pc at 20fps+ and 720p+ at normal Minecraft settings (with free programs like OBS)\n",
drop_down: ["Yes", "No", ""],
},
{
label: "You may share anything else you wish here.",
name: "other",
type: "textarea",
min_length: 2,
max_length: 2000,
required: false,
},
],
backend: `${process.env.REACT_APP_BACKEND_BASE_URL}/api/apply/staffApplication`,
userInput: {
username: '', email: '', discord: ''
, age: '', pronoun: '', avg_time: '', event_experience: ''
, discord_vc: '', other: ''
},
spec: Yup.object().shape({
username: Yup.string()
.min(3, 'Username should be at least 3 characters')
.max(16, 'Username should not exceed 16 characters')
.matches(/^[a-zA-Z0-9_]*$/, 'Username should only include alphanumeric characters and underscore')
.required('Please enter your username'),
email: Yup.string()
.email('Invalid email')
.min(3, 'Email should be at least 3 characters')
.max(254, 'Email should not exceed 254 characters')
.required('Please enter your email'),
discord: Yup.string()
.min(2, 'Discord name should be at least 2 characters')
.max(32, 'Discord name should be at most 32 characters')
.matches(/^(?!.*\.\.)([a-z0-9._]{2,32})$/, 'Please enter a valid Discord name')
.required('Please enter your Discord name'),
age: Yup.number()
.typeError('Input must be a number')
.integer('Please enter a whole number')
.min(0, 'Please enter a valid age')
.max(999, 'We do not accept players older than 999 years old sorry!')
.required('You are required to fill out your age'),
pronoun: Yup.string()
.max(16, 'Pronouns can\'t be longer than 16 characters'),
avg_time: Yup.number()
.typeError('Please enter a number')
.integer('Please enter a whole number')
.min(0, 'Please enter a positive number')
.max(168, 'There are only 168 hours in a week')
.required('Please enter the average time you will be available each week'),
event_experience: Yup.string()
.min(2, 'Please provide your experience with running/working on events, if you don\'t have any you can say that instead')
.max(2000, 'Please provide at most 2000 characters')
.required('Please enter your event experience or simply say you don\'t have any'),
discord_vc: Yup.string()
.matches(/(yes|no)$/i, 'Yes or no')
.required('An answer is required'),
other: Yup.string()
.max(2000, 'Please provide at most 2000 characters')
}),
title: "Event Application",
backendFormName: "EventApplication",
};
@@ -0,0 +1,39 @@
import {FormData} from "./formInterfaces";
import {useEffect, useState, useCallback} from "react";
import GenericForm from "./genericForm";
const FormActiveRedirect = (formData: FormData) => {
const [isLoading, setLoading] = useState(true);
const [isFormActive, setFormActive] = useState(false);
const handleCheckForm = useCallback(async () => {
setFormActive(true);
setLoading(false);
// const result = await fetch(`${process.env.REACT_APP_BACKEND_BASE_URL}/api/checks/formActive`, {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ formName: formData.backendFormName })
// });
// const response = await result.json();
// setFormActive(response.isActive);
// setLoading(false);
}, [formData.backendFormName]);
useEffect(() => {
handleCheckForm().then(() => {});
}, [handleCheckForm]);
if (isLoading) {
return <div className={"container"}><h2>Checking if form is active</h2></div>;
}
if (!isFormActive) {
return <div className={"container"}><h2>The {formData.title} is not currently active</h2></div>;
}
return (
<GenericForm {...formData} />
);
}
export default FormActiveRedirect;
+28
View File
@@ -0,0 +1,28 @@
import {FormProperties} from "./formInterfaces";
import {contact} from "./data/contact";
import {apply} from "./data/apply";
import {event_apply} from "./data/event_apply";
import {minecraft_appeal} from "./data/appeal";
const formProperties: FormProperties[] = [
{
path: 'contact',
formData: contact
},
{
path: 'apply',
formData: apply
},
{
path: 'event-apply',
formData: event_apply
},
{
path: 'appeal/minecraft',
formData: minecraft_appeal
},
]
export function getFormProperties(): FormProperties[] {
return formProperties
}
+113
View File
@@ -0,0 +1,113 @@
import React, {useEffect, useState} from "react";
import './GenericForm.css';
import {Field} from "formik";
import {FormHandlerProps} from "./formInterfaces";
import ReactSelect from 'react-select';
const FormHTML: React.FC<FormHandlerProps> = ({
steps,
currentStep,
handleChange,
setFieldTouched,
setFieldValue,
values,
prevLength,
setPrevLength
}) => {
const currentField = steps[currentStep];
let fieldOptions = currentField.drop_down && Array.isArray(currentField.drop_down)
? currentField.drop_down.map((value: string) => ({ value, label: value }))
: [];
const fieldValues = values[currentStep] ? values[currentStep].split(', ').map(value => ({ value, label: value })) : []
const [selectedOptions, setSelectedOptions] = useState(fieldValues);
const [options, setOptions] = useState<string[]>([]);
useEffect(() => {
const { processInput, drop_down = [] } = steps[currentStep];
if (processInput) {
processInput(values['username']).then(newOptions => {
setOptions(newOptions);
//TODO be an unsetter for some error field
});
} else {
setOptions(drop_down);
console.log("No data") //TODO be a setter for some error field
}
}, [currentStep, steps]);
if (currentField.type === 'select') {
return (
<ReactSelect
name={currentField.name}
isMulti={true}
options={fieldOptions}
value={selectedOptions}
onChange={(selected) => {
let value: string = '';
if (selected === null) {
value = '';
setSelectedOptions([]);
} else if (Array.isArray(selected)) {
value = selected.map(s => s.value).join(', ');
setSelectedOptions(selected);
}
setFieldValue(currentField.name, value);
if (prevLength !== value.length) {
setFieldTouched(currentField.name);
setPrevLength(value.length);
}
}}
/>
);
} else if (currentField.type === 'dropdown') {
return (
<Field as="select"
name={steps[currentStep].name}
{...(steps[currentStep].multiple && { multiple: true })}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
handleChange(e);
if (prevLength !== values[steps[currentStep].name].length) {
setFieldTouched(steps[currentStep].name);
setPrevLength(values[steps[currentStep].name].length);
}
}}>
{steps[currentStep].drop_down?.map((option, i) => (
<option key={i} value={option}>
{option}
</option>
))}
{options.map((option, i) => (
<option key={i} value={option}>
{option}
</option>
))}
{options.length === 0 ? "<p>No data found, please check if your username is valid. Or if this was a discord punishment, please use the discord appeal form</p>":"<p></p>"}
</Field>
);
} else {
return (
<Field
type={steps[currentStep].type}
name={steps[currentStep].name}
required={steps[currentStep].required}
min={steps[currentStep].min_length}
max={steps[currentStep].max_length}
as={(steps[currentStep].type === "textarea") ? "textarea" : "input"}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
handleChange(e);
if (prevLength !== values[steps[currentStep].name].length) {
setFieldTouched(steps[currentStep].name);
setPrevLength(values[steps[currentStep].name].length);
}
}}
/>
);
}
};
export default FormHTML;
+48
View File
@@ -0,0 +1,48 @@
import * as Yup from "yup";
import React from "react";
type InputNames = "username" | "email" | "question" | "discord" | "pc_requirements" | "age" | "pronoun" | "join_date" |
"avg_time" | "available_days" | "available_time" | "staff_experience" | "plugin_experience" | "why_staff" |
"expectations_mod" | "event_experience" | "discord_vc" | "other" | "punishment" | "appeal";
export interface Step {
label: string;
name: InputNames;
type: "text" | "email" | "textarea" | "date" | "dropdown" | "select";
min_length: number;
max_length: number;
required: boolean;
additional_info?: string;
drop_down?: string[]
multiple?: boolean
processInput?: (input: string) => Promise<string[]>;
}
export interface UserInput {
[key: string]: string;
}
export type FormData = {
backendFormName: string;
steps: Step[];
backend: string;
userInput: UserInput;
spec: Yup.Schema<any>;
title: string;
}
export interface FormProperties {
path: string
formData: FormData;
}
export type FormHandlerProps = {
steps: Step[];
currentStep: number;
handleChange: (event: React.ChangeEvent<any>) => void;
setFieldTouched: (name: string) => void;
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void;
values: UserInput;
prevLength: number;
setPrevLength: (len: number) => void;
};
+138
View File
@@ -0,0 +1,138 @@
import React, {useState} from "react";
import './GenericForm.css';
import {useNavigate} from 'react-router-dom'
import {ErrorMessage, Form, FormikProvider, FormikValues, useFormik} from "formik";
import {Step, UserInput, FormData} from './formInterfaces';
import * as Yup from "yup";
import FormHTML from "./formHTML";
const GenericForm = (formData: FormData) => {
const steps: Step[] = formData.steps;
const backend: string = formData.backend;
const userInput: UserInput = formData.userInput;
const spec: Yup.Schema<any> = formData.spec;
const navigate = useNavigate();
const [currentStep, setCurrentStep] = useState<number>(0);
const handleSubmit = async (formikValues: FormikValues) => {
console.log(JSON.stringify(formikValues))
try {
const response = await fetch(backend, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formikValues)
})
if (!response.ok) {
let json: string = JSON.stringify(formikValues);
const blob = new Blob([json], {type: "application/json"});
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'your_form_data.json';
link.click();
URL.revokeObjectURL(url);
//TODO clean up
alert("Your form submission was denied by the server, or the server was unable to process it, if you didn't mess with the data please contact the administrator at [email protected]");
} else {
navigate('/verify-email', {
state: {
email: formikValues['email']
}
});
}
} catch (e) {
alert("Your form submission was denied by the server, if you didn't mess with the data please contact the administrator at [email protected]")
}
};
const next = () => {
setCurrentStep(current => current + 1)
}
const prev = () => {
setCurrentStep(current => Math.max(current - 1, 0))
}
const formik = useFormik({
initialValues: userInput,
validationSchema: spec,
onSubmit: (values) => {
handleSubmit(values);
},
});
const {
touched,
errors,
isValid,
handleChange,
values,
setFieldTouched,
setFieldValue,
} = formik;
const [prevLength, setPrevLength] = useState(0);
return (
<div>
<div>
<h1>{formData.title}</h1>
</div>
<div>
<FormikProvider value={formik}>
<Form>
<div>
<div>
<label>
<label className="headline">
{steps[currentStep].label}
</label>
<label className="description">
{
steps[currentStep].additional_info ?
steps[currentStep].additional_info?.split('\n').map((line, i) => (
<React.Fragment key={i}>{line}<br/></React.Fragment>
))
: null
}
</label>
</label>
<label>
<FormHTML steps={steps} currentStep={currentStep} handleChange={handleChange}
setFieldTouched={setFieldTouched} setFieldValue={setFieldValue} values={values}
prevLength={prevLength} setPrevLength={setPrevLength}>
</FormHTML>
</label>
</div>
<div>
<label className="error-message">
<ErrorMessage name={steps[currentStep].name} component="div"/>
</label>
</div>
<div>
<button style={{marginLeft: 0}} className="button-outer" type="button" onClick={prev} disabled={currentStep === 0}>
Previous
</button>
<button className={currentStep === (steps.length - 1) ? "" : "button-outer"} type="button" onClick={next}
hidden={currentStep === (steps.length - 1)}
disabled={(!touched[steps[currentStep].name] || !!errors[steps[currentStep].name]) || currentStep === (steps.length - 1)}>
Next
</button>
<input className={currentStep !== (steps.length - 1) ? "" : "button-outer"} type="submit" value="Submit"
hidden={currentStep !== (steps.length - 1)}
disabled={!isValid || currentStep !== (steps.length - 1)}
/>
</div>
</div>
</Form>
</FormikProvider>
</div>
</div>
);
};
export default GenericForm;
+1 -5
View File
@@ -4,11 +4,7 @@ import './Header.css';
const Header: FC = () => {
return (
<header>
<div></div>
<div></div>
</header>
<div></div>
)
};
+3
View File
@@ -11,6 +11,9 @@ const Home: FunctionComponent = () => {
<header className="App-header">
<h1>Welcome to the Altitude forms page</h1>
<h2><a href="/contact">Contact us.</a></h2>
<h2><a href="/apply">Apply for staff.</a></h2>
<h2><a href="/event-apply">Apply for events.</a></h2>
<h2><a href="/appeal">Appeal a punishment.</a></h2>
</header>
</div>
);
+12
View File
@@ -38,3 +38,15 @@ table {
border: 1px solid #ddd;
padding: 10px;
}
.fields {
display: flex;
flex-direction: column;
align-items: flex-start;
max-width: 1020px;
width: 80%;
}
.field {
margin-bottom: 20px;
}
+17 -13
View File
@@ -6,7 +6,7 @@ import './ThankYou.css';
const ThankYou: FC = () => {
const location = useLocation();
type DynamicFormData = {
[key: string]: string;
[key: string]: any;
};
if (location.state === null || location.state.formData === undefined) {
@@ -26,19 +26,23 @@ const ThankYou: FC = () => {
</Helmet>
<header className="header">Thank you for completing the form and verifying your email!<br></br>This is the data you entered:</header>
<div className="fields">
<table>
<tbody>
{Object.entries(formData).map(([key, value]) => (
<tr className="form-data-row" id={key}>
<td className="form-data-key">{key}</td>
<td className="form-data-value">{value}</td>
</tr>
))}
</tbody>
</table>
{Object.entries(formData).map(([key, value]) => (
<div className={"field"}>
<p><strong>{key}</strong></p>
{
typeof value === "string" && value.includes("\n") ?
value
.split("\n")
.filter(str => str.trim() !== "")
.map((str, index) => <p style={{ wordWrap: 'break-word' }} key={index}>{str}</p>)
: <p style={{ wordWrap: 'break-word' }}>{value}</p>
}
</div>
))}
</div>
</div>
);
</div>
)
;
}
+1 -1
View File
@@ -42,7 +42,7 @@ const VerifyMail: FC = () => {
eMail: email
}
console.log(verificationData);
fetch('https://forms-backend.alttd.com/api/verify_email/form', {
fetch(`${process.env.REACT_APP_BACKEND_BASE_URL}/api/verify_email/form`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',