diff --git a/docusaurus.config.js b/docusaurus.config.js index 3c7cfab..22ce049 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -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", diff --git a/i18n/en/code.json b/i18n/en/code.json index 6947580..07942c4 100644 --- a/i18n/en/code.json +++ b/i18n/en/code.json @@ -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" } } diff --git a/i18n/sl/code.json b/i18n/sl/code.json index 3c1c26c..7bda752 100644 --- a/i18n/sl/code.json +++ b/i18n/sl/code.json @@ -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" } } diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx index e1d5b90..5576486 100644 --- a/src/components/HomepageFeatures/index.tsx +++ b/src/components/HomepageFeatures/index.tsx @@ -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>; - description: JSX.Element; -}; - -const PrivateServices: ServicesSection = { - title: "Private Services", - description: ( - <> - Services that require id.tjo.space account. - - ), - services: [ - { - title: "Chat", - Svg: require("@site/static/img/undraw_chat_tjo_space.svg").default, - description: ( - <> - Use chat.tjo.space 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 cloud.tjo.space Nextcloud - server as a personal cloud to store your Photos, Videos, - Files, Calendar, Contacts 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 code.tjo.space 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 paperless.tjo.space{" "} - 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 rss.tjo.space 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 search.tjo.space private - meta search engine that doesn't track you. - - ), - }, - { - title: "Send", - Svg: require("@site/static/img/undraw_send_tjo_space.svg").default, - description: ( - <> - Use send.tjo.space 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 yt.tjo.space 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 mail.tjo.space to get your - personal @tjo.space email address. - - ), - }, - { - title: "Vault", - Svg: require("@site/static/img/undraw_vault_tjo_space.svg").default, - description: ( - <> - Use vault.tjo.space Bitwarden - server to securily store your passwords. - - ), - }, - { - title: "VPN", - Svg: require("@site/static/img/undraw_vpn_tjo_space.svg").default, - description: ( - <> - Use vpn.tjo.space 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 (
@@ -175,16 +22,18 @@ export default function HomepageFeatures(): JSX.Element {

Services that we provide

- {[PublicServices, PrivateServices, UpcomingServices].map( - ({ title, description, services }) => { + {Object.entries(sections).map( + ([sectionKind, { title, description }]) => { return ( <>

{title}

{description}

- {services.map((props, idx) => ( - - ))} + {services + .filter((service) => service.sectionKind === sectionKind) + .map((props, idx) => ( + + ))}
); diff --git a/src/components/NavbarItems/CustomStatusNavbarItem.tsx b/src/components/NavbarItems/CustomStatusNavbarItem.tsx index 408f26f..9d8e2e5 100644 --- a/src/components/NavbarItems/CustomStatusNavbarItem.tsx +++ b/src/components/NavbarItems/CustomStatusNavbarItem.tsx @@ -27,8 +27,7 @@ function Mobile({ healthy, status }) { href="https://status.tjo.space" style={{ display: "inline-block", width: "100%" }} > - {status} - + {status} ); diff --git a/src/components/NavbarItems/ServicesNavbarItem.tsx b/src/components/NavbarItems/ServicesNavbarItem.tsx new file mode 100644 index 0000000..36ea6d1 --- /dev/null +++ b/src/components/NavbarItems/ServicesNavbarItem.tsx @@ -0,0 +1,54 @@ +import Translate from "@docusaurus/Translate"; +import { ServiceSectionKind, services } from "@site/src/services"; +import React from "react"; + +function Mobile() { + return ( +
  • + + Services + +
      + {services + .filter( + (service) => service.sectionKind !== ServiceSectionKind.UPCOMING + ) + .map((service) => ( +
    • + + {service.title} + +
    • + ))} +
    +
  • + ); +} + +export default function ServicesNavbarItem(props: { + content: string; + mobile?: boolean; +}): JSX.Element | null { + if (props.mobile) return ; + + return ( +
    + + Services + +
      + {services + .filter( + (service) => service.sectionKind !== ServiceSectionKind.UPCOMING + ) + .map((service) => ( +
    • + + {service.title} + +
    • + ))} +
    +
    + ); +} diff --git a/src/css/custom.css b/src/css/custom.css index 390f927..21f5c0d 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -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; +} diff --git a/src/services.tsx b/src/services.tsx new file mode 100644 index 0000000..dea00f6 --- /dev/null +++ b/src/services.tsx @@ -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>; + 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 id.tjo.space 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 chat.tjo.space 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 cloud.tjo.space Nextcloud + server as a personal cloud to store your Photos, Videos, + Files, Calendar, Contacts 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 code.tjo.space 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 paperless.tjo.space{" "} + 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 rss.tjo.space 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 search.tjo.space 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 send.tjo.space 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 yt.tjo.space 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 mail.tjo.space to get your + personal @tjo.space 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 vault.tjo.space 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 vpn.tjo.space 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; +}); diff --git a/src/theme/NavbarItem/ComponentTypes.js b/src/theme/NavbarItem/ComponentTypes.js index 999a620..4cc6a36 100644 --- a/src/theme/NavbarItem/ComponentTypes.js +++ b/src/theme/NavbarItem/ComponentTypes.js @@ -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, };