feat: Integrate Docusaurus for documentation and enhance project structure

- Added Docusaurus configuration and initial setup for documentation.
- Created multiple documentation pages covering installation, configuration, and core concepts.
- Implemented a GitHub Actions workflow for automatic deployment of documentation to GitHub Pages.
- Updated .gitignore to exclude Docusaurus build artifacts and dependencies.
- Enhanced README with a link to the online documentation.
This commit is contained in:
StarFleetCPTN
2025-04-12 13:01:53 -07:00
parent 0aa68bc8e7
commit 834f066704
90 changed files with 24649 additions and 15 deletions
@@ -0,0 +1,71 @@
import type {ReactNode} from 'react';
import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
type FeatureItem = {
title: string;
Svg: React.ComponentType<React.ComponentProps<'svg'>>;
description: ReactNode;
};
const FeatureList: FeatureItem[] = [
{
title: 'Easy to Use',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
used to get your website up and running quickly.
</>
),
},
{
title: 'Focus on What Matters',
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
ahead and move your docs into the <code>docs</code> directory.
</>
),
},
{
title: 'Powered by React',
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
be extended while reusing the same header and footer.
</>
),
},
];
function Feature({title, Svg, description}: FeatureItem) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures(): ReactNode {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}
@@ -0,0 +1,11 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}
+206
View File
@@ -0,0 +1,206 @@
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #2e6db8;
--ifm-color-primary-dark: #2962a6;
--ifm-color-primary-darker: #275c9c;
--ifm-color-primary-darkest: #204c81;
--ifm-color-primary-light: #3378ca;
--ifm-color-primary-lighter: #3e7fcf;
--ifm-color-primary-lightest: #5a92d6;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
/* Custom colors */
--ifm-color-secondary: #54b4d3;
--ifm-color-success: #28a745;
--ifm-color-info: #54b4d3;
--ifm-color-warning: #ffc107;
--ifm-color-danger: #dc3545;
/* Font settings */
--ifm-font-family-base: system-ui, -apple-system, 'Segoe UI', Roboto, Ubuntu, Cantarell, 'Noto Sans', sans-serif;
--ifm-heading-font-weight: 600;
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-color-primary: #4d94ff;
--ifm-color-primary-dark: #2d81ff;
--ifm-color-primary-darker: #1d77ff;
--ifm-color-primary-darkest: #0058dc;
--ifm-color-primary-light: #6da7ff;
--ifm-color-primary-lighter: #7db1ff;
--ifm-color-primary-lightest: #aeccff;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
/* Custom colors in dark mode */
--ifm-background-color: #1a1a1a;
--ifm-background-surface-color: #242526;
--ifm-color-secondary: #4290ac;
--ifm-color-success: #2a9d47;
--ifm-color-info: #4290ac;
--ifm-color-warning: #d9a406;
--ifm-color-danger: #bd2130;
}
.hero--primary {
--ifm-hero-background-color: var(--ifm-color-primary);
--ifm-hero-text-color: var(--ifm-font-color-base-inverse);
padding: 4rem 2rem;
}
/* Add custom button spacing on homepage */
.buttons {
gap: 1rem;
display: flex;
align-items: center;
justify-content: center;
}
/* Logo styling */
.navbar__logo {
height: 2.5rem;
margin-right: 0.5rem;
}
/* Card styling for feature sections */
.card {
border-radius: 8px;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
overflow: hidden;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
/* Section styling */
.section {
padding: 4rem 0;
}
.sectionAlt {
background-color: var(--ifm-color-emphasis-100);
}
/* Footer styling */
.footer {
padding: 2rem 0;
background-color: var(--ifm-color-primary-darkest);
color: var(--ifm-color-white);
}
.footer a {
color: var(--ifm-color-primary-lightest);
}
.footer a:hover {
color: var(--ifm-color-white);
text-decoration: underline;
}
.footer__title {
color: var(--ifm-color-white);
}
.footer__link-item {
opacity: 0.85;
transition: opacity 0.2s;
}
.footer__link-item:hover {
opacity: 1;
}
.footer__bottom {
border-top: 1px solid rgba(255, 255, 255, 0.2);
padding-top: 1rem;
margin-top: 1rem;
}
[data-theme='dark'] .footer {
background-color: #191919;
border-top: 1px solid #333;
}
/* Documentation styling */
.markdown h1:first-child {
--ifm-h1-font-size: 2.5rem;
margin-bottom: 1.5rem;
}
.markdown > h2 {
--ifm-h2-font-size: 2rem;
margin-top: 2.5rem;
margin-bottom: 1rem;
padding-bottom: 0.3rem;
border-bottom: 1px solid var(--ifm-color-emphasis-300);
}
.markdown > h3 {
--ifm-h3-font-size: 1.5rem;
margin-top: 2rem;
}
/* Code block styling */
pre {
border-radius: 8px;
}
/* Discord button styling */
.header-discord-link:hover {
opacity: 0.8;
}
.header-discord-link::before {
content: '';
width: 24px;
height: 24px;
display: flex;
background: url("../../static/img/discord.svg") no-repeat;
background-size: 100% 100%;
margin-right: 8px;
}
[data-theme='dark'] .header-discord-link::before {
filter: brightness(0) invert(1);
}
/* Discord badge for other elements */
.discord-badge {
display: inline-flex;
align-items: center;
margin-left: 8px;
font-size: 0.9rem;
padding: 4px 8px;
border-radius: 8px;
background-color: #5865F2;
color: white;
text-decoration: none;
transition: background-color 0.2s;
}
.discord-badge:hover {
background-color: #4752c4;
text-decoration: none;
color: white;
}
.discord-badge::before {
content: '';
width: 16px;
height: 16px;
display: inline-block;
background: url("../../static/img/discord.svg") no-repeat;
background-size: 100% 100%;
margin-right: 6px;
filter: brightness(0) invert(1);
}
+39
View File
@@ -0,0 +1,39 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
}
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
}
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.section {
padding: 4rem 0;
}
.sectionAlt {
background-color: var(--ifm-color-emphasis-100);
}
+182
View File
@@ -0,0 +1,182 @@
import React from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import Heading from '@theme/Heading';
import styles from './index.module.css';
function HomepageHeader() {
const {siteConfig} = useDocusaurusContext();
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<div className="row">
<div className="col col--8 col--offset-2">
<img
src="/img/logo.svg"
alt="GoMFT Logo"
style={{width: '120px', marginBottom: '1.5rem'}}
/>
<Heading as="h1" className="hero__title">
{siteConfig.title}
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/docs/introduction/overview">
Get Started
</Link>
<Link
className="button button--outline button--lg button--secondary"
to="https://github.com/StarFleetCPTN/GoMFT">
GitHub
</Link>
</div>
</div>
</div>
</div>
</header>
);
}
function FeatureList() {
return [
{
title: 'Easy to Use',
description: (
<>
GoMFT was designed from the ground up to be easily installed and
used to get your file transfers up and running quickly.
</>
),
},
{
title: 'Multi-Protocol Support',
description: (
<>
GoMFT leverages the power of rclone to support over 40 storage
systems including S3, SFTP, Google Drive, and more.
</>
),
},
{
title: 'Powerful Scheduling',
description: (
<>
Schedule your file transfers using familiar cron syntax for recurring transfers,
or run them on-demand with the intuitive web interface.
</>
),
},
];
}
interface FeatureProps {
title: string;
description: React.ReactElement;
}
function Feature({title, description}: FeatureProps) {
return (
<div className={clsx('col col--4')}>
<div className="text--center padding-horiz--md">
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>
);
}
export default function Home(): React.ReactNode {
const {siteConfig} = useDocusaurusContext();
return (
<Layout
title={`${siteConfig.title} - Modern Managed File Transfer Solution`}
description="GoMFT is a modern, open-source managed file transfer solution with multi-protocol support, scheduling capabilities, and a user-friendly web interface">
<HomepageHeader />
<main>
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList().map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
<section className={clsx(styles.section, styles.sectionAlt)}>
<div className="container">
<div className="row">
<div className="col col--6">
<Heading as="h2">Modern Web Interface</Heading>
<p>
GoMFT provides a clean, responsive web interface for managing your file transfers.
The dashboard gives you at-a-glance information about transfer status, recent jobs,
and system health.
</p>
<Link
className="button button--primary"
to="/docs/core-concepts/monitoring">
Learn More
</Link>
</div>
<div className="col col--6">
<img src="/img/dashboard.gomft.png" alt="GoMFT Dashboard" className="shadow--md" style={{borderRadius: '8px'}} />
</div>
</div>
</div>
</section>
<section className={styles.section}>
<div className="container">
<div className="row">
<div className="col col--6">
<img src="/img/transfer.config.gomft.png" alt="Transfer Configuration" className="shadow--md" style={{borderRadius: '8px'}} />
</div>
<div className="col col--6">
<Heading as="h2">Easy Deployment</Heading>
<p>
Deploy GoMFT quickly using Docker, or install it directly on your system.
The application is lightweight and can run on various platforms including
Linux, macOS, and Windows.
</p>
<Link
className="button button--primary"
to="/docs/getting-started/installation">
Installation Guide
</Link>
</div>
</div>
</div>
</section>
<section className={clsx(styles.section, styles.sectionAlt)}>
<div className="container">
<div className="text--center">
<Heading as="h2">Ready to Get Started?</Heading>
<p>
Check out our documentation to learn how to set up and use GoMFT for your file transfer needs.
</p>
<div className={styles.buttons}>
<Link
className="button button--primary button--lg"
to="/docs/introduction/overview">
Read the Docs
</Link>
<Link
className="button button--secondary button--lg"
to="https://github.com/StarFleetCPTN/GoMFT">
GitHub Repository
</Link>
</div>
</div>
</div>
</section>
</main>
</Layout>
);
}
+7
View File
@@ -0,0 +1,7 @@
---
title: Markdown page example
---
# Markdown page example
You don't need React to write simple standalone pages.
+14
View File
@@ -0,0 +1,14 @@
import React, {type ReactNode} from 'react';
import SearchBar from '@theme-original/SearchBar';
import type SearchBarType from '@theme/SearchBar';
import type {WrapperProps} from '@docusaurus/types';
type Props = WrapperProps<typeof SearchBarType>;
export default function SearchBarWrapper(props: Props): ReactNode {
return (
<>
<SearchBar {...props} />
</>
);
}