Skip to content

Commit ce24466

Browse files
Merge pull request #21 from educates/develop
Image carrousel, featured content and downloads and some extras
2 parents 3b99f1a + 2465d15 commit ce24466

26 files changed

+751
-479
lines changed

docusaurus.config.ts

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,28 @@ const config: Config = {
2424

2525
customFields: {
2626
educatesProject: {
27-
projectGitHubUrl: "https://github.com/educates/educates-training-platform",
28-
contributingUrl: "https://github.com/educates/educates-training-platform/blob/develop/CONTRIBUTING.md",
27+
projectGitHubUrl:
28+
"https://github.com/educates/educates-training-platform",
29+
projectSlackUrl: "https://kubernetes.slack.com/archives/C05UWT4SKRV",
30+
contributingUrl:
31+
"https://github.com/educates/educates-training-platform/blob/develop/CONTRIBUTING.md",
2932
sponsorshipUrl: "https://github.com/sponsors/educates",
33+
downloadsUrl:
34+
"https://github.com/educates/educates-training-platform/releases",
3035
descriptionTitle: "Interactive Training Platform",
31-
description: "The Educates project provides a system for hosting interactive workshop environments in Kubernetes,"
32-
+ "or on top of a local container runtime. It can be used for self paced or supervised workshops."
33-
+ "It can also be useful where you need to package up demos of applications hosted in Kubernetes "
34-
+ "or a local container runtime.",
36+
description:
37+
"The Educates project provides a system for hosting interactive workshop environments in Kubernetes, " +
38+
"or on top of a local container runtime. It can be used for self paced or supervised workshops. " +
39+
"It can also be useful where you need to package up demos of applications hosted in Kubernetes " +
40+
"or a local container runtime.",
3541
screenshot: "/img/screenshot.png",
3642
youtubeUrl: "https://www.youtube.com/@EducatesTrainingPlatform",
37-
}
43+
},
3844
},
3945

4046
onBrokenLinks: "throw",
4147
onBrokenMarkdownLinks: "warn",
48+
onBrokenAnchors: "warn",
4249

4350
markdown: {
4451
mermaid: true,
@@ -119,7 +126,7 @@ const config: Config = {
119126
// Replace with your project's social card
120127
image: "img/logo.svg",
121128
colorMode: {
122-
defaultMode: 'light',
129+
defaultMode: "light",
123130
disableSwitch: true,
124131
respectPrefersColorScheme: false,
125132
},
@@ -138,15 +145,38 @@ const config: Config = {
138145
src: "img/logo.svg",
139146
},
140147
items: [
141-
{ to: '/#use-cases', label: 'Use Cases', position: 'left' },
142-
{ to: '/#features', label: 'Features', position: 'left' },
143-
{ to: '/#team', label: 'Team', position: 'left' },
144-
// { to: '/#references', label: 'References', position: 'left' },
145-
{ to: '/#pricing', label: 'Pricing', position: 'left' },
146-
{ to: '/getting-started-guides', label: 'Getting Started', position: 'left' },
147-
{ to: '/blog', label: 'Blog', position: 'left' },
148-
{ href: 'https://docs.educates.dev', label: 'Docs', position: 'left' },
149-
{ href: 'https://github.com/educates/educates-training-platform', label: 'GitHub', position: 'right' },
148+
{
149+
type: "dropdown",
150+
label: "Project",
151+
position: "left",
152+
items: [
153+
{ to: "/#use-cases", label: "Use Cases" },
154+
{ to: "/#features", label: "Features" },
155+
{ to: "/#team", label: "Team" },
156+
// { to: '/#references', label: 'References', position: 'left' },
157+
{ to: "/#pricing", label: "Pricing" },
158+
{ to: "/#featured-content", label: "Featured Content" },
159+
],
160+
},
161+
{ to: "/downloads", label: "Downloads", position: "left" },
162+
{
163+
type: "dropdown",
164+
label: "Guides",
165+
position: "left",
166+
items: [
167+
{ to: "/getting-started-guides", label: "Getting Started" },
168+
{ to: "/getting-started-guides/setup", label: "Setup" },
169+
{ to: "/getting-started-guides/about", label: "About" },
170+
{ to: "/getting-started-guides/authoring", label: "Authoring" },
171+
],
172+
},
173+
{ to: "/blog", label: "Blog", position: "left" },
174+
{ href: "https://docs.educates.dev", label: "Docs", position: "right" },
175+
{
176+
href: "https://github.com/educates/educates-training-platform",
177+
label: "GitHub",
178+
position: "right",
179+
},
150180
// { href: '/login', label: 'Login / Sign Up', position: 'right', className: 'navbar-login-button' },
151181
],
152182
},
@@ -161,11 +191,13 @@ const config: Config = {
161191
{ label: "Team", to: "/#team" },
162192
// { label: "References", to: "/#references" },
163193
{ label: "Pricing", to: "/#pricing" },
194+
{ label: "Downloads", to: "/downloads" },
164195
],
165196
},
166197
{
167198
title: "Docs",
168199
items: [
200+
{ label: "Featured Content", to: "/#featured-content" },
169201
{ label: "Blog", to: "/blog" },
170202
{
171203
label: "Getting Started Guides",

package-lock.json

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@emotion/react": "^11.14.0",
2424
"@emotion/styled": "^11.14.0",
2525
"@mdx-js/react": "^3.1.0",
26+
"@mui/icons-material": "^7.1.0",
2627
"@mui/material": "^7.1.0",
2728
"asciinema-player": "^3.9.0",
2829
"clsx": "^2.1.1",
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import React, { useEffect, useState, useRef } from 'react';
2+
import Box from '@mui/material/Box';
3+
import IconButton from '@mui/material/IconButton';
4+
import ArrowBackIos from '@mui/icons-material/ArrowBackIos';
5+
import ArrowForwardIos from '@mui/icons-material/ArrowForwardIos';
6+
import Typography from '@mui/material/Typography';
7+
8+
export interface CarrouselItem {
9+
image: string;
10+
title: string;
11+
description: string;
12+
}
13+
14+
interface CarrouselProps {
15+
images: CarrouselItem[];
16+
altPrefix?: string;
17+
imageClassName?: string;
18+
boxSx?: object;
19+
}
20+
21+
const Carrousel: React.FC<CarrouselProps> = ({ images, altPrefix = 'Carousel image', imageClassName, boxSx }) => {
22+
const [currentImage, setCurrentImage] = useState(0);
23+
const [paused, setPaused] = useState(false);
24+
const intervalRef = useRef<NodeJS.Timeout | null>(null);
25+
const interval = 3000;
26+
27+
useEffect(() => {
28+
if (!paused) {
29+
intervalRef.current = setInterval(() => {
30+
setCurrentImage((prev) => (prev + 1) % images.length);
31+
}, interval);
32+
}
33+
return () => {
34+
if (intervalRef.current) clearInterval(intervalRef.current);
35+
};
36+
}, [paused, images.length]);
37+
38+
const goToPrev = () => {
39+
setCurrentImage((prev) => (prev - 1 + images.length) % images.length);
40+
};
41+
const goToNext = () => {
42+
setCurrentImage((prev) => (prev + 1) % images.length);
43+
};
44+
const goToIndex = (idx: number) => setCurrentImage(idx);
45+
46+
const { image, title, description } = images[currentImage];
47+
48+
return (
49+
<Box
50+
sx={{ width: '80%', position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', ...boxSx }}
51+
onMouseEnter={() => setPaused(true)}
52+
onMouseLeave={() => setPaused(false)}
53+
>
54+
{/* Left Arrow */}
55+
<IconButton
56+
aria-label="Previous image"
57+
onClick={goToPrev}
58+
sx={{ position: 'absolute', left: 0, top: '50%', transform: 'translateY(-50%)', zIndex: 2, bgcolor: 'rgba(255,255,255,0.7)' }}
59+
>
60+
<ArrowBackIos />
61+
</IconButton>
62+
{/* Image */}
63+
<img
64+
src={image}
65+
alt={`${altPrefix} ${currentImage + 1}`}
66+
className={imageClassName}
67+
style={{ width: '100%' }}
68+
/>
69+
{/* Right Arrow */}
70+
<IconButton
71+
aria-label="Next image"
72+
onClick={goToNext}
73+
sx={{ position: 'absolute', right: 0, top: '50%', transform: 'translateY(-50%)', zIndex: 2, bgcolor: 'rgba(255,255,255,0.7)' }}
74+
>
75+
<ArrowForwardIos />
76+
</IconButton>
77+
{/* Dots - below the image */}
78+
<Box sx={{ mt: 2, display: 'flex', justifyContent: 'center', gap: 1, position: 'static' }}>
79+
{images.map((_, idx) => (
80+
<Box
81+
key={idx}
82+
onClick={() => goToIndex(idx)}
83+
sx={{
84+
width: 12,
85+
height: 12,
86+
borderRadius: '50%',
87+
background: idx === currentImage ? '#1976d2' : '#ccc',
88+
cursor: 'pointer',
89+
border: idx === currentImage ? '2px solid #1976d2' : '2px solid #ccc',
90+
transition: 'background 0.2s, border 0.2s',
91+
}}
92+
/>
93+
))}
94+
</Box>
95+
{/* Title and Description below indicators */}
96+
<Box sx={{ mt: 2, textAlign: 'center', width: '100%' }}>
97+
<Typography variant="h6" component="h3" sx={{ mb: 1 }}>
98+
{title}
99+
</Typography>
100+
<Typography
101+
color="text.secondary"
102+
sx={{
103+
maxWidth: 800,
104+
mx: 'auto',
105+
height: '6rem', // Fixed height for 3 lines (1.5rem per line)
106+
minHeight: '6rem',
107+
lineHeight: '1.5rem',
108+
overflow: 'hidden',
109+
textOverflow: 'ellipsis',
110+
display: '-webkit-box',
111+
WebkitLineClamp: 4, // Limit to 3 lines
112+
WebkitBoxOrient: 'vertical',
113+
}}
114+
>
115+
{description}
116+
</Typography>
117+
</Box>
118+
</Box>
119+
);
120+
};
121+
122+
export default Carrousel;

src/components/ImageAndText/index.tsx

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

src/components/Pricing/Pricing.tsx

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

0 commit comments

Comments
 (0)