Skip to content
Merged
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
140 changes: 84 additions & 56 deletions crowdsec-docs/src/components/home-page/get-to-know-us.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,70 @@ import ThemedImage from "@theme/ThemedImage";
import React from "react";
import { HomePageItem } from "./home-item";

type StaticData = {
type ItemData = {
icon: React.FC<React.HTMLAttributes<HTMLSpanElement>>;
title: string;
description: string;
link: string;
};

const staticData: StaticData[] = [
// Core Products - Main CrowdSec offerings
const coreProducts: ItemData[] = [
{
icon: () => <img src="/img/crowdsec_logo.png" className="h-6 w-9" alt="CrowdSec logo" />,
title: "What is CrowdSec?",
description: "Data curated solution with a bunch of millions IPs detected by our large community.",
link: "https://www.crowdsec.net",
icon: () => <img src="/img/icons/radar-target.webp" className="h-6 w-6" alt="security engine" />,
title: "Security Engine",
description: "Detect threats with behavior analysis and community intelligence.",
link: "/u/getting_started/intro",
},
{
icon: () => <img src="/img/icons/radar-target.webp" className="h-6 w-6" alt="security engines" />,
title: "Security Engines",
description: "Secure yourself.",
link: "/u/getting_started/intro",
icon: () => <img src="/img/icons/shield.webp" className="h-6 w-6" alt="blocklists" />,
title: "Blocklists",
description: "Subscribe to curated threat intelligence feeds.",
link: "/u/blocklists/intro",
},
{
icon: () => <img src="/img/icons/world.webp" className="h-6 w-6" alt="CTI" />,
title: "CTI",
description: "Query our threat intelligence database programmatically.",
link: "/u/cti_api/intro",
},
];

// Tools & Integration
const toolsAndIntegration: ItemData[] = [
{
icon: () => <span className="text-2xl">🖥️</span>,
title: "CrowdSec Console",
description: "Manage and monitor your security.",
title: "Console",
description: "Manage, monitor, and visualize your security from one dashboard.",
link: "/u/console/intro",
},
{
icon: () => <span className="text-2xl">🧑🏻‍💻</span>,
title: "CrowdSec CLI",
description: "Use our command line interface.",
link: "/docs/next/cscli/",
icon: () => <img src="/img/icons/waf.webp" className="h-6 w-6" alt="web application firewall" />,
title: "AppSec / WAF",
description: "Protect web applications from OWASP Top 10 and custom threats.",
link: "/docs/next/appsec/intro",
},
{
icon: () => <img src="/img/icons/waf.webp" className="h-6 w-6" alt="Web application firewall" />,
title: "CrowdSec WAF",
description: "Protect your web applications.",
link: "/docs/next/appsec/intro",
icon: () => <span className="text-2xl">🧑🏻‍💻</span>,
title: "CLI Reference",
description: "Complete command-line interface documentation.",
link: "/docs/next/cscli/",
},
];

// Resources & Help
const resources: ItemData[] = [
{
icon: () => <img src="/img/icons/shield.webp" className="h-6 w-6" alt="blocklists" />,
title: "Blocklists",
description: "Block thousands of IPs.",
link: "/u/blocklists/intro",
icon: () => <img src="/img/crowdsec_logo.png" className="h-6 w-9" alt="CrowdSec logo" />,
title: "About CrowdSec",
description: "Learn how our community-powered security works.",
link: "https://www.crowdsec.net",
},
{
icon: () => <img src="/img/icons/world.webp" className="h-6 w-6" alt="world API" />,
title: "APIs",
description: "Integrate with your tools.",
link: "/u/cti_api/intro",
icon: () => <span className="text-2xl">🛠️</span>,
title: "Online Sandbox",
description: "Try CrowdSec in an interactive browser environment.",
link: "https://killercoda.com/iiamloz/scenario/crowdsec-setup",
},
{
icon: () => (
Expand All @@ -64,42 +79,55 @@ const staticData: StaticData[] = [
alt="OpenAI logo"
/>
),
title: "Custom GPT",
description: "Get help from our custom documentation GPT.",
title: "AI Assistant",
description: "Get help from our documentation-trained GPT.",
link: "https://chatgpt.com/g/g-682c3a61a78081918417571116c2b563-crowdsec-documentation",
},
];

const GetToKnowUs = (): React.JSX.Element => {
return (
<section>
<h2 className="text-left">Get to know us!</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="md:col-span-2">
<HomePageItem
title={staticData[0].title}
description={staticData[0].description}
link={staticData[0].link}
icon={staticData[0].icon}
/>
</div>
{staticData.slice(1, staticData.length - 1).map((props) => (
<HomePageItem
title={props.title}
description={props.description}
link={props.link}
icon={props.icon}
key={props.title}
/>
<div className="text-left mb-6">
<h2 className="mb-2 text-2xl md:text-3xl font-semibold">Explore CrowdSec</h2>
<p className="max-w-2xl text-base text-foreground/70">
Discover our products, tools, and resources to build a comprehensive security solution.
</p>
</div>

{/* Core Products */}
<div className="text-left mt-8">
<h3 className="mb-1 text-lg font-medium text-primary">Products</h3>
<p className="max-w-xl text-sm text-foreground/60 mb-4">
Our main security components that work together to protect your infrastructure.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
{coreProducts.map((item) => (
<HomePageItem title={item.title} description={item.description} link={item.link} icon={item.icon} key={item.title} />
))}
</div>

{/* Tools & Integration */}
<div className="text-left mt-10">
<h3 className="mb-1 text-lg font-medium text-primary">Tools & Integration</h3>
<p className="max-w-xl text-sm text-foreground/60 mb-4">Extend and integrate CrowdSec with your existing workflows.</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
{toolsAndIntegration.map((item) => (
<HomePageItem title={item.title} description={item.description} link={item.link} icon={item.icon} key={item.title} />
))}
</div>

{/* Resources */}
<div className="text-left mt-10">
<h3 className="mb-1 text-lg font-medium text-primary">Resources</h3>
<p className="max-w-xl text-sm text-foreground/60 mb-4">Learn more and get help with your CrowdSec journey.</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
{resources.map((item) => (
<HomePageItem title={item.title} description={item.description} link={item.link} icon={item.icon} key={item.title} />
))}
<div className="md:col-span-2">
<HomePageItem
title={staticData[staticData.length - 1].title}
description={staticData[staticData.length - 1].description}
link={staticData[staticData.length - 1].link}
icon={staticData[staticData.length - 1].icon}
/>
</div>
</div>
</section>
);
Expand Down
14 changes: 8 additions & 6 deletions crowdsec-docs/src/components/home-page/home-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ type Props = {
};

export const HomePageItem = (props: Props): React.JSX.Element => (
<Link key={props.title} href={props.link} className="border-0 hover:no-underline">
<Link key={props.title} href={props.link} className="border-0 hover:no-underline group">
<div
className={
"w-full flex justify-start items-center border border-solid border-gray-100 dark:border-transparent dark:bg-gray-200 flex-row rounded-lg px-2 py-2 gap-2 flex-1 cursor-pointer shadow-md dark:shadow-none ease-in-out duration-300 hover:scale-101 active:scale-99 hover:dark:bg-gray-300 hover:bg-neutral-200"
"w-full h-full flex justify-start items-center border border-solid border-gray-200 dark:border-gray-300 dark:bg-gray-200 flex-row rounded-lg px-3 py-3 gap-3 cursor-pointer shadow-sm dark:shadow-none transition-all duration-200 hover:shadow-md hover:border-primary/30 dark:hover:border-primary/50 hover:dark:bg-gray-300 hover:bg-gray-50"
}
>
<span className="w-12 h-12 rounded-lg inline-flex items-center justify-center border border-solid border-gray-200 dark:bg-gray-50 bg-white">
<span className="w-11 h-11 rounded-lg inline-flex items-center justify-center border border-solid border-gray-200 dark:border-gray-300 dark:bg-gray-100 bg-white flex-shrink-0">
{(!Array.isArray(props.icon) && <props.icon className="icon icon-xl" />) || <CIcon icon={props.icon} size="xl" />}
</span>

<div className="flex flex-col">
<span className={"text-md font-semibold flex-1 text-left text-foreground"}>{props.title}</span>
{props.description && <p className="text-sm text-left text-foreground/70 mb-0">{props.description}</p>}
<div className="flex flex-col min-w-0">
<span className="text-base font-semibold text-left text-foreground group-hover:text-primary transition-colors duration-200">
{props.title}
</span>
{props.description && <p className="text-sm text-left text-foreground/60 mb-0 line-clamp-2">{props.description}</p>}
</div>
</div>
</Link>
Expand Down
44 changes: 25 additions & 19 deletions crowdsec-docs/src/components/home-page/quick-start.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,42 +92,48 @@ const multiServerSetup: StaticData[] = [
const QuickStart = (): React.JSX.Element => {
return (
<section>
<div className="text-left">
<h2 className="mb-1">Select your environment</h2>
<p className="max-w-xl text-sm text-foreground/70">We can secure your stack. Just select your platform and get started.</p>
<div className="text-left mb-6">
<h2 className="mb-2 text-2xl md:text-3xl font-semibold">Installation</h2>
<p className="max-w-2xl text-base text-foreground/70">
Choose your platform to install the CrowdSec Security Engine. Each guide walks you through setup, configuration, and
connecting to the CrowdSec Console.
</p>
</div>

<div className="text-left">
<h4 className="mb-1">Single Server Setup</h4>
<p className="max-w-xl text-sm text-foreground/70">
Install CrowdSec on a single server. This is the simplest way to get started with CrowdSec.
{/* Single Server */}
<div className="text-left mt-8">
<h3 className="mb-1 text-lg font-medium text-primary">Single Server</h3>
<p className="max-w-xl text-sm text-foreground/60 mb-4">
Standalone installation for protecting a single machine or service.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
{singleServerSetup.map((props) => (
<HomePageItem title={props.text} description="" link={props.link} icon={props.icon} key={props.text} />
))}
</div>
<div className="grid grid-cols-1 gap-4 mt-4">

{/* Healthcheck */}
<div className="mt-4">
<HomePageItem
title="Installation Healthcheck"
description=""
description="Verify your installation is working correctly"
link="/u/getting_started/health_check"
icon={MonitorHeartIcon}
key="Installation Healthcheck"
/>
</div>
<p className="text-xs mt-1 mb-4 text-foreground/70 text-right">
*Logos and trademarks, such as the logos above, are the property of their respective owners and are used here for
identification purposes only.
</p>
<div className="text-left">
<h4 className="mb-1">Multi-Server Setup</h4>
<p className="max-w-xl text-sm text-foreground/70">
Use CrowdSec within a multi-server environment. This is the advanced way to get started.

<p className="text-xs mt-2 text-foreground/50 text-right">*Logos and trademarks are property of their respective owners.</p>

{/* Multi-Server */}
<div className="text-left mt-10">
<h3 className="mb-1 text-lg font-medium text-primary">Multi-Server</h3>
<p className="max-w-xl text-sm text-foreground/60 mb-4">
Distributed deployment for organizations managing multiple servers or infrastructure.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
{multiServerSetup.map((props) => (
<HomePageItem title={props.text} description={props.description} link={props.link} icon={props.icon} key={props.text} />
))}
Expand Down
55 changes: 55 additions & 0 deletions crowdsec-docs/src/components/product-page/feature-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Link from "@docusaurus/Link";
import React from "react";

export type FeatureCardProps = {
title: string;
description: string;
link: string;
icon: string;
};

export const FeatureCard = ({ title, description, link, icon }: FeatureCardProps): React.JSX.Element => (
<Link href={link} className="hover:no-underline group">
<div className="h-full border border-solid border-border rounded-lg p-5 bg-card hover:shadow-md hover:border-primary/30 transition-all duration-200">
<div className="text-3xl mb-3">{icon.startsWith("/") ? <img src={icon} alt={title} className="h-8 w-8" /> : icon}</div>
<h3 className="text-lg font-semibold mb-2 text-gray-900 dark:text-gray-900 group-hover:text-primary transition-colors">
{title}
</h3>
<p className="text-sm text-gray-600 dark:text-gray-700 mb-0">{description}</p>
</div>
</Link>
);

export type IntegrationCardProps = {
title: string;
description: string;
link: string;
icon: React.ReactNode;
};

export const IntegrationCard = ({ title, description, link, icon }: IntegrationCardProps): React.JSX.Element => (
<Link href={link} className="hover:no-underline group">
<div className="h-full border border-solid border-border rounded-lg p-4 bg-card hover:shadow-md hover:border-primary/30 transition-all duration-200 flex items-center gap-4">
<div className="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0">{icon}</div>
<div>
<h3 className="text-base font-semibold text-gray-900 dark:text-gray-900 group-hover:text-primary transition-colors mb-1">
{title}
</h3>
<p className="text-sm text-gray-600 dark:text-gray-700 mb-0">{description}</p>
</div>
</div>
</Link>
);

export type IntegrationItemProps = {
title: string;
link: string;
};

export const IntegrationItem = ({ title, link }: IntegrationItemProps): React.JSX.Element => (
<Link href={link} className="hover:no-underline group">
<div className="border border-solid border-border rounded-lg px-4 py-3 bg-card hover:shadow-md hover:border-primary/30 transition-all duration-200">
<span className="text-sm font-medium text-gray-900 dark:text-gray-900 group-hover:text-primary transition-colors">{title}</span>
</div>
</Link>
);
4 changes: 4 additions & 0 deletions crowdsec-docs/src/components/product-page/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type { FeatureCardProps, IntegrationCardProps, IntegrationItemProps } from "./feature-card";
export { FeatureCard, IntegrationCard, IntegrationItem } from "./feature-card";
export { ProductPageLayout } from "./product-page-layout";
export { Section } from "./section";
Loading