Compare commits
7 commits
92b6f1c558
...
d528b65bf2
Author | SHA1 | Date | |
---|---|---|---|
|
d528b65bf2 | ||
|
0202b451de | ||
|
d48c752d31 | ||
|
7306fcefc8 | ||
|
b3ab1c438e | ||
|
b9ffff1791 | ||
|
21282c83ac |
12 changed files with 224 additions and 24 deletions
|
@ -27,9 +27,6 @@ FROM ark.sudovanilla.org/korbs/bun:amd64 AS based
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Run in Production
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
|
|
||||||
# Run
|
# Run
|
||||||
EXPOSE 2014
|
EXPOSE 2014
|
||||||
CMD bun run build && bun start
|
CMD bun run build && bun start
|
|
@ -5,6 +5,7 @@ import { SiteSettings } from './config.json'
|
||||||
|
|
||||||
// Integrations
|
// Integrations
|
||||||
import mdx from '@astrojs/mdx'
|
import mdx from '@astrojs/mdx'
|
||||||
|
import pagefind from "astro-pagefind"
|
||||||
|
|
||||||
// Astro Configuration
|
// Astro Configuration
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
@ -13,7 +14,8 @@ export default defineConfig({
|
||||||
base: SiteSettings.SiteBase,
|
base: SiteSettings.SiteBase,
|
||||||
// Integrations
|
// Integrations
|
||||||
integrations: [
|
integrations: [
|
||||||
mdx()
|
mdx(),
|
||||||
|
pagefind()
|
||||||
],
|
],
|
||||||
// Server Output
|
// Server Output
|
||||||
output: "static",
|
output: "static",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "butterflyvu",
|
"name": "butterflyvu",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "SudoVanilla"
|
"name": "SudoVanilla"
|
||||||
|
@ -22,9 +22,9 @@
|
||||||
"email": "support@sudovanilla.org"
|
"email": "support@sudovanilla.org"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
|
"postbuild": "pagefind --root-selector article --site dist/",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"docker:start": "docker compose up -d",
|
"docker:start": "docker compose up -d",
|
||||||
"docker:stop": "docker compose down",
|
"docker:stop": "docker compose down",
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
"astro-breadcrumbs": "^3.2.0",
|
"astro-breadcrumbs": "^3.2.0",
|
||||||
"astro-bun-adapter": "^1.0.2",
|
"astro-bun-adapter": "^1.0.2",
|
||||||
"astro-feelback": "^0.3.4",
|
"astro-feelback": "^0.3.4",
|
||||||
|
"astro-pagefind": "^1.6.0",
|
||||||
"astro-seo": "^0.8.4",
|
"astro-seo": "^0.8.4",
|
||||||
"markdoc": "^0.1.3"
|
"markdoc": "^0.1.3"
|
||||||
},
|
},
|
||||||
|
|
81
src/components/Search.astro
Normal file
81
src/components/Search.astro
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
---
|
||||||
|
import '@styles/search.scss'
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
readonly id?: string;
|
||||||
|
readonly className?: string;
|
||||||
|
readonly query?: string;
|
||||||
|
readonly uiOptions?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id, className, query, uiOptions = {} } = Astro.props;
|
||||||
|
const bundlePath = `${import.meta.env.BASE_URL}pagefind/`;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div
|
||||||
|
id={id}
|
||||||
|
class:list={[className, "pagefind-init"]}
|
||||||
|
data-pagefind-ui
|
||||||
|
data-bundle-path={bundlePath}
|
||||||
|
data-query={query}
|
||||||
|
data-ui-options={JSON.stringify(uiOptions)}
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
// @ts-ignore
|
||||||
|
import { PagefindUI } from "@pagefind/default-ui";
|
||||||
|
|
||||||
|
function initPageFind() {
|
||||||
|
const allSelector = "[data-pagefind-ui]";
|
||||||
|
for (const el of document.querySelectorAll(
|
||||||
|
`${allSelector}.pagefind-init`
|
||||||
|
)) {
|
||||||
|
const elSelector = [
|
||||||
|
...(el.id ? [`#${el.id}`] : []),
|
||||||
|
...[...el.classList.values()].map((c) => `.${c}`),
|
||||||
|
allSelector,
|
||||||
|
].join("");
|
||||||
|
const bundlePath = el.getAttribute("data-bundle-path");
|
||||||
|
const opts = JSON.parse(el.getAttribute("data-ui-options") ?? "{}");
|
||||||
|
new PagefindUI({
|
||||||
|
...opts,
|
||||||
|
element: elSelector,
|
||||||
|
bundlePath,
|
||||||
|
});
|
||||||
|
el.classList.remove("pagefind-init");
|
||||||
|
var query = el.getAttribute("data-query");
|
||||||
|
|
||||||
|
// Check if the current URL has any query params
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const params = new URLSearchParams(url.search);
|
||||||
|
if (params.has("q")) {
|
||||||
|
query = params.get("q");
|
||||||
|
}
|
||||||
|
|
||||||
|
const input = el.querySelector<HTMLInputElement>(`input[type="text"]`);
|
||||||
|
|
||||||
|
input?.focus();
|
||||||
|
|
||||||
|
if (input) {
|
||||||
|
input.value = query;
|
||||||
|
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||||
|
|
||||||
|
// Add Listener to update the URL when the input changes
|
||||||
|
input.addEventListener("input", (e) => {
|
||||||
|
const input = e.target as HTMLInputElement;
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const params = new URLSearchParams(url.search);
|
||||||
|
params.set("q", input.value);
|
||||||
|
window.history.replaceState({}, "", `${url.pathname}?${params}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("astro:page-load", initPageFind);
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", initPageFind);
|
||||||
|
} else {
|
||||||
|
initPageFind();
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,14 +1,16 @@
|
||||||
---
|
---
|
||||||
// Settings
|
// Settings
|
||||||
import { SiteSettings, HeaderItems } from '@config'
|
import { SiteSettings, HeaderItems } from '@config'
|
||||||
|
import Search from '@components/Search.astro'
|
||||||
---
|
---
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
<div class="start">
|
<div class="header-start">
|
||||||
<h2><a style="text-decoration: none;" href="/">{SiteSettings.SiteName}</a></h2>
|
<h2><a style="text-decoration: none;" href="/">{SiteSettings.SiteName}</a></h2>
|
||||||
|
<Search/>
|
||||||
</div>
|
</div>
|
||||||
<div class="end">
|
<div class="header-end">
|
||||||
{HeaderItems.map((item) => (
|
{HeaderItems.map((item) => (
|
||||||
<a href={item.link}>{item.text}</a>
|
<a href={item.link}>{item.text}</a>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -13,6 +13,27 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
||||||
|
|
||||||
<Prism lang="jsx" code={
|
<Prism lang="jsx" code={
|
||||||
`
|
`
|
||||||
|
---
|
||||||
|
// Settings
|
||||||
|
import { SiteSettings } from '@config'
|
||||||
|
import {version} from '../../package.json'
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
const { frontmatter } = Astro.props
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import Head from '@components/global/Head.astro'
|
||||||
|
import Header from '@components/global/Header.astro'
|
||||||
|
import FeelbackYesNo from "astro-feelback/components/FeelbackYesNo.astro";
|
||||||
|
|
||||||
|
// Styles
|
||||||
|
import "@styles/index.scss";
|
||||||
|
import "@styles/splash.scss";
|
||||||
|
import "@styles/feelback.css";
|
||||||
|
---
|
||||||
|
|
||||||
|
<Head/>
|
||||||
|
<Header/>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="splash">
|
<div class="splash">
|
||||||
|
@ -32,20 +53,27 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="footer-start">
|
<div class="footer-start">
|
||||||
<p>© {ORG_NAME}. All right reserved.</p>
|
<p>© {SiteSettings.OrgName}. All right reserved.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-end">
|
<div class="footer-end">
|
||||||
{WHITELABEL ?
|
{SiteSettings.WhiteLabel ?
|
||||||
<p>Built with <a href="#">ButterflyVu</a></p>
|
<p>Built with <a href="#">ButterflyVu</a></p>
|
||||||
:
|
:
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
{SiteSettings.FooterVersion ?
|
||||||
|
<p style="opacity: 0.5;">v{version}</p>
|
||||||
|
:
|
||||||
|
null
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
} />
|
} />
|
||||||
|
|
||||||
|
This is the source code to the splash template layout.
|
||||||
|
|
||||||
|
|
||||||
## Video Player
|
## Video Player
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
---
|
---
|
||||||
Type: Document
|
Type: Document
|
||||||
Title: Welcome
|
Title: Welcome
|
||||||
Banner: "/splash-logo.webp"
|
|
||||||
PrimaryText: "Primary"
|
|
||||||
SecondaryText: "Secondary"
|
|
||||||
PrimaryLink: "#"
|
|
||||||
SecondaryLink: "#"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Documentation template for the Astro Web Framework.
|
Documentation template for the Astro Web Framework.
|
||||||
|
|
|
@ -21,7 +21,7 @@ import "@styles/prism.css"
|
||||||
<Head/>
|
<Head/>
|
||||||
<Header/>
|
<Header/>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="content">
|
<article>
|
||||||
<Sidebar/>
|
<Sidebar/>
|
||||||
<div class="document">
|
<div class="document">
|
||||||
<h1>{frontmatter.Title}</h1>
|
<h1>{frontmatter.Title}</h1>
|
||||||
|
@ -44,7 +44,7 @@ import "@styles/prism.css"
|
||||||
null
|
null
|
||||||
} -->
|
} -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</article>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="footer-start">
|
<div class="footer-start">
|
||||||
<p>© {SiteSettings.OrgName}. All right reserved.</p>
|
<p>© {SiteSettings.OrgName}. All right reserved.</p>
|
||||||
|
|
|
@ -20,8 +20,8 @@ import "@styles/feelback.css";
|
||||||
<Head/>
|
<Head/>
|
||||||
<Header/>
|
<Header/>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="content">
|
<div class="content" data-pagefind-body>
|
||||||
<div class="splash">
|
<article class="splash">
|
||||||
<div class="splash-content">
|
<div class="splash-content">
|
||||||
<h1>{frontmatter.Title}</h1>
|
<h1>{frontmatter.Title}</h1>
|
||||||
<p>{frontmatter.Description}</p>
|
<p>{frontmatter.Description}</p>
|
||||||
|
@ -31,7 +31,7 @@ import "@styles/feelback.css";
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img src={frontmatter.Banner}/>
|
<img src={frontmatter.Banner}/>
|
||||||
</div>
|
</article>
|
||||||
<div class="document">
|
<div class="document">
|
||||||
<slot/>
|
<slot/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,4 +53,5 @@ import "@styles/feelback.css";
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</html>
|
|
@ -1,6 +1,7 @@
|
||||||
body {
|
body {
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
padding: 0px 24px;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
background: #0a0a0a;
|
background: #0a0a0a;
|
||||||
color: white;
|
color: white;
|
||||||
|
@ -44,7 +45,8 @@ blockquote {
|
||||||
|
|
||||||
header {
|
header {
|
||||||
background: #161616;
|
background: #161616;
|
||||||
width: 100%;
|
width: calc(100% - 48px);
|
||||||
|
padding: 0px 24px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
|
@ -55,7 +57,12 @@ header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
.end {
|
.header-start {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.header-end {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
a {
|
a {
|
||||||
|
@ -71,7 +78,7 @@ header {
|
||||||
.page {
|
.page {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
.content {
|
article {
|
||||||
padding-top: 90px;
|
padding-top: 90px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -124,3 +131,25 @@ header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 775px){
|
||||||
|
.content {
|
||||||
|
flex-direction: column !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 650px){
|
||||||
|
.header-content {
|
||||||
|
flex-direction: column;
|
||||||
|
padding-bottom: 24px;
|
||||||
|
}
|
||||||
|
.page .content {
|
||||||
|
padding-top: 114px !important;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
flex-direction: column !important;
|
||||||
|
align-items: center;
|
||||||
|
* {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
src/styles/search.scss
Normal file
53
src/styles/search.scss
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
input {
|
||||||
|
background: #0a0a0a;
|
||||||
|
color: white;
|
||||||
|
border: 1px #2d2d2d solid;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mark {
|
||||||
|
background: gainsboro;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: -2px -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagefind-ui__message {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.pagefind-ui__results {
|
||||||
|
padding: 0px 18px;
|
||||||
|
}
|
||||||
|
.pagefind-ui__drawer {
|
||||||
|
position: absolute;
|
||||||
|
top: 79px;
|
||||||
|
max-width: 620px;
|
||||||
|
background: rgba(22, 22, 22, 0.75);
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px #2d2d2d solid;
|
||||||
|
backdrop-filter: blur(24px);
|
||||||
|
padding: 12px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagefind-ui__search-clear, .pagefind-ui__hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 916px){
|
||||||
|
.pagefind-ui__drawer {
|
||||||
|
left: 12px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: calc(100% - 74px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 650px){
|
||||||
|
.pagefind-ui__drawer {
|
||||||
|
top: 122px !important;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,9 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.splash-action {
|
.splash-action {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
@ -21,4 +24,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 775px){
|
||||||
|
.splash {
|
||||||
|
padding: 64px 0px;
|
||||||
|
img {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue