-
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathindex.tsx
More file actions
111 lines (100 loc) · 3.24 KB
/
index.tsx
File metadata and controls
111 lines (100 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import React, { useEffect, useRef, useState } from 'react';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import styles from './styles.module.css';
interface Integration {
name: string;
logo: string;
description: string;
}
const integrations: Integration[] = [
{
name: 'GitHub',
logo: '/img/github logo.webp',
description: 'Issues, PRs & repository files',
},
{
name: 'Linear',
logo: '/img/linear.jpeg',
description: 'Project & issue tracking',
},
{
name: 'Notion',
logo: '/img/notion logo.png',
description: 'Pages & databases',
},
];
function IntegrationCard({ integration, index }: { integration: Integration; index: number }): React.ReactElement {
const logoSrc = useBaseUrl(integration.logo);
return (
<div
className={`${styles.card} ${styles.animateIn}`}
style={{ transitionDelay: `${0.2 + index * 0.1}s` }}
>
<img
src={logoSrc}
alt={integration.name}
className={styles.cardLogo}
/>
<div className={styles.cardInfo}>
<h3 className={styles.cardName}>{integration.name}</h3>
<p className={styles.cardDescription}>{integration.description}</p>
</div>
</div>
);
}
export default function IntegrationShowcase(): React.ReactElement {
const [isVisible, setIsVisible] = useState(false);
const sectionRef = useRef<HTMLElement>(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
}
},
{ threshold: 0.2 }
);
if (sectionRef.current) {
observer.observe(sectionRef.current);
}
return () => observer.disconnect();
}, []);
return (
<section ref={sectionRef} className={styles.showcase}>
<div className={styles.container}>
<div className={styles.content}>
<div className={`${styles.textSide} ${isVisible ? styles.visible : ''}`}>
<p className={`${styles.sectionLabel} ${styles.animateIn}`}>
Integrations
</p>
<h2 className={`${styles.title} ${styles.animateIn}`}>Works With Your Stack</h2>
<p className={`${styles.subtitle} ${styles.animateIn} ${styles.delay1}`}>
Pull specs from where your work lives. Connect your favorite tools and let Ralph build from them.
</p>
<div className={styles.grid}>
{integrations.map((integration, index) => (
<IntegrationCard key={integration.name} integration={integration} index={index} />
))}
</div>
<div className={`${styles.cta} ${styles.animateIn} ${styles.delay3}`}>
<Link
to="https://github.com/rubenmarcus/ralph-starter"
className={styles.ctaLink}
>
Contribute on GitHub →
</Link>
</div>
</div>
<div className={`${styles.imageSide} ${isVisible ? styles.visible : ''}`}>
<img
src={useBaseUrl('/img/stack.png')}
alt="Ralph with integrations"
className={styles.ralphImage}
/>
</div>
</div>
</div>
</section>
);
}