This commit is contained in:
parent
49c564c3d9
commit
b659b7ac48
9 changed files with 286 additions and 164 deletions
|
@ -114,7 +114,7 @@ const config = {
|
|||
},
|
||||
{ to: "/blog", label: "Blog", position: "left" },
|
||||
{ type: "custom-status-navbar-item", position: "left" },
|
||||
|
||||
{ type: "custom-services-navbar-item", position: "left" },
|
||||
{
|
||||
type: "search",
|
||||
position: "right",
|
||||
|
|
|
@ -331,5 +331,17 @@
|
|||
},
|
||||
"home.tagline": {
|
||||
"message": "Your personal space in the cloud."
|
||||
},
|
||||
"Services": {
|
||||
"message": "Services"
|
||||
},
|
||||
"Public Services": {
|
||||
"message": "Public Services"
|
||||
},
|
||||
"Private Services": {
|
||||
"message": "Private Services"
|
||||
},
|
||||
"Upcoming Services": {
|
||||
"message": "Upcoming Services"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@
|
|||
"description": "The ARIA label and title attribute for expand button of doc sidebar"
|
||||
},
|
||||
"theme.SearchPage.existingResultsTitle": {
|
||||
"message": "Search results for \"{query}\"",
|
||||
"message": "Rezultati za iskanje \"{query}\"",
|
||||
"description": "The search page title for non-empty query"
|
||||
},
|
||||
"theme.SearchPage.emptyResultsTitle": {
|
||||
|
@ -331,5 +331,17 @@
|
|||
},
|
||||
"home.tagline": {
|
||||
"message": "Tvoj osebni prostor v oblaku."
|
||||
},
|
||||
"Services": {
|
||||
"message": "Storitve"
|
||||
},
|
||||
"Public Services": {
|
||||
"message": "Javne Storitve"
|
||||
},
|
||||
"Private Services": {
|
||||
"message": "Zasebne Storitve"
|
||||
},
|
||||
"Upcoming Services": {
|
||||
"message": "Prihajajoče Storitve"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,162 +1,9 @@
|
|||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import styles from "./styles.module.css";
|
||||
import { ServiceDescription, sections, services } from "@site/src/services";
|
||||
|
||||
type ServicesSection = {
|
||||
title: string;
|
||||
description: string | JSX.Element;
|
||||
services: ServiceItem[];
|
||||
};
|
||||
|
||||
type ServiceItem = {
|
||||
title: string;
|
||||
Svg: React.ComponentType<React.ComponentProps<"svg">>;
|
||||
description: JSX.Element;
|
||||
};
|
||||
|
||||
const PrivateServices: ServicesSection = {
|
||||
title: "Private Services",
|
||||
description: (
|
||||
<>
|
||||
Services that require <b>id.tjo.space</b> account.
|
||||
</>
|
||||
),
|
||||
services: [
|
||||
{
|
||||
title: "Chat",
|
||||
Svg: require("@site/static/img/undraw_chat_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://chat.tjo.space">chat.tjo.space</a> Metrix server
|
||||
which you can use to chat with other users of tjo.space or world wide
|
||||
with anyone else on the Matrix network.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Cloud",
|
||||
Svg: require("@site/static/img/undraw_cloud_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://cloud.tjo.space">cloud.tjo.space</a> Nextcloud
|
||||
server as a personal cloud to store your <b>Photos</b>, <b>Videos</b>,
|
||||
<b>Files</b>, <b>Calendar</b>, <b>Contacts</b> as well as share all
|
||||
that with other users of tjo.space or anyone else.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Code",
|
||||
Svg: require("@site/static/img/undraw_code_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://code.tjo.space">code.tjo.space</a> Gitea server
|
||||
as a Git repository and CI/CD system.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Paperless",
|
||||
Svg: require("@site/static/img/undraw_paperless_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://paperless.tjo.space">paperless.tjo.space</a>{" "}
|
||||
Paperless server to archive your documents and make them searchable.
|
||||
Can be connected to your email provider so that all attachments are
|
||||
autmatically archived.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "RSS",
|
||||
Svg: require("@site/static/img/undraw_rss_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://rss.tjo.space">rss.tjo.space</a> server as a RSS
|
||||
reader for all of your news, blogs and podcasts.
|
||||
</>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const PublicServices: ServicesSection = {
|
||||
title: "Public Services",
|
||||
description: "Services that are available to everyone.",
|
||||
services: [
|
||||
{
|
||||
title: "Search",
|
||||
Svg: require("@site/static/img/undraw_search_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://search.tjo.space">search.tjo.space</a> private
|
||||
meta search engine that doesn't track you.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Send",
|
||||
Svg: require("@site/static/img/undraw_send_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://send.tjo.space">send.tjo.space</a> to create
|
||||
private temporary link to share files up to 20GB in size.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Watch",
|
||||
Svg: require("@site/static/img/undraw_yt_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://yt.tjo.space">yt.tjo.space</a> an Invidious
|
||||
server to privately watch YouTube videos.
|
||||
</>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const UpcomingServices: ServicesSection = {
|
||||
title: "Upcoming Services",
|
||||
description:
|
||||
"Services that we plan to provide in the future, but are not quite ready yet.",
|
||||
services: [
|
||||
{
|
||||
title: "Mail",
|
||||
Svg: require("@site/static/img/undraw_mail_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://mail.tjo.space">mail.tjo.space</a> to get your
|
||||
personal <b>@tjo.space</b> email address.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Vault",
|
||||
Svg: require("@site/static/img/undraw_vault_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://vault.tjo.space">vault.tjo.space</a> Bitwarden
|
||||
server to securily store your passwords.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "VPN",
|
||||
Svg: require("@site/static/img/undraw_vpn_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://vpn.tjo.space">vpn.tjo.space</a> Tailscale server
|
||||
to securily connect with other tjo.space users or use one of available
|
||||
exit locations to have secure internet connection.
|
||||
</>
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function Service({ title, Svg, description }: ServiceItem) {
|
||||
function Service({ title, Svg, description }: ServiceDescription) {
|
||||
return (
|
||||
<div className={clsx("col col--4 service")}>
|
||||
<div className="text--center">
|
||||
|
@ -175,14 +22,16 @@ export default function HomepageFeatures(): JSX.Element {
|
|||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<h1 className={styles.featureHeader}>Services that we provide</h1>
|
||||
{[PublicServices, PrivateServices, UpcomingServices].map(
|
||||
({ title, description, services }) => {
|
||||
{Object.entries(sections).map(
|
||||
([sectionKind, { title, description }]) => {
|
||||
return (
|
||||
<>
|
||||
<h2 className={styles.featureHeader}>{title}</h2>
|
||||
<h3 className={styles.featureSubHeader}>{description}</h3>
|
||||
<div className={clsx("row", styles.row)}>
|
||||
{services.map((props, idx) => (
|
||||
{services
|
||||
.filter((service) => service.sectionKind === sectionKind)
|
||||
.map((props, idx) => (
|
||||
<Service key={idx} {...props} />
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -27,8 +27,7 @@ function Mobile({ healthy, status }) {
|
|||
href="https://status.tjo.space"
|
||||
style={{ display: "inline-block", width: "100%" }}
|
||||
>
|
||||
{status}
|
||||
<Healthy healthy={healthy}></Healthy>
|
||||
{status} <Healthy healthy={healthy}></Healthy>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
|
|
54
src/components/NavbarItems/ServicesNavbarItem.tsx
Normal file
54
src/components/NavbarItems/ServicesNavbarItem.tsx
Normal file
|
@ -0,0 +1,54 @@
|
|||
import Translate from "@docusaurus/Translate";
|
||||
import { ServiceSectionKind, services } from "@site/src/services";
|
||||
import React from "react";
|
||||
|
||||
function Mobile() {
|
||||
return (
|
||||
<li className="menu__list-item">
|
||||
<span className="menu__link menu__link--sublist">
|
||||
<Translate>Services</Translate>
|
||||
</span>
|
||||
<ul className="menu__list">
|
||||
{services
|
||||
.filter(
|
||||
(service) => service.sectionKind !== ServiceSectionKind.UPCOMING
|
||||
)
|
||||
.map((service) => (
|
||||
<li className="menu__list-item">
|
||||
<a className="menu__link" href={service.url}>
|
||||
{service.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ServicesNavbarItem(props: {
|
||||
content: string;
|
||||
mobile?: boolean;
|
||||
}): JSX.Element | null {
|
||||
if (props.mobile) return <Mobile></Mobile>;
|
||||
|
||||
return (
|
||||
<div className="navbar__item dropdown dropdown--hoverable">
|
||||
<span className="navbar__link">
|
||||
<Translate>Services</Translate>
|
||||
</span>
|
||||
<ul className="dropdown__menu">
|
||||
{services
|
||||
.filter(
|
||||
(service) => service.sectionKind !== ServiceSectionKind.UPCOMING
|
||||
)
|
||||
.map((service) => (
|
||||
<li>
|
||||
<a className="dropdown__link" href={service.url}>
|
||||
{service.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -28,3 +28,8 @@
|
|||
--ifm-color-primary-lightest: #e64dff;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.navbar__search-input {
|
||||
border-radius: var(--ifm-button-border-radius);
|
||||
width: auto;
|
||||
}
|
||||
|
|
189
src/services.tsx
Normal file
189
src/services.tsx
Normal file
|
@ -0,0 +1,189 @@
|
|||
import { translate } from "@docusaurus/Translate";
|
||||
import React from "react";
|
||||
|
||||
export enum ServiceSectionKind {
|
||||
PUBLIC = "PUBLIC",
|
||||
PRIVATE = "PRIVATE",
|
||||
UPCOMING = "UPCOMING",
|
||||
}
|
||||
|
||||
export interface ServicesSection {
|
||||
title: string;
|
||||
description: string | JSX.Element;
|
||||
}
|
||||
|
||||
export interface ServiceDescription {
|
||||
sectionKind: ServiceSectionKind;
|
||||
title: string;
|
||||
url: string;
|
||||
Svg: React.ComponentType<React.ComponentProps<"svg">>;
|
||||
description: JSX.Element;
|
||||
}
|
||||
|
||||
export const sections: { [key in ServiceSectionKind]: ServicesSection } = {
|
||||
[ServiceSectionKind.PUBLIC]: {
|
||||
title: translate({ message: "Public Services" }),
|
||||
description: "Services that are available to everyone.",
|
||||
},
|
||||
[ServiceSectionKind.PRIVATE]: {
|
||||
title: translate({ message: "Private Services" }),
|
||||
description: (
|
||||
<>
|
||||
Services that require <b>id.tjo.space</b> account.
|
||||
</>
|
||||
),
|
||||
},
|
||||
[ServiceSectionKind.UPCOMING]: {
|
||||
title: translate({ message: "Upcoming Services" }),
|
||||
description:
|
||||
"Services that we plan to provide in the future, but are not quite ready yet.",
|
||||
},
|
||||
};
|
||||
|
||||
export const services: ServiceDescription[] = [
|
||||
{
|
||||
sectionKind: ServiceSectionKind.PRIVATE,
|
||||
title: "Chat",
|
||||
url: "https://chat.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_chat_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://chat.tjo.space">chat.tjo.space</a> Metrix server
|
||||
which you can use to chat with other users of tjo.space or world wide
|
||||
with anyone else on the Matrix network.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.PRIVATE,
|
||||
title: "Cloud",
|
||||
url: "https://code.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_cloud_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://cloud.tjo.space">cloud.tjo.space</a> Nextcloud
|
||||
server as a personal cloud to store your <b>Photos</b>, <b>Videos</b>,
|
||||
<b>Files</b>, <b>Calendar</b>, <b>Contacts</b> as well as share all that
|
||||
with other users of tjo.space or anyone else.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.PRIVATE,
|
||||
title: "Code",
|
||||
url: "https://code.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_code_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://code.tjo.space">code.tjo.space</a> Gitea server as
|
||||
a Git repository and CI/CD system.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.PRIVATE,
|
||||
title: "Paperless",
|
||||
url: "https://paperless.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_paperless_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://paperless.tjo.space">paperless.tjo.space</a>{" "}
|
||||
Paperless server to archive your documents and make them searchable. Can
|
||||
be connected to your email provider so that all attachments are
|
||||
autmatically archived.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.PRIVATE,
|
||||
title: "RSS",
|
||||
url: "https://rss.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_rss_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://rss.tjo.space">rss.tjo.space</a> server as a RSS
|
||||
reader for all of your news, blogs and podcasts.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.PUBLIC,
|
||||
title: "Search",
|
||||
url: "https://search.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_search_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://search.tjo.space">search.tjo.space</a> private meta
|
||||
search engine that doesn't track you.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.PUBLIC,
|
||||
title: "Send",
|
||||
url: "https://send.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_send_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://send.tjo.space">send.tjo.space</a> to create
|
||||
private temporary link to share files up to 20GB in size.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.PUBLIC,
|
||||
title: "Watch",
|
||||
url: "https://yt.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_yt_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://yt.tjo.space">yt.tjo.space</a> an Invidious server
|
||||
to privately watch YouTube videos.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.UPCOMING,
|
||||
title: "Mail",
|
||||
url: "https://mail.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_mail_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://mail.tjo.space">mail.tjo.space</a> to get your
|
||||
personal <b>@tjo.space</b> email address.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.UPCOMING,
|
||||
title: "Vault",
|
||||
url: "https://vault.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_vault_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://vault.tjo.space">vault.tjo.space</a> Bitwarden
|
||||
server to securily store your passwords.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
sectionKind: ServiceSectionKind.UPCOMING,
|
||||
title: "VPN",
|
||||
url: "https://vpn.tjo.space",
|
||||
Svg: require("@site/static/img/undraw_vpn_tjo_space.svg").default,
|
||||
description: (
|
||||
<>
|
||||
Use <a href="https://vpn.tjo.space">vpn.tjo.space</a> Tailscale server
|
||||
to securily connect with other tjo.space users or use one of available
|
||||
exit locations to have secure internet connection.
|
||||
</>
|
||||
),
|
||||
},
|
||||
].sort((a, b) => {
|
||||
const titleA = a.title.toUpperCase();
|
||||
const titleB = b.title.toUpperCase();
|
||||
|
||||
if (titleA < titleB) return -1;
|
||||
if (titleA > titleB) return 1;
|
||||
return 0;
|
||||
});
|
|
@ -8,6 +8,7 @@ import DocSidebarNavbarItem from "@theme/NavbarItem/DocSidebarNavbarItem";
|
|||
import DocsVersionNavbarItem from "@theme/NavbarItem/DocsVersionNavbarItem";
|
||||
import DocsVersionDropdownNavbarItem from "@theme/NavbarItem/DocsVersionDropdownNavbarItem";
|
||||
import CustomStatusNavbarItem from "@site/src/components/NavbarItems/CustomStatusNavbarItem";
|
||||
import ServicesNavbarItem from "@site/src/components/NavbarItems/ServicesNavbarItem";
|
||||
const ComponentTypes = {
|
||||
default: DefaultNavbarItem,
|
||||
localeDropdown: LocaleDropdownNavbarItem,
|
||||
|
@ -22,4 +23,5 @@ const ComponentTypes = {
|
|||
export default {
|
||||
...ComponentTypes,
|
||||
"custom-status-navbar-item": CustomStatusNavbarItem,
|
||||
"custom-services-navbar-item": ServicesNavbarItem,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue