working download and blog
This commit is contained in:
+243
@@ -0,0 +1,243 @@
|
||||
---
|
||||
authors: Kleo dev, John Doe
|
||||
title: Testing
|
||||
description: Test
|
||||
image: /background.png
|
||||
date: 2025-04-16
|
||||
tags: test, testing
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
**Advertisement :)**
|
||||
|
||||
- **[pica](https://nodeca.github.io/pica/demo/)** - high quality and fast image
|
||||
resize in browser.
|
||||
- **[babelfish](https://github.com/nodeca/babelfish/)** - developer friendly
|
||||
i18n with plurals support and easy syntax.
|
||||
|
||||
You will like those projects!
|
||||
|
||||
---
|
||||
|
||||
# h1 Heading 8-)
|
||||
|
||||
## h2 Heading
|
||||
|
||||
### h3 Heading
|
||||
|
||||
#### h4 Heading
|
||||
|
||||
##### h5 Heading
|
||||
|
||||
###### h6 Heading
|
||||
|
||||
## Horizontal Rules
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Typographic replacements
|
||||
|
||||
Enable typographer option to see result.
|
||||
|
||||
(c) (C) (r) (R) (tm) (TM) (p) (P) +-
|
||||
|
||||
test.. test... test..... test?..... test!....
|
||||
|
||||
!!!!!! ???? ,, -- ---
|
||||
|
||||
"Smartypants, double quotes" and 'single quotes'
|
||||
|
||||
## Emphasis
|
||||
|
||||
**This is bold text**
|
||||
|
||||
**This is bold text**
|
||||
|
||||
_This is italic text_
|
||||
|
||||
_This is italic text_
|
||||
|
||||
~~Strikethrough~~
|
||||
|
||||
## Blockquotes
|
||||
|
||||
> Blockquotes can also be nested...
|
||||
>
|
||||
> > ...by using additional greater-than signs right next to each other...
|
||||
> >
|
||||
> > > ...or with spaces between arrows.
|
||||
|
||||
## Lists
|
||||
|
||||
Unordered
|
||||
|
||||
- Create a list by starting a line with `+`, `-`, or `*`
|
||||
- Sub-lists are made by indenting 2 spaces:
|
||||
- Marker character change forces new list start:
|
||||
- Ac tristique libero volutpat at
|
||||
* Facilisis in pretium nisl aliquet
|
||||
- Nulla volutpat aliquam velit
|
||||
- Very easy!
|
||||
|
||||
Ordered
|
||||
|
||||
1. Lorem ipsum dolor sit amet
|
||||
2. Consectetur adipiscing elit
|
||||
3. Integer molestie lorem at massa
|
||||
|
||||
4. You can use sequential numbers...
|
||||
5. ...or keep all the numbers as `1.`
|
||||
|
||||
Start numbering with offset:
|
||||
|
||||
57. foo
|
||||
1. bar
|
||||
|
||||
## Code
|
||||
|
||||
Inline `code`
|
||||
|
||||
Indented code
|
||||
|
||||
// Some comments
|
||||
line 1 of code
|
||||
line 2 of code
|
||||
line 3 of code
|
||||
|
||||
Block code "fences"
|
||||
|
||||
```
|
||||
Sample text here...
|
||||
```
|
||||
|
||||
Syntax highlighting
|
||||
|
||||
```js
|
||||
var foo = function (bar) {
|
||||
return bar++;
|
||||
};
|
||||
|
||||
console.log(foo(5));
|
||||
```
|
||||
|
||||
## Tables
|
||||
|
||||
| Option | Description |
|
||||
| ------ | ------------------------------------------------------------------------- |
|
||||
| data | path to data files to supply the data that will be passed into templates. |
|
||||
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||
| ext | extension to be used for dest files. |
|
||||
|
||||
Right aligned columns
|
||||
|
||||
| Option | Description |
|
||||
| -----: | ------------------------------------------------------------------------: |
|
||||
| data | path to data files to supply the data that will be passed into templates. |
|
||||
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||
| ext | extension to be used for dest files. |
|
||||
|
||||
## Links
|
||||
|
||||
[link text](http://dev.nodeca.com)
|
||||
|
||||
[link with title](http://nodeca.github.io/pica/demo/ "title text!")
|
||||
|
||||
Autoconverted link https://github.com/nodeca/pica (enable linkify to see)
|
||||
|
||||
## Images
|
||||
|
||||

|
||||

|
||||
|
||||
Like links, Images also have a footnote style syntax
|
||||
|
||||
![Alt text][id]
|
||||
|
||||
With a reference later in the document defining the URL location:
|
||||
|
||||
[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
|
||||
|
||||
## Plugins
|
||||
|
||||
The killer feature of `markdown-it` is very effective support of
|
||||
[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin).
|
||||
|
||||
### [Emojies](https://github.com/markdown-it/markdown-it-emoji)
|
||||
|
||||
> Classic markup: :wink: :cry: :laughing: :yum:
|
||||
>
|
||||
> Shortcuts (emoticons): :-) :-( 8-) ;)
|
||||
|
||||
see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji.
|
||||
|
||||
### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup)
|
||||
|
||||
- 19^th^
|
||||
- H~2~O
|
||||
|
||||
### [\<ins>](https://github.com/markdown-it/markdown-it-ins)
|
||||
|
||||
++Inserted text++
|
||||
|
||||
### [\<mark>](https://github.com/markdown-it/markdown-it-mark)
|
||||
|
||||
==Marked text==
|
||||
|
||||
### [Footnotes](https://github.com/markdown-it/markdown-it-footnote)
|
||||
|
||||
Footnote 1 link[^first].
|
||||
|
||||
Footnote 2 link[^second].
|
||||
|
||||
Inline footnote^[Text of inline footnote] definition.
|
||||
|
||||
Duplicated footnote reference[^second].
|
||||
|
||||
[^first]: Footnote **can have markup**
|
||||
|
||||
and multiple paragraphs.
|
||||
|
||||
[^second]: Footnote text.
|
||||
|
||||
### [Definition lists](https://github.com/markdown-it/markdown-it-deflist)
|
||||
|
||||
Term 1
|
||||
|
||||
: Definition 1
|
||||
with lazy continuation.
|
||||
|
||||
Term 2 with _inline markup_
|
||||
|
||||
: Definition 2
|
||||
|
||||
{ some code, part of Definition 2 }
|
||||
|
||||
Third paragraph of definition 2.
|
||||
|
||||
_Compact style:_
|
||||
|
||||
Term 1
|
||||
~ Definition 1
|
||||
|
||||
Term 2
|
||||
~ Definition 2a
|
||||
~ Definition 2b
|
||||
|
||||
### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr)
|
||||
|
||||
This is HTML abbreviation example.
|
||||
|
||||
It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on.
|
||||
|
||||
\*[HTML]: Hyper Text Markup Language
|
||||
|
||||
### [Custom containers](https://github.com/markdown-it/markdown-it-container)
|
||||
|
||||
::: warning
|
||||
_here be dragons_
|
||||
:::
|
||||
Generated
+1205
-3
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -12,7 +12,8 @@
|
||||
"lucide-react": "^0.488.0",
|
||||
"next": "15.3.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
"react-dom": "^19.0.0",
|
||||
"react-markdown": "^10.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import Footer from "@/components/Footer";
|
||||
import Header from "@/components/Header";
|
||||
import listNews from "@/lib/news";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Download() {
|
||||
return (
|
||||
<div className="flex-1 flex flex-col h-screen">
|
||||
<div className="flex flex-col bg-[url('/background.png')] bg-center bg-no-repeat h-52">
|
||||
<Header />
|
||||
|
||||
<h1 className="text-5xl font-black m-auto w-max font-['Panton']">
|
||||
DOWNLOAD
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="w-full h-full flex flex-col items-center pt-6">
|
||||
Release downloads aren't available yet :(
|
||||
<Link
|
||||
href="https://github.com/saturnclientmc/saturnclient/releases/"
|
||||
target="_blank"
|
||||
className="hover:cursor-pointer mt-10 relative bg-red border text-white py-4 px-6 rounded-xl backdrop-blur-xs w-max group transition-colors duration-300 hover:text-[#e2bf7d] animate-fadeIn"
|
||||
>
|
||||
Download on GitHub
|
||||
</Link>
|
||||
<div className="flex flex-col items-center mt-4 gap-2">
|
||||
<p>Step 1: Download the latest release from GitHub</p>
|
||||
<p>Step 2: Locate your Minecraft mods folder (fabric required)</p>
|
||||
<p>Step 3: Place the downloaded release into the mods folder</p>
|
||||
<p>
|
||||
Step 4: Launch the game on the official minecraft launcher (fabric)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
h1 {
|
||||
font-size: xx-large;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: medium;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style-type: decimal;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 10px;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import Markdown from "react-markdown";
|
||||
import "./Markdown.css";
|
||||
|
||||
export default function Md({ children }: { children: string }) {
|
||||
return <Markdown>{children}</Markdown>;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { readFileSync } from "fs";
|
||||
import smartSplit from "@/lib/smartSplit";
|
||||
import { parseNews } from "@/lib/news";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import Md from "./Markdown";
|
||||
|
||||
export default async function News({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ id: string }>;
|
||||
}) {
|
||||
const contents = readFileSync(`news/${(await params).id}.md`, "utf-8");
|
||||
|
||||
const { authors, title, description, image, date } = parseNews(
|
||||
contents,
|
||||
(await params).id
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className="bg-[url('/background.png')] bg-center bg-no-repeat h-96"
|
||||
style={{ backgroundImage: `url(${image})` }}
|
||||
>
|
||||
<Header />
|
||||
|
||||
<h1 className="font-black m-auto w-max font-['Panton'] !text-5xl mt-14">
|
||||
{title}
|
||||
</h1>
|
||||
|
||||
<p className="m-auto w-max font-['Panton'] !text-2xl mt-5">
|
||||
{description}
|
||||
</p>
|
||||
<p className="m-auto w-max font-['Panton'] !text-xl">
|
||||
written by {authors.join(", ")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-[54rem] mx-auto mt-10">
|
||||
<div className="rounded-2xl bg-[#111] p-5 markdown">
|
||||
<Md>{smartSplit(contents, "---", 3)[2]}</Md>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+11
-8
@@ -1,5 +1,6 @@
|
||||
import Footer from "@/components/Footer";
|
||||
import Header from "@/components/Header";
|
||||
import listNews from "@/lib/news";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
@@ -14,14 +15,16 @@ import Link from "next/link";
|
||||
// },
|
||||
// ];
|
||||
|
||||
const newsList = Array(3 * 6).fill({
|
||||
authors: [],
|
||||
title: "Hello World",
|
||||
description: "lorem ipsum ipsum lorem",
|
||||
image: "/background.png",
|
||||
date: "2025-04-16",
|
||||
id: "",
|
||||
});
|
||||
// const newsList = Array(3 * 6).fill({
|
||||
// authors: [],
|
||||
// title: "Hello World",
|
||||
// description: "lorem ipsum ipsum lorem",
|
||||
// image: "/background.png",
|
||||
// date: "2025-04-16",
|
||||
// id: "",
|
||||
// });
|
||||
|
||||
const newsList = listNews();
|
||||
|
||||
export default function News() {
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { readdirSync, readFileSync } from "fs";
|
||||
|
||||
export interface News {
|
||||
authors: string[];
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
date: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export function parseNews(news: string, id: string): News {
|
||||
const content = news.split("---", 2)[1];
|
||||
|
||||
const params: News = {
|
||||
authors: [],
|
||||
title: "Undefined title",
|
||||
description: "",
|
||||
image: "/background.png",
|
||||
date: "Undefined date",
|
||||
id,
|
||||
};
|
||||
|
||||
content.split("\n").forEach((v) => {
|
||||
const [key, value] = v.split(":").map((v) => v.trim());
|
||||
if (key === "authors") {
|
||||
params.authors = value.split(",").map((v) => v.trim());
|
||||
} else if (
|
||||
key === "title" ||
|
||||
key === "description" ||
|
||||
key === "image" ||
|
||||
key === "date"
|
||||
) {
|
||||
params[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
export default function listNews(): News[] {
|
||||
const newsIdList = readdirSync("news");
|
||||
|
||||
if (newsIdList === null) return [];
|
||||
|
||||
return newsIdList.map((v) => {
|
||||
return parseNews(
|
||||
readFileSync(`news/${v}`, "utf-8"),
|
||||
v.replaceAll(".md", "")
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export default function smartSplit(
|
||||
str: string,
|
||||
separator: string,
|
||||
limit: number
|
||||
) {
|
||||
const parts = str.split(separator);
|
||||
if (parts.length <= limit) return parts;
|
||||
|
||||
const head = parts.slice(0, limit - 1);
|
||||
const tail = parts.slice(limit - 1).join(separator);
|
||||
return [...head, tail];
|
||||
}
|
||||
Reference in New Issue
Block a user