Skip to content

Commit 8cf0c3b

Browse files
tristantrhcourdent
andauthored
feat: add money pages (#1275)
* Improve workflow animation * Improve animation * Improve animation for workflows * Improve wording of Workflow hero section * Refactor tab system * Improvements * Add github component * Convert png to webp and remove unused png * Add FAQ for workflow solutions page * Init scrips as endpoints money page * Add animation to script & endpoints section * Create temporary animation * Improve global animation * Improve global animation * Improve global animation * Improve animation * Improve animation * Improve animation * Improve animation * Improve animation * Improve animation * Improve animation * Improve animation * Improve animation * Improve animation * Improve animation * Add animation to landing page * Improve landing structure * Improve landing structure * Nits * Improve AEO * Improve wordings * Add backlinks * Convert png to webp * Remove temporary page * Nits * Put back missing container * Restore current landing page * Update Schedules page to Triggers page * Improve Trigger solutions page * Improve FAQ section * Fix landing missing element * Rename workflow automations by workflows * AEO optimization * Improve dropdown order * Improve backlinks * Improve backlinks --------- Co-authored-by: Henri Courdent <122811744+hcourdent@users.noreply.github.com>
1 parent bb7b6b2 commit 8cf0c3b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+3197
-923
lines changed

src/components/case-studies/CaseStudyBackLink.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ const USE_CASE_LABELS = {
77
'internal-tools': 'Internal tools',
88
'data-pipelines': 'Data pipelines',
99
'ai-agents': 'AI agents',
10-
'scheduled-tasks': 'Scheduled tasks',
11-
'workflow-automation': 'Workflow automation',
10+
'triggers': 'Triggers',
11+
'workflows': 'Workflows',
1212
};
1313

1414
export default function CaseStudyBackLink() {
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React, { useState } from 'react';
2+
import Link from '@docusaurus/Link';
3+
import { motion } from 'framer-motion';
4+
import { BookOpen } from 'lucide-react';
5+
6+
const fadeIn = {
7+
initial: { opacity: 0, y: 30 },
8+
whileInView: { opacity: 1, y: 0 },
9+
viewport: { once: true },
10+
transition: { duration: 0.5 },
11+
};
12+
13+
export default function TabFeatureSection({ title, subtitle, features }) {
14+
const [active, setActive] = useState(0);
15+
return (
16+
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-16">
17+
<motion.div {...fadeIn} className="mb-16">
18+
<h2 className="text-3xl sm:text-4xl font-bold text-gray-900 dark:text-white mb-4">
19+
{title}
20+
</h2>
21+
{subtitle && (
22+
<p className="text-lg text-gray-600 dark:text-gray-300">{subtitle}</p>
23+
)}
24+
</motion.div>
25+
26+
<div className="grid grid-cols-1 md:grid-cols-[280px_1fr] gap-6">
27+
{/* Left: clickable list */}
28+
<div className="flex flex-col gap-2">
29+
{features.map((feat, i) => (
30+
<button
31+
key={feat.label || feat.title}
32+
onClick={() => setActive(i)}
33+
className={`flex items-center gap-3 px-4 py-4 rounded-xl text-left transition-colors border ${
34+
i === active
35+
? 'bg-blue-600 text-white border-blue-600'
36+
: 'bg-white dark:bg-gray-950 text-gray-700 dark:text-gray-300 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600'
37+
}`}
38+
>
39+
<feat.icon
40+
className={`w-5 h-5 flex-shrink-0 ${
41+
i === active ? 'text-white' : 'text-blue-500'
42+
}`}
43+
/>
44+
<span className="font-medium text-sm">
45+
{feat.label || feat.title}
46+
</span>
47+
</button>
48+
))}
49+
</div>
50+
51+
{/* Right: content panel — all panels stay mounted, only opacity changes */}
52+
<div className="p-8 rounded-2xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-950 relative overflow-hidden">
53+
{features.map((feat, i) => (
54+
<div
55+
key={feat.label || feat.title}
56+
className={`transition-opacity duration-200 ${
57+
i === active
58+
? 'opacity-100 relative'
59+
: 'opacity-0 absolute inset-0 pointer-events-none p-8'
60+
}`}
61+
>
62+
<div className="flex items-center gap-3 mb-4">
63+
<div className="w-10 h-10 rounded-lg bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center">
64+
<feat.icon className="w-5 h-5 text-blue-600 dark:text-blue-400" />
65+
</div>
66+
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white">
67+
{feat.title}
68+
</h3>
69+
</div>
70+
<p className="text-gray-600 dark:text-gray-300 text-lg mb-4">
71+
{feat.desc}
72+
</p>
73+
{feat.embed ? (
74+
<div className="rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden mt-2 p-4 bg-white">
75+
<iframe
76+
src={feat.embed}
77+
title={feat.title}
78+
className="w-full border-0 bg-white rounded"
79+
style={{ height: '480px' }}
80+
loading="lazy"
81+
/>
82+
</div>
83+
) : feat.image ? (
84+
<img
85+
src={feat.image}
86+
alt={feat.title}
87+
className="rounded-lg border border-gray-200 dark:border-gray-700 w-full"
88+
/>
89+
) : (
90+
<div className="w-full h-48 rounded-lg bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 flex items-center justify-center">
91+
<span className="text-gray-400 dark:text-gray-500 text-sm">
92+
Screenshot coming soon
93+
</span>
94+
</div>
95+
)}
96+
{feat.docLink && (
97+
<div className="flex justify-end mt-3">
98+
<Link
99+
to={feat.docLink}
100+
className="inline-flex items-center gap-1.5 text-blue-600 dark:text-blue-400 text-sm font-medium hover:underline !no-underline"
101+
>
102+
<BookOpen className="w-4 h-4" /> Read the docs
103+
</Link>
104+
</div>
105+
)}
106+
</div>
107+
))}
108+
</div>
109+
</div>
110+
</div>
111+
);
112+
}

src/components/use-cases/UseCaseCarousel.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ const fadeIn = {
1111
};
1212

1313
const allUseCases = [
14-
{ label: 'Internal tools', subtitle: 'Build production-grade internal tools with backend scripts, data tables and React, Vue or Svelte frontends.', to: '/use-cases/internal-tools', cover: '/img/money-pages/frontend.png' },
15-
{ label: 'Data pipelines', subtitle: 'Orchestrate ETL jobs with parallel branches, DuckDB queries and connections to any database or S3 bucket.', to: '/use-cases/data-pipelines', cover: '/img/money-pages/data-pipelines-card.png' },
14+
{ label: 'Internal tools', subtitle: 'Build production-grade internal tools with backend scripts, data tables and React, Vue or Svelte frontends.', to: '/use-cases/internal-tools', cover: '/img/money-pages/frontend.webp' },
15+
{ label: 'Data pipelines', subtitle: 'Orchestrate ETL jobs with parallel branches, DuckDB queries and connections to any database or S3 bucket.', to: '/use-cases/data-pipelines', cover: '/img/money-pages/data-pipelines-card.webp' },
1616
{ label: 'AI agents', subtitle: 'Build AI agents with tool-calling, DAG orchestration, sandboxes and direct access to your scripts and resources.', to: '/use-cases/ai-agents', cover: '/img/money-pages/ai-agent-card.webp' },
17-
// { label: 'Workflow automation', subtitle: 'Chain scripts into flows with approval steps, parallel branches, loops and conditional logic.', to: '/use-cases/workflow-automation', cover: '/img/money-pages/parallel-branches.webp' },
18-
{ label: 'Scheduled tasks', subtitle: 'Run scripts on cron schedules, webhooks or custom triggers with retries and error handlers built in.', to: '/use-cases/scheduled-tasks', cover: '/img/money-pages/cron-schedules-card.png' },
17+
{ label: 'Workflows', subtitle: 'Chain scripts into flows with approval steps, parallel branches, loops and conditional logic.', to: '/use-cases/workflows', cover: '/img/money-pages/parallel-branches.webp' },
18+
{ label: 'Triggers', subtitle: 'Trigger scripts and flows from schedules, webhooks, Kafka, Postgres, websockets, emails and more.', to: '/use-cases/triggers', cover: '/img/money-pages/cron-schedules-card.webp' },
1919
];
2020

2121
export default function UseCaseCarousel({ current, subtitle }) {

src/components/use-cases/UseCaseLayout.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ interface UseCaseData {
1212
headline: string;
1313
description: string;
1414
link: string;
15+
image?: string;
1516
}
1617

1718
interface UseCaseLayoutProps {
@@ -31,20 +32,11 @@ export default function UseCaseLayout({ Content, frontMatter, useCaseData }: Use
3132
const pageSchema = useCaseData
3233
? {
3334
'@context': 'https://schema.org',
34-
'@type': 'SoftwareApplication',
35+
'@type': 'WebPage',
3536
name: useCaseData.name,
3637
headline: useCaseData.headline,
3738
description: useCaseData.description,
38-
applicationCategory: 'DeveloperApplication',
39-
operatingSystem: 'Web',
40-
offers: [
41-
{
42-
'@type': 'Offer',
43-
name: 'Community Edition',
44-
price: '0',
45-
priceCurrency: 'USD'
46-
}
47-
],
39+
...(useCaseData.image ? { image: useCaseData.image } : {}),
4840
publisher: {
4941
'@type': 'Organization',
5042
name: 'Windmill',
@@ -65,6 +57,7 @@ export default function UseCaseLayout({ Content, frontMatter, useCaseData }: Use
6557
title={`${frontMatter.title} | Windmill`}
6658
description={frontMatter.description}
6759
url={pageUrl}
60+
{...(useCaseData?.image ? { image: useCaseData.image } : {})}
6861
/>
6962
{pageSchema && (
7063
<Head>

src/data/use-cases/index.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import { internalToolsUseCase } from './internal-tools';
2-
import { workflowAutomationUseCase } from './workflow-automation';
2+
import { workflowAutomationUseCase } from './workflows';
33
import { dataPipelinesUseCase } from './data-pipelines';
4-
import { scriptsAndEndpointsUseCase } from './scripts-and-endpoints';
54
import { aiAgentsUseCase } from './ai-agents';
6-
import { scheduledTasksUseCase } from './scheduled-tasks';
5+
import { triggersUseCase } from './triggers';
76

87
export const useCases = [
98
internalToolsUseCase,
109
workflowAutomationUseCase,
1110
dataPipelinesUseCase,
12-
scriptsAndEndpointsUseCase,
1311
aiAgentsUseCase,
14-
scheduledTasksUseCase,
12+
triggersUseCase,
1513
];

src/data/use-cases/scheduled-tasks.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/data/use-cases/scripts-and-endpoints.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/data/use-cases/triggers.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const triggersUseCase = {
2+
slug: 'triggers',
3+
name: 'Triggers',
4+
headline: 'How to trigger scripts and flows with Windmill',
5+
description: 'Schedules, webhooks, Kafka, Postgres, websockets, emails and more — with retries and alerting built in.',
6+
icon: 'ClockIcon',
7+
link: '/use-cases/triggers',
8+
image: 'https://www.windmill.dev/img/money-pages/triggers.webp',
9+
released: true,
10+
};
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
export const workflowAutomationUseCase = {
2-
slug: 'workflow-automation',
3-
name: 'Workflow automation',
2+
slug: 'workflows',
3+
name: 'Workflows',
44
headline: 'How to automate workflows with Windmill',
55
description: 'Orchestrate multi-step processes across services with branching, retries and approval steps.',
66
icon: 'ArrowPathIcon',
7-
link: '/use-cases/workflow-automation',
7+
link: '/use-cases/workflows',
8+
image: 'https://www.windmill.dev/img/money-pages/dag-workflow.webp',
89
released: true,
910
};

0 commit comments

Comments
 (0)