shtuff
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
BASE_URL=localhost:3004
|
BASE_URL=localhost:3003
|
||||||
JWT_SECRET=950b15c8c1c8a27dd716bba3ab51d96ce49afa85cae72884cf22e936e1bc0cb9
|
JWT_SECRET=950b15c8c1c8a27dd716bba3ab51d96ce49afa85cae72884cf22e936e1bc0cb9
|
||||||
ENV=development
|
ENV=development
|
||||||
@@ -12,7 +12,7 @@ var ENV string
|
|||||||
|
|
||||||
// URLs
|
// URLs
|
||||||
var BASE_URL string
|
var BASE_URL string
|
||||||
const PORT = "3004"
|
const PORT = "3003"
|
||||||
|
|
||||||
// Auth
|
// Auth
|
||||||
var JWT_SECRET string
|
var JWT_SECRET string
|
||||||
|
|||||||
@@ -32,14 +32,6 @@ body {
|
|||||||
color: var(--green);
|
color: var(--green);
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--green);
|
|
||||||
transition: background .2s, padding .2s, color .2s;
|
|
||||||
padding: 4px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
button {
|
||||||
background-color: var(--green);
|
background-color: var(--green);
|
||||||
color: var(--tan);
|
color: var(--tan);
|
||||||
|
|||||||
Binary file not shown.
@@ -1,19 +0,0 @@
|
|||||||
css(`
|
|
||||||
nav-bar {
|
|
||||||
position: fixed;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
export default class NavBar extends HTMLElement {
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
|
|
||||||
this.innerHTML += /* html */ `
|
|
||||||
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("nav-bar", NavBar)
|
|
||||||
@@ -1,581 +0,0 @@
|
|||||||
css(`
|
|
||||||
questionnaire- {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 250px 1fr;
|
|
||||||
gap: 20px;
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
margin-top: 17vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toc {
|
|
||||||
position: sticky;
|
|
||||||
top: 17vh;
|
|
||||||
align-self: start;
|
|
||||||
background: var(--tan);
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid var(--brown);
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toc h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toc a {
|
|
||||||
display: block;
|
|
||||||
margin: 5px 0;
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--green);
|
|
||||||
}
|
|
||||||
|
|
||||||
.toc a.active {
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--red);
|
|
||||||
}
|
|
||||||
|
|
||||||
section {
|
|
||||||
border: 1px solid var(--brown);
|
|
||||||
margin-bottom: 2vh;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
background: none;
|
|
||||||
user-select: none;
|
|
||||||
transition: background 0.2s, border 0.2s, color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-content {
|
|
||||||
scroll-margin-top: 20px;
|
|
||||||
padding-bottom: 40px;
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus,
|
|
||||||
textarea:focus,
|
|
||||||
select:focus {
|
|
||||||
outline: 1px solid #ddbb36;
|
|
||||||
border: 1px solid #c4a52f
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Normal state */
|
|
||||||
form button {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loading: morph into circle + pulse */
|
|
||||||
form button.loading {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 50%;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
animation: pulse 1s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Success state */
|
|
||||||
button.success {
|
|
||||||
background: #28a745;
|
|
||||||
color: white;
|
|
||||||
border-radius: 4px;
|
|
||||||
width: auto;
|
|
||||||
animation: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0% { transform: scale(1); opacity: 1; }
|
|
||||||
50% { transform: scale(1.1); opacity: 0.7; }
|
|
||||||
100% { transform: scale(1); opacity: 1; }
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
export default class Questionnaire extends HTMLElement {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.pages = [
|
|
||||||
{ title: "Demographic Information", slug: "demographic", content: this.demographicContent() },
|
|
||||||
{ title: "Contact Information", slug: "contact", content: this.contactContent() },
|
|
||||||
{ title: "Personal History", slug: "personal-history", content: this.personalHistoryContent() },
|
|
||||||
{ title: "Ancestry", slug: "ancestry", content: this.ancestryContent() },
|
|
||||||
{ title: "Skills", slug: "skills", content: this.skillsContent() },
|
|
||||||
{ title: "Interest", slug: "interest", content: this.interestContent() },
|
|
||||||
{ title: "Criminal Record", slug: "criminal", content: this.criminalContent() },
|
|
||||||
{ title: "Political Perspectives", slug: "political", content: this.politicalContent() },
|
|
||||||
{ title: "Religious/Philosophical Views", slug: "religious", content: this.religiousContent() },
|
|
||||||
{ title: "Federal Employment", slug: "federal-employment", content: this.federalEmploymentContent() },
|
|
||||||
{ title: "Social Perspectives", slug: "social", content: this.socialContent() },
|
|
||||||
];
|
|
||||||
this.pageHTML = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
this.fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchData() {
|
|
||||||
try {
|
|
||||||
const res = await fetch("/api/get-application");
|
|
||||||
if (!res.ok) throw new Error(`HTTP error ${res.status}`);
|
|
||||||
this.data = await res.json();
|
|
||||||
console.log(this.data)
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Failed to fetch questionnaire:", err);
|
|
||||||
this.data = {};
|
|
||||||
}
|
|
||||||
this.render()
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
this.Layout();
|
|
||||||
this.Forms();
|
|
||||||
this.setupScrollSpy();
|
|
||||||
this.populateFormData();
|
|
||||||
this.markSectionsComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
Layout() {
|
|
||||||
this.innerHTML = /* html */`
|
|
||||||
<nav class="toc">
|
|
||||||
<h2>Contents</h2>
|
|
||||||
${this.pages.map(p => `
|
|
||||||
<a href="#${p.slug}" data-slug="${p.slug}">${p.title}</a>
|
|
||||||
`).join("")}
|
|
||||||
<a href="#submit">Submit</a>
|
|
||||||
</nav>
|
|
||||||
<div class="sections">
|
|
||||||
${this.pages.map(p => /* html */`
|
|
||||||
<section id="${p.slug}" class="section-content">
|
|
||||||
<h1 style="margin-left: 3rem; margin-top: 3rem">${p.title}</h1>
|
|
||||||
<div class="form-container">
|
|
||||||
<form></form>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
`).join("")}
|
|
||||||
<section id="submit" class="section-content">
|
|
||||||
<h1 style="margin-left: 3rem; margin-top: 3rem">Submit Application</h1>
|
|
||||||
<button style="margin-left: 3rem; margin-top: 3rem; background-color: gray" disabled>Submit</button>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
Forms() {
|
|
||||||
this.pages.forEach(page => {
|
|
||||||
const form = this.querySelector(`#${page.slug} form`);
|
|
||||||
if (form) form.innerHTML = page.content;
|
|
||||||
form.innerHTML += `<button type="submit">Save</button>`
|
|
||||||
form.addEventListener("submit", this.onFormSubmit)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
populateFormData() {
|
|
||||||
Object.entries(this.data).forEach(([key, value]) => {
|
|
||||||
const fields = document.querySelectorAll(`[name="${key}"]`);
|
|
||||||
if (!fields.length) return;
|
|
||||||
|
|
||||||
fields.forEach(field => {
|
|
||||||
if (field.type === "checkbox" || field.type === "radio") {
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
field.checked = value.includes(field.value);
|
|
||||||
} else {
|
|
||||||
field.checked = field.value === value;
|
|
||||||
}
|
|
||||||
} else if (field.tagName === "SELECT" && field.multiple && Array.isArray(value)) {
|
|
||||||
Array.from(field.options).forEach(opt => {
|
|
||||||
opt.selected = value.includes(opt.value);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
field.value = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
markSectionsComplete() {
|
|
||||||
let allFormsComplete = true
|
|
||||||
let forms = document.querySelectorAll("form")
|
|
||||||
for(let i =0; i<forms.length; i++) {
|
|
||||||
let form = forms[i]
|
|
||||||
if(form.checkValidity()) {
|
|
||||||
form.closest("section").style.backgroundColor = "#0080003d"
|
|
||||||
let toc = document.querySelector(`[data-slug=${form.closest("section").id}]`)
|
|
||||||
if(!toc.innerHTML.includes("✓"))
|
|
||||||
toc.innerHTML += " ✓"
|
|
||||||
} else {
|
|
||||||
allFormsComplete = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(allFormsComplete) {
|
|
||||||
let button = document.querySelector("section#submit button")
|
|
||||||
button.style.backgroundColor = ""
|
|
||||||
button.removeAttribute("disabled")
|
|
||||||
button.addEventListener("click", () => window.location.href = "/complete")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setupScrollSpy() {
|
|
||||||
const tocLinks = this.querySelectorAll(".toc a");
|
|
||||||
const sections = this.querySelectorAll(".section-content");
|
|
||||||
|
|
||||||
const observer = new IntersectionObserver((entries) => {
|
|
||||||
entries.forEach(entry => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
const id = entry.target.id;
|
|
||||||
history.replaceState(null, "", `#${id}`);
|
|
||||||
tocLinks.forEach(link => {
|
|
||||||
link.classList.toggle("active", link.dataset.slug === id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, {
|
|
||||||
rootMargin: "-50% 0px -50% 0px", // middle of screen
|
|
||||||
threshold: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
sections.forEach(section => observer.observe(section));
|
|
||||||
}
|
|
||||||
|
|
||||||
onFormSubmit = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
let form = e.target
|
|
||||||
let button = form.querySelector('button[type="submit"]');
|
|
||||||
|
|
||||||
if (!form.checkValidity()) {
|
|
||||||
// Let the browser display native validation errors
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const showButtonLoading = () => {
|
|
||||||
button.classList.add('loading');
|
|
||||||
button.disabled = true;
|
|
||||||
button.textContent = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const showButtonError = () => {
|
|
||||||
button.classList.remove('loading');
|
|
||||||
button.disabled = false;
|
|
||||||
button.textContent = 'Save';
|
|
||||||
if(!form.querySelector("p .error")) {
|
|
||||||
form.parentElement.appendChild(html(`<p class="error" style="color: red">There has been an error. Please try again.</p>`))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const showButtonSuccess = () => {
|
|
||||||
if(form.parentElement.querySelector("p")) {
|
|
||||||
form.parentElement.querySelector("p").remove()
|
|
||||||
}
|
|
||||||
button.classList.remove('loading');
|
|
||||||
button.classList.add('success');
|
|
||||||
button.textContent = 'Success!';
|
|
||||||
console.log(this)
|
|
||||||
this.markSectionsComplete()
|
|
||||||
}
|
|
||||||
|
|
||||||
showButtonLoading()
|
|
||||||
|
|
||||||
// Collect form data
|
|
||||||
const data = new FormData(form);
|
|
||||||
const values = {};
|
|
||||||
data.forEach((v, k) => {
|
|
||||||
if (values[k]) {
|
|
||||||
// Already an array? push new value
|
|
||||||
if (Array.isArray(values[k])) {
|
|
||||||
values[k].push(v);
|
|
||||||
} else {
|
|
||||||
values[k] = [values[k], v];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
values[k] = v;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
fetch('/api/application-save', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(values)
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
if (!res.ok) {
|
|
||||||
throw new Error(`Server error: ${res.status}`);
|
|
||||||
}
|
|
||||||
return res.text();
|
|
||||||
})
|
|
||||||
.then(responseData => {
|
|
||||||
console.log(form, form.parentElement)
|
|
||||||
showButtonSuccess()
|
|
||||||
console.log('Server response:', responseData);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
showButtonError()
|
|
||||||
console.error('Submission error:', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Form submitted:", values);
|
|
||||||
}
|
|
||||||
|
|
||||||
demographicContent() {
|
|
||||||
return /* html */`
|
|
||||||
<label for="firstName">First Name *</label>
|
|
||||||
<input type="text" name="firstName" class="form-control" required>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<label for="lastName">Last Name *</label>
|
|
||||||
<input type="text" name="lastName" class="form-control" required>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<label for="age">Age *</label>
|
|
||||||
<input type="text" name="age" class="form-control" required>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<label for="gender">Gender *</label>
|
|
||||||
<select name="gender" class="form-control" required>
|
|
||||||
<option value="">Select...</option>
|
|
||||||
<option value="male">Male</option>
|
|
||||||
<option value="female">Female</option>
|
|
||||||
</select>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<label for="ethnicity">Type of Application *</label>
|
|
||||||
<select name="applicationType" class="form-control" required>
|
|
||||||
<option value="">Select...</option>
|
|
||||||
<option value="single">Single</option>
|
|
||||||
<option value="couple">Couple</option>
|
|
||||||
<option value="family">Family</option>
|
|
||||||
</select>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<label for="sexualOrientation">Sexual Orientation *</label>
|
|
||||||
<select name="sexualOrientation" class="form-control" required>
|
|
||||||
<option value="">Select...</option>
|
|
||||||
<option value="straight">Straight</option>
|
|
||||||
<option value="gay">Gay</option>
|
|
||||||
<option value="bisexual">Bisexual</option>
|
|
||||||
<option value="other">Other</option>
|
|
||||||
</select>
|
|
||||||
<br><br>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
contactContent() {
|
|
||||||
return /* html */`
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="telegram">Telegram Username *</label>
|
|
||||||
<input type="text" name="telegram" class="form-control" required>
|
|
||||||
<small style="display:block;margin-top:.25rem;color:#666;">A Telegram account is required to be interviewed by the PMA</small>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="email-2">Secondary Email</label>
|
|
||||||
<input type="email" name="email-2" class="form-control">
|
|
||||||
<small style="display:block;margin-top:.25rem;color:#666;">Not required - you may add a secondary email in case our messages don't reach you</small>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="phone">Phone Number</label>
|
|
||||||
<input type="tel" name="phone" class="form-control">
|
|
||||||
<small style="display:block;margin-top:.25rem;color:#666;">Not required, but recommended if you don't provide a Telegram handle.</small>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
personalHistoryContent() {
|
|
||||||
return /* html */`
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="personalHistory">Where did you come from, where did you grow up, and where do you live now? *</label>
|
|
||||||
<textarea name="personalHistory" class="form-control" required minlength="10"></textarea>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
ancestryContent() {
|
|
||||||
return /* html */`
|
|
||||||
<div class="form-group">
|
|
||||||
<p>Please select all that apply to your ancestry/heritage:</p>
|
|
||||||
<div class="ancestry-grid">
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="english"> English</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="irish"> Irish</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="scottish"> Scottish</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="welsh"> Welsh</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="german"> German</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="french"> French</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="dutch"> Dutch</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="scandinavian"> Scandinavian</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="slavic"> Slavic</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="balkan"> Balkan</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="iberian"> Iberian</label>
|
|
||||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="other">Other</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ancestryDetails">Tell us more about your ancestry and family history *</label>
|
|
||||||
<textarea name="ancestryDetails" class="form-control" required minlength="20" placeholder="Please provide details about your family background, heritage, and any ancestral connections you're aware of."></textarea>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
skillsContent() {
|
|
||||||
return /* html */`
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="skills">Describe any special skills or trades you have. *</label>
|
|
||||||
<textarea name="skills" class="form-control" required minlength="50" placeholder="e.g., carpentry, plumbing, electrical, masonry, welding"></textarea>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
interestContent() {
|
|
||||||
return /* html */`
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="interest">Why are you interested in Return To The Land, and how did you find out about us? *</label>
|
|
||||||
<textarea name="interest" class="form-control" required minlength="20"></textarea>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
criminalContent() {
|
|
||||||
return /* html */`
|
|
||||||
<label for="criminal">Do you have a criminal record? If so, please explain. Otherwise, just say "no". *</label>
|
|
||||||
<textarea name="criminal" class="form-control" required></textarea>
|
|
||||||
<br><br>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
politicalContent() {
|
|
||||||
return /* html */`
|
|
||||||
<label for="politicsNotes">Give a quick summary of your political ideas. *</label>
|
|
||||||
<textarea name="politicsNotes" class="form-control" style="width:100%;min-height:120px" required minlength="40"></textarea>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
religiousContent() {
|
|
||||||
return /* html */`
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Do you identify with a particular religion? *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="religionIdent" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="religionIdent" value="no"> No</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="religionName">If yes, which?</label>
|
|
||||||
<input name="religionName" class="form-control" placeholder="e.g., Catholic, Orthodox, Protestant, Deist, Other">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Do you regularly attend services or observances?</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="attendance" value="weekly"> Weekly</label>
|
|
||||||
<label><input type="radio" name="attendance" value="monthly"> Monthly</label>
|
|
||||||
<label><input type="radio" name="attendance" value="occasionally"> Occasionally</label>
|
|
||||||
<label><input type="radio" name="attendance" value="never"> Never</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="philosophy">Briefly describe your moral or philosophical outlook *</label>
|
|
||||||
<textarea name="philosophy" class="form-control" required></textarea>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
federalEmploymentContent() {
|
|
||||||
return /* html */`
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Are you currently employed by, or otherwise receive funds to perform work for, the United States federal government or a contractor/affiliate/partner? *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="employedByGovernment" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="employedByGovernment" value="no"> No</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
socialContent() {
|
|
||||||
return /* html */`
|
|
||||||
<p class="note">Please answer these questions regarding controversial topics. Anything that needs further explanation can be done in the interview.</p>
|
|
||||||
<br>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>I support gay marriage *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="gays" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="gays" value="no"> No</label>
|
|
||||||
<label><input type="radio" name="gays" value="neutral"> Neutral</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>I support transgenderism *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="trannies" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="trannies" value="no"> No</label>
|
|
||||||
<label><input type="radio" name="trannies" value="neutral"> Neutral</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>I support foreign immigration *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="immigration" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="immigration" value="no"> No</label>
|
|
||||||
<label><input type="radio" name="immigration" value="neutral"> Neutral</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>I support the COVID vaccine and mask *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="vax" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="vax" value="no"> No</label>
|
|
||||||
<label><input type="radio" name="vax" value="neutral"> Neutral</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>I support abortion *</label>
|
|
||||||
<div class="form-group">
|
|
||||||
<label><input type="radio" name="abortion" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="abortion" value="no"> No</label>
|
|
||||||
<label><input type="radio" name="abortion" value="neutral"> Neutral</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>I support segregation *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="segregation" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="segregation" value="no"> No</label>
|
|
||||||
<label><input type="radio" name="segregation" value="neutral"> Neutral</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>I support procreation *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label><input type="radio" name="procreation" value="yes" required> Yes</label>
|
|
||||||
<label><input type="radio" name="procreation" value="no"> No</label>
|
|
||||||
<label><input type="radio" name="procreation" value="neutral"> Neutral</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Multiculturalism preference *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="multiculturalism" value="yes" required> I prefer a community with a variety of different ancestral origins</label>
|
|
||||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="multiculturalism" value="no"> I prefer a community where everyone shares common continental ancestry</label>
|
|
||||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="multiculturalism" value="neutral"> Neutral</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>How often do you think about the Roman empire? *</label>
|
|
||||||
<div class="radio-row">
|
|
||||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="romanEmpire" value="daily" required> Every day, at least once</label>
|
|
||||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="romanEmpire" value="weekly"> A few times a week, probably</label>
|
|
||||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="romanEmpire" value="rarely"> Very rarely</label>
|
|
||||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="romanEmpire" value="never"> Never</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("questionnaire-", Questionnaire);
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
:root {
|
|
||||||
--bar-bg: #ccc;
|
|
||||||
--bar-fill: var(--green, #4caf50);
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-container {
|
|
||||||
position: absolute;
|
|
||||||
top: 20vh;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
background: var(--green);
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
margin-top: calc(20vh + 30px);
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, minmax(250px, 1fr));
|
|
||||||
gap: 20px;
|
|
||||||
max-width: 90vw;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section:hover {
|
|
||||||
background: var(--red);
|
|
||||||
color: var(--tan);
|
|
||||||
}
|
|
||||||
|
|
||||||
.section:hover .status {
|
|
||||||
color: var(--tan);
|
|
||||||
}
|
|
||||||
|
|
||||||
.section h2 {
|
|
||||||
margin: 0 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
|
||||||
font-weight: bold;
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Questionnaire Pages */
|
|
||||||
.form-container {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 2rem auto;
|
|
||||||
padding: 2rem;
|
|
||||||
/* background: rgba(255, 255, 255, 0.9); */
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-container input {
|
|
||||||
background: var(--tan);
|
|
||||||
border: 1px solid var(--brown);
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-container select {
|
|
||||||
background: var(--tan);
|
|
||||||
border: 1px solid var(--brown);
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-group { margin-bottom: 1.5rem; }
|
|
||||||
label { display: block; margin-bottom: 0.5rem; font-weight: bold; }
|
|
||||||
|
|
||||||
.form-control {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0.5rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
background: var(--tan);
|
|
||||||
border: 1px solid var(--brown)
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea.form-control { min-height: 120px; resize: vertical; }
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
background-color: var(--green);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn:hover { background-color: var(--dark-green); }
|
|
||||||
|
|
||||||
.btn-outline { background: none; border: 1px solid var(--green); color: var(--green); }
|
|
||||||
|
|
||||||
.radio-row { margin: 0.25rem 0; }
|
|
||||||
.note { color: #444; margin: 0.5rem 0 0 0; }
|
|
||||||
|
|
||||||
/* Grid/option helpers used by ancestry */
|
|
||||||
.ancestry-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
|
|
||||||
.ancestry-option { border: 1px solid var(--brown); padding: 1rem; border-radius: 4px; cursor: pointer; transition: all 0.2s; }
|
|
||||||
.ancestry-option:hover { border-color: var(--green); background-color: rgba(76, 175, 80, 0.1); }
|
|
||||||
.ancestry-option input[type="checkbox"] { margin-right: 0.5rem; }
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Hyperia | Application</title>
|
|
||||||
<link rel="stylesheet" href="_/code/shared.css">
|
|
||||||
<link rel="icon" href="_/icons/logo.svg">
|
|
||||||
<script src="_/code/util.js"></script>
|
|
||||||
<link rel="stylesheet" href="index.css">
|
|
||||||
<script type="module">
|
|
||||||
import NavBar from "./components/NavBar.js"
|
|
||||||
import Questionnaire from "./components/Questionnaire.js"
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav-bar></nav-bar>
|
|
||||||
|
|
||||||
<questionnaire-></questionnaire->
|
|
||||||
|
|
||||||
<div style="position: fixed; bottom: 2vh; left: 1vw">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#items {
|
#items {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 45vh;
|
top: 47vh;
|
||||||
left: 50vw;
|
left: 50vw;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
text-underline-offset: 5px;
|
text-underline-offset: 5px;
|
||||||
transition: background .02s, color .2s;
|
transition: background .02s, color .2s;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
color: black;
|
||||||
|
|
||||||
display: inline-block; /* makes background and padding behave */
|
display: inline-block; /* makes background and padding behave */
|
||||||
padding: 0.2em 0.5em; /* adds breathing room */
|
padding: 0.2em 0.5em; /* adds breathing room */
|
||||||
@@ -51,6 +52,12 @@
|
|||||||
background: var(--red); /* background color works now */
|
background: var(--red); /* background color works now */
|
||||||
color: white; /* optional: change text color for contrast */
|
color: white; /* optional: change text color for contrast */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
#title {
|
||||||
|
font-size: 30vw
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="_/code/util.js"></script>
|
<script src="_/code/util.js"></script>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
@@ -66,11 +73,12 @@
|
|||||||
<img src="_/icons/left_plant.svg" style="position: absolute; left: 25%; top: 23vh; width: 70%; transform: translateX(-50%)">
|
<img src="_/icons/left_plant.svg" style="position: absolute; left: 25%; top: 23vh; width: 70%; transform: translateX(-50%)">
|
||||||
<img src="_/icons/right_plant.svg" style="position: absolute; left: 75%; top: 23vh; width: 70%; transform: translateX(-50%)">
|
<img src="_/icons/right_plant.svg" style="position: absolute; left: 75%; top: 23vh; width: 70%; transform: translateX(-50%)">
|
||||||
<div style="height: 2vh"></div>
|
<div style="height: 2vh"></div>
|
||||||
<span style="font-family: Canterbury; color: black; font-size: 5vh;">A <br>Society</span>
|
<span style="font-family: Canterbury; color: black; font-size: 4.5vh;">A <br>Classical <br> Christian <br> Society</span>
|
||||||
<div style="height: 2vh"></div>
|
<div style="height: 2vh"></div>
|
||||||
<div style="color: black; font-size: 2.2vh; z-index: 1; cursor: default;">
|
<div style="color: black; font-size: 2vh; z-index: 1; cursor: default;">
|
||||||
<a>ABOUT</a> | <a>SERVICES</a> | <a>JOIN</a>
|
<a href="signin">SIGN IN</a>
|
||||||
|
<a href="join">JOIN</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
77
ui/public/pages/join.html
Normal file
77
ui/public/pages/join.html
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Hyperia</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" href="_/icons/logo.svg">
|
||||||
|
<link rel="stylesheet" href="_/code/shared.css">
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--green: #0B5538;
|
||||||
|
--tan: #FFDFB4;
|
||||||
|
--red: #BC1C02;
|
||||||
|
--brown: #c6a476
|
||||||
|
}
|
||||||
|
|
||||||
|
#items {
|
||||||
|
position: absolute;
|
||||||
|
top: 45vh;
|
||||||
|
left: 50vw;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center; /* centers children horizontally */
|
||||||
|
text-align: center; /* ensures text inside spans is centered */
|
||||||
|
}
|
||||||
|
|
||||||
|
#title {
|
||||||
|
font-size: 10vh;
|
||||||
|
position: absolute;
|
||||||
|
left: 2vw;
|
||||||
|
top: 2vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
cursor: default;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 5px;
|
||||||
|
transition: background .02s, color .2s;
|
||||||
|
user-select: none;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: inline-block; /* makes background and padding behave */
|
||||||
|
padding: 0.2em 0.5em; /* adds breathing room */
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--green);
|
||||||
|
color: var(--tan);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:active {
|
||||||
|
background: var(--red); /* background color works now */
|
||||||
|
color: white; /* optional: change text color for contrast */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="_/code/util.js"></script>
|
||||||
|
<script type="module">
|
||||||
|
import PageFooter from "./components/Footer.js"
|
||||||
|
import NavBar from "./components/NavBar.js"
|
||||||
|
import SideBar from "./components/SideBar.js"
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span id="title" style="font-family: Canterbury; color: var(--red); margin-bottom: 10vh">hyperia</span>
|
||||||
|
<div id="items">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
Array.from($("a*")).forEach((link) => {
|
||||||
|
link.addEventListener("click", () => window.history.pushState("", "", link.innerHTML.toLowerCase()))
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
122
ui/public/pages/signin.html
Normal file
122
ui/public/pages/signin.html
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Hyperia</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" href="_/icons/logo.svg">
|
||||||
|
<link rel="stylesheet" href="_/code/shared.css">
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--green: #0B5538;
|
||||||
|
--tan: #FFDFB4;
|
||||||
|
--red: #BC1C02;
|
||||||
|
--brown: #c6a476
|
||||||
|
}
|
||||||
|
|
||||||
|
#items {
|
||||||
|
position: absolute;
|
||||||
|
top: 45vh;
|
||||||
|
left: 50vw;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center; /* centers children horizontally */
|
||||||
|
text-align: center; /* ensures text inside spans is centered */
|
||||||
|
}
|
||||||
|
|
||||||
|
#title {
|
||||||
|
font-size: 10vh;
|
||||||
|
position: absolute;
|
||||||
|
left: 2vw;
|
||||||
|
top: 2vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
cursor: default;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 5px;
|
||||||
|
transition: background .02s, color .2s;
|
||||||
|
user-select: none;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: inline-block; /* makes background and padding behave */
|
||||||
|
padding: 0.2em 0.5em; /* adds breathing room */
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--green);
|
||||||
|
color: var(--tan);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:active {
|
||||||
|
background: var(--red); /* background color works now */
|
||||||
|
color: white; /* optional: change text color for contrast */
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
border-top: 2px solid var(--green);
|
||||||
|
border-bottom: 2px solid var(--green);
|
||||||
|
height: 2em;
|
||||||
|
width: 15vw;
|
||||||
|
padding: 0.2em;
|
||||||
|
transition: border .2s, padding .2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: none;
|
||||||
|
padding: 0.4em;
|
||||||
|
border-top: 2px solid var(--red);
|
||||||
|
border-bottom: 2px solid var(--red);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus::placeholder {
|
||||||
|
color: var(--red)
|
||||||
|
}
|
||||||
|
|
||||||
|
input::placeholder {
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:-webkit-autofill,
|
||||||
|
input:-webkit-autofill:focus {
|
||||||
|
transition: background-color 600000s 0s, color 600000s 0s;
|
||||||
|
}
|
||||||
|
input[data-autocompleted] {
|
||||||
|
background-color: #c7a67b !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
input {
|
||||||
|
width: 50vw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script src="_/code/util.js"></script>
|
||||||
|
<script type="module">
|
||||||
|
import PageFooter from "./components/Footer.js"
|
||||||
|
import NavBar from "./components/NavBar.js"
|
||||||
|
import SideBar from "./components/SideBar.js"
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span onclick="window.location = '/'"id="title" style="cursor: default; font-family: Canterbury; color: var(--red); margin-bottom: 10vh">hyperia</span>
|
||||||
|
<div id="items">
|
||||||
|
<input placeholder="email"></input>
|
||||||
|
<br>
|
||||||
|
<input placeholder="password"></input>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
Array.from($("a*")).forEach((link) => {
|
||||||
|
link.addEventListener("click", () => window.history.pushState("", "", link.innerHTML.toLowerCase()))
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user