Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ _site
.jekyll-cache
.jekyll-metadata
vendor
yarn.lock

.idea/

Expand Down
15 changes: 15 additions & 0 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ const config: Config = {
src: 'img/apple-touch-icon.png',
},
items: [
{
type: 'dropdown',
label: 'Software',
position: 'left',
items: [
{
to: '/software/geyser',
label: 'Geyser',
},
{
to: '/software/floodgate',
label: 'Floodgate',
},
]
},
{
type: 'dropdown',
label: 'Wiki',
Expand Down
25 changes: 25 additions & 0 deletions src/components/SoftwareFeature/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { PropsWithChildren } from 'react';
import styles from "./styles.module.scss";
import clsx from 'clsx';

interface SoftwareFeatureProps {
title: string;
image?: string;
flipped?: boolean;
}

export default function SoftwareFeature({ title, image, flipped, children }: PropsWithChildren<SoftwareFeatureProps>) {
return (
<div className={clsx(styles.feature, { [styles.flipped]: flipped })}>
<div className={clsx(styles.content, "text--left padding-horiz--md")}>
<h3 className={styles.title}>{title}</h3>
{children}
</div>
{image && (
<div>
<img src={image} alt={title} />
</div>
)}
</div>
);
}
40 changes: 40 additions & 0 deletions src/components/SoftwareFeature/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.feature {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}

.feature.flipped > *:first-child {
order: 2;
}

.feature.flipped > *:last-child {
order: 1;
}

.content {
margin-top: auto;
margin-bottom: auto;
}

.title {
font-size: 30px;
}

@media (max-width: 768px) {
.feature {
grid-template-columns: 1fr;
}

.feature > *:first-child {
order: 2;
}

.feature > *:last-child {
order: 1;
}

.title {
margin-top: 15px;
}
}
36 changes: 36 additions & 0 deletions src/components/SoftwareHero/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import styles from './styles.module.scss';

interface SoftwareHeroProps {
icon?: string;
software: string;
tagline?: string;
description: string;
downloadsUrl: string;
docsUrl: string;
}

const SoftwareHero: React.FC<SoftwareHeroProps> = ({ icon, software, tagline, description, downloadsUrl, docsUrl }) => {
return (
<div className={styles.heroBanner}>
<div className="container">
{icon && <img src={icon} className={styles.icon} />}

<h1 className={styles.software}>{software}</h1>
<p className={styles.tagline}>{tagline}</p>
<p className={styles.description}>{description}</p>

<div className={styles.buttons}>
<a href={downloadsUrl} className={styles.button}>
Downloads
</a>
<a href={docsUrl} className={styles.button}>
Documentation
</a>
</div>
</div>
</div>
);
};

export default SoftwareHero;
63 changes: 63 additions & 0 deletions src/components/SoftwareHero/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.heroBanner {
width: 100%;
padding: 20px 0;
position: relative;
}

.icon {
height: 80px;
width: 80px;
}

.software {
font-size: 60px;
margin: 0;
}

.tagline {
font-size: 28px;
font-weight: 600;
margin-bottom: 15px;
}

.description {
font-size: 18px;
}

.buttons {
display: flex;
gap: 10px;
flex-wrap: wrap;
}


.button {
border: 3px solid var(--ifm-tabs-color-active);
border-radius: var(--ifm-global-radius);
text-align: center;
font-size: 18px;
transition: background-color 0.5s ease, color 0.5s ease;
padding: 5px 20px;

&:hover {
background-color: var(--ifm-color-primary);
color: #fff;
text-decoration: none;
}
}

@media (max-width: 768px) {
.software {
font-size: 40px;
margin-bottom: 10px;
}

.tagline {
font-size: 24px;
line-height: 1.3;
}

.description {
font-size: 16px;
}
}
69 changes: 69 additions & 0 deletions src/components/SoftwareStats/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import { useColorMode } from '@docusaurus/theme-common';
import styles from './styles.module.scss';

interface SoftwareStatsProps {
githubStars: string;
githubCommits: string;
bstatsServers?: string;
bstatsPlayers?: string;
}

const SoftwareStats: React.FC<SoftwareStatsProps> = ({ githubStars, githubCommits, bstatsServers, bstatsPlayers }) => {
return (
<div className={styles.statsSection}>
<div className="container">
<div className={styles.flex}>
<Stat
label="GitHub Stars"
value={githubStars}
whiteIcon="/img/icons/github-white.svg"
darkIcon="/img/icons/github-dark.svg"
/>

<Stat
label="Commits"
value={githubCommits}
whiteIcon="/img/icons/commit-white.svg"
darkIcon="/img/icons/commit-dark.svg"
/>

{bstatsServers && (
<Stat
label="Total Servers"
value={bstatsServers}
whiteIcon="/img/icons/server-white.svg"
darkIcon="/img/icons/server-dark.svg"
/>
)}

{bstatsPlayers && (
<Stat
label="Total Players"
value={bstatsPlayers}
whiteIcon="/img/icons/user-white.svg"
darkIcon="/img/icons/user-dark.svg"
/>
)}
</div>
</div>
</div>
);
};

const Stat = ({ label, whiteIcon, darkIcon, value }) => {
const { colorMode } = useColorMode();
const icon = colorMode === 'dark' ? whiteIcon : darkIcon;

return (
<div className={styles.stat}>
<img src={icon} className={styles.statImage} />
<div className={styles.statContent}>
<div className={styles.statLabel}>{label}</div>
<div className={styles.statValue}>{value}</div>
</div>
</div>
)
}

export default SoftwareStats;
68 changes: 68 additions & 0 deletions src/components/SoftwareStats/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.statsSection {
padding: 20px 0;
}

.flex {
display: flex;
column-gap: 50px;
row-gap: 20px;
flex-wrap: wrap;
}

.stat {
display: flex;
column-gap: 15px;
row-gap: 10px;
width: 180px;
flex-wrap: wrap;
}

.statImage {
height: 40px;
width: 40px;
margin-top: auto;
margin-bottom: auto;
}

.statContent {
margin-top: auto;
margin-bottom: auto;
}

.statLabel {
font-weight: bold;
font-size: 18px;
}

.statValue {
font-size: 30px;
line-height: 1;
}

@media (max-width: 600px) {
.stat {
flex-direction: column;
width: auto;
}
}

@media (max-width: 768px) {
.flex {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}

.statImage {
height: 30px;
width: 30px;
}

.statLabel {
font-size: 16px;
}

.statValue {
font-size: 20px;
}
}
Loading
Loading