Convert to static site

This commit is contained in:
Korbs 2024-10-24 14:05:27 -04:00
parent 72a2c018af
commit 07efc68286
16 changed files with 12 additions and 527 deletions

View file

@ -1,11 +1,9 @@
FROM node:lts AS runtime
FROM node:lts AS build
WORKDIR /app
COPY . .
RUN npm i
RUN npm run build
ENV HOST=0.0.0.0
ENV PORT=4321
EXPOSE 4321
CMD node ./dist/server/entry.mjs
FROM httpd:2.4 AS runtime
COPY --from=build /app/dist /usr/local/apache2/htdocs/
EXPOSE 80

View file

@ -1,8 +1,5 @@
import { defineConfig } from 'astro/config';
import markdoc from '@astrojs/markdoc';
import AutoImport from 'astro-auto-import';
import keystatic from '@keystatic/astro';
import node from '@astrojs/node';
import robotsTxt from 'astro-robots-txt';
import mdx from '@astrojs/mdx';
import vue from "@astrojs/vue";
@ -16,9 +13,7 @@ export default defineConfig({
'/docs/': '/docs/minpluto/introduction/',
'/docs/minpluto': '/docs/minpluto/introduction/' // ?
},
integrations: [markdoc(), ...(process.env.SKIP_KEYSTATIC ? [] : [keystatic()]), AutoImport({
imports: ['./src/components/keystatic/Image.astro', './src/components/init/SoftwareItem.astro']
}), mdx(), robotsTxt({
integrations: [markdoc(), mdx(), robotsTxt({
policy: [{
userAgent: 'Googlebot',
disallow: '/'
@ -72,10 +67,7 @@ export default defineConfig({
disallow: '/'
}]
}), vue()],
output: 'server',
adapter: node({
mode: 'standalone'
}),
output: 'static',
server: {
port: 2014,
host: true

BIN
bun.lockb

Binary file not shown.

View file

@ -1,212 +0,0 @@
import { config, fields, collection } from '@keystatic/core';
import { block, inline, wrapper } from '@keystatic/core/content-components'
export default config({
ui: {
brand: {
name: 'SudoVanilla CMS',
mark: ({ colorScheme }) => {
let path = colorScheme === 'dark'
? 'https://md.sudovanilla.org/images/sv-logo-4.png'
: 'https://md.sudovanilla.org/images/SudoVanilla%20Logo%20-%20Purple.svg';
return <img src={path} height={24} />
},
},
navigation: {
'blog': ['posts', 'recommended_reading'],
'documentations': ['docs_minpluto', 'docs_zorn', 'docs_penpot'],
'others': ['init_privacy']
},
},
storage: {
kind: 'local',
},
collections: {
posts: collection({
label: 'Posts',
slugField: 'url',
path: 'src/content/posts/*',
format: { contentField: 'content' },
entryLayout: 'content',
schema: {
title: fields.text({
label: 'Text',
}),
url: fields.slug({ name: { label: 'URL' } }),
image: fields.url({
label: 'Image Banner',
description: 'Image URL'
}),
date: fields.date({
label: 'Event date',
description: 'The date of the event'
}),
content: fields.mdx({
components: {
img: block({
label: 'Image',
schema: {
alt: fields.text({ label: 'Alt Text' }),
src: fields.url({ label: 'Image URL' }),
}
}),
},
label: 'Content',
formatting: true,
dividers: true,
links: true,
}),
},
}),
// Init Privacy
init_privacy: collection({
label: 'Init Privacy',
slugField: 'title',
path: 'src/content/init/*',
format: { contentField: 'content' },
entryLayout: 'content',
schema: {
title: fields.slug({ name: { label: 'Title' } }),
content: fields.mdx({
components: {
Image: block({
label: 'Image',
schema: {
Alt: fields.text({ label: 'Alt Text' }),
Source: fields.url({ label: 'Image URL' }),
}
}),
SoftwareItem: wrapper({
label: 'Software',
schema: {
icon: fields.url({ label: 'Icon URL' }),
title: fields.text({ label: 'Title' }),
developer: fields.text({ label: 'Developer Name' }),
screenshot: fields.url({ label: 'Screenshot' }),
homepage: fields.url({ label: 'Homepage' }),
source: fields.url({ label: 'Source Code' }),
// Featured media
goto: fields.conditional(
// First, define a `select` field with all the available "conditions"
fields.select({
label: 'Download or View URL',
description: "If it's a downloadable software, choose the Download option. If it's a website that is used, then use the View option.",
options: [
{ label: 'Please Select One', value: 'none' },
{ label: 'Download', value: 'download' },
{ label: 'View', value: 'view' },
],
defaultValue: 'none',
}),
{
none: fields.empty(),
download: fields.object({
url: fields.url({ label: 'URL' }),
}),
view: fields.object({
url: fields.url({ label: 'URL' }),
}),
}
),
}
})
},
label: 'Content',
formatting: true,
dividers: true,
links: true,
}),
},
}),
// Recommended Reading
recommended_reading: collection({
label: 'Recommended Reading',
slugField: 'title',
path: 'src/content/recommend-reading/*',
format: { contentField: 'content' },
entryLayout: 'form',
schema: {
title: fields.slug({ name: { label: 'Title' } }),
author: fields.text({
label: 'Author Name',
description: 'Who wrote it'
}),
date: fields.date({
label: 'Date',
description: 'The published date'
}),
url: fields.url({
label: 'URL',
description: 'The external URL to the post'
}),
image: fields.url({
label: 'Image Banner',
description: 'Image URL'
}),
content: fields.mdx({
label: 'Content (Not Shown)',
formatting: false,
dividers: false,
links: false,
}),
},
}),
// Documentations
docs_minpluto: collection({
label: 'MinPluto',
slugField: 'title',
path: 'src/content/minpluto/*',
format: { contentField: 'content' },
entryLayout: 'content',
schema: {
title: fields.slug({ name: { label: 'Title' } }),
software: fields.select({
label: 'Software',
options: [
{ label: 'MinPluto', value: 'minpluto' },
],
defaultValue: 'minpluto'
}),
content: fields.mdx({
label: 'Content',
formatting: true,
dividers: true,
links: true,
}),
},
}),
docs_penpot: collection({
label: 'Penpot Desktop',
slugField: 'title',
path: 'src/content/penpot-desktop/*',
format: { contentField: 'content' },
entryLayout: 'content',
schema: {
title: fields.slug({ name: { label: 'Title' } }),
content: fields.mdx({
label: 'Content',
formatting: true,
dividers: true,
links: true,
}),
},
}),
docs_zorn: collection({
label: 'Zorn Player',
slugField: 'title',
path: 'src/content/zorn/*',
format: { contentField: 'content' },
entryLayout: 'content',
schema: {
title: fields.slug({ name: { label: 'Title' } }),
content: fields.mdx({
label: 'Content',
formatting: true,
dividers: true,
links: true,
}),
},
}),
},
});

View file

@ -14,15 +14,12 @@
"dependencies": {
"@astrojs/markdoc": "^0.11.5",
"@astrojs/mdx": "^3.1.8",
"@astrojs/node": "^8.3.4",
"@astrojs/partytown": "^2.1.2",
"@astrojs/vue": "^4.5.2",
"@iconoir/vue": "^7.9.0",
"@keystatic/astro": "^5.0.2",
"@keystatic/core": "^0.5.38",
"@meilisearch/instant-meilisearch": "^0.21.1",
"@minpluto/zorn": "^0.4.51",
"astro": "^4.16.6",
"astro": "^4.16.7",
"astro-auto-import": "^0.4.4",
"astro-color-mode": "^0.7.1",
"astro-json-element": "^1.1.4",
@ -31,11 +28,11 @@
"docs-searchbar.js": "^2.5.0",
"json-truncate": "^3.0.0",
"meilisearch": "^0.44.1",
"reshaped": "^3.1.8",
"reshaped": "^3.2.3",
"untruncate-json": "^0.0.1",
"vue": "^3.5.12"
},
"devDependencies": {
"sass": "^1.80.3"
"sass": "^1.80.4"
}
}

View file

@ -5,8 +5,7 @@ const {
Title,
Description,
Source,
Link,
Status
Link
} = Astro.props
// Icons
@ -16,15 +15,6 @@ import {CheckCircleSolid, XmarkCircleSolid} from '@iconoir/vue'
<div class="service">
<div class="service-icon">
<img width="92" src={Icon}/>
{
()=> {
if (Status === "online") {
return <p style="color: rgb(121, 235, 121)" class="service-status"><CheckCircleSolid/> Online</p>
} else if (Status === "offline") {
return <p style="color: rgb(248, 77, 77)" class="service-status"><XmarkCircleSolid/> Offline</p>
}
}
}
</div>
<div class="service-content">
<div>

View file

@ -2,21 +2,6 @@
// Properties
const { MobileTitle, NoSubHeader } = Astro.props;
// Netweak Status
const NetweakPing = await fetch('https://status.sudovanilla.org/json');
const NetweakStatus = await NetweakPing.json();
if (NetweakStatus.status === 'minor_outage') {
var MinorOutage = true
var StatusText = 'Minor outage'
} else if (NetweakStatus.status === 'major_outage') {
var MajorOutage = true
var StatusText = 'Major outage'
} else if (NetweakStatus.status === 'operational') {
var Operational = true
var StatusText = 'Everything is up!'
}
// Components
import SudoVanilla from "@components/global/SudoVanillaLogo.astro";
@ -55,9 +40,7 @@ SunLight
<a class="header-link-item" href="/instances/">Instances</a>
<a class="header-link-item" href="/docs/">Docs</a>
<a class="header-link-item" href="/init/">Init Privacy</a>
<a title={StatusText} data-tooltip-placement="bottom" class="header-link-item" href="https://status.sudovanilla.org/">Status</a>
<a class="header-link-item" href="https://status.sudovanilla.org/">Status</a>
<button id="toggle-da-theme" data-color-mode-switch style="display: none;"></button>
<button onclick="document.querySelector('#toggle-da-theme').click()" data-color-mode-switch class="theme-toggle-button theme-is-light"><SunLight/></button>
<button onclick="document.querySelector('#toggle-da-theme').click()" data-color-mode-switch class="theme-toggle-button theme-is-dark"><HalfMoon/></button>

View file

@ -9,27 +9,6 @@ import Default from "@layouts/Default.astro";
// Components
import Sidebar from "@components/docs/sidebar.astro";
import SearchModal from '@components/docs/SearchBox.astro'
// Get Content
import { getCollection, getEntry } from "astro:content";
const { slug } = Astro.params;
if (!slug) throw new Error("Slug not found");
const post = await getEntry(ProjectCollection, slug);
if (!post) throw new Error("No post found for this slug");
const { Content } = await post.render();
// Generate static pages
export async function getStaticPaths() {
const posts = await getCollection(ProjectCollection);
return posts.map((post) => ({ params: { slug: post.slug } }));
}
export const prerender = true;
// Icons
import { BookmarkBook, InputSearch, KeyCommand, ReportColumns, Search } from "@iconoir/vue";
// Hightlight Active Project
if (ProjectCollection === 'minpluto') {
@ -41,9 +20,6 @@ if (ProjectCollection === 'zorn') {
if (ProjectCollection === 'penpot-desktop') {
var Hightlight_Penpot = true
}
if (ProjectCollection === 'nexus-polestar') {
var Hightlight_Nexus = true
}
---
<Default MobileTitle="SudoVanilla Documentation">
<Fragment slot="sub-header">
@ -80,8 +56,6 @@ if (ProjectCollection === 'nexus-polestar') {
<slot slot="sidebar-items"/>
</Sidebar>
<div class="doc-content">
<h1 style="margin-top: 0px;">{post.data.title}</h1>
<Content />
</div>
</div>
</Fragment>

View file

@ -1,26 +0,0 @@
import untruncateJson from "untruncate-json";
// List Posts
import { getCollection } from "astro:content";
const posts = await getCollection("minpluto");
const json = JSON.stringify(
posts.map((post) => {
return {
id: Math.floor(Math.random() * 100),
title: post.data.title,
url: '/docs/minpluto/' + post.slug
};
})
);
export async function GET({params, request}) {
return new Response(
JSON.stringify(json), {
status: 200,
headers: {
"Content-Type": "application/json"
}
}
);
}

View file

@ -1,25 +0,0 @@
// List Posts
import { getCollection } from "astro:content";
const posts = await getCollection("zorn");
const json = JSON.stringify(
posts.map((post) => {
return {
id: Math.floor(Math.random() * 100),
title: post.data.title,
body: post.body,
url: '/docs/zorn/' + post.slug
};
})
);
export async function GET({params, request}) {
return new Response(
JSON.stringify(json), {
status: 200,
headers: {
"Content-Type": "application/json"
}
}
);
}

View file

@ -1,33 +0,0 @@
---
// Layout
import Document from '@layouts/Document.astro'
// Icons
import {ServerConnection,PeaceHand, SlashSquare, ClipboardCheck} from "@iconoir/vue";
---
<Document ProjectCollection="minpluto">
<slot name="sidebar-items">
<h2>Getting Started</h2>
<a href="/docs/minpluto/introduction/">
<PeaceHand/>
<p>Introduction </p>
</a>
<a href="/docs/minpluto/compatibility/">
<ClipboardCheck />
<p>Compatibility</p>
</a>
<a href="/docs/minpluto/requirements/">
<ClipboardCheck />
<p>Requirements</p>
</a>
<a href="/docs/minpluto/self-hosting/">
<ServerConnection />
<p>Self-Hosting</p>
</a>
<a href="/docs/minpluto/api/">
<SlashSquare />
<p>API</p>
</a>
</slot>
</Document>

View file

@ -1,41 +0,0 @@
---
// Layout
import Document from '@layouts/Document.astro'
// Icons
import {ServerConnection,PeaceHand, QuestionMark, WifiOff, DownloadCircle, ShieldAlert, ChatBubble} from "@iconoir/vue";
---
<Document ProjectCollection="penpot-desktop">
<slot name="sidebar-items">
<h2>Getting Started</h2>
<a href="/docs/penpot-desktop/introduction/">
<PeaceHand/>
<p>Introduction </p>
</a>
<a href="/docs/penpot-desktop/faq/">
<QuestionMark />
<p>FAQ</p>
</a>
<a href="/docs/penpot-desktop/offline-use/">
<WifiOff />
<p>Offline Use</p>
</a>
<a href="/docs/penpot-desktop/instance/">
<ServerConnection />
<p>Instance</p>
</a>
<a href="/docs/penpot-desktop/progress/">
<DownloadCircle />
<p>Installation</p>
</a>
<a href="/docs/penpot-desktop/progress/">
<ShieldAlert />
<p>Security Policy</p>
</a>
<a href="/docs/penpot-desktop/progress/">
<ChatBubble />
<p>Support</p>
</a>
</slot>
</Document>

View file

@ -1,17 +0,0 @@
---
// Layout
import Document from '@layouts/Document.astro'
// Icons
import {ServerConnection,PeaceHand} from "@iconoir/vue";
---
<Document ProjectCollection="zorn">
<slot name="sidebar-items">
<h2>Getting Started</h2>
<a href="/docs/zorn/introduction/">
<PeaceHand/>
<p>Introduction </p>
</a>
</slot>
</Document>

View file

@ -1,50 +0,0 @@
---
// Layout
import Default from "@layouts/Default.astro";
// Components
import Hero from "@components/Hero.astro";
import Heading from "@components/Heading.astro";
import Posts from "@components/blog/posts.astro";
import LargeCard from "@components/Feature.astro";
// Icons
import { BookmarkBook, ReportColumns } from "@iconoir/vue";
---
<Default MobileTitle="Init Privacy">
<Fragment slot="sub-header">
<p class="header-sub-service">Init Privacy</p>
<div>
<a href="/init/software/browsers/">Softwares</a>
<a href="/init/software/websites/">Websites</a>
<a href="/init/software/disclaimer/">Disclaimers</a>
</div>
</Fragment>
<Fragment slot="body">
<Hero
Title="Init Privacy"
Description="Your data is your business"
UseImage
Image="https://images.pexels.com/photos/179993/pexels-photo-179993.jpeg"
Credit="Black and White CCTV Cameras. Shot by Thomas Windisch on Pexels."
/>
<LargeCard
Title="User Freedom"
Description="Switching to free and open source solutions means better security and privacy. These options are more transparent, can be contributed to by the community and developers, and be audited by third-parties. Proprietary options are closed source and we don't know how they work."
Image="https://md.sudovanilla.org/images/init/osi.png"
CTA_Primary="Explore Alternatives"
CTA_Primary_Link="/init/software/browsers/"
/>
<LargeCard
Title="Taking Back Control"
Description="There is a lot of distrust in big tech because of the amount of power we've let these big companies accumlate. Your data is up for grab and being sold to advertisers, it's time to stop this."
Image="https://md.sudovanilla.org/images/init/data-and-privacy.png"
/>
<LargeCard
Title="Campaigns and Websites"
Description="You can view other websites besides from SudoVanilla to view other options on protecting yourself online and choosing what software to use. There are many websites that do this and do resesarch on options for you like Offshore.CAT, Privacy Guides, and more. There are also campaigns for the open source community from Free Software Foundation."
Image="https://md.sudovanilla.org/images/init/sites-sp.png"
/>
</Fragment>
</Default>

View file

@ -1,6 +0,0 @@
---
// Layout
import Document from '@layouts/Init.astro'
---
<Document/>

View file

@ -3,37 +3,12 @@
import Default from "@layouts/Default.astro";
// Components
import Hero from "@components/Hero.astro";
import Heading from "@components/Heading.astro";
import Posts from "@components/blog/posts.astro";
import LargeCard from "@components/Feature.astro";
import Service from "@components/Service.astro";
// List Posts
import { getCollection } from "astro:content";
const posts = await getCollection("posts");
// Netweak Status
const NetweakPing = await fetch('https://status.sudovanilla.org/json');
const NetweakStatus = await NetweakPing.json();
var StatusForCinny = NetweakStatus.services['25'].status
var StatusForPhanpy = NetweakStatus.services['26'].status
var StatusForFeishin = NetweakStatus.services['32'].status
var StatusForAsciinema = NetweakStatus.services['30'].status
var StatusForOpengist = NetweakStatus.services['24'].status
var StatusForPingvin = NetweakStatus.services['22'].status
var StatusForNarvisearch = NetweakStatus.services['31'].status
var StatusFor4Get = NetweakStatus.services['10'].status
var StatusForFreshRSS = NetweakStatus.services['28'].status
var StatusForMiniflux = NetweakStatus.services['29'].status
var StatusForTeddit = NetweakStatus.services['21'].status
var StatusForSafetwitch = NetweakStatus.services['20'].status
var StatusForHyperpipe = NetweakStatus.services['27'].status
var StatusForRimgo = NetweakStatus.services['16'].status
var StatusForAnonymousoverflow = NetweakStatus.services['17'].status
var StatusForQuetre = NetweakStatus.services['19'].status
var StatusForLibmedium = NetweakStatus.services['23'].status
---
<Default MobileTitle="Instances">
@ -99,7 +74,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="Matrix Chat"
Link="https://chat.sudovanilla.org/"
Source="https://github.com/cinnyapp/cinny"
Status={StatusForCinny}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/element.svg"
@ -114,7 +88,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="Mastodon"
Link="https://m.sudovanilla.org/"
Source="https://github.com/cheeaun/phanpy"
Status={StatusForPhanpy}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/feishin.png"
@ -122,7 +95,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="Jellyfin Music"
Link="https://ms.sudovanilla.org/"
Source="https://github.com/jeffvli/feishin"
Status={StatusForFeishin}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/Photon.svg"
@ -147,7 +119,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="Terminal Recordings"
Link="https://tr.sudovanilla.org/"
Source="https://github.com/asciinema/asciinema"
Status={StatusForAsciinema}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/OpenGist.svg"
@ -155,7 +126,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="Gist"
Link="https://gist.sudovanilla.org/"
Source="https://github.com/thomiceli/opengist"
Status={StatusForOpengist}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/Pingvin.png"
@ -163,7 +133,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="File Share"
Link="https://s.sudovanilla.org/"
Source="https://github.com/stonith404/pingvin-share"
Status={StatusForPingvin}
/>
<Service
Icon="https://4get.sudovanilla.org/favicon.ico"
@ -171,7 +140,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="Search Engine"
Link="https://4get.sudovanilla.org/"
Source="https://git.lolcat.ca/lolcat/4get"
Status={StatusFor4Get}
/>
<Service
Icon="https://md.sudovanilla.org/images/logo-white.png"
@ -186,7 +154,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="RSS Feed"
Link="https://fr.sudovanilla.org/"
Source="https://github.com/FreshRSS/FreshRSS"
Status={StatusForFreshRSS}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/zipline_small.png"
@ -211,7 +178,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="For Reddit"
Link="https://t.sudovanilla.org/"
Source="https://codeberg.org/teddit/teddit"
Status={StatusForTeddit}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/SafeTwitch.webp"
@ -219,7 +185,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="For Twitch"
Link="https://twitch.sudovanilla.org/"
Source="https://codeberg.org/SafeTwitch/safetwitch"
Status={StatusForSafetwitch}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/Rimgo.svg"
@ -227,7 +192,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="For Imgur"
Link="https://i.sudovanilla.org/"
Source="https://codeberg.org/rimgo/rimgo"
Status={StatusForRimgo}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/AnonymousOverflow.webp"
@ -235,7 +199,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="For StackOverflow"
Link="https://o.sudovanilla.org/"
Source="https://github.com/httpjamesm/AnonymousOverflow"
Status={StatusForAnonymousoverflow}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/Quetre.webp"
@ -243,7 +206,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="For Quora"
Link="https://a.sudovanilla.org/"
Source="https://github.com/zyachel/quetre"
Status={StatusForQuetre}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/libmedium.png"
@ -251,7 +213,6 @@ var StatusForLibmedium = NetweakStatus.services['23'].status
Description="For Medium"
Link="https://r.sudovanilla.org/"
Source="https://github.com/realaravinth/libmedium"
Status={StatusForLibmedium}
/>
<Service
Icon="https://md.sudovanilla.org/images/icons/Invidious.webp"