mirror of
https://github.com/aaif-goose/goose.git
synced 2026-07-03 14:10:03 +02:00
docs: recipe video carousel (#4660)
This commit is contained in:
@@ -57,5 +57,10 @@ import styles from '@site/src/components/Card/styles.module.css';
|
||||
description="Automatically render visual representations of data as you interact with it, powered by MCP-UI"
|
||||
link="/blog/2025/08/27/autovisualiser-with-mcp-ui"
|
||||
/>
|
||||
<Card
|
||||
title="How to Make An MCP Server MCP-UI Compatible"
|
||||
description="Making an MCP server MCP-UI compatible requires just a few lines of code"
|
||||
link="/blog/2025/09/08/turn-any-mcp-server-mcp-ui-compatible"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
+26
-1
@@ -6,6 +6,7 @@ description: Reusable and shareable AI workflows
|
||||
|
||||
import Card from '@site/src/components/Card';
|
||||
import styles from '@site/src/components/Card/styles.module.css';
|
||||
import VideoCarousel from '@site/src/components/VideoCarousel';
|
||||
|
||||
<h1 className={styles.pageTitle}>Recipes</h1>
|
||||
<p className={styles.pageDescription}>
|
||||
@@ -22,7 +23,7 @@ import styles from '@site/src/components/Card/styles.module.css';
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.categorySection}>
|
||||
<h2 className={styles.categoryTitle}>📚 Documentation & Guides</h2>
|
||||
@@ -91,3 +92,27 @@ import styles from '@site/src/components/Card/styles.module.css';
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.categorySection}>
|
||||
<h2 className={styles.categoryTitle}>🎥 More Videos</h2>
|
||||
|
||||
<VideoCarousel
|
||||
id="more-videos"
|
||||
videos={[
|
||||
{
|
||||
type: 'iframe',
|
||||
src: 'https://youtube.com/embed/1szmJSKInnU',
|
||||
title: 'Advanced Tips for Recipes/Sub-Recipes in Goose',
|
||||
description: 'Advanced tips for using recipes and sub-recipes in goose',
|
||||
duration: '10:07'
|
||||
},
|
||||
{
|
||||
type: 'iframe',
|
||||
src: 'https://youtube.com/embed/gvg7DomaJuA',
|
||||
title: 'Headless Goose, Scheduling a Parallel-Subagent Recipe',
|
||||
description: 'Schedule a recipe to run two subagents in parallel',
|
||||
duration: '5:50'
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -0,0 +1,99 @@
|
||||
// src/components/VideoCarousel.js
|
||||
import React from 'react';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Navigation, Pagination, FreeMode } from 'swiper/modules';
|
||||
import 'swiper/css';
|
||||
import 'swiper/css/navigation';
|
||||
import 'swiper/css/pagination';
|
||||
import 'swiper/css/free-mode';
|
||||
|
||||
const VideoCarousel = ({ videos, id, width = '100%', names = [] }) => {
|
||||
const [activeIndex, setActiveIndex] = React.useState(0);
|
||||
|
||||
const getCurrentVideoName = () => {
|
||||
if (Array.isArray(names) && names.length > activeIndex && names[activeIndex]) {
|
||||
return names[activeIndex];
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="carousel-container">
|
||||
{getCurrentVideoName() && (
|
||||
<h3 className="carousel-header">{getCurrentVideoName()}</h3>
|
||||
)}
|
||||
<Swiper
|
||||
spaceBetween={16}
|
||||
slidesPerView={1.2}
|
||||
freeMode={true}
|
||||
navigation
|
||||
pagination={{ clickable: true }}
|
||||
modules={[Navigation, Pagination, FreeMode]}
|
||||
className={`swiper-container-${id}`}
|
||||
style={{ width: width }}
|
||||
onSlideChange={(swiper) => setActiveIndex(swiper.activeIndex)}
|
||||
>
|
||||
{videos.map((video, index) => (
|
||||
<SwiperSlide key={index}>
|
||||
<div>
|
||||
<div
|
||||
className="video-responsive video-container"
|
||||
style={{
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
paddingBottom: "56.25%", // 16:9 aspect ratio
|
||||
height: 0,
|
||||
overflow: "hidden"
|
||||
}}
|
||||
>
|
||||
{video.type === 'iframe' ? (
|
||||
<iframe
|
||||
src={video.src}
|
||||
title={video.title || `Video ${index + 1}`}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
border: 0
|
||||
}}
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
) : (
|
||||
<video
|
||||
controls
|
||||
src={video.src}
|
||||
title={video.title || `Video ${index + 1}`}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
border: 0
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{(video.description || video.duration) && (
|
||||
<div style={{ marginTop: -32, marginBottom: 48, marginLeft: 8, fontSize: '1em', color: '#444' }}>
|
||||
{video.description && <span>{video.description}</span>}
|
||||
{video.duration && (
|
||||
<span style={{ marginLeft: 8, color: '#888', fontSize: '0.95em' }}>
|
||||
<span style={{ marginRight: 8 }}>•</span>
|
||||
{video.duration}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoCarousel;
|
||||
Reference in New Issue
Block a user