feat(Nextjs): New Pitch Deck layout added

This commit is contained in:
shiva raj badu 2025-07-23 15:59:16 +05:45
parent 33299da3ac
commit b1bef2c2f0
No known key found for this signature in database
23 changed files with 3014 additions and 10 deletions

View file

@ -15,7 +15,7 @@ import {
} from "@/components/ui/popover";
import { PresentationGenerationApi } from "../../services/api/presentation-generation";
import { OverlayLoader } from "@/components/ui/overlay-loader";
import { useDispatch, useSelector } from "react-redux";
import { useSelector } from "react-redux";
import Link from "next/link";
@ -24,7 +24,6 @@ import { toast } from "sonner";
import Announcement from "@/components/Announcement";
import { getStaticFileUrl } from "../../utils/others";
import { PptxPresentationModel } from "@/types/pptx_models";
import HeaderNav from "../../components/HeaderNab";
@ -64,7 +63,8 @@ const Header = ({
}
const pptx_path = await PresentationGenerationApi.exportAsPPTX(pptx_model);
if (pptx_path) {
window.open(pptx_path, '_self');
// window.open(pptx_path, '_self');
downloadLink(pptx_path);
} else {
throw new Error("No path returned from export");
}
@ -97,7 +97,8 @@ const Header = ({
if (response.ok) {
const { path: pdfPath } = await response.json();
window.open(pdfPath, '_blank');
// window.open(pdfPath, '_blank');
downloadLink(pdfPath);
} else {
throw new Error("Failed to export PDF");
}
@ -112,6 +113,18 @@ const Header = ({
setShowLoader(false);
}
};
const downloadLink = (path: string) => {
// if we have popup access give direct download if not redirect to the path
if (window.opener) {
window.open(path, '_blank');
} else {
const link = document.createElement('a');
link.href = path;
link.download = path.split('/').pop() || 'download';
document.body.appendChild(link);
link.click();
}
};
const ExportOptions = ({ mobile }: { mobile: boolean }) => (
<div className={`space-y-2 max-md:mt-4 ${mobile ? "" : "bg-white"} rounded-lg`}>

View file

@ -40,6 +40,7 @@ export async function GET() {
const settingsContent = await fs.readFile(settingsPath, 'utf-8')
settings = JSON.parse(settingsContent) as GroupSetting
} catch (settingsError) {
console.warn(`No settings.json found for group ${groupName} or invalid JSON`)
// Provide default settings if setting.json is missing or invalid
settings = {
@ -47,8 +48,7 @@ export async function GET() {
ordered: false,
isDefault: false
}
// write the settings to the file
fs.writeFile(settingsPath, JSON.stringify(settings, null, 2))
}
if (layoutFiles.length > 0) {

View file

@ -39,9 +39,7 @@ export const PresentationCard = ({
e.preventDefault();
e.stopPropagation();
toast.loading("Deleting presentation", {
description: "Please wait while we delete the presentation",
});
const response = await DashboardApi.deletePresentation(id);
if (response) {

View file

@ -36,6 +36,9 @@ export const OverlayLoader = ({
return (
<div
style={{
zIndex: 1000
}}
className={cn(
"fixed inset-0 bg-black/70 z-50 flex items-center justify-center transition-opacity duration-300",
isVisible ? "opacity-100" : "opacity-0"

View file

@ -0,0 +1,95 @@
import * as z from 'zod';
import { ImageSchema, IconSchema } from '@/presentation-layouts/defaultSchemes';
export const Schema = z.object({
title: z.string()
.min(5)
.max(50)
.default("Quarterly Business Review")
.meta({
description: "Main slide title",
}),
subtitle: z.string()
.min(3)
.max(100)
.optional()
.default("Q1 2024 Performance Summary")
.meta({
description: "Optional subtitle",
}),
metrics: z.array(z.object({
label: z.string().min(2).max(20),
value: z.string().min(1).max(10),
trend: z.enum(['up', 'down', 'stable'])
})).default([
{ label: "Revenue", value: "$2.4M", trend: "up" },
{ label: "Growth", value: "15%", trend: "up" }
]).meta({
description: "Key performance metrics",
}),
chartImage: ImageSchema.default({
__image_url__: "https://example.com/quarterly-chart.png",
__image_prompt__: "Quarterly performance chart showing upward trend"
}).meta({
description: "Main performance chart",
}),
trendIcon: IconSchema.default({
__icon_url__: "https://example.com/trend-up.svg",
__icon_query__: "upward trend arrow icon"
}).meta({
description: "Trend indicator icon",
}),
});
type SchemaType = z.infer<typeof Schema>;
export default function ExampleComponent({ data }: { data: SchemaType }) {
const { title, subtitle, metrics, chartImage, trendIcon } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white">
<header className="slide-header">
{title && <h1 className="text-4xl font-bold text-gray-900">{title}</h1>}
{subtitle && <p className="text-xl text-gray-600 mt-2">{subtitle}</p>}
</header>
<main className="slide-content flex-1 flex">
{chartImage?.__image_url__ && (
<div className="chart-section flex-1">
<img
src={chartImage.__image_url__}
alt={chartImage.__image_prompt__}
className="w-full h-auto max-h-96 object-contain"
/>
</div>
)}
{metrics && metrics.length > 0 && (
<div className="metrics-section w-1/3 ml-6">
<h2 className="text-2xl font-semibold mb-4">Key Metrics</h2>
{metrics.map((metric, index) => (
<div key={index} className="metric-item mb-4 p-3 bg-gray-50 rounded">
<div className="flex items-center justify-between">
<span className="font-medium">{metric.label}</span>
{trendIcon?.__icon_url__ && (
<img
src={trendIcon.__icon_url__}
alt={metric.trend}
className="w-6 h-6"
/>
)}
</div>
<span className="text-2xl font-bold text-blue-600">
{metric.value}
</span>
</div>
))}
</div>
)}
</main>
</div>
);
}

View file

@ -0,0 +1,36 @@
import * as z from "zod";
// Note:
// If you want to use Image and Icon Must Use these Schemas.
// Image and icons are only media support for PDF and PPTX.
import { ImageSchema, IconSchema } from "./defaultSchemes";
// Schema definition
export const Schema = z.object({
// Note:
// Schema fields
// Each fields must have a default value (this is important for Layout-preview)
// Each fields must have a meta description
// Each fields must have a min and max length, length must support the layout design.
// Each Array fields must have a min and max length
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const SlideStructure = ({ data }: { data: Partial<SchemaType> }) => {
// Note:
// Data is already parse so not need to parse again.
// Must have consistent aspect ratio (16:9) and max-width 1280px.
// Validate each data before rendering using && operator or optional chaining
// These layout are exported as PDF and PPTX so must be optimized for both.
// Component design, layout, styles, etc.
// Content must be properly fit in the container, if need adjust the lenght of the content and items in Schema.
// See ExampleComponent.tsx for more details.
// Font Size must fit the desing and and the content must be properly fit in the container.
};
export default SlideStructure;

View file

@ -91,7 +91,6 @@ const chartWithBulletsSlideSchema = z.object({
export const Schema = chartWithBulletsSlideSchema
console.log(z.toJSONSchema(chartWithBulletsSlideSchema))
export type ChartWithBulletsSlideData = z.infer<typeof chartWithBulletsSlideSchema>

View file

@ -0,0 +1,154 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("ABOUT US")
.meta({
description: "Main title for the about us section",
}),
subtitle: z.string()
.min(10)
.max(20)
.default("GET TO KNOW US BETTER")
.meta({
description: "Subtitle describing the section",
}),
companyDescription: z.string()
.min(100)
.max(200)
.default("At our company, we believe in the transformative power of compelling storytelling, data-driven strategies, and cutting-edge creativity. Our mission is simple: to empower businesses with strategic marketing solutions that not only elevate brand visibility but also drive tangible growth and success.")
.meta({
description: "Main company description paragraph",
}),
additionalText: z.string()
.min(50)
.max(200)
.default("What sets us apart is not just our expertise but our commitment to understanding the unique DNA of each client.")
.meta({
description: "Additional descriptive text",
}),
businessImage: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Business person analyzing charts and graphs with pen in hand"
}).meta({
description: "Business analytics image showing data analysis",
}),
showDecoCircle: z.boolean()
.default(true)
.meta({
description: "Show decorative circle element",
}),
showTealAccent: z.boolean()
.default(true)
.meta({
description: "Show teal accent areas",
}),
showBeigSquare: z.boolean()
.default(true)
.meta({
description: "Show beige square decoration",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const AboutUsSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, companyDescription, additionalText, businessImage, showDecoCircle, showTealAccent, showBeigSquare } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex">
{/* Left Side - Content */}
<div className="w-3/5 relative bg-white px-16 py-12 flex flex-col justify-center">
{/* Title Section */}
<div className="mb-0">
{mainTitle && (
<h1 className="text-3xl lg:text-4xl font-black text-teal-700 leading-tight mb-4">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold text-gray-800 tracking-wide mb-6">
{subtitle}
</p>
)}
{/* Decorative gray line */}
<div className="w-1 h-20 bg-gray-400 mb-8"></div>
</div>
{/* Description Text */}
{companyDescription && (
<p className="text-base leading-relaxed text-gray-700 max-w-xl">
{companyDescription}
</p>
)}
{/* Additional Text */}
{additionalText && (
<div>
<p className="text-base leading-relaxed text-gray-700 max-w-xl">
{additionalText}
</p>
</div>
)}
</div>
{/* Right Side - Image and Decorative Elements */}
<div className="w-2/5 relative">
{/* Yellow Square - Top Right */}
{showBeigSquare && (
<div className="absolute bottom-0 right-0 w-24 h-24 bg-yellow-300 z-20"></div>
)}
{/* Decorative Circle - On Yellow Square */}
{showDecoCircle && (
<div className="absolute top-6 right-6 w-6 h-6 border-2 border-teal-600 rounded-full z-30"></div>
)}
{/* Business Image - Left positioned */}
{businessImage?.__image_url__ && (
<div className="absolute right-36 top-1/2 -translate-y-1/2 h-[500px] w-[350px] z-20 shadow-lg">
<img
src={businessImage.__image_url__}
alt={businessImage.__image_prompt__}
className="w-full h-full object-cover"
/>
</div>
)}
{/* Teal Accent Areas */}
{showTealAccent && (
<>
{/* Vertical Teal Strip - Center */}
<div className="absolute top-0 right-0 bottom-16 h-full w-[300px] bg-teal-600 z-10"></div>
</>
)}
</div>
</div>
</div>
);
};
export default AboutUsSlide;

View file

@ -0,0 +1,222 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, ResponsiveContainer } from "recharts";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("BUSINESS MODEL")
.meta({
description: "Main title for the business model section",
}),
subtitle: z.string()
.min(10)
.max(25)
.default("OUR BUSINESS MODEL")
.meta({
description: "Subtitle describing the business model",
}),
description: z.string()
.min(50)
.max(300)
.default("Our business model thrives on delivering value through strategic innovation, client-centric solutions, and a dynamic blend of creativity and analytics.")
.meta({
description: "Description of the business model",
}),
businessImage: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80",
__image_prompt__: "Business professionals analyzing charts and data on tablet and computer"
}).meta({
description: "Business analytics header image",
}),
chartData: z.array(z.object({
name: z.string(),
series1: z.number(),
series2: z.number(),
series3: z.number()
})).min(3).max(6).default([
{ name: "Item 1", series1: 5, series2: 4, series3: 3 },
{ name: "Item 2", series1: 8, series2: 7, series3: 4 },
{ name: "Item 3", series1: 15, series2: 10, series3: 5 },
{ name: "Item 4", series1: 18, series2: 15, series3: 8 },
{ name: "Item 5", series1: 22, series2: 20, series3: 8 }
]).meta({
description: "Chart data for business metrics",
}),
showYellowAccent: z.boolean()
.default(true)
.meta({
description: "Show yellow accent decoration",
}),
showTealAccents: z.boolean()
.default(true)
.meta({
description: "Show teal accent decorations",
}),
})
// Chart configuration
const chartConfig = {
series1: {
label: "Series 1",
color: "#1D9A8A",
},
series2: {
label: "Series 2",
color: "#E8F4B8",
},
series3: {
label: "Series 3",
color: "#A8C97F",
},
};
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const BusinessModelSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, description, businessImage, chartData, showYellowAccent, showTealAccents } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Header Image with Teal Decorative Elements */}
<div className="relative h-1/3">
{/* Business Image */}
{businessImage?.__image_url__ && (
<div className="absolute inset-0">
<img
src={businessImage.__image_url__}
alt={businessImage.__image_prompt__}
className="w-full h-full object-cover"
/>
</div>
)}
{/* Teal Decorative Accents */}
{showTealAccents && (
<>
{/* Top left teal block */}
<div className="absolute top-0 left-0 w-20 h-full bg-teal-600 z-10"></div>
{/* Top right teal block */}
<div className="absolute top-0 right-0 w-32 h-full bg-teal-600 z-10"></div>
</>
)}
{/* Yellow Accent */}
{showYellowAccent && (
<div className="absolute top-0 right-32 w-24 h-16 bg-yellow-300 z-15"></div>
)}
</div>
{/* Content Section */}
<div className="h-2/3 flex">
{/* Left Side - Title and Description */}
<div className="w-1/2 px-16 py-8 flex flex-col justify-center bg-gray-50">
{/* Title Section */}
<div className="mb-6">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-tight mb-4">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold text-gray-800 tracking-wide mb-6">
{subtitle}
</p>
)}
</div>
{/* Description */}
{description && (
<div>
<p className="text-base leading-relaxed text-gray-700">
{description}
</p>
</div>
)}
</div>
{/* Right Side - Chart */}
<div className="w-1/2 px-8 py-8 flex flex-col justify-center bg-white">
{/* Chart Legend */}
<div className="flex items-center justify-end mb-4 space-x-4">
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-teal-600 rounded-full"></div>
<span className="text-sm text-gray-600">Series 1</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-yellow-200 rounded-full"></div>
<span className="text-sm text-gray-600">Series 2</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-green-400 rounded-full"></div>
<span className="text-sm text-gray-600">Series 3</span>
</div>
</div>
{/* Chart Container */}
{chartData && chartData.length > 0 && (
<div className="flex-1">
<ChartContainer config={chartConfig} className="h-full w-full">
<ResponsiveContainer width="100%" height="100%">
<BarChart
data={chartData}
margin={{ top: 10, right: 20, left: 0, bottom: 30 }}
barCategoryGap="20%"
>
<CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
<XAxis
dataKey="name"
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#666' }}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#666' }}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<Bar
dataKey="series1"
fill="#1D9A8A"
radius={[2, 2, 0, 0]}
barSize={20}
/>
<Bar
dataKey="series2"
fill="#E8F4B8"
radius={[2, 2, 0, 0]}
barSize={20}
/>
<Bar
dataKey="series3"
fill="#A8C97F"
radius={[2, 2, 0, 0]}
barSize={20}
/>
</BarChart>
</ResponsiveContainer>
</ChartContainer>
</div>
)}
</div>
</div>
</div>
);
};
export default BusinessModelSlide;

View file

@ -0,0 +1,157 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("HELLO FRIENDS!")
.meta({
description: "Main greeting title",
}),
subtitle: z.string()
.min(5)
.max(20)
.default("GREETING FROM US")
.meta({
description: "Subtitle for the greeting",
}),
welcomeText: z.string()
.min(50)
.max(300)
.default("Ladies and gentlemen, a warm welcome to our business pitch deck presentation. Your time and attention are greatly appreciated. Today, we're excited to share our vision, accomplishments, and the exciting roadmap ahead. Let's embark on this journey together, and thank you for considering an investment in our innovative venture.")
.meta({
description: "Main welcome message text",
}),
officeImage: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1497366216548-37526070297c?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Modern office workspace with desk, computer, and large window view"
}).meta({
description: "Office workspace image in circular frame",
}),
buttonText: z.string()
.min(3)
.max(20)
.default("Thank you")
.meta({
description: "Text for the call-to-action button",
}),
showSpeechBubble: z.boolean()
.default(true)
.meta({
description: "Show decorative speech bubble",
}),
showDecoCircle: z.boolean()
.default(true)
.meta({
description: "Show decorative circle element",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const HelloFriendsSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, welcomeText, officeImage, buttonText, showSpeechBubble, showDecoCircle } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex">
{/* Left Side - Teal Background */}
<div className="w-1/3 relative bg-teal-600">
{/* Speech Bubble */}
{showSpeechBubble && (
<div className="absolute top-16 left-16 z-20">
<div className="w-16 h-10 bg-yellow-200 rounded-2xl relative">
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 flex space-x-1">
<div className="w-2 h-2 bg-teal-600 rounded-full"></div>
<div className="w-2 h-2 bg-teal-600 rounded-full"></div>
<div className="w-2 h-2 bg-teal-600 rounded-full"></div>
</div>
{/* Speech bubble tail */}
<div className="absolute bottom-0 left-6 transform translate-y-full">
<div className="w-0 h-0 border-l-4 border-r-4 border-t-8 border-l-transparent border-r-transparent border-t-yellow-200"></div>
</div>
</div>
</div>
)}
{/* Decorative Circle */}
{showDecoCircle && (
<div className="absolute bottom-16 left-16 w-8 h-8 border-4 border-white rounded-full z-20"></div>
)}
</div>
{/* Right Side - White Background */}
<div className="w-2/3 relative bg-white">
{/* Content */}
<div className="pl-32 pr-16 py-12 h-full flex flex-col justify-center">
{/* Title Section */}
<div className="mb-8">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-tight mb-4">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold text-gray-800 tracking-wide mb-6">
{subtitle}
</p>
)}
{/* Decorative underline */}
<div className="w-32 h-1 bg-yellow-300 mb-8"></div>
</div>
{/* Welcome Text */}
{welcomeText && (
<div className="mb-8">
<p className="text-base leading-relaxed text-gray-700">
{welcomeText}
</p>
</div>
)}
{/* Thank You Button */}
{buttonText && (
<div>
<button className="bg-teal-600 hover:bg-teal-700 text-white font-semibold px-8 py-3 rounded-full transition-colors duration-200">
{buttonText}
</button>
</div>
)}
</div>
</div>
</div>
{/* Overlapping Circular Office Image */}
{officeImage?.__image_url__ && (
<div className="absolute top-1/2 left-72 transform -translate-x-1/2 -translate-y-1/2 z-30">
<div className="w-96 h-96 rounded-full overflow-hidden bg-white p-2 shadow-2xl">
<img
src={officeImage.__image_url__}
alt={officeImage.__image_prompt__}
className="w-full h-full object-cover rounded-full"
/>
</div>
</div>
)}
</div>
);
};
export default HelloFriendsSlide;

View file

@ -0,0 +1,155 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("MARKET SIZE")
.meta({
description: "Main title for the market size section",
}),
subtitle: z.string()
.min(10)
.max(25)
.default("OUR CLIENTS COME FROM EVERYWHERE")
.meta({
description: "Subtitle describing global reach",
}),
globalDescription: z.string()
.min(50)
.max(200)
.default("With a global perspective, our marketing agency has proudly served multinational clients, delivering tailored strategies that transcend borders and cultures, ensuring consistent brand success on a worldwide scale.")
.meta({
description: "Description of global market presence",
}),
worldMapImage: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1516245834210-c4c142787335?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80",
__image_prompt__: "World map with location pins showing global business presence"
}).meta({
description: "World map image showing global reach",
}),
marketDefinitions: z.array(z.object({
acronym: z.string().min(2).max(10),
fullName: z.string().min(10).max(50),
description: z.string().min(50).max(300)
})).min(3).max(3).default([
{
acronym: "TAM",
fullName: "Total Available Market (TAM)",
description: "The Total Available Market (TAM) represents the entire potential demand for our product or service, reflecting the vast landscape of opportunities awaiting exploration and market capture."
},
{
acronym: "SAM",
fullName: "Serviceable Available Market (SAM)",
description: "The Serviceable Available Market (SAM) represents the specific segment of the Total Available Market where our product or service can be realistically and effectively offered, defining the target audience for our strategic market approach."
},
{
acronym: "SOM",
fullName: "Serviceable Obtainable Market (SOM)",
description: "The Serviceable Obtainable Market (SOM) signifies the realistic and achievable portion of the Serviceable Available Market where our business aims to capture market share, emphasizing our practical and strategic approach to market penetration."
}
]).meta({
description: "Market size definitions for TAM, SAM, and SOM",
}),
showYellowUnderline: z.boolean()
.default(true)
.meta({
description: "Show yellow decorative underline",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const MarketSizeSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, globalDescription, worldMapImage, marketDefinitions, showYellowUnderline } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex">
{/* Left Side - Teal Background with Map */}
<div className="w-1/2 relative bg-teal-600 px-16 py-12 flex flex-col text-white">
{/* Title Section */}
<div className="mb-8">
{mainTitle && (
<h1 className="text-5xl lg:text-6xl font-black leading-tight mb-4">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold tracking-wide mb-4">
{subtitle}
</p>
)}
{/* Yellow Decorative Underline */}
{showYellowUnderline && (
<div className="w-24 h-1 bg-yellow-300 "></div>
)}
</div>
{/* World Map Image */}
{worldMapImage?.__image_url__ && (
<div className="flex-1 flex items-center justify-center">
<div className="w-full max-w-md">
<img
src={worldMapImage.__image_url__}
alt={worldMapImage.__image_prompt__}
className="w-full h-auto object-contain opacity-90"
/>
</div>
</div>
)}
{/* Global Description */}
{globalDescription && (
<div>
<p className="text-base leading-relaxed">
{globalDescription}
</p>
</div>
)}
</div>
{/* Right Side - White Background with Market Definitions */}
<div className="w-1/2 relative bg-white px-16 py-12 flex flex-col justify-center">
{/* Market Definitions */}
{marketDefinitions && marketDefinitions.length >= 3 && (
<div className="space-y-8">
{marketDefinitions.slice(0, 3).map((definition, index) => (
<div key={index} className="mb-8">
{/* Header with rounded background */}
<div className="bg-teal-600 text-white px-6 py-3 rounded-full mb-4">
<h3 className="text-lg font-bold text-center">
{definition.fullName}
</h3>
</div>
{/* Description */}
<p className="text-base leading-relaxed text-gray-700 px-2">
{definition.description}
</p>
</div>
))}
</div>
)}
</div>
</div>
</div>
);
};
export default MarketSizeSlide;

View file

@ -0,0 +1,145 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(10)
.default("OUR SERVICE")
.meta({
description: "Main title for the service section",
}),
services: z.array(z.object({
title: z.string().min(5).max(40),
description: z.string().min(30).max(100),
image: ImageSchema
})).min(3).max(3).default([
{
title: "Strategic Brand Development",
description: "Our agency specializes in strategic brand development, ensuring that your brand not only resonates with your target audience but also stands out in a crowded market.",
image: {
__image_url__: "https://images.unsplash.com/photo-1553877522-43269d4ea984?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Business team working on brand strategy with documents and tablet"
}
},
{
title: "Data-Driven Marketing",
description: "Our data-driven approach ensures that every campaign is backed by insights, maximizing ROI and driving tangible results.",
image: {
__image_url__: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Business analytics with charts, graphs and keyboard on desk"
}
},
{
title: "Creative Content Production",
description: "Content is king, and our agency excels in producing creative, engaging, and impactful content that resonates with your audience.",
image: {
__image_url__: "https://images.unsplash.com/photo-1542744094-3a31f272c490?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Creative professional working on laptop with design and content"
}
}
]).meta({
description: "Three main services with titles, descriptions and images",
}),
companyLogo: ImageSchema.default({
__image_url__: "https://via.placeholder.com/40x40/FFFFFF/1D9A8A?text=C",
__image_prompt__: "Clean modern company logo icon in white"
}).meta({
description: "Company logo icon",
}),
companyName: z.string()
.min(2)
.max(25)
.default("Company Name")
.meta({
description: "Company name for branding",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const OurServiceSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, services, companyLogo, companyName } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-gray-100 relative overflow-hidden">
{/* Header with Title and Company Branding */}
<div className="h-full flex flex-col">
{/* Top Section */}
<div className="flex ">
{/* Left - Title */}
<div className="w-2/3 px-16 py-12 bg-gray-100">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-tight mb-4">
{mainTitle}
</h1>
)}
</div>
{/* Right - Teal Background with Company Branding */}
<div className="w-1/3 bg-teal-600 px-16 py-12 flex items-center justify-end">
<div className="flex items-center space-x-3">
{companyLogo?.__image_url__ && (
<div className="w-10 h-10">
<img
src={companyLogo.__image_url__}
alt={companyLogo.__image_prompt__}
className="w-full h-full object-contain"
/>
</div>
)}
{companyName && (
<span className="text-xl font-bold text-white">
{companyName}
</span>
)}
</div>
</div>
</div>
{/* Bottom Section - Services Grid */}
<div className="flex-1 px-16 py-8 bg-white">
{services && services.length >= 3 && (
<div className="grid grid-cols-3 gap-8 h-full">
{services.slice(0, 3).map((service, index) => (
<div key={index} className="flex flex-col">
{/* Service Image */}
<div className="h-48 w-full mb-6">
<img
src={service.image.__image_url__}
alt={service.image.__image_prompt__}
className="w-full h-full object-cover rounded-lg"
/>
</div>
{/* Service Content */}
<div className="flex-1">
<h3 className="text-xl font-bold text-teal-700 mb-4 leading-tight">
{service.title}
</h3>
<p className="text-base leading-relaxed text-gray-700">
{service.description}
</p>
</div>
</div>
))}
</div>
)}
</div>
</div>
</div>
);
};
export default OurServiceSlide;

View file

@ -0,0 +1,155 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(20)
.default("PROBLEMS")
.meta({
description: "Main title for the problems section",
}),
subtitle: z.string()
.min(10)
.max(25)
.default("WE WILL SOLVE THE PROBLEMS")
.meta({
description: "Subtitle describing the section",
}),
problems: z.array(z.object({
number: z.string().min(1).max(3),
title: z.string().min(5).max(40),
description: z.string().min(20).max(200)
})).min(2).max(3).default([
{
number: "01",
title: "Lack of Brand Visibility",
description: "Many businesses struggle with gaining visibility in a saturated market. Our solution involves a comprehensive analysis of your brand, audience, and competitors, leading to the development of a strategic branding."
},
{
number: "02",
title: "Ineffective Digital Presence",
description: "Weak online presence can hinder business growth. Our agency offers an integrated approach to digital marketing, covering SEO optimization, social media management, content marketing, and more."
},
{
number: "03",
title: "Lack of Targeted Lead Generation",
description: "Many businesses struggle with generating quality leads that convert into customers. Our solution involves a meticulous understanding of your target audience, allowing us to develop highly targeted lead generation campaigns."
}
]).meta({
description: "List of problems with numbers, titles and descriptions",
}),
workspaceImage: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1542744173-8e7e53415bb0?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Clean modern workspace with laptop, plant, and documents on desk"
}).meta({
description: "Workspace image showing business environment",
}),
showDecoCircle: z.boolean()
.default(true)
.meta({
description: "Show decorative circle element",
}),
showTealAccent: z.boolean()
.default(true)
.meta({
description: "Show teal accent block",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const ProblemsSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, problems, workspaceImage, showDecoCircle, showTealAccent } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex">
{/* Left Side - Content */}
<div className="w-3/5 relative bg-white px-16 py-12 flex flex-col justify-start">
{/* Title Section */}
<div className="mb-12">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-tight mb-4">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold text-gray-800 tracking-wide">
{subtitle}
</p>
)}
</div>
{/* Problems List */}
{problems && problems.length > 0 && (
<div className="space-y-8">
{problems.map((problem, index) => (
<div key={index} className="flex items-start space-x-6">
{/* Number Circle */}
<div className="w-16 h-16 bg-yellow-200 rounded-full flex items-center justify-center flex-shrink-0">
<span className="text-teal-700 font-bold text-xl">
{problem.number}
</span>
</div>
{/* Content */}
<div className="flex-1">
<h3 className="text-xl font-bold text-gray-900 mb-3">
{problem.title}
</h3>
<p className="text-base leading-relaxed text-gray-700">
{problem.description}
</p>
</div>
</div>
))}
</div>
)}
</div>
{/* Right Side - Image and Decorative Elements */}
<div className="w-2/5 relative">
{/* Decorative Circle */}
{showDecoCircle && (
<div className="absolute top-12 left-8 w-8 h-8 border-4 border-teal-600 rounded-full z-20"></div>
)}
{/* Workspace Image */}
{workspaceImage?.__image_url__ && (
<div className="absolute top-8 right-8 bottom-20 left-4 z-15 shadow-lg">
<img
src={workspaceImage.__image_url__}
alt={workspaceImage.__image_prompt__}
className="w-full h-full object-cover rounded-lg"
/>
</div>
)}
{/* Teal Accent Block - Right Edge */}
{showTealAccent && (
<div className="absolute top-0 right-0 bottom-0 w-16 bg-teal-600 z-10"></div>
)}
</div>
</div>
{/* Bottom Teal Stripe */}
<div className="absolute bottom-0 left-0 right-0 h-4 bg-teal-600 z-5"></div>
</div>
);
};
export default ProblemsSlide;

View file

@ -0,0 +1,179 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("SOLUTIONS")
.meta({
description: "Main title for the solutions section",
}),
subtitle: z.string()
.min(10)
.max(25)
.default("SOLUTIONS OF THE PROBLEMS")
.meta({
description: "Subtitle describing the section",
}),
solutions: z.array(z.object({
number: z.string().min(1).max(3),
title: z.string().min(5).max(40),
description: z.string().min(20).max(300)
})).min(2).max(3).default([
{
number: "01",
title: "Lack of Brand Visibility",
description: "By defining your unique value proposition and creating a consistent brand identity, we ensure your business stands out and remains memorable in the minds of your target audience."
},
{
number: "02",
title: "Ineffective Digital Presence",
description: "Through data-driven insights, we tailor strategies to maximize online visibility, engage your audience, and drive meaningful interactions, converting online engagements into tangible business outcomes."
},
{
number: "03",
title: "Lack of Targeted Lead Generation",
description: "By leveraging strategic content, paid advertising, and personalized engagement tactics, we ensure that your marketing efforts are focused on reaching and converting the right audience."
}
]).meta({
description: "List of solutions with numbers, titles and descriptions",
}),
workspaceImages: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Business person working on laptop with charts and analytics"
}).meta({
description: "Two workspace images for left side",
}),
companyLogo: ImageSchema.default({
__image_url__: "https://via.placeholder.com/40x40/1D9A8A/FFFFFF?text=C",
__image_prompt__: "Clean modern company logo icon"
}).meta({
description: "Company logo icon",
}),
companyName: z.string()
.min(2)
.max(25)
.default("Company Name")
.meta({
description: "Company name for branding",
}),
showYellowUnderline: z.boolean()
.default(true)
.meta({
description: "Show yellow decorative underline",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const SolutionsSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, solutions, workspaceImages, companyLogo, companyName, showYellowUnderline } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex">
{/* Left Side - Images and Branding */}
<div className="w-1/2 relative bg-gray-100 px-16 py-12 flex flex-col">
{/* Title Section */}
<div className="mb-8">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-tight mb-4">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold text-gray-800 tracking-wide mb-4">
{subtitle}
</p>
)}
{/* Yellow Decorative Underline */}
{showYellowUnderline && (
<div className="w-24 h-1 bg-yellow-300"></div>
)}
</div>
{/* Images */}
{workspaceImages && (
<div className="flex-1 space-y-6">
<div className="h-full w-full">
<img
src={workspaceImages.__image_url__}
alt={workspaceImages.__image_prompt__}
className="w-full h-full object-cover rounded-lg shadow-md"
/>
</div>
</div>
)}
{/* Company Branding */}
<div className="mt-8 flex items-center space-x-3">
{companyLogo?.__image_url__ && (
<div className="w-10 h-10">
<img
src={companyLogo.__image_url__}
alt={companyLogo.__image_prompt__}
className="w-full h-full object-contain"
/>
</div>
)}
{companyName && (
<span className="text-xl font-bold text-teal-700">
{companyName}
</span>
)}
</div>
</div>
{/* Right Side - Teal Background with Solutions */}
<div className="w-1/2 relative bg-teal-600 px-16 py-12 flex flex-col justify-center">
{/* Solutions List */}
{solutions && solutions.length > 0 && (
<div className="space-y-8">
{solutions.map((solution, index) => (
<div key={index} className="flex items-start space-x-4">
{/* Number Circle */}
<div className="w-12 h-12 bg-yellow-200 rounded-full flex items-center justify-center flex-shrink-0">
<span className="text-teal-700 font-bold text-lg">
{solution.number}
</span>
</div>
{/* Content */}
<div className="flex-1">
<h3 className="text-xl font-bold text-white mb-3">
{solution.title}
</h3>
<p className="text-base leading-relaxed text-white">
{solution.description}
</p>
</div>
</div>
))}
</div>
)}
</div>
</div>
</div>
);
};
export default SolutionsSlide;

View file

@ -0,0 +1,229 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("STATISTIC")
.meta({
description: "Main title for the statistic section",
}),
subtitle: z.string()
.min(10)
.max(25)
.default("CLIENT'S SATISFACTION")
.meta({
description: "Subtitle describing the statistic focus",
}),
description: z.string()
.min(100)
.max(400)
.default("At the heart of our success lies the unwavering satisfaction of our clients. We take pride in fostering lasting partnerships, consistently exceeding expectations, and delivering results that not only meet but surpass the unique objectives of each client we serve.")
.meta({
description: "Description of client satisfaction approach",
}),
circularMetric: z.object({
value: z.number().min(0).max(100),
label: z.string().min(5).max(30),
percentage: z.string().min(2).max(5)
}).default({
value: 90,
label: "CLIENT'S REPEAT ORDER",
percentage: "90%"
}).meta({
description: "Main circular chart metric",
}),
statisticBlocks: z.array(z.object({
percentage: z.string().min(2).max(5),
description: z.string().min(20).max(150),
backgroundColor: z.enum(["teal", "beige"])
})).min(2).max(2).default([
{
percentage: "90%",
description: "Our client loyalty speaks volumes as evidenced by a robust repeat order rate",
backgroundColor: "teal"
},
{
percentage: "99%",
description: "Our paramount focus on client satisfaction is the bedrock of our agency's success.",
backgroundColor: "beige"
}
]).meta({
description: "Two statistic blocks with percentages and descriptions",
}),
companyLogo: ImageSchema.default({
__image_url__: "https://via.placeholder.com/40x40/FFFFFF/1D9A8A?text=C",
__image_prompt__: "Clean modern company logo icon in white"
}).meta({
description: "Company logo icon",
}),
companyName: z.string()
.min(2)
.max(25)
.default("Company Name")
.meta({
description: "Company name for branding",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const StatisticCircularSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, description, circularMetric, statisticBlocks, companyLogo, companyName } = data;
const getBackgroundClass = (bg: string) => {
switch (bg) {
case "teal": return "bg-teal-600 text-white";
case "beige": return "bg-yellow-200 text-gray-900";
default: return "bg-gray-200 text-gray-900";
}
};
// Calculate stroke dash array for circular progress
const radius = 150;
const circumference = 2 * Math.PI * radius;
const strokeDasharray = circumference;
const strokeDashoffset = circumference - (circumference * (circularMetric?.value || 90) / 100);
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex flex-col">
{/* Header Section */}
<div className="flex h-32">
{/* Left - Title */}
<div className="w-1/2 px-16 py-8 bg-gray-100 flex flex-col justify-center">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-tight mb-2">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold text-gray-800 tracking-wide">
{subtitle}
</p>
)}
</div>
{/* Right - Company Branding */}
<div className="w-1/2 bg-teal-600 px-16 py-8 flex items-center justify-end">
<div className="flex items-center space-x-3">
{companyLogo?.__image_url__ && (
<div className="w-10 h-10">
<img
src={companyLogo.__image_url__}
alt={companyLogo.__image_prompt__}
className="w-full h-full object-contain"
/>
</div>
)}
{companyName && (
<span className="text-xl font-bold text-white">
{companyName}
</span>
)}
</div>
</div>
</div>
{/* Content Section */}
<div className="flex-1 flex">
{/* Left Side - Circular Chart */}
<div className="w-1/2 px-8 py-8 bg-gray-100 flex items-center justify-center">
<div className="relative">
{/* Circular Progress SVG */}
<svg width="340" height="340" className="transform -rotate-90">
{/* Background circle */}
<circle
cx="170"
cy="170"
r={radius}
stroke="#E5E7EB"
strokeWidth="25"
fill="transparent"
/>
{/* Progress circle */}
<circle
cx="170"
cy="170"
r={radius}
stroke="#1D9A8A"
strokeWidth="25"
fill="transparent"
strokeDasharray={strokeDasharray}
strokeDashoffset={strokeDashoffset}
strokeLinecap="round"
className="transition-all duration-1000 ease-out"
/>
</svg>
{/* Center Content */}
<div className="absolute inset-0 flex flex-col items-center justify-center">
{circularMetric?.label && (
<p className="text-sm font-semibold text-gray-800 mb-4 text-center max-w-32 leading-tight">
{circularMetric.label}
</p>
)}
{circularMetric?.percentage && (
<span className="text-7xl font-black text-teal-700">
{circularMetric.percentage}
</span>
)}
</div>
</div>
</div>
{/* Right Side - Content and Statistics */}
<div className="w-1/2 bg-white flex flex-col">
{/* Description */}
<div className="px-16 py-8 flex-1 flex items-start justify-center flex-col">
{description && (
<p className="text-base leading-relaxed text-gray-700">
{description}
</p>
)}
</div>
{/* Statistics Blocks */}
{statisticBlocks && statisticBlocks.length > 0 && (
<div className="px-16 pb-8 space-y-4">
{statisticBlocks.map((block, index) => (
<div key={index} className="flex items-stretch">
{/* Percentage Block */}
<div className={`w-24 h-20 ${getBackgroundClass(block.backgroundColor)} flex items-center justify-center flex-shrink-0`}>
<span className="text-2xl font-black">
{block.percentage}
</span>
</div>
{/* Description Block */}
<div className="flex-1 border-2 border-gray-900 p-4 h-20 flex items-center">
<p className="text-sm leading-relaxed text-gray-900">
{block.description}
</p>
</div>
</div>
))}
</div>
)}
</div>
</div>
</div>
</div>
);
};
export default StatisticCircularSlide;

View file

@ -0,0 +1,330 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart';
import { BarChart, Bar, AreaChart, Area, XAxis, YAxis, CartesianGrid, ResponsiveContainer } from "recharts";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("STATISTIC")
.meta({
description: "Main title for the statistic section",
}),
companyLogo: ImageSchema.default({
__image_url__: "https://via.placeholder.com/40x40/FFFFFF/1D9A8A?text=C",
__image_prompt__: "Clean modern company logo icon in white"
}).meta({
description: "Company logo icon",
}),
companyName: z.string()
.min(2)
.max(25)
.default("Company Name")
.meta({
description: "Company name for branding",
}),
barChartData: z.array(z.object({
name: z.string(),
series1: z.number(),
series2: z.number(),
series3: z.number()
})).min(5).max(5).default([
{ name: "Item 1", series1: 5, series2: 5, series3: 8 },
{ name: "Item 2", series1: 8, series2: 8, series3: 15 },
{ name: "Item 3", series1: 15, series2: 10, series3: 18 },
{ name: "Item 4", series1: 18, series2: 14, series3: 22 },
{ name: "Item 5", series1: 22, series2: 20, series3: 8 }
]).meta({
description: "Bar chart data for customer satisfaction",
}),
areaChartData: z.array(z.object({
name: z.string(),
series1: z.number(),
series2: z.number(),
series3: z.number()
})).min(5).max(5).default([
{ name: "Item 1", series1: 20, series2: 30, series3: 15 },
{ name: "Item 2", series1: 40, series2: 45, series3: 35 },
{ name: "Item 3", series1: 45, series2: 50, series3: 80 },
{ name: "Item 4", series1: 50, series2: 45, series3: 85 },
{ name: "Item 5", series1: 80, series2: 75, series3: 120 }
]).meta({
description: "Area chart data for repeat order rate",
}),
leftChartTitle: z.string()
.min(5)
.max(40)
.default("Our Customer's Satisfaction")
.meta({
description: "Title for the left chart",
}),
leftChartDescription: z.string()
.min(20)
.max(200)
.default("An impressive client satisfaction rate underscores our unwavering commitment to delivering exceptional service and exceeding expectations.")
.meta({
description: "Description for the left chart",
}),
rightChartTitle: z.string()
.min(5)
.max(40)
.default("Repeat Order Rate")
.meta({
description: "Title for the right chart",
}),
rightChartDescription: z.string()
.min(20)
.max(200)
.default("Our remarkable client repeat order rate of 123 times are testament to the quality of our products/services and the trust our clients place in our ability.")
.meta({
description: "Description for the right chart",
}),
})
// Chart configuration
const chartConfig = {
series1: {
label: "Series 1",
color: "#1D9A8A",
},
series2: {
label: "Series 2",
color: "#A8C97F",
},
series3: {
label: "Series 3",
color: "#E8F4B8",
},
};
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const StatisticDualChartSlide = ({ data }: { data: Partial<SchemaType> }) => {
const {
mainTitle,
companyLogo,
companyName,
barChartData,
areaChartData,
leftChartTitle,
leftChartDescription,
rightChartTitle,
rightChartDescription
} = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Header Section */}
<div className="h-20 bg-teal-600 px-16 py-4 flex justify-between items-center">
{/* Title */}
{mainTitle && (
<h1 className="text-4xl font-black text-white">
{mainTitle}
</h1>
)}
{/* Company Branding */}
<div className="flex items-center space-x-3">
{companyLogo?.__image_url__ && (
<div className="w-8 h-8">
<img
src={companyLogo.__image_url__}
alt={companyLogo.__image_prompt__}
className="w-full h-full object-contain"
/>
</div>
)}
{companyName && (
<span className="text-lg font-bold text-white">
{companyName}
</span>
)}
</div>
</div>
{/* Content Section */}
<div className="flex-1 h-[calc(100%-80px)] flex">
{/* Left Chart Section */}
<div className="w-1/2 p-8 bg-gray-50 flex flex-col">
{/* Chart Legend */}
<div className="flex items-center justify-start mb-4 space-x-4">
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-teal-600 rounded-full"></div>
<span className="text-sm text-gray-600">Series 1</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-green-400 rounded-full"></div>
<span className="text-sm text-gray-600">Series 2</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-yellow-200 rounded-full"></div>
<span className="text-sm text-gray-600">Series 3</span>
</div>
</div>
{/* Bar Chart */}
{barChartData && barChartData.length > 0 && (
<div className="flex-1 mb-6">
<ChartContainer config={chartConfig} className="h-full w-full">
<ResponsiveContainer width="100%" height="100%">
<BarChart
data={barChartData}
margin={{ top: 10, right: 20, left: 0, bottom: 30 }}
barCategoryGap="20%"
>
<CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
<XAxis
dataKey="name"
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#666' }}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#666' }}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<Bar
dataKey="series1"
fill="#1D9A8A"
radius={[2, 2, 0, 0]}
barSize={15}
/>
<Bar
dataKey="series2"
fill="#A8C97F"
radius={[2, 2, 0, 0]}
barSize={15}
/>
<Bar
dataKey="series3"
fill="#E8F4B8"
radius={[2, 2, 0, 0]}
barSize={15}
/>
</BarChart>
</ResponsiveContainer>
</ChartContainer>
</div>
)}
{/* Chart Description */}
<div className="space-y-3">
{leftChartTitle && (
<h3 className="text-xl font-bold text-gray-900">
{leftChartTitle}
</h3>
)}
{leftChartDescription && (
<p className="text-base leading-relaxed text-gray-700">
{leftChartDescription}
</p>
)}
</div>
</div>
{/* Right Chart Section */}
<div className="w-1/2 p-8 bg-white flex flex-col">
{/* Chart Legend */}
<div className="flex items-center justify-end mb-4 space-x-4">
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-yellow-200 rounded-full"></div>
<span className="text-sm text-gray-600">Series 1</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-green-400 rounded-full"></div>
<span className="text-sm text-gray-600">Series 2</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-teal-600 rounded-full"></div>
<span className="text-sm text-gray-600">Series 3</span>
</div>
</div>
{/* Area Chart */}
{areaChartData && areaChartData.length > 0 && (
<div className="flex-1 mb-6">
<ChartContainer config={chartConfig} className="h-full w-full">
<ResponsiveContainer width="100%" height="100%">
<AreaChart
data={areaChartData}
margin={{ top: 10, right: 20, left: 0, bottom: 30 }}
>
<CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
<XAxis
dataKey="name"
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#666' }}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#666' }}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<Area
type="monotone"
dataKey="series3"
stackId="1"
stroke="#1D9A8A"
fill="#1D9A8A"
fillOpacity={0.8}
/>
<Area
type="monotone"
dataKey="series2"
stackId="1"
stroke="#A8C97F"
fill="#A8C97F"
fillOpacity={0.8}
/>
<Area
type="monotone"
dataKey="series1"
stackId="1"
stroke="#E8F4B8"
fill="#E8F4B8"
fillOpacity={0.8}
/>
</AreaChart>
</ResponsiveContainer>
</ChartContainer>
</div>
)}
{/* Chart Description */}
<div className="space-y-3">
{rightChartTitle && (
<h3 className="text-xl font-bold text-gray-900">
{rightChartTitle}
</h3>
)}
{rightChartDescription && (
<p className="text-base leading-relaxed text-gray-700">
{rightChartDescription}
</p>
)}
</div>
</div>
</div>
</div>
);
};
export default StatisticDualChartSlide;

View file

@ -0,0 +1,262 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, ResponsiveContainer } from "recharts";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(12)
.default("STATISTIC")
.meta({
description: "Main title for the statistic section",
}),
subtitle: z.string()
.min(10)
.max(18)
.default("CLIENT'S SATISFACTION")
.meta({
description: "Subtitle describing the statistic focus",
}),
description: z.string()
.min(80)
.max(200)
.default("At the heart of our success lies the unwavering satisfaction of our clients. We take pride in fostering lasting partnerships, consistently exceeding expectations, and delivering results that not only meet but surpass the unique objectives of each client we serve.")
.meta({
description: "Description of client satisfaction approach",
}),
businessImage: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1552664730-d307ca884978?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Business team meeting discussing charts and documents at table"
}).meta({
description: "Business meeting image showing team collaboration",
}),
chartData: z.array(z.object({
name: z.string(),
series1: z.number(),
series2: z.number(),
series3: z.number()
})).min(5).max(5).default([
{ name: "Item 1", series1: 18, series2: 0, series3: 0 },
{ name: "Item 2", series1: 30, series2: 12, series3: 8 },
{ name: "Item 3", series1: 26, series2: 38, series3: 20 },
{ name: "Item 4", series1: 40, series2: 30, series3: 35 },
{ name: "Item 5", series1: 42, series2: 45, series3: 32 }
]).meta({
description: "Line chart data for satisfaction metrics",
}),
bulletPoints: z.array(z.object({
text: z.string().min(20).max(100),
color: z.enum(["teal", "beige", "light"])
})).min(3).max(3).default([
{
text: "From brand positioning and messaging to visual identity, we guide you through every step.",
color: "teal"
},
{
text: "Navigate the path to increased sales with our insightful report and offering a strategic roadmap.",
color: "beige"
},
{
text: "Amplify your revenue streams, engage customers, and unlock the full potential of your business.",
color: "light"
}
]).meta({
description: "Three bullet points with different colored indicators",
}),
showYellowUnderline: z.boolean()
.default(true)
.meta({
description: "Show yellow decorative underline",
}),
})
// Chart configuration
const chartConfig = {
series1: {
label: "Series 1",
color: "#1D9A8A",
},
series2: {
label: "Series 2",
color: "#A8C97F",
},
series3: {
label: "Series 3",
color: "#E8F4B8",
},
};
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const StatisticSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, description, businessImage, chartData, bulletPoints, showYellowUnderline } = data;
const getColorClass = (color: string) => {
switch (color) {
case "teal": return "bg-teal-600";
case "beige": return "bg-yellow-300";
case "light": return "bg-gray-300";
default: return "bg-gray-300";
}
};
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex">
{/* Left Side - Teal Background with Content and Image */}
<div className="w-1/2 relative bg-teal-600">
{/* Top Content Section */}
<div className="px-16 pt-12 text-white flex-1">
{/* Title Section */}
<div className="mb-4">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black leading-tight mb-1">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold tracking-wide mb-1">
{subtitle}
</p>
)}
{/* Yellow Decorative Underline */}
{showYellowUnderline && (
<div className="w-24 h-1 bg-yellow-300 mb-4"></div>
)}
</div>
{/* Description */}
{description && (
<div>
<p className="text-base leading-relaxed">
{description}
</p>
</div>
)}
</div>
{/* Bottom Business Image */}
<div className="relative h-80 mx-16 mt-10">
{businessImage?.__image_url__ && (
<img
src={businessImage.__image_url__}
alt={businessImage.__image_prompt__}
className="max-w-full w-full h-full object-cover"
/>
)}
</div>
</div>
{/* Right Side - Chart and Bullet Points */}
<div className="w-1/2 relative bg-white">
{/* Chart Section */}
<div className="flex-1 px-8 pt-8">
{/* Chart Legend */}
<div className="flex items-center justify-end mb-4 space-x-4">
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-yellow-300 rounded-full"></div>
<span className="text-sm text-gray-600">Series 1</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-gray-300 rounded-full"></div>
<span className="text-sm text-gray-600">Series 2</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-teal-600 rounded-full"></div>
<span className="text-sm text-gray-600">Series 3</span>
</div>
</div>
{/* Chart Container */}
{chartData && chartData.length > 0 && (
<div className="h-64">
<ChartContainer config={chartConfig} className="h-full w-full">
<ResponsiveContainer width="100%" height="100%">
<LineChart
data={chartData}
margin={{ top: 10, right: 20, left: 0, bottom: 30 }}
>
<CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
<XAxis
dataKey="name"
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#666' }}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fontSize: 12, fill: '#666' }}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<Line
type="monotone"
dataKey="series1"
stroke="#E8F4B8"
strokeWidth={3}
dot={{ fill: "#E8F4B8", strokeWidth: 2, r: 4 }}
/>
<Line
type="monotone"
dataKey="series2"
stroke="#A8C97F"
strokeWidth={3}
dot={{ fill: "#A8C97F", strokeWidth: 2, r: 4 }}
/>
<Line
type="monotone"
dataKey="series3"
stroke="#1D9A8A"
strokeWidth={3}
dot={{ fill: "#1D9A8A", strokeWidth: 2, r: 4 }}
/>
</LineChart>
</ResponsiveContainer>
</ChartContainer>
</div>
)}
</div>
{/* Bullet Points Section */}
<div className="px-8 pb-6 space-y-4 mt-10">
{bulletPoints && bulletPoints.length > 0 && (
<>
{bulletPoints.map((point, index) => (
<div key={index} className="flex items-start space-x-4">
<div className={`w-6 h-6 ${getColorClass(point.color)} rounded-full flex-shrink-0 mt-1`}></div>
<p className="text-base leading-relaxed text-gray-700">
{point.text}
</p>
</div>
))}
</>
)}
</div>
</div>
</div>
</div>
);
};
export default StatisticSlide;

View file

@ -0,0 +1,161 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(20)
.default("TABLE OF CONTENT")
.meta({
description: "Main title for the table of contents",
}),
subtitle: z.string()
.min(10)
.max(25)
.default("PITCH DECK PRESENTATION")
.meta({
description: "Subtitle describing the presentation type",
}),
contentItems: z.array(z.object({
number: z.string().min(1).max(3),
title: z.string().min(3).max(30)
})).min(4).max(8).default([
{ number: "01", title: "Hello Friends!" },
{ number: "02", title: "About Us" },
{ number: "03", title: "What We Believe" },
{ number: "04", title: "Problems & Solutions" },
{ number: "05", title: "Market Size" },
{ number: "06", title: "Statistic" }
]).meta({
description: "List of content items with numbers and titles",
}),
heroImage: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1498050108023-c5249f4df085?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Modern laptop and office workspace on wooden desk"
}).meta({
description: "Hero image showing professional workspace",
}),
companyLogo: ImageSchema.default({
__image_url__: "https://via.placeholder.com/40x40/1D9A8A/FFFFFF?text=C",
__image_prompt__: "Clean modern company logo icon"
}).meta({
description: "Company logo icon",
}),
companyName: z.string()
.min(2)
.max(25)
.default("Company Name")
.meta({
description: "Company name for branding",
}),
decorativeCircle: z.boolean()
.default(true)
.meta({
description: "Show decorative circle element",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const TableOfContentsSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, contentItems, heroImage, companyLogo, companyName, decorativeCircle } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex">
{/* Left Side - Content */}
<div className="w-3/5 px-16 py-12 flex flex-col justify-center">
{/* Title Section */}
<div className="mb-12">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-tight mb-4">
{mainTitle}
</h1>
)}
{/* Decorative underline */}
<div className="w-32 h-1 bg-yellow-300 mb-6"></div>
{subtitle && (
<p className="text-base font-medium text-gray-700 tracking-wide">
{subtitle}
</p>
)}
</div>
{/* Content Items */}
{contentItems && contentItems.length > 0 && (
<div className="grid grid-cols-2 gap-6">
{contentItems.map((item, index) => (
<div key={index} className="flex items-center space-x-4">
<div className="w-12 h-12 bg-yellow-200 rounded-full flex items-center justify-center flex-shrink-0">
<span className="text-teal-700 font-bold text-lg">
{item.number}
</span>
</div>
<div className="text-gray-900 font-medium text-lg">
{item.title}
</div>
</div>
))}
</div>
)}
</div>
{/* Right Side - Image and Branding */}
<div className="w-2/5 relative bg-teal-600">
{/* Hero Image */}
{heroImage?.__image_url__ && (
<div className="absolute top-0 left-0 right-0 h-1/2">
<img
src={heroImage.__image_url__}
alt={heroImage.__image_prompt__}
className="w-full h-full object-cover"
/>
</div>
)}
{/* Decorative Circle */}
{decorativeCircle && (
<div className="absolute bottom-24 left-1/2 transform -translate-x-1/2 w-32 h-32 bg-yellow-200 rounded-full"></div>
)}
{/* Company Branding */}
<div className="absolute bottom-8 left-8 flex items-center space-x-3">
{companyLogo?.__image_url__ && (
<div className="w-10 h-10">
<img
src={companyLogo.__image_url__}
alt={companyLogo.__image_prompt__}
className="w-full h-full object-contain"
/>
</div>
)}
{companyName && (
<span className="text-white font-bold text-xl">
{companyName}
</span>
)}
</div>
</div>
</div>
</div>
);
};
export default TableOfContentsSlide;

View file

@ -0,0 +1,180 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("TESTIMONIAL")
.meta({
description: "Main title for the testimonial section",
}),
companyLogo: ImageSchema.default({
__image_url__: "https://via.placeholder.com/40x40/FFFFFF/1D9A8A?text=C",
__image_prompt__: "Clean modern company logo icon in white"
}).meta({
description: "Company logo icon",
}),
companyName: z.string()
.min(2)
.max(25)
.default("Company Name")
.meta({
description: "Company name for branding",
}),
testimonials: z.array(z.object({
text: z.string().min(30).max(200),
clientName: z.string().min(2).max(30),
clientPhoto: ImageSchema,
rating: z.number().min(1).max(5),
backgroundColor: z.enum(["beige", "teal", "light"])
})).min(3).max(3).default([
{
text: "In a world flooded with marketing noise, this company stands out as a beacon of creativity and effectiveness.",
clientName: "Benjamin Shah",
clientPhoto: {
__image_url__: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80",
__image_prompt__: "Professional headshot of smiling businessman"
},
rating: 5,
backgroundColor: "beige"
},
{
text: "The level of expertise and personalized attention to our unique needs has made them an invaluable partner.",
clientName: "Murad Naser",
clientPhoto: {
__image_url__: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80",
__image_prompt__: "Professional headshot of confident businessman with beard"
},
rating: 5,
backgroundColor: "teal"
},
{
text: "I've been thoroughly impressed with the exceptional level of service and creativity they bring to the table.",
clientName: "Drew Feig",
clientPhoto: {
__image_url__: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80",
__image_prompt__: "Professional headshot of smiling young businessman"
},
rating: 5,
backgroundColor: "light"
}
]).meta({
description: "Three client testimonials with photos and ratings",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const TestimonialSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, companyLogo, companyName, testimonials } = data;
const getBackgroundClass = (bg: string) => {
switch (bg) {
case "teal": return "bg-teal-600 text-white";
case "beige": return "bg-yellow-100 text-gray-900";
case "light": return "bg-gray-100 text-gray-900";
default: return "bg-gray-100 text-gray-900";
}
};
const getStarColor = (bg: string) => {
return bg === "teal" ? "text-yellow-400" : "text-yellow-500";
};
const renderStars = (rating: number, backgroundColor: string) => {
return (
<div className={`flex space-x-1 mb-6 ${getStarColor(backgroundColor)}`}>
{[...Array(5)].map((_, index) => (
<svg
key={index}
className="w-6 h-6 fill-current"
viewBox="0 0 24 24"
>
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
</svg>
))}
</div>
);
};
return (
<div className="aspect-video max-w-[1280px] w-full bg-gray-50 relative overflow-hidden">
{/* Header Section */}
<div className="h-20 bg-teal-600 px-16 py-4 flex justify-between items-center">
{/* Title */}
{mainTitle && (
<h1 className="text-4xl font-black text-white">
{mainTitle}
</h1>
)}
{/* Company Branding */}
<div className="flex items-center space-x-3">
{companyLogo?.__image_url__ && (
<div className="w-8 h-8">
<img
src={companyLogo.__image_url__}
alt={companyLogo.__image_prompt__}
className="w-full h-full object-contain"
/>
</div>
)}
{companyName && (
<span className="text-lg font-bold text-white">
{companyName}
</span>
)}
</div>
</div>
{/* Testimonials Section */}
<div className="flex-1 h-[calc(100%-80px)] px-16 py-12 flex items-center justify-center">
{testimonials && testimonials.length > 0 && (
<div className="grid grid-cols-3 gap-8 w-full max-w-6xl">
{testimonials.map((testimonial, index) => (
<div
key={index}
className={`${getBackgroundClass(testimonial.backgroundColor)} rounded-3xl p-8 flex flex-col items-center text-center h-full`}
>
{/* Stars */}
{renderStars(testimonial.rating, testimonial.backgroundColor)}
{/* Testimonial Text */}
<p className="text-base leading-relaxed mb-8 flex-1 flex items-center">
{testimonial.text}
</p>
{/* Client Photo */}
{testimonial.clientPhoto?.__image_url__ && (
<div className="w-20 h-20 rounded-full overflow-hidden mb-4 border-4 border-white shadow-lg">
<img
src={testimonial.clientPhoto.__image_url__}
alt={testimonial.clientPhoto.__image_prompt__}
className="w-full h-full object-cover"
/>
</div>
)}
{/* Client Name */}
<h3 className="text-lg font-bold">
{testimonial.clientName}
</h3>
</div>
))}
</div>
)}
</div>
</div>
);
};
export default TestimonialSlide;

View file

@ -0,0 +1,183 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
companyName: z.string()
.min(2)
.max(15)
.default("Company Name")
.meta({
description: "Company name displayed prominently",
}),
mainTitle: z.string()
.min(5)
.max(20)
.default("THANK YOU")
.meta({
description: "Main thank you title in large bold letters",
}),
subtitle: z.string()
.min(10)
.max(40)
.default("FOR YOUR NICE ATTENTION")
.meta({
description: "Subtitle thanking the audience",
}),
companyLogo: ImageSchema.default({
__image_url__: "https://via.placeholder.com/40x40/22C55E/FFFFFF?text=C",
__image_prompt__: "Company logo - geometric green icon"
}).meta({
description: "Company logo icon",
}),
contactInfo: z.object({
telephone: z.string().min(10).max(20).default("+123-456-7890"),
address: z.string().min(10).max(50).default("123 Anywhere St., Any City, ST 12345"),
website: z.string().min(10).max(30).default("www.reallygreatsite.com")
}).default({
telephone: "+123-456-7890",
address: "123 Anywhere St., Any City, ST 12345",
website: "www.reallygreatsite.com"
}).meta({
description: "Company contact information",
}),
presentationDate: z.string()
.min(5)
.max(20)
.default("December 2023")
.meta({
description: "Date of the presentation",
}),
decorativeCircle: z.boolean()
.default(true)
.meta({
description: "Show decorative circle element",
}),
arrowButton: z.boolean()
.default(true)
.meta({
description: "Show navigation arrow button",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const ThankYouSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { companyName, mainTitle, subtitle, companyLogo, contactInfo, presentationDate, decorativeCircle, arrowButton } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Header with Logo and Arrow */}
<div className="absolute top-0 left-0 right-0 px-16 py-8 flex justify-between items-center z-20">
{/* Company Logo and Name */}
<div className="flex items-center space-x-3">
{companyLogo?.__image_url__ && (
<div className="w-10 h-10">
<img
src={companyLogo.__image_url__}
alt={companyLogo.__image_prompt__}
className="w-full h-full object-contain"
/>
</div>
)}
{companyName && (
<span className="text-2xl font-bold text-gray-900">
{companyName}
</span>
)}
</div>
{/* Arrow Button */}
{arrowButton && (
<div className="w-12 h-12 bg-teal-600 rounded-full flex items-center justify-center">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</div>
)}
</div>
{/* Decorative Circle */}
{decorativeCircle && (
<div className="absolute top-20 right-16 w-96 h-96 bg-yellow-100 rounded-full opacity-60 z-10"></div>
)}
{/* Main Content */}
<div className="relative z-15 h-full flex flex-col justify-center px-16">
<div className="max-w-4xl">
{/* Main Title */}
{mainTitle && (
<h1 className="text-8xl lg:text-9xl font-black text-teal-700 leading-none tracking-tight mb-4">
{mainTitle}
</h1>
)}
{/* Subtitle with Circle Bullet */}
{subtitle && (
<div className="flex items-center space-x-4 mb-12">
<div className="w-4 h-4 bg-teal-600 rounded-full"></div>
<h2 className="text-2xl font-bold text-gray-800 tracking-wide">
{subtitle}
</h2>
</div>
)}
</div>
</div>
{/* Footer with Contact Info */}
<div className="absolute bottom-0 left-0 right-0 px-16 py-8 border-t-2 border-gray-300">
<div className="flex justify-between items-center text-gray-700">
<div className="flex space-x-16 text-sm">
{/* Telephone */}
{contactInfo?.telephone && (
<div>
<div className="font-semibold text-gray-900 mb-1">Telephone</div>
<div>{contactInfo.telephone}</div>
</div>
)}
{/* Address */}
{contactInfo?.address && (
<div>
<div className="font-semibold text-gray-900 mb-1">Address</div>
<div>{contactInfo.address}</div>
</div>
)}
{/* Website */}
{contactInfo?.website && (
<div>
<div className="font-semibold text-gray-900 mb-1">Website</div>
<div>{contactInfo.website}</div>
</div>
)}
</div>
{/* Presentation Date */}
{presentationDate && (
<div className="text-right">
<div className="text-lg font-bold text-gray-900">
{presentationDate}
</div>
</div>
)}
</div>
</div>
</div>
);
};
export default ThankYouSlide;

View file

@ -0,0 +1,184 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
companyName: z.string()
.min(2)
.max(15)
.default("Thynk Unlimited")
.meta({
description: "Company name displayed prominently",
}),
mainTitle: z.string()
.min(5)
.max(15)
.default("PITCH DECK")
.meta({
description: "Main title in large bold letters",
}),
subtitle: z.string()
.min(10)
.max(40)
.default("BUSINESS PRESENTATION")
.meta({
description: "Subtitle describing the presentation type",
}),
companyLogo: ImageSchema.default({
__image_url__: "https://via.placeholder.com/40x40/22C55E/FFFFFF?text=T",
__image_prompt__: "Thynk Unlimited logo - geometric green icon"
}).meta({
description: "Company logo icon",
}),
contactInfo: z.object({
telephone: z.string().min(10).max(20).default("+123-456-7890"),
address: z.string().min(10).max(50).default("123 Anywhere St., Any City, ST 12345"),
website: z.string().min(10).max(30).default("www.reallygreatsite.com")
}).default({
telephone: "+123-456-7890",
address: "123 Anywhere St., Any City, ST 12345",
website: "www.reallygreatsite.com"
}).meta({
description: "Company contact information",
}),
presentationDate: z.string()
.min(5)
.max(20)
.default("December 2023")
.meta({
description: "Date of the presentation",
}),
decorativeCircle: z.boolean()
.default(true)
.meta({
description: "Show decorative circle element",
}),
arrowButton: z.boolean()
.default(true)
.meta({
description: "Show navigation arrow button",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const ThynkTitleSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { companyName, mainTitle, subtitle, companyLogo, contactInfo, presentationDate, decorativeCircle, arrowButton } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Header with Logo and Arrow */}
<div className="absolute top-0 left-0 right-0 px-16 py-8 flex justify-between items-center z-20">
{/* Company Logo and Name */}
<div className="flex items-center space-x-3">
{companyLogo?.__image_url__ && (
<div className="w-10 h-10">
<img
src={companyLogo.__image_url__}
alt={companyLogo.__image_prompt__}
className="w-full h-full object-contain"
/>
</div>
)}
{companyName && (
<span className="text-2xl font-bold text-gray-900">
{companyName}
</span>
)}
</div>
{/* Arrow Button */}
{arrowButton && (
<div className="w-12 h-12 bg-teal-600 rounded-full flex items-center justify-center">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</div>
)}
</div>
{/* Decorative Circle */}
{decorativeCircle && (
<div className="absolute top-20 right-16 w-96 h-96 bg-yellow-100 rounded-full opacity-60 z-10"></div>
)}
{/* Main Content */}
<div className="relative z-15 h-full flex flex-col justify-center px-16">
<div className="">
{/* Main Title */}
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-none tracking-tight mb-4">
{mainTitle}
</h1>
)}
{/* Subtitle with Circle Bullet */}
{subtitle && (
<div className="flex items-center space-x-4 mb-12">
<div className="w-4 h-4 bg-teal-600 rounded-full"></div>
<h2 className="text-xl font-bold text-gray-800 tracking-wide">
{subtitle}
</h2>
</div>
)}
</div>
</div>
{/* Footer with Contact Info */}
<div className="absolute bottom-0 left-0 right-0 px-16 py-8 border-t-2 border-gray-300">
<div className="flex justify-between items-center text-gray-700">
<div className="flex space-x-16 text-sm">
{/* Telephone */}
{contactInfo?.telephone && (
<div>
<div className="font-semibold text-gray-900 mb-1">Telephone</div>
<div>{contactInfo.telephone}</div>
</div>
)}
{/* Address */}
{contactInfo?.address && (
<div>
<div className="font-semibold text-gray-900 mb-1">Address</div>
<div>{contactInfo.address}</div>
</div>
)}
{/* Website */}
{contactInfo?.website && (
<div>
<div className="font-semibold text-gray-900 mb-1">Website</div>
<div>{contactInfo.website}</div>
</div>
)}
</div>
{/* Presentation Date */}
{presentationDate && (
<div className="text-right">
<div className="text-lg font-bold text-gray-900">
{presentationDate}
</div>
</div>
)}
</div>
</div>
</div>
);
};
export default ThynkTitleSlide;

View file

@ -0,0 +1,159 @@
import * as z from "zod";
import { ImageSchema, IconSchema } from "../defaultSchemes";
// Schema definition
export const Schema = z.object({
mainTitle: z.string()
.min(5)
.max(15)
.default("WHAT WE BELIEVE")
.meta({
description: "Main title for the beliefs section",
}),
subtitle: z.string()
.min(10)
.max(30)
.default("ABOUT OUR VISION AND MISSION")
.meta({
description: "Subtitle describing the section",
}),
visionTitle: z.string()
.min(3)
.max(15)
.default("VISION")
.meta({
description: "Vision section title",
}),
visionText: z.string()
.min(50)
.max(300)
.default("Our vision is to be the catalyst for transformative marketing solutions that redefine industry standards. We envision a future where brands not only captivate their audience but also inspire meaningful connections.")
.meta({
description: "Vision statement text",
}),
missionTitle: z.string()
.min(3)
.max(15)
.default("MISSION")
.meta({
description: "Mission section title",
}),
missionText: z.string()
.min(50)
.max(400)
.default("Our mission is to deliver strategic and impactful marketing solutions that propel businesses to new heights of success. We are committed to leveraging our expertise in data-driven insights, creative storytelling, and cutting-edge technology to craft bespoke campaigns.")
.meta({
description: "Mission statement text",
}),
teamImage: ImageSchema.default({
__image_url__: "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
__image_prompt__: "Business team collaboration meeting with documents and discussion"
}).meta({
description: "Team collaboration image",
}),
showYellowAccent: z.boolean()
.default(true)
.meta({
description: "Show yellow accent block",
}),
})
// Type inference
type SchemaType = z.infer<typeof Schema>;
// Component definition
const WhatWeBelieveSlide = ({ data }: { data: Partial<SchemaType> }) => {
const { mainTitle, subtitle, visionTitle, visionText, missionTitle, missionText, teamImage, showYellowAccent } = data;
return (
<div className="aspect-video max-w-[1280px] w-full bg-white relative overflow-hidden">
{/* Main Content Area */}
<div className="h-full flex">
{/* Left Side - Image */}
<div className="w-1/2 relative">
{/* Team Image */}
{teamImage?.__image_url__ && (
<div className="absolute top-0 left-0 bottom-32 right-0">
<img
src={teamImage.__image_url__}
alt={teamImage.__image_prompt__}
className="w-full h-full object-cover"
/>
</div>
)}
{/* Yellow Accent Block - Bottom Left */}
{showYellowAccent && (
<div className="absolute bottom-0 left-0 w-32 h-32 bg-yellow-300 z-10"></div>
)}
{/* Teal Accent Block - Bottom */}
<div className="absolute bottom-0 left-32 right-0 h-32 bg-teal-600 z-10"></div>
</div>
{/* Right Side - Content */}
<div className="w-1/2 relative bg-white ">
<div className="px-16 py-12">
{/* Title Section */}
<div className="mb-8">
{mainTitle && (
<h1 className="text-4xl lg:text-5xl font-black text-teal-700 leading-tight mb-4">
{mainTitle}
</h1>
)}
{subtitle && (
<p className="text-base font-semibold text-gray-800 tracking-wide mb-8">
{subtitle}
</p>
)}
</div>
{/* Vision Section */}
<div className="mb-8">
{visionTitle && (
<h2 className="text-2xl font-bold text-teal-700 mb-4">
{visionTitle}
</h2>
)}
{visionText && (
<p className="text-base leading-relaxed text-gray-700">
{visionText}
</p>
)}
</div>
</div>
{/* Mission Section with Teal Background */}
<div className="bg-teal-600 p-6 absolute bottom-0 left-0 right-0 px-16 text-white">
{missionTitle && (
<h2 className="text-2xl font-bold mb-4">
{missionTitle}
</h2>
)}
{missionText && (
<p className="text-base leading-relaxed">
{missionText}
</p>
)}
</div>
</div>
</div>
</div>
);
};
export default WhatWeBelieveSlide;

View file

@ -0,0 +1,5 @@
{
"description": "This is a new pitch deck layout with a focus on simplicity and clarity.",
"ordered": false,
"isDefault": false
}