add pubnix

This commit is contained in:
Akis 2023-01-07 19:29:58 +02:00
parent 24fcc0f54e
commit 4f52c71c7a
Signed by untrusted user: akis
GPG Key ID: 267BF5C6677944ED
11 changed files with 264 additions and 19 deletions

View File

@ -1,7 +1,13 @@
<script lang="ts"> <script lang="ts">
export let inputType: string = ""; export let inputType: string = "";
export let inputName: string = "";
export let inputPlaceholder: string = ""; export let inputPlaceholder: string = "";
export let select: boolean = true;
export let selectType: string = ""; export let selectType: string = "";
export let input2: boolean = false;
export let input2Type: string = "";
export let input2Name: string = "";
export let input2Placeholder: string = "";
</script> </script>
<div <div
@ -9,11 +15,21 @@
> >
<input <input
type={inputType} type={inputType}
name={inputType} name={inputName}
class="form-textbox" class="form-textbox"
placeholder={inputPlaceholder} placeholder={inputPlaceholder}
required required
/> />
{#if input2}
<input
type={input2Type}
name={input2Name}
class="form-textbox"
placeholder={input2Placeholder}
required
/>
{/if}
{#if select}
<select <select
name={selectType} name={selectType}
required required
@ -21,12 +37,15 @@
> >
<slot /> <slot />
</select> </select>
{/if}
</div> </div>
<style> {#if select}
<style>
@media screen and (max-width: 640px) { @media screen and (max-width: 640px) {
div > :nth-child(2) { div > :nth-child(2) {
width: 100%; width: 100%;
} }
} }
</style> </style>
{/if}

View File

@ -10,13 +10,13 @@
let innerWidth: number = 0; let innerWidth: number = 0;
$: showMenuButton = innerWidth < 1030; $: showMenuButton = innerWidth < 1090;
let menuOpen = false; let menuOpen = false;
$: menuOpen = innerWidth > 1030; $: menuOpen = innerWidth > 1090;
$: menuOpenMobile = innerWidth < 1030 && menuOpen; $: menuOpenMobile = innerWidth < 1090 && menuOpen;
let showThemeToggle: boolean = true; let showThemeToggle: boolean = true;
@ -35,6 +35,7 @@
const menus = [ const menus = [
{ name: "Instances", url: "/instances" }, { name: "Instances", url: "/instances" },
{ name: "Donate", url: "/donate" }, { name: "Donate", url: "/donate" },
{ name: "Pubnix", url: "/pubnix" },
{ name: "Contact us", url: "/contact" }, { name: "Contact us", url: "/contact" },
{ name: "Our team", url: "/team" }, { name: "Our team", url: "/team" },
{ name: "Timeline", url: "/timeline" }, { name: "Timeline", url: "/timeline" },
@ -160,7 +161,7 @@
@apply border-b border-b-solid border-b-grey; @apply border-b border-b-solid border-b-grey;
} }
@media (min-width: 1030px) { @media (min-width: 1090px) {
.hasJS { .hasJS {
flex-direction: row; flex-direction: row;
padding-top: 0; padding-top: 0;

View File

@ -26,6 +26,7 @@
/> />
<Meta <Meta
inputType="email" inputType="email"
inputName="email"
inputPlaceholder="Your email" inputPlaceholder="Your email"
selectType="commentType" selectType="commentType"
> >

View File

@ -0,0 +1,15 @@
import type { PageServerLoad } from "./$types";
export const load = (async ({ fetch }) => {
try {
const request = await fetch("https://publapi.projectsegfau.lt/online");
if (request.ok) {
return request.json();
} else {
return { error: true, message: "Error: " + request.status };
}
} catch (err) {
return { error: true, message: "Error: " + err };
}
}) satisfies PageServerLoad;

View File

@ -0,0 +1,63 @@
<script lang="ts">
import Hero from "$lib/Hero.svelte";
import LinkButton from "$lib/LinkButton.svelte";
import type { PageData } from "./$types";
export let data: PageData;
</script>
<svelte:head>
<title>Pubnix | Project Segfault</title>
</svelte:head>
<Hero marginTop="4">
<h1 class="text-5xl font-800">
<span class="text-accent">Project Segfault</span> pubnix
</h1>
<div
class="flex flex-col sm:flex-row justify-center items-center gap-4 m-4"
>
<LinkButton
url="/pubnix/register"
title="Register"
icon="i-ic:outline-plus"
/>
<LinkButton
url="/pubnix/users"
title="Users"
icon="i-ic:outline-people text-xl"
/>
<LinkButton
url="/pubnix/faq"
title="FAQ"
icon="i-ic:outline-question-mark"
/>
</div>
</Hero>
<div class="flex flex-col items-center text-center mt-16">
<h1>Online users</h1>
{#if !data.error}
{#if data.users.length > 0}
<div class="flex flex-col gap-4">
{#each data.users as user}
<div class="flex flex-row gap-4">
<div class="flex flex-col">
<span class="text-2xl font-800">{user.username}</span>
<span class="text-sm">{user.email}</span>
</div>
<div class="flex flex-col">
<span class="text-sm">Joined</span>
<span class="text-sm">{user.joined}</span>
</div>
</div>
{/each}
</div>
{:else}
<p>No users online</p>
{/if}
{:else}
<p>{data.message}</p>
{/if}
</div>

View File

@ -0,0 +1,12 @@
<svelte:head>
<title>Pubnix FAQ | Project Segfault</title>
</svelte:head>
<div class="flex flex-col items-center m-auto text-center prose justify-center">
<h1>Pubnix FAQ</h1>
<p>Here are some frequently asked questions about the pubnix.</p>
<h2>What is a pubnix?</h2>
<span>A pubnix is a [[Unix?]] server provided by a person or a group to a group for non-commercial recreational goals.</span>
</div>

View File

@ -0,0 +1,40 @@
import type { Actions } from "./$types";
import Joi from "joi";
import { fail } from "@sveltejs/kit";
import { env } from "$env/dynamic/private";
export const actions: Actions = {
default: async ({ request, fetch, getClientAddress }) => {
const formData = await request.formData();
const BodyTypeSchema = Joi.object({
username: Joi.string().required(),
email: Joi.string().email().required()
});
if (BodyTypeSchema.validate(Object.fromEntries(formData.entries())).error) {
return fail(400, { error: true, message: String(BodyTypeSchema.validate(Object.fromEntries(formData.entries())).error) });
} else {
const request = await fetch("https://publapi.projectsegfau.lt/signup", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
username: formData.get("username"),
email: formData.get("email"),
ip: getClientAddress()
})
}).then((res) => res.json())
.catch((err) => {
return fail(400, { error: true, message: "Error: " + err });
});
if (request.ok) {
return { success: true, message: request.message, username: request.username, email: request.email };
} else {
return fail(400, { error: true, message: "Error: " + request.status });
}
}
}
}

View File

@ -0,0 +1,41 @@
<script lang="ts">
import type { ActionData } from "./$types";
import { Note, Meta } from "$lib/Form";
export let form: ActionData;
</script>
<svelte:head>
<title>Pubnix registration | Project Segfault</title>
</svelte:head>
<div class="pubnix-form flex flex-col items-center text-center">
<h2>Pubnix registration</h2>
<form
method="POST"
class="flex flex-col gap-4 w-fit"
>
<Note
content="Your IP will be logged for anti-abuse measures."
icon="i-ic:outline-lock text-xl"
/>
<Meta
inputType="email"
inputName="email"
inputPlaceholder="Your email"
input2
input2Type="text"
input2Placeholder="Your username"
input2Name="username"
select={false}
/>
{#if form?.success}
{form.message}
{/if}
{#if form?.error}
{form.message}
{/if}
<button type="submit" class="form-button">Submit</button>
</form>
</div>

View File

@ -0,0 +1,15 @@
import type { PageServerLoad } from "./$types";
export const load = (async ({ fetch }) => {
try {
const request = await fetch("https://publapi.projectsegfau.lt/users");
if (request.ok) {
return request.json();
} else {
return { error: true, message: "Error: " + request.status };
}
} catch (err) {
return { error: true, message: "Error: " + err };
}
}) satisfies PageServerLoad;

View File

@ -0,0 +1,38 @@
<script lang="ts">
import Hero from "$lib/Hero.svelte";
import LinkButton from "$lib/LinkButton.svelte";
import type { PageData } from "./$types";
export let data: PageData;
</script>
<svelte:head>
<title>Pubnix users | Project Segfault</title>
</svelte:head>
<div class="flex flex-col items-center text-center">
<h1>All users</h1>
{#if !data.error}
{#if data.users.length > 0}
<div class="flex flex-col gap-4">
{#each data.users as user}
<div class="flex flex-row gap-4">
<div class="flex flex-col">
<span class="text-2xl font-800">{user.username}</span>
<span class="text-sm">{user.email}</span>
</div>
<div class="flex flex-col">
<span class="text-sm">Joined</span>
<span class="text-sm">{user.joined}</span>
</div>
</div>
{/each}
</div>
{:else}
<p>There are no users</p>
{/if}
{:else}
<p>{data.message}</p>
{/if}
</div>

View File

@ -50,7 +50,7 @@ export default defineConfig({
lg: "1024px", lg: "1024px",
xl: "1280px", xl: "1280px",
"2xl": "1536px", "2xl": "1536px",
nav: "1030px" nav: "1090px"
} }
}, },