feat: update slide layouts with improved descriptions and schema validations

This commit is contained in:
sudipnext 2025-07-25 17:21:32 +05:45
parent ec398bbbee
commit 395914106e
11 changed files with 136 additions and 81 deletions

View file

@ -4,13 +4,13 @@ import * as z from "zod";
export const layoutId = "intro-pitchdeck-slide";
export const layoutName = "Intro Pitch Deck Slide";
export const layoutDescription =
"A visually appealing introduction slide for a pitch deck, featuring a large title, company name, date, and contact information with a modern design.";
"A visually appealing introduction slide for a pitch deck, featuring a large title, company name, date, and contact information with a modern design. This Slide is always the first slide in a pitch deck, setting the tone for the presentation with a clean and professional look.";
const introPitchDeckSchema = z.object({
title: z.string().min(2).max(15).default("Pitch Deck").meta({
description: "Main title of the slide",
}),
description: z.string().default("").meta({
description: "Empty description as per the design",
description: "Description as per the design",
}),
contactNumber: z.string().default("+123-456-7890").meta({
description: "Contact phone number displayed in footer",
@ -42,7 +42,15 @@ interface IntroSlideLayoutProps {
const IntroPitchDeckSlide: React.FC<IntroSlideLayoutProps> = ({
data: slideData,
}) => {
const { title, description, contactNumber, contactAddress, contactWebsite, companyName, date } = slideData;
const {
title,
description,
contactNumber,
contactAddress,
contactWebsite,
companyName,
date,
} = slideData;
return (
<>
{/* Montserrat Font */}
@ -72,43 +80,53 @@ const IntroPitchDeckSlide: React.FC<IntroSlideLayoutProps> = ({
transform: "translateY(-50%)",
}}
>
{title && <div className="relative inline-block">
<h1
className="text-7xl font-bold text-[#1E4CD9] leading-none"
id="pitchdeck-title"
>
{title}
</h1>
{/* Blue underline */}
<span
className="block bg-[#1E4CD9] h-[4px] absolute left-0"
style={{
width: "100%",
bottom: "-0.5em",
transition: "width 0.3s",
}}
/>
</div>}
{title && (
<div className="relative inline-block">
<h1
className="text-7xl font-bold text-[#1E4CD9] leading-none"
id="pitchdeck-title"
>
{title}
</h1>
{/* Blue underline */}
<span
className="block bg-[#1E4CD9] h-[4px] absolute left-0"
style={{
width: "100%",
bottom: "-0.5em",
transition: "width 0.3s",
}}
/>
</div>
)}
</div>
{/* Bottom Contact Row */}
<div className="absolute bottom-8 left-10 right-10 flex flex-wrap items-center gap-10 text-[#1E4CD9] text-sm font-medium">
{contactNumber && <div className="flex items-center gap-2">
<span className="text-lg">📞</span>
<span>{contactNumber}</span>
</div>}
{contactAddress && <div className="flex items-center gap-2">
<span className="text-lg">📍</span>
<span>{contactAddress}</span>
</div>}
{contactWebsite && <div className="flex items-center gap-2">
<span className="text-lg">🌐</span>
<span>{contactWebsite}</span>
</div>}
{description && <div className="flex items-center gap-2">
<span className="text-lg">💬</span>
<span>{description}</span>
</div>}
{contactNumber && (
<div className="flex items-center gap-2">
<span className="text-lg">📞</span>
<span>{contactNumber}</span>
</div>
)}
{contactAddress && (
<div className="flex items-center gap-2">
<span className="text-lg">📍</span>
<span>{contactAddress}</span>
</div>
)}
{contactWebsite && (
<div className="flex items-center gap-2">
<span className="text-lg">🌐</span>
<span>{contactWebsite}</span>
</div>
)}
{description && (
<div className="flex items-center gap-2">
<span className="text-lg">💬</span>
<span>{description}</span>
</div>
)}
</div>
</div>
</>

View file

@ -25,7 +25,7 @@ const aboutCompanySlideSchema = z.object({
description: "Company name displayed in header",
}),
date: z.string().min(5).max(30).default("June 13, 2038").meta({
description: "Date displayed in header",
description: "Today Date displayed in header",
}),
image: ImageSchema.optional().meta({
description:

View file

@ -83,11 +83,11 @@ const problemStatementSlideSchema = z.object({
description:
"List of problem categories with titles, descriptions, and optional icons",
}),
companyName: z.string().min(2).max(50).default("Rimberio").meta({
companyName: z.string().min(2).max(50).default("presenton").meta({
description: "Company name displayed in header",
}),
date: z.string().min(5).max(30).default("June 13, 2038").meta({
description: "Date displayed in header",
description: "Today Date displayed in header",
}),
});

View file

@ -11,8 +11,8 @@ const solutionSlideSchema = z.object({
companyName: z.string().min(2).max(50).default("presenton").meta({
description: "Company name displayed in header",
}),
date: z.string().min(5).max(50).default("June 13, 2038").meta({
description: "Date displayed in header",
date: z.string().min(5).max(30).default("June 13, 2038").meta({
description: "Today Date displayed in header",
}),
title: z.string().min(3).max(25).default("Businesses struggle").meta({
description: "Main title of the slide",
@ -46,7 +46,8 @@ const solutionSlideSchema = z.object({
.default([
{
title: "Market",
description: "Innovative and widely accepted. Innovative and widely accepted. Innovative and widely accepted.",
description:
"Innovative and widely accepted. Innovative and widely accepted. Innovative and widely accepted.",
icon: {
__icon_query__: "market innovation",
__icon_url__:

View file

@ -12,7 +12,7 @@ const productOverviewSlideSchema = z.object({
description: "Company name displayed in header",
}),
date: z.string().min(5).max(50).default("June 13, 2038").meta({
description: "Date displayed in header",
description: "Today Date displayed in header",
}),
title: z.string().min(3).max(40).default("Product Overview").meta({
description: "Main title of the slide",

View file

@ -11,11 +11,11 @@ const marketSizeSlideSchema = z.object({
title: z.string().min(3).max(15).default("Market Size").meta({
description: "Main slide title",
}),
companyName: z.string().min(3).max(30).default("Rimberio").meta({
description: "Presenter's name",
companyName: z.string().min(2).max(50).default("presenton").meta({
description: "Company name displayed in header",
}),
date: z.string().default("June 13, 2038").meta({
description: "Presentation date",
date: z.string().min(5).max(50).default("June 13, 2038").meta({
description: "Today Date displayed in header",
}),
mapImage: ImageSchema.default({
__image_url__:
@ -51,7 +51,11 @@ const marketSizeSlideSchema = z.object({
description:
"The SOM is a smaller fraction of the SAM that is the target of a serviceable and realistically achievable market in the short to medium term.",
},
]),
])
.meta({
description:
"Market statistics including TAM, SAM, and SOM with labels, values, and descriptions.",
}),
description: z
.string()
.default(

View file

@ -14,10 +14,10 @@ export const layoutDescription =
// Make the schema generic: allow any label/value pairs for comparison
const marketValidationSchema = z.object({
companyName: z.string().min(2).max(50).default("presenton").meta({
description: "Company name in header",
description: "Company name displayed in header",
}),
date: z.string().min(5).max(50).default("June 13, 2038").meta({
description: "Date in header",
description: "Today Date displayed in header",
}),
title: z.string().min(3).max(20).default("Market Validation").meta({
description: "Title of the slide",
@ -58,7 +58,8 @@ const marketValidationSchema = z.object({
{ label: "Liceria & Co.", metricLabel: "Revenue ($K)", value: 1010 },
])
.meta({
description: "Market benchmark data (generic metric)",
description:
"Comparison data for market validation, allowing flexible labels and values",
}),
image: ImageSchema.optional().meta({
description: "Optional decorative image",

View file

@ -16,24 +16,38 @@ export const layoutName = "Company Traction Slide";
export const layoutDescription =
"A slide layout designed to present company traction data, including growth statistics over the years, a chart visualization, and key metrics in a visually appealing format.";
const growthStatsSchema = z.object({
year: z.string(),
})
.catchall(z.number());
const growthStatsSchema = z
.object({
year: z.string(),
})
.catchall(z.number())
.meta({
description:
"Growth statistics for a specific year, with any number of metrics as key-value pairs where keys are metric names and values are numbers.",
});
// growthStats: list of dicts, each dict is { year: string, <metric1>: number, <metric2>: number, ... }
const tractionSchema = z.object({
companyName: z.string().default("presention"),
date: z.string().default("June 13, 2038"),
title: z.string().default("Company Traction"),
companyName: z.string().min(2).max(50).default("presenton").meta({
description: "Company name displayed in header",
}),
date: z.string().min(5).max(50).default("June 13, 2038").meta({
description: "Today Date displayed in header",
}),
title: z.string().default("Company Traction").meta({
description: "Main title of the slide",
}),
description: z
.string()
.min(3)
.max(200)
.default(
"Traction is a period where the company is feeling momentum during its development period. If traction momentum is not harnessed, sales figures can decline and the customer base can shrink. In general, companies will judge success by the amount of revenue and new customers they receive.",
),
)
.meta({
description:
"Main content text describing the company's traction and growth momentum.",
}),
// growthStats is a list of objects, each with a 'year' and any number of metric keys (all numbers)
growthStats: z
.array(growthStatsSchema)
@ -88,7 +102,11 @@ const tractionSchema = z.object({
internetOfThings: 65,
others: 52,
}),
]),
])
.meta({
description:
"Growth statistics for the company, used for chart visualization. Each entry is an object representing a specific year, with the 'year' key as a string (e.g., '2020'), and additional keys for each metric (such as 'artificialIntelligence', 'internetOfThings', 'others'), where the values are numbers representing the metric's value for that year. Example:\n\n[\n { year: '2020', artificialIntelligence: 5, internetOfThings: 10, others: 8 },\n { year: '2021', artificialIntelligence: 10, internetOfThings: 20, others: 15 },\n ...\n]\nThis structure allows the chart to dynamically render multiple series over time, with each metric visualized as a separate line.",
}),
});
export const Schema = tractionSchema;

View file

@ -17,14 +17,22 @@ export const layoutDescription =
"A business model presentation slide displaying CAC metrics and monetization strategy.";
const businessModelSchema = z.object({
companyName: z.string().default("presenton"),
date: z.string().default("June 13, 2038"),
companyName: z.string().min(2).max(50).default("presenton").meta({
description: "Company name displayed in header",
}),
date: z.string().min(5).max(50).default("June 13, 2038").meta({
description: "Today Date displayed in header",
}),
title: z.string().min(3).max(20).default("Business Model"),
description: z
.string()
.default(
"Describe how you monetize, who your customers are, your distribution channels or fee structure. The goal is to give an idea of how this business will sustain your product or service and explain how your company will make money and achieve its goals. This can be shown with graphs, statistics, or charts. Use the Lifetime Value (LTV) and Customer Acquisition Cost (CAC) metrics to provide a clearer picture.",
),
)
.meta({
description:
"Description of the business model, monetization strategy, and customer acquisition costs.",
}),
cacChart: z
.array(
z.object({
@ -32,10 +40,19 @@ const businessModelSchema = z.object({
percentage: z.number().min(0).max(100),
}),
)
.min(2)
.max(5)
.default([
{ label: "Internet of Things", percentage: 70 },
{ label: "Artificial Intelligence", percentage: 60 },
]),
{ label: "Blockchain", percentage: 50 },
{ label: "Cloud Computing", percentage: 40 },
{ label: "Cybersecurity", percentage: 30 },
])
.meta({
description:
"Array of objects representing Customer Acquisition Cost (CAC) metrics for different business segments or channels. Each object should include a 'label' (the name of the segment or channel) and a 'percentage' (the CAC as a percentage value, from 0 to 100). This data is visualized in the bar chart to illustrate the distribution of CAC across various categories.",
}),
});
export const Schema = businessModelSchema;
@ -50,9 +67,9 @@ const BusinessModelSlide: React.FC<Props> = ({ data }) => {
data?.cacChart && Array.isArray(data.cacChart) && data.cacChart.length > 0
? data.cacChart
: [
{ label: "Internet of Things", percentage: 70 },
{ label: "Artificial Intelligence", percentage: 60 },
];
{ label: "Internet of Things", percentage: 70 },
{ label: "Artificial Intelligence", percentage: 60 },
];
return (
<>

View file

@ -83,11 +83,11 @@ const modernTeamSlideSchema = z.object({
.meta({
description: "List of team members with their information",
}),
companyName: z.string().default("presenton").meta({
description: "Company name to display in the header",
companyName: z.string().min(2).max(50).default("presenton").meta({
description: "Company name displayed in header",
}),
date: z.string().default("June 13, 2038").meta({
description: "Date to display in the header",
date: z.string().min(5).max(50).default("June 13, 2038").meta({
description: "Today Date displayed in header",
}),
});

View file

@ -4,7 +4,7 @@ import * as z from "zod";
export const layoutId = "thank-you-slide";
export const layoutName = "Thank You Slide";
export const layoutDescription =
"A simple, plain thank you slide for closing presentations.";
"A simple, plain thank you slide for closing presentations. This is always the last slide in a presentation, providing a clean and professional closing message with company contact information.";
const thankYouSlideSchema = z.object({
title: z.string().min(3).max(30).default("Thank You!").meta({
@ -13,11 +13,11 @@ const thankYouSlideSchema = z.object({
subtitle: z.string().min(0).max(100).default("").meta({
description: "Optional subtitle or closing remark",
}),
companyName: z.string().min(2).max(30).default("Rimberio").meta({
companyName: z.string().min(2).max(50).default("presenton").meta({
description: "Company name displayed in header",
}),
date: z.string().min(5).max(30).default("June 13, 2038").meta({
description: "Date displayed in header",
date: z.string().min(5).max(50).default("June 13, 2038").meta({
description: "Today Date displayed in header",
}),
address: z
.string()
@ -72,10 +72,7 @@ const ThankYouSlideLayout: React.FC<ThankYouSlideLayoutProps> = ({ data }) => {
<div className="flex flex-1 flex-col px-16 pb-16 justify-between">
{/* Thank You and description */}
<div className="flex flex-col items-start w-full pt-16">
<h1
className="font-bold text-8xl text-white mb-6 mt-8 text-left w-full"
>
<h1 className="font-bold text-8xl text-white mb-6 mt-8 text-left w-full">
{data?.title || "Thank You!"}
</h1>
{data?.subtitle && (
@ -83,7 +80,6 @@ const ThankYouSlideLayout: React.FC<ThankYouSlideLayoutProps> = ({ data }) => {
{data.subtitle}
</div>
)}
</div>
{/* Footer area */}