mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 03:59:05 +01:00
322 lines
16 KiB
TypeScript
322 lines
16 KiB
TypeScript
import { ComponentChildren } from 'preact';
|
|
import Card from '../../components/Card.js';
|
|
import Section from '../../components/Section.js';
|
|
import DownloadButton from '../../components/DownloadButton.js';
|
|
import "./index.css";
|
|
import { useColorScheme, usePageTitle } from '../../hooks.js';
|
|
import Button, { Link } from '../../components/Button.js';
|
|
import gitHubIcon from "../../assets/boxicons/bx-github.svg?raw";
|
|
import dockerIcon from "../../assets/boxicons/bx-docker.svg?raw";
|
|
import noteStructureIcon from "../../assets/boxicons/bx-folder.svg?raw";
|
|
import attributesIcon from "../../assets/boxicons/bx-tag.svg?raw";
|
|
import hoistingIcon from "../../assets/boxicons/bx-chevrons-up.svg?raw";
|
|
import revisionsIcon from "../../assets/boxicons/bx-history.svg?raw";
|
|
import syncIcon from "../../assets/boxicons/bx-refresh-cw.svg?raw";
|
|
import protectedNotesIcon from "../../assets/boxicons/bx-shield.svg?raw";
|
|
import jumpToIcon from "../../assets/boxicons/bx-send-alt.svg?raw";
|
|
import searchIcon from "../../assets/boxicons/bx-search.svg?raw";
|
|
import webClipperIcon from "../../assets/boxicons/bx-paperclip.svg?raw";
|
|
import importExportIcon from "../../assets/boxicons/bx-swap-horizontal.svg?raw";
|
|
import shareIcon from "../../assets/boxicons/bx-globe.svg?raw";
|
|
import codeIcon from "../../assets/boxicons/bx-code.svg?raw";
|
|
import restApiIcon from "../../assets/boxicons/bx-extension.svg?raw";
|
|
import textNoteIcon from "../../assets/boxicons/bx-note.svg?raw";
|
|
import fileIcon from "../../assets/boxicons/bx-file.svg?raw";
|
|
import canvasIcon from "../../assets/boxicons/bx-pen.svg?raw";
|
|
import mermaidIcon from "../../assets/boxicons/bx-vector-square.svg?raw";
|
|
import mindmapIcon from "../../assets/boxicons/bx-network-chart.svg?raw";
|
|
import calendarIcon from "../../assets/boxicons/bx-calendar.svg?raw";
|
|
import tableIcon from "../../assets/boxicons/bx-table.svg?raw";
|
|
import boardIcon from "../../assets/boxicons/bx-columns-3.svg?raw";
|
|
import geomapIcon from "../../assets/boxicons/bx-map.svg?raw";
|
|
import { getPlatform } from '../../download-helper.js';
|
|
import { useEffect, useState } from 'preact/hooks';
|
|
import { Trans, useTranslation } from 'react-i18next';
|
|
|
|
export function Home() {
|
|
usePageTitle("");
|
|
|
|
return (
|
|
<>
|
|
<HeroSection />
|
|
<OrganizationBenefitsSection />
|
|
<ProductivityBenefitsSection />
|
|
<NoteTypesSection />
|
|
<ExtensibilityBenefitsSection />
|
|
<CollectionsSection />
|
|
<FaqSection />
|
|
<FinalCta />
|
|
</>
|
|
);
|
|
}
|
|
|
|
function HeroSection() {
|
|
const { t } = useTranslation();
|
|
const platform = getPlatform();
|
|
const colorScheme = useColorScheme();
|
|
const [ screenshotUrl, setScreenshotUrl ] = useState<string>();
|
|
|
|
useEffect(() => {
|
|
switch (platform) {
|
|
case "macos":
|
|
setScreenshotUrl(`/screenshot_desktop_mac_${colorScheme}.webp`);
|
|
break;
|
|
case "linux":
|
|
setScreenshotUrl(`/screenshot_desktop_linux_${colorScheme}.webp`);
|
|
break;
|
|
case "windows":
|
|
default:
|
|
setScreenshotUrl(`/screenshot_desktop_win_${colorScheme}.webp`);
|
|
break;
|
|
}
|
|
}, [ colorScheme ]);
|
|
|
|
return (
|
|
<Section className="hero-section">
|
|
<div class="title-section">
|
|
<h1>{t("hero_section.title")}</h1>
|
|
<p>{t("hero_section.subtitle")}</p>
|
|
|
|
<div className="download-wrapper">
|
|
<DownloadButton big />
|
|
<Button href="./get-started/" className="mobile-only" text={t("hero_section.get_started")} />
|
|
<div className="additional-options">
|
|
<Button iconSvg={gitHubIcon} outline text={t("hero_section.github")} href="https://github.com/TriliumNext/Trilium/" openExternally />
|
|
<Button iconSvg={dockerIcon} outline text={t("hero_section.dockerhub")} href="https://hub.docker.com/r/triliumnext/trilium" openExternally />
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="screenshot-container">
|
|
{screenshotUrl && <img class="screenshot" src={screenshotUrl} alt={t("hero_section.screenshot_alt")} />}
|
|
</div>
|
|
</Section>
|
|
)
|
|
}
|
|
|
|
function OrganizationBenefitsSection() {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<>
|
|
<Section className="benefits" title={t("organization_benefits.title")}>
|
|
<div className="benefits-container grid-3-cols">
|
|
<Card iconSvg={noteStructureIcon} title={t("organization_benefits.note_structure_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/index.html">{t("organization_benefits.note_structure_description")}</Card>
|
|
<Card iconSvg={attributesIcon} title={t("organization_benefits.attributes_title")} moreInfoUrl="https://docs.triliumnotes.org/User Guide/User Guide/Advanced Usage/Attributes/index.html">{t("organization_benefits.attributes_description")}</Card>
|
|
<Card iconSvg={hoistingIcon} title={t("organization_benefits.hoisting_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Note%20Hoisting.html">{t("organization_benefits.hoisting_description")}</Card>
|
|
</div>
|
|
</Section>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function ProductivityBenefitsSection() {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<>
|
|
<Section className="benefits accented" title={t("productivity_benefits.title")}>
|
|
<div className="benefits-container grid-3-cols">
|
|
<Card iconSvg={revisionsIcon} title={t("productivity_benefits.revisions_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/Note%20Revisions.html">{t("productivity_benefits.revisions_content")}</Card>
|
|
<Card iconSvg={syncIcon} title={t("productivity_benefits.sync_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Synchronization.html">{t("productivity_benefits.sync_content")}</Card>
|
|
<Card iconSvg={protectedNotesIcon} title={t("productivity_benefits.protected_notes_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/Protected%20Notes.html">{t("productivity_benefits.protected_notes_content")}</Card>
|
|
<Card iconSvg={jumpToIcon} title={t("productivity_benefits.jump_to_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Jump%20to.html">{t("productivity_benefits.jump_to_content")}</Card>
|
|
<Card iconSvg={searchIcon} title={t("productivity_benefits.search_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Search.html">{t("productivity_benefits.search_content")}</Card>
|
|
<Card iconSvg={webClipperIcon} title={t("productivity_benefits.web_clipper_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Web%20Clipper.html">{t("productivity_benefits.web_clipper_content")}</Card>
|
|
</div>
|
|
</Section>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function NoteTypesSection() {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<Section className="note-types" title={t("note_types.title")}>
|
|
<ListWithScreenshot horizontal items={[
|
|
{
|
|
title: t("note_types.text_title"),
|
|
imageUrl: "/type_text.webp",
|
|
iconSvg: textNoteIcon,
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Text/index.html",
|
|
description: t("note_types.text_description")
|
|
},
|
|
{
|
|
title: t("note_types.code_title"),
|
|
imageUrl: "/type_code.webp",
|
|
iconSvg: codeIcon,
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Code.html",
|
|
description: t("note_types.code_description")
|
|
},
|
|
{
|
|
title: t("note_types.file_title"),
|
|
imageUrl: "/type_file.webp",
|
|
iconSvg: fileIcon,
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/File.html",
|
|
description: t("note_types.file_description")
|
|
},
|
|
{
|
|
title: t("note_types.canvas_title"),
|
|
imageUrl: "/type_canvas.webp",
|
|
iconSvg: canvasIcon,
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Canvas.html",
|
|
description: t("note_types.canvas_description")
|
|
},
|
|
{
|
|
title: t("note_types.mermaid_title"),
|
|
imageUrl: "/type_mermaid.webp",
|
|
iconSvg: mermaidIcon,
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Mermaid%20Diagrams/index.html",
|
|
description: t("note_types.mermaid_description")
|
|
},
|
|
{
|
|
title: t("note_types.mindmap_title"),
|
|
imageUrl: "/type_mindmap.webp",
|
|
iconSvg: mindmapIcon,
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Mind%20Map.html",
|
|
description: t("note_types.mindmap_description")
|
|
}
|
|
]} />
|
|
<p>
|
|
<Trans
|
|
i18nKey="note_types.others_list"
|
|
components={[
|
|
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Note%20Map.html" openExternally />,
|
|
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Relation%20Map.html" openExternally />,
|
|
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Saved%20Search.html" openExternally />,
|
|
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Render%20Note.html" openExternally />,
|
|
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Web%20View.html" openExternally />
|
|
]}
|
|
/>
|
|
</p>
|
|
</Section>
|
|
);
|
|
}
|
|
|
|
function ExtensibilityBenefitsSection() {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<>
|
|
<Section className="benefits accented" title={t("extensibility_benefits.title")}>
|
|
<div className="benefits-container grid-4-cols">
|
|
<Card iconSvg={importExportIcon} title={t("extensibility_benefits.import_export_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Import%20%26%20Export/Markdown/index.html">{t("extensibility_benefits.import_export_description")}</Card>
|
|
<Card iconSvg={shareIcon} title={t("extensibility_benefits.share_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Advanced%20Usage/Sharing/Serving%20directly%20the%20content%20o.html">{t("extensibility_benefits.share_description")}</Card>
|
|
<Card iconSvg={codeIcon} title={t("extensibility_benefits.scripting_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Scripting/Custom%20Widgets/index.html">{t("extensibility_benefits.scripting_description")}</Card>
|
|
<Card iconSvg={restApiIcon} title={t("extensibility_benefits.api_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Advanced%20Usage/ETAPI%20%28REST%20API%29/index.html">{t("extensibility_benefits.api_description")}</Card>
|
|
</div>
|
|
</Section>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function CollectionsSection() {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<Section className="collections" title={t("collections.title")}>
|
|
<ListWithScreenshot items={[
|
|
{
|
|
title: t("collections.calendar_title"),
|
|
imageUrl: "/collection_calendar.webp",
|
|
iconSvg: calendarIcon,
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Calendar%20View.html",
|
|
description: t("collections.calendar_description")
|
|
},
|
|
{
|
|
title: t("collections.table_title"),
|
|
iconSvg: tableIcon,
|
|
imageUrl: "/collection_table.webp",
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Table%20View.html",
|
|
description: t("collections.table_description")
|
|
},
|
|
{
|
|
title: t("collections.board_title"),
|
|
iconSvg: boardIcon,
|
|
imageUrl: "/collection_board.webp",
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Board%20View.html",
|
|
description: t("collections.board_description")
|
|
},
|
|
{
|
|
title: t("collections.geomap_title"),
|
|
iconSvg: geomapIcon,
|
|
imageUrl: "/collection_geomap.webp",
|
|
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Geo%20Map%20View.html",
|
|
description: t("collections.geomap_description")
|
|
}
|
|
]} />
|
|
</Section>
|
|
);
|
|
}
|
|
|
|
function ListWithScreenshot({ items, horizontal, cardExtra }: {
|
|
items: { title: string, imageUrl: string, description: string, moreInfo: string, iconSvg?: string }[];
|
|
horizontal?: boolean;
|
|
cardExtra?: ComponentChildren;
|
|
}) {
|
|
const [ selectedItem, setSelectedItem ] = useState(items[0]);
|
|
const { t } = useTranslation();
|
|
|
|
return (
|
|
<div className={`list-with-screenshot ${horizontal ? "horizontal" : ""}`}>
|
|
<ul>
|
|
{items.map(item => (
|
|
<li className={`${item === selectedItem ? "selected" : ""}`}>
|
|
<Card
|
|
title={item.title}
|
|
onMouseEnter={() => setSelectedItem(item)}
|
|
onClick={() => setSelectedItem(item)}
|
|
moreInfoUrl={item.moreInfo}
|
|
iconSvg={item.iconSvg}
|
|
>
|
|
{item.description}
|
|
</Card>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
|
|
<div className="details">
|
|
{selectedItem && (
|
|
<>
|
|
<img src={selectedItem.imageUrl} alt={t("components.list_with_screenshot_alt")} loading="lazy" />
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function FaqSection() {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<Section className="faq" title={t("faq.title")}>
|
|
<div class="grid-2-cols">
|
|
<FaqItem question={t("faq.mobile_question")}>{t("faq.mobile_answer")}</FaqItem>
|
|
<FaqItem question={t("faq.database_question")}>{t("faq.database_answer")}</FaqItem>
|
|
<FaqItem question={t("faq.server_question")}>{t("faq.server_answer")}</FaqItem>
|
|
<FaqItem question={t("faq.scaling_question")}>{t("faq.scaling_answer")}</FaqItem>
|
|
<FaqItem question={t("faq.network_share_question")}>{t("faq.network_share_answer")}</FaqItem>
|
|
<FaqItem question={t("faq.security_question")}>{t("faq.security_answer")}</FaqItem>
|
|
</div>
|
|
</Section>
|
|
);
|
|
}
|
|
|
|
function FaqItem({ question, children }: { question: string; children: ComponentChildren }) {
|
|
return (
|
|
<Card title={question}>
|
|
{children}
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
function FinalCta() {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<Section className="final-cta accented" title={t("final_cta.title")}>
|
|
<p>{t("final_cta.description")}</p>
|
|
|
|
<div class="buttons">
|
|
<Button href="./get-started/" text={t("final_cta.get_started")} />
|
|
</div>
|
|
</Section>
|
|
)
|
|
}
|