forked from ProjectSegfault/website
Merge pull request #62 from ProjectSegfault/pubnix-v2
Split form into reusable components
This commit is contained in:
commit
35c788df0f
@ -1,125 +1,16 @@
|
||||
<script lang="ts">
|
||||
import HCaptcha from "svelte-hcaptcha";
|
||||
let submit = false;
|
||||
|
||||
let showSubmitButton = () => {
|
||||
submit = !submit;
|
||||
};
|
||||
import { Note, Captcha, Form, Meta, TextArea } from "$lib/Form";
|
||||
</script>
|
||||
|
||||
<form
|
||||
action="https://segfautils.projectsegfau.lt/api/form"
|
||||
method="POST"
|
||||
id="contact-form"
|
||||
>
|
||||
<div class="note">
|
||||
<div class="i-fa6-solid:lock" />
|
||||
<b>Your IP will be logged for anti-abuse measures.</b>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
class="form-textbox"
|
||||
placeholder="Your email"
|
||||
required
|
||||
/>
|
||||
<select id="commentType" name="commentType" required class="button">
|
||||
<option value="" selected disabled>Select a type of comment</option>
|
||||
<option value="Feedback">Feedback</option>
|
||||
<option value="Suggestion">Suggestion</option>
|
||||
<option value="Question">Question</option>
|
||||
<option value="Bug">Bug</option>
|
||||
</select>
|
||||
</div>
|
||||
<textarea
|
||||
id="comment"
|
||||
name="message"
|
||||
rows="4"
|
||||
cols="25"
|
||||
required
|
||||
class="form-textbox"
|
||||
placeholder="Your message"
|
||||
/>
|
||||
<div class="note">
|
||||
<div class="i-fa6-solid:circle-info" />
|
||||
<b>The submit button will be visible when you complete the Captcha.</b>
|
||||
</div>
|
||||
<HCaptcha
|
||||
sitekey="67e84266-980c-4050-8a39-142a91928fe8"
|
||||
on:success={showSubmitButton}
|
||||
/>
|
||||
{#if submit}
|
||||
<input type="submit" value="Submit" class="button" />
|
||||
{/if}
|
||||
</form>
|
||||
|
||||
<style>
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.note {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.meta > * {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.meta {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.meta > * {
|
||||
width: calc(100% - 1rem);
|
||||
}
|
||||
|
||||
.meta > *:nth-child(2) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.form-textbox {
|
||||
background-color: var(--secondary);
|
||||
color: var(--text);
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
padding: 0.5rem;
|
||||
font-family: var(--font-primary);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.button {
|
||||
background-color: var(--secondary);
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 0.5rem;
|
||||
cursor: pointer;
|
||||
color: var(--text);
|
||||
font-family: var(--font-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.button:not(select):hover {
|
||||
background-color: var(--accent);
|
||||
text-decoration: none;
|
||||
transition: all 0.5s;
|
||||
color: var(--secondary);
|
||||
}
|
||||
</style>
|
||||
<Form action="https://segfautils.projectsegfau.lt/api/form" method="POST" id="contact-form" >
|
||||
<Note content="Your IP will be logged for anti-abuse measures." icon="i-fa6-solid:lock" />
|
||||
<Meta inputType="email" inputPlaceholder="Your email" selectType="commentType">
|
||||
<option value="" selected disabled>Select a type of comment</option>
|
||||
<option value="Feedback">Feedback</option>
|
||||
<option value="Suggestion">Suggestion</option>
|
||||
<option value="Question">Question</option>
|
||||
<option value="Bug">Bug</option>
|
||||
</Meta>
|
||||
<TextArea id="comment" name="message" placeholder="Your message" />
|
||||
<Captcha />
|
||||
</Form>
|
19
src/lib/Form/Captcha.svelte
Normal file
19
src/lib/Form/Captcha.svelte
Normal file
@ -0,0 +1,19 @@
|
||||
<script>
|
||||
import HCaptcha from "svelte-hcaptcha";
|
||||
import { Note } from "$lib/Form";
|
||||
|
||||
let submit = false;
|
||||
|
||||
let showSubmitButton = () => {
|
||||
submit = !submit;
|
||||
};
|
||||
</script>
|
||||
|
||||
<Note content="The submit button will be visible when you complete the Captcha." icon="i-fa6-solid:circle-info" />
|
||||
<HCaptcha
|
||||
sitekey="67e84266-980c-4050-8a39-142a91928fe8"
|
||||
on:success={showSubmitButton}
|
||||
/>
|
||||
{#if submit}
|
||||
<input type="submit" value="Submit" class="form-button" />
|
||||
{/if}
|
50
src/lib/Form/Form.svelte
Normal file
50
src/lib/Form/Form.svelte
Normal file
@ -0,0 +1,50 @@
|
||||
<script lang="ts">
|
||||
export let action: string;
|
||||
export let method: string;
|
||||
export let id: string;
|
||||
</script>
|
||||
|
||||
<form
|
||||
{action}
|
||||
{method}
|
||||
{id}
|
||||
>
|
||||
<slot />
|
||||
</form>
|
||||
|
||||
<style>
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
:global(.form-button) {
|
||||
background-color: var(--secondary);
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 0.5rem;
|
||||
cursor: pointer;
|
||||
color: var(--text);
|
||||
font-family: var(--font-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
:global(.form-button:not(select):hover) {
|
||||
background-color: var(--accent);
|
||||
text-decoration: none;
|
||||
transition: all 0.5s;
|
||||
color: var(--secondary);
|
||||
}
|
||||
|
||||
:global(.form-textbox) {
|
||||
background-color: var(--secondary);
|
||||
color: var(--text);
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
padding: 0.5rem;
|
||||
font-family: var(--font-primary);
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
47
src/lib/Form/Meta.svelte
Normal file
47
src/lib/Form/Meta.svelte
Normal file
@ -0,0 +1,47 @@
|
||||
<script lang="ts">
|
||||
export let inputType: string;
|
||||
export let inputPlaceholder: string;
|
||||
export let selectType: string;
|
||||
</script>
|
||||
|
||||
<div class="meta">
|
||||
<input
|
||||
type={inputType}
|
||||
name={inputType}
|
||||
class="form-textbox"
|
||||
placeholder={inputPlaceholder}
|
||||
required
|
||||
/>
|
||||
<select name={selectType} required class="form-button">
|
||||
<slot />
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.meta > * {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.meta {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.meta > * {
|
||||
width: calc(100% - 1rem);
|
||||
}
|
||||
|
||||
.meta > *:nth-child(2) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
19
src/lib/Form/Note.svelte
Normal file
19
src/lib/Form/Note.svelte
Normal file
@ -0,0 +1,19 @@
|
||||
<script lang="ts">
|
||||
export let content: string;
|
||||
export let icon: string;
|
||||
</script>
|
||||
|
||||
<div class="note">
|
||||
{#if icon}
|
||||
<div class={icon} />
|
||||
{/if}
|
||||
<b>{content}</b>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.note {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
</style>
|
15
src/lib/Form/TextArea.svelte
Normal file
15
src/lib/Form/TextArea.svelte
Normal file
@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
export let id: string;
|
||||
export let name: string;
|
||||
export let placeholder: string;
|
||||
</script>
|
||||
|
||||
<textarea
|
||||
{id}
|
||||
{name}
|
||||
rows="4"
|
||||
cols="25"
|
||||
required
|
||||
class="form-textbox"
|
||||
{placeholder}
|
||||
/>
|
5
src/lib/Form/index.ts
Normal file
5
src/lib/Form/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export { default as Note } from "./Note.svelte";
|
||||
export { default as Captcha } from "./Captcha.svelte";
|
||||
export { default as Form } from "./Form.svelte";
|
||||
export { default as Meta } from "./Meta.svelte";
|
||||
export { default as TextArea } from "./TextArea.svelte";
|
@ -2,9 +2,11 @@
|
||||
export let title: string;
|
||||
export let description: string;
|
||||
export let marginTop: string;
|
||||
let styles: string = "";
|
||||
export { styles as style };
|
||||
</script>
|
||||
|
||||
<div class="hero" style="margin-top: {marginTop}%;">
|
||||
<div class="hero" style="margin-top: {marginTop}%; {styles}">
|
||||
{#if title}
|
||||
<h1>{title}</h1>
|
||||
{/if}
|
||||
|
Loading…
Reference in New Issue
Block a user