mirror of
https://github.com/ProjectSegfault/website
synced 2026-06-09 18:23:15 +05:30
v3
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import instances from "./instances";
|
||||
import type { PageServerLoad } from "./$types";
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch }) => {
|
||||
return {
|
||||
instances: await fetch("/api/status").then(
|
||||
(res) => res.json()
|
||||
)
|
||||
};
|
||||
};
|
||||
export const load = (() => {
|
||||
const meta = {
|
||||
title: "Instances"
|
||||
}
|
||||
|
||||
return { instances, ...meta };
|
||||
}) satisfies PageServerLoad;
|
||||
@@ -1,91 +1,31 @@
|
||||
<script lang="ts">
|
||||
import { CardInner, CardOuter, LinksOuter, Link } from "$lib/Card";
|
||||
import InstanceLink from "./InstanceLink.svelte";
|
||||
import dayjs from "dayjs";
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
export let data: PageData;
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Our instances | Project Segfault</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Our collection of instances."
|
||||
/>
|
||||
</svelte:head>
|
||||
<div class="h1-no-lg flex flex-col sm:(flex-row items-center) gap-4 !mb-0">
|
||||
<span class="text-4xl font-bold">{data.title}</span>
|
||||
<a href="/instances/advanced" class="button sm:w-fit"><div class="i-ic:outline-computer" /> Advanced</a>
|
||||
</div>
|
||||
|
||||
<h1>Our instances</h1>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<CardOuter>
|
||||
<div class="flex flex-col">
|
||||
{#each data.instances as category}
|
||||
<div class="flex flex-col">
|
||||
{#each data.instances.status as group}
|
||||
<h2>{group.name}</h2>
|
||||
<div class="flex flex-row flex-wrap gap-8">
|
||||
{#each group.data as item}
|
||||
<CardInner
|
||||
title={item.name}
|
||||
description={item.description}
|
||||
icon={item.icon}
|
||||
>
|
||||
<LinksOuter>
|
||||
{#if item.geo}
|
||||
<InstanceLink
|
||||
url={item.geo}
|
||||
item={item.statusGeo}
|
||||
type="geo"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if item.eu}
|
||||
<InstanceLink
|
||||
url={item.eu}
|
||||
item={item.statusEu}
|
||||
type="eu"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if item.us}
|
||||
<InstanceLink
|
||||
url={item.us}
|
||||
item={item.statusUs}
|
||||
type="us"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if item.bp}
|
||||
<InstanceLink
|
||||
url={item.bp}
|
||||
item={item.statusBp}
|
||||
type="backup"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if item.tor}
|
||||
<InstanceLink
|
||||
url={item.tor}
|
||||
type="tor"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if item.torBp}
|
||||
<InstanceLink
|
||||
url={item.torBp}
|
||||
type="torBp"
|
||||
/>
|
||||
{/if}
|
||||
</LinksOuter>
|
||||
</CardInner>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
<h2>{category.name}</h2>
|
||||
<div class="flex flex-row flex-wrap gap-4">
|
||||
{#each category.data as instance}
|
||||
<a href={instance.geo || instance.eu} class="flex flex-row items-center gap-4 rounded bg-secondary p-4 w-110 no-underline text-text">
|
||||
{#if instance.icon}
|
||||
<img src={instance.icon} alt="{instance.name} logo" class="h-20 rounded">
|
||||
{/if}
|
||||
<div>
|
||||
<span class="text-2xl">{instance.name}</span>
|
||||
<p>{instance.description}</p>
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</CardOuter>
|
||||
|
||||
<span class="bg-secondary w-fit p-2 rounded-2"
|
||||
>Instances status last updated: {dayjs
|
||||
.unix(data.instances.updated)
|
||||
.format("DD/MM/YYYY HH:mm:ss")}
|
||||
</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Link } from "$lib/Card";
|
||||
|
||||
export let url: string;
|
||||
export let item: any = 200;
|
||||
export let type: "geo" | "eu" | "us" | "backup" | "tor" | "torBp" = "geo";
|
||||
</script>
|
||||
|
||||
{#if type === "tor" || type === "torBp"}
|
||||
<Link
|
||||
{url}
|
||||
class="torcolored"
|
||||
>
|
||||
<div class="flex flex-row items-center gap-1">
|
||||
<div class="i-simple-icons:tor {type === "torBp" ? "" : "h-6 w-6"}" />
|
||||
{#if type === "torBp"}
|
||||
<span class="text-base">Backup</span>
|
||||
{/if}
|
||||
</div>
|
||||
</Link>
|
||||
{:else}
|
||||
<Link
|
||||
{url}
|
||||
class="web {item === 200
|
||||
? ''
|
||||
: 'pointer-events-none cursor-default opacity-50'}"
|
||||
>
|
||||
<div class="flex items-center gap-2 text-base">
|
||||
<div
|
||||
class={item === 200
|
||||
? "i-ic:outline-open-in-new text-xl"
|
||||
: "i-ic:outline-close"}
|
||||
/>
|
||||
<span>
|
||||
{#if item !== 200}
|
||||
({item})
|
||||
{/if}
|
||||
{#if type === "geo"}
|
||||
GeoDNS
|
||||
{:else if type === "eu"}
|
||||
EU
|
||||
{:else if type === "us"}
|
||||
US
|
||||
{:else if type === "backup"}
|
||||
Backup
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
{/if}
|
||||
@@ -0,0 +1,10 @@
|
||||
import instances from "../instances";
|
||||
import type { PageServerLoad } from "./$types";
|
||||
|
||||
export const load = (() => {
|
||||
const meta = {
|
||||
title: "Instances"
|
||||
}
|
||||
|
||||
return { instances, ...meta };
|
||||
}) satisfies PageServerLoad;
|
||||
@@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
export let data: PageData;
|
||||
</script>
|
||||
|
||||
<div class="h1-no-lg flex flex-col sm:(flex-row items-center) gap-4 !mb-0">
|
||||
<span class="text-4xl font-bold">{data.title}</span>
|
||||
<a href="/instances" class="button sm:w-fit"><div class="i-ic:outline-computer" /> Simple</a>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
{#each data.instances as category}
|
||||
{#each category.data as instance}
|
||||
<h2>{instance.name}</h2>
|
||||
<div class="flex flex-row gap-2">
|
||||
{#if instance.geo}
|
||||
<a href={instance.geo}>GeoDNS</a>
|
||||
{/if}
|
||||
{#if instance.eu}
|
||||
<a href={instance.eu}>EU</a>
|
||||
{/if}
|
||||
{#if instance.us}
|
||||
<a href={instance.us}>US</a>
|
||||
{/if}
|
||||
{#if instance.bp}
|
||||
<a href={instance.bp}>Backup</a>
|
||||
{/if}
|
||||
{#if instance.tor}
|
||||
<a href={instance.tor}>Tor</a>
|
||||
{/if}
|
||||
{#if instance.torBp}
|
||||
<a href={instance.torBp}>Tor backup</a>
|
||||
{/if}
|
||||
{#if instance.i2p}
|
||||
<a href={instance.i2p}>I2P</a>
|
||||
{/if}
|
||||
{#if instance.i2pBp}
|
||||
<a href={instance.i2pBp}>I2P backup</a>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{/each}
|
||||
</div>
|
||||
@@ -0,0 +1,208 @@
|
||||
interface Instances {
|
||||
name: string;
|
||||
data: Instance[];
|
||||
}
|
||||
|
||||
interface Instance {
|
||||
name: string;
|
||||
description: string;
|
||||
geo?: string;
|
||||
eu?: string;
|
||||
us?: string;
|
||||
bp?: string;
|
||||
tor?: string;
|
||||
torBp?: string;
|
||||
i2p?: string;
|
||||
i2pBp?: string;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
const instances: Instances[] = [
|
||||
{
|
||||
name: "Privacy front-ends",
|
||||
data: [
|
||||
{
|
||||
name: "Invidious",
|
||||
description: "A frontend for YouTube.",
|
||||
eu: "https://invidious.projectsegfau.lt/",
|
||||
us: "https://inv.us.projectsegfau.lt",
|
||||
bp: "https://inv.bp.projectsegfau.lt",
|
||||
tor: "http://inv.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
torBp: "http://invbp.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http:////pjsfhqamc7k6htnumrvn4cwqqdoggeepj7u5viyimgnxg3gar72q.b32.i2p",
|
||||
i2pBp: "http://pjsfi2szfkb4guqzmfmlyq4no46fayertjrwt4h2uughccrh2lvq.b32.i2p",
|
||||
icon: "/icons/invidious.svg"
|
||||
},
|
||||
{
|
||||
name: "Librarian",
|
||||
description: "A frontend for LBRY/Odysee.",
|
||||
geo: "https://lbry.projectsegfau.lt/",
|
||||
eu: "https://lbry.eu.projectsegfau.lt/",
|
||||
tor: "http://lbry.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsf7uucpqf2crcmfo3nvwdmjhirxxjfyuvibdfp5x3af2ghqnaa.b32.i2p",
|
||||
icon: "/icons/librarian.png"
|
||||
},
|
||||
{
|
||||
name: "Libreddit",
|
||||
description: "A frontend for Reddit.",
|
||||
geo: "https://libreddit.projectsegfau.lt/",
|
||||
eu: "https://libreddit.eu.projectsegfau.lt/",
|
||||
us: "https://libreddit.us.projectsegfau.lt",
|
||||
tor: "http://libreddit.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfkref7g66mji45kyccqnn5hmjtjp3cfodozabpyplj2rmv5sa.b32.i2p",
|
||||
icon: "/icons/libreddit.png"
|
||||
},
|
||||
{
|
||||
name: "Nitter",
|
||||
description: "A frontend for Twitter.",
|
||||
geo: "https://nitter.projectsegfau.lt/",
|
||||
eu: "https://nitter.eu.projectsegfau.lt/",
|
||||
us: "https://nitter.us.projectsegfau.lt",
|
||||
tor: "http://nitter.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfs4ukb6prmfx3qx3a5ef2cpcupkvcrxdh72kqn2rxc2cw4nka.b32.i2p",
|
||||
icon: "/icons/nitter.png"
|
||||
},
|
||||
{
|
||||
name: "Piped",
|
||||
description: "Another frontend for YouTube.",
|
||||
eu: "https://piped.projectsegfau.lt/",
|
||||
us: "https://piped.us.projectsegfau.lt",
|
||||
icon: "/icons/piped.svg"
|
||||
},
|
||||
{
|
||||
name: "Beatbump",
|
||||
description: "A frontend for YouTube Music.",
|
||||
geo: "https://bb.projectsegfau.lt/",
|
||||
eu: "https://bb.eu.projectsegfau.lt/",
|
||||
us: "https://bb.us.projectsegfau.lt/",
|
||||
tor: "http://beatbump.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsflmvtqax7ii44qy4ladap65c3kqspbs7h7krqy7x43uovklla.b32.i2p",
|
||||
icon: "/icons/beatbump.svg"
|
||||
},
|
||||
{
|
||||
name: "BreezeWiki",
|
||||
description: "A frontend for Fandom.",
|
||||
geo: "https://bw.projectsegfau.lt/",
|
||||
eu: "https://bw.eu.projectsegfau.lt/",
|
||||
us: "https://bw.us.projectsegfau.lt/",
|
||||
tor: "http://breezewiki.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfk4xvekoc7wx4pteevp3q2wy7jmzlem7rvl74nx33zkdr4vyq.b32.i2p",
|
||||
icon: "/icons/breezewiki.svg"
|
||||
},
|
||||
{
|
||||
name: "Scribe",
|
||||
description: "A frontend for Medium.",
|
||||
geo: "https://scribe.projectsegfau.lt/",
|
||||
eu: "https://scribe.eu.projectsegfau.lt/",
|
||||
us: "https://scribe.us.projectsegfau.lt/",
|
||||
tor: "http://scribe.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsflkkkcn33ahmzmpyq6idy2knkzh4atp7zaetqfsnenpyori6a.b32.i2p"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Useful tools and services",
|
||||
data: [
|
||||
{
|
||||
name: "Element",
|
||||
description: "A feature-rich Matrix client.",
|
||||
eu: "https://chat.projectsegfau.lt/",
|
||||
tor: "http://element.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfiixntiokc4ioroivnw7dd5hhqmvn2pt2jwfgrqdex5qjnroq.b32.i2p",
|
||||
icon: "/icons/element.svg"
|
||||
},
|
||||
{
|
||||
name: "Hydrogen",
|
||||
description: "A lightweight Matrix client.",
|
||||
eu: "https://hydrogen.projectsegfau.lt/",
|
||||
tor: "http://hydrogen.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfoanqklg3eb3ktvqwmpyiy54b77orr7bmymkwmu56c3zjfltq.b32.i2p",
|
||||
icon: "/icons/hydrogen.svg"
|
||||
},
|
||||
{
|
||||
name: "Cinny",
|
||||
description: "An elegant Matrix client.",
|
||||
eu: "https://cinny.projectsegfau.lt/",
|
||||
tor: "http://cinny.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfgcl4gfbfrk5qte7qb7hqnfwyhflrjcqdldlzmy6yyr2l65oa.b32.i2p",
|
||||
icon: "/icons/cinny.svg"
|
||||
},
|
||||
{
|
||||
name: "SearXNG",
|
||||
description: "A private meta-search engine.",
|
||||
eu: "https://search.projectsegfau.lt/",
|
||||
us: "https://search.us.projectsegfau.lt",
|
||||
tor: "http://search.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfwklrellqoj275kzeu2tz4c3j5zktnqod56s7l5dc25ro3wgq.b32.i2p",
|
||||
icon: "/icons/searxng.svg"
|
||||
},
|
||||
{
|
||||
name: "Gitea",
|
||||
description: "A web interface for Git, alternative to GitHub.",
|
||||
eu: "https://git.projectsegfau.lt/",
|
||||
tor: "http://git.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfdrtv2465bisenvzhfvdleznx4arlih2hlnrhpzugailnm7iq.b32.i2p",
|
||||
icon: "/icons/gitea.png"
|
||||
},
|
||||
{
|
||||
name: "Akkoma",
|
||||
description: "Federated microblogging platform.",
|
||||
eu: "https://social.projectsegfau.lt/",
|
||||
tor: "http://social.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsflarasgpaod2wqccnl7dbolexm7awjz7atqe73nfkhckr66ca.b32.i2p",
|
||||
icon: "/icons/akkoma.png"
|
||||
},
|
||||
{
|
||||
name: "Vikunja",
|
||||
description: "A task management platform.",
|
||||
eu: "https://todo.projectsegfau.lt/",
|
||||
tor: "http://todo.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
|
||||
i2p: "http://pjsfivs2sxudfy65kojxqophc6vqjqdr6woczy6hzaxvxvbj3bkq.b32.i2p",
|
||||
icon: "/icons/vikunja.png"
|
||||
},
|
||||
{
|
||||
name: "Jitsi",
|
||||
description: "An open source video conferencing platform.",
|
||||
eu: "https://jitsi.projectsegfau.lt",
|
||||
icon: "/icons/jitsi.svg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Internal services",
|
||||
data: [
|
||||
{
|
||||
name: "Portainer",
|
||||
description: "Portainer instance for our servers.",
|
||||
eu: "https://portainer.projectsegfau.lt/",
|
||||
icon: "/icons/portainer.png"
|
||||
},
|
||||
{
|
||||
name: "Authentik",
|
||||
description: "Our OAuth provider.",
|
||||
eu: "https://sekuritee.projectsegfau.lt/",
|
||||
icon: "/icons/authentik.png"
|
||||
},
|
||||
{
|
||||
name: "mailcow",
|
||||
description: "Our mail server and webmail.",
|
||||
eu: "https://mail.projectsegfau.lt/",
|
||||
icon: "/icons/mailcow.svg"
|
||||
},
|
||||
{
|
||||
name: "Plausible analytics",
|
||||
description: "Analytics for our website.",
|
||||
eu: "https://analytics.projectsegfau.lt/projectsegfau.lt",
|
||||
icon: "/icons/plausible.png"
|
||||
},
|
||||
{
|
||||
name: "MediaWiki",
|
||||
description: "Our wiki.",
|
||||
eu: "https://wiki.projectsegfau.lt/",
|
||||
icon: "/icons/mediawiki.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default instances;
|
||||
Reference in New Issue
Block a user