forked from ProjectSegfault/website
implement state api
This commit is contained in:
3815
pnpm-lock.yaml
generated
3815
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
131
src/lib/Announcements.svelte
Normal file
131
src/lib/Announcements.svelte
Normal file
@ -0,0 +1,131 @@
|
||||
<script lang="ts">
|
||||
import fetchState from "$lib/fetchState";
|
||||
|
||||
const promise = fetchState("announcements");
|
||||
|
||||
import Note from "$lib/Form/Note.svelte";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
let announcements: any = [];
|
||||
async function fetchAnnouncements() {
|
||||
const url = `https://segfautils.projectsegfau.lt/api/announcements`;
|
||||
const response = await fetch(url);
|
||||
announcements = await response.json();
|
||||
return announcements;
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await promise}
|
||||
<span />
|
||||
{:then state}
|
||||
{#if state.enabled === "true"}
|
||||
<div class="announcements">
|
||||
{#await fetchAnnouncements()}
|
||||
<span />
|
||||
{:then}
|
||||
<div class="announcement-container">
|
||||
<div class="announcement">
|
||||
<div class="general">
|
||||
{#if announcements.severity === "info"}
|
||||
<div class="i-fa6-solid:circle-info" />
|
||||
{:else}
|
||||
<div class="i-fa6-solid:triangle-exclamation" />
|
||||
{/if}
|
||||
<span>
|
||||
{dayjs
|
||||
.unix(announcements.created)
|
||||
.format("DD/MM/YYYY HH:mm")}
|
||||
</span>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h1>{announcements.title}</h1>
|
||||
</div>
|
||||
|
||||
{#if announcements.link}
|
||||
<div class="read-more">
|
||||
<a href={announcements.link}>Read more...</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:catch}
|
||||
<span />
|
||||
{/await}
|
||||
</div>
|
||||
|
||||
<noscript>
|
||||
<div class="no-js">
|
||||
<Note
|
||||
content="Announcements do not work without JavaScript enabled."
|
||||
/>
|
||||
</div>
|
||||
<style>
|
||||
.announcements {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</noscript>
|
||||
|
||||
{#if announcements.severity === "info"}
|
||||
<style>
|
||||
.announcement {
|
||||
background-color: #8caaee;
|
||||
}
|
||||
</style>
|
||||
{:else if announcements.severity === "low"}
|
||||
<style>
|
||||
.announcement {
|
||||
background-color: #a6d189;
|
||||
}
|
||||
</style>
|
||||
{:else if announcements.severity === "medium"}
|
||||
<style>
|
||||
.announcement {
|
||||
background-color: #e5c890;
|
||||
}
|
||||
</style>
|
||||
{:else if announcements.severity === "high"}
|
||||
<style>
|
||||
.announcement {
|
||||
background-color: #e78284;
|
||||
}
|
||||
</style>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.announcement-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.announcement {
|
||||
color: #252525 !important;
|
||||
padding: 2rem 1rem;
|
||||
border-radius: 10px;
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.announcement a {
|
||||
color: #252525;
|
||||
}
|
||||
|
||||
.announcement .general {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.no-js {
|
||||
@apply flex justify-center text-center text-red;
|
||||
}
|
||||
</style>
|
||||
{:else}
|
||||
<div class="flex items-center gap-1 text-center justify-center mt-16">
|
||||
<div class="i-fa6-solid:circle-info" />
|
||||
<span>Announcements are currently disabled.</span>
|
||||
</div>
|
||||
{/if}
|
||||
{/await}
|
@ -1,27 +1,43 @@
|
||||
<script lang="ts">
|
||||
import { Note, Captcha, Form, Meta, TextArea } from "$lib/Form";
|
||||
import fetchState from "$lib/fetchState";
|
||||
|
||||
const promise = fetchState("form");
|
||||
</script>
|
||||
|
||||
<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>
|
||||
{#await promise}
|
||||
loading
|
||||
{:then state}
|
||||
{#if state.enabled === "true"}
|
||||
<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>
|
||||
{:else}
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="i-fa6-solid:circle-info" />
|
||||
<span>The contact form is currently disabled.</span>
|
||||
</div>
|
||||
{/if}
|
||||
{/await}
|
||||
|
@ -18,4 +18,4 @@
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -38,7 +38,10 @@
|
||||
href={url}>{name}</a
|
||||
>
|
||||
{/each}
|
||||
<a href="https://matrix.to/#/#project-segfault:projectsegfau.lt/" class="icon">
|
||||
<a
|
||||
href="https://matrix.to/#/#project-segfault:projectsegfau.lt/"
|
||||
class="icon"
|
||||
>
|
||||
<div class="i-simple-icons:matrix" />
|
||||
<span>Matrix</span>
|
||||
</a>
|
||||
|
@ -15,8 +15,11 @@
|
||||
|
||||
<DarkMode bind:theme />
|
||||
|
||||
<button on:click={toggle} class="cursor-pointer flex items-center py-1 px-0 bg-transparent border-0 font-[var(--font-primary)] color-[var(--text)]">
|
||||
<div class="i-fa6-solid:{theme === "dark" ? "sun" : "moon"}" />
|
||||
<button
|
||||
on:click={toggle}
|
||||
class="cursor-pointer flex items-center py-1 px-0 bg-transparent border-0 font-[var(--font-primary)] color-[var(--text)]"
|
||||
>
|
||||
<div class="i-fa6-solid:{theme === 'dark' ? 'sun' : 'moon'}" />
|
||||
<span class="ml-2">Toggle theme</span>
|
||||
</button>
|
||||
|
||||
@ -27,4 +30,4 @@
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
7
src/lib/fetchState.ts
Normal file
7
src/lib/fetchState.ts
Normal file
@ -0,0 +1,7 @@
|
||||
let state: any = [];
|
||||
export default async function fetchState(module: "announcements" | "form") {
|
||||
const url = `https://segfautils.projectsegfau.lt/api/set/${module}`;
|
||||
const response = await fetch(url);
|
||||
state = await response.json();
|
||||
return state;
|
||||
}
|
@ -2,20 +2,9 @@
|
||||
import SvelteSeo from "svelte-seo";
|
||||
import Hero from "$lib/Hero.svelte";
|
||||
import LinkButton from "$lib/LinkButton.svelte";
|
||||
import Note from "$lib/Form/Note.svelte";
|
||||
import dayjs from "dayjs";
|
||||
import Announcements from "$lib/Announcements.svelte";
|
||||
|
||||
let description: string = "Open source development and hosted services.";
|
||||
|
||||
let announcements: any = [];
|
||||
async function fetchAnnouncements() {
|
||||
const url = `https://segfautils.projectsegfau.lt/api/announcements`;
|
||||
const response = await fetch(url);
|
||||
announcements = await response.json();
|
||||
return announcements;
|
||||
}
|
||||
|
||||
const promise = fetchAnnouncements();
|
||||
</script>
|
||||
|
||||
<SvelteSeo title="Home | Project Segfault" {description} />
|
||||
@ -41,76 +30,7 @@
|
||||
</div>
|
||||
</Hero>
|
||||
|
||||
<div class="announcements">
|
||||
{#await promise}
|
||||
<span />
|
||||
{:then}
|
||||
<div class="announcement-container">
|
||||
<div class="announcement">
|
||||
<div class="general">
|
||||
{#if announcements.severity === "info"}
|
||||
<div class="i-fa6-solid:circle-info" />
|
||||
{:else}
|
||||
<div class="i-fa6-solid:triangle-exclamation" />
|
||||
{/if}
|
||||
<span>
|
||||
{dayjs
|
||||
.unix(announcements.created)
|
||||
.format("DD/MM/YYYY HH:mm")}
|
||||
</span>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h1>{announcements.title}</h1>
|
||||
</div>
|
||||
|
||||
{#if announcements.link}
|
||||
<div class="read-more">
|
||||
<a href={announcements.link}>Read more...</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:catch}
|
||||
<span />
|
||||
{/await}
|
||||
</div>
|
||||
|
||||
<noscript>
|
||||
<div class="no-js">
|
||||
<Note content="Announcements do not work without JavaScript enabled." />
|
||||
</div>
|
||||
<style>
|
||||
.announcements {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</noscript>
|
||||
|
||||
{#if announcements.severity === "info"}
|
||||
<style>
|
||||
.announcement {
|
||||
background-color: #8caaee;
|
||||
}
|
||||
</style>
|
||||
{:else if announcements.severity === "low"}
|
||||
<style>
|
||||
.announcement {
|
||||
background-color: #a6d189;
|
||||
}
|
||||
</style>
|
||||
{:else if announcements.severity === "medium"}
|
||||
<style>
|
||||
.announcement {
|
||||
background-color: #e5c890;
|
||||
}
|
||||
</style>
|
||||
{:else if announcements.severity === "high"}
|
||||
<style>
|
||||
.announcement {
|
||||
background-color: #e78284;
|
||||
}
|
||||
</style>
|
||||
{/if}
|
||||
<Announcements />
|
||||
|
||||
<style>
|
||||
.buttons {
|
||||
@ -127,33 +47,4 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.announcement-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.announcement {
|
||||
color: #252525 !important;
|
||||
padding: 2rem 1rem;
|
||||
border-radius: 10px;
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.announcement a {
|
||||
color: #252525;
|
||||
}
|
||||
|
||||
.announcement .general {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.no-js {
|
||||
@apply flex justify-center text-center text-red;
|
||||
}
|
||||
</style>
|
||||
|
@ -14,5 +14,6 @@ description: We're not anarchists, so we have some rules.
|
||||
5. While we do try to keep your data safe, you have to acknowledge that **we are not responsible** if anything **unintentional** happens (such as **data loss**, **inability to extract your data** due |