From 9e54c6bb9eb285b7221a0ae4722dc6c25b401625 Mon Sep 17 00:00:00 2001 From: shiva raj badu Date: Sun, 22 Feb 2026 19:16:16 +0545 Subject: [PATCH] feat: Outline and upload page design --- .../dashboard/components/Header.tsx | 10 +- .../components/HeaderNab.tsx | 4 +- .../outline/components/CustomTemplateCard.tsx | 131 +++++++++++++----- .../outline/components/OutlineContent.tsx | 3 +- .../outline/components/OutlinePage.tsx | 4 +- .../outline/components/TemplateSelection.tsx | 92 ++++++++---- .../upload/components/UploadPage.tsx | 4 +- .../(presentation-generator)/upload/page.tsx | 4 +- 8 files changed, 175 insertions(+), 77 deletions(-) diff --git a/servers/nextjs/app/(presentation-generator)/(dashboard)/dashboard/components/Header.tsx b/servers/nextjs/app/(presentation-generator)/(dashboard)/dashboard/components/Header.tsx index 4b763c3d..6cfda534 100644 --- a/servers/nextjs/app/(presentation-generator)/(dashboard)/dashboard/components/Header.tsx +++ b/servers/nextjs/app/(presentation-generator)/(dashboard)/dashboard/components/Header.tsx @@ -11,16 +11,16 @@ import { trackEvent, MixpanelEvent } from "@/utils/mixpanel"; const Header = () => { const pathname = usePathname(); return ( -
+
{(pathname !== "/upload" && pathname !== "/dashboard") && } trackEvent(MixpanelEvent.Navigation, { from: pathname, to: "/dashboard" })}> Presentation logo
@@ -29,7 +29,7 @@ const Header = () => { href="/custom-template" prefetch={false} onClick={() => trackEvent(MixpanelEvent.Navigation, { from: pathname, to: "/custom-template" })} - className="flex items-center gap-2 px-3 py-2 text-white hover:bg-primary/80 rounded-md transition-colors outline-none" + className="flex items-center gap-2 px-3 py-2 text-[#101323] rounded-md transition-colors outline-none" role="menuitem" > @@ -39,7 +39,7 @@ const Header = () => { href="/template-preview" prefetch={false} onClick={() => trackEvent(MixpanelEvent.Navigation, { from: pathname, to: "/template-preview" })} - className="flex items-center gap-2 px-3 py-2 text-white hover:bg-primary/80 rounded-md transition-colors outline-none" + className="flex items-center gap-2 px-3 py-2 text-[#101323] rounded-md transition-colors outline-none" role="menuitem" > diff --git a/servers/nextjs/app/(presentation-generator)/components/HeaderNab.tsx b/servers/nextjs/app/(presentation-generator)/components/HeaderNab.tsx index cb0f0338..09614d03 100644 --- a/servers/nextjs/app/(presentation-generator)/components/HeaderNab.tsx +++ b/servers/nextjs/app/(presentation-generator)/components/HeaderNab.tsx @@ -18,7 +18,7 @@ const HeaderNav = () => { trackEvent(MixpanelEvent.Navigation, { from: pathname, to: "/dashboard" })} > @@ -31,7 +31,7 @@ const HeaderNav = () => { trackEvent(MixpanelEvent.Navigation, { from: pathname, to: "/settings" })} > diff --git a/servers/nextjs/app/(presentation-generator)/outline/components/CustomTemplateCard.tsx b/servers/nextjs/app/(presentation-generator)/outline/components/CustomTemplateCard.tsx index dbd1c94a..4a5ac6fa 100644 --- a/servers/nextjs/app/(presentation-generator)/outline/components/CustomTemplateCard.tsx +++ b/servers/nextjs/app/(presentation-generator)/outline/components/CustomTemplateCard.tsx @@ -32,22 +32,76 @@ export const CustomTemplateCard = memo(({ template, onSelectTemplate, selectedTe const isSelected = selectedTemplate === template.id; return ( + // { + // onSelectTemplate(template.id); + // }} + // > + //
+ //
+ //

+ // {template.name} + //

+ + //
+ + + + // {/* Layout previews */} + //
+ // {customLoading ? ( + // // Loading placeholders + // [...Array(Math.min(4, template.layoutCount))].map((_, index) => ( + //
+ // + //
+ // )) + // ) : previewLayouts && previewLayouts?.length > 0 ? ( + // // Actual layout previews - using memoized component + // previewLayouts?.slice(0, 4).map((layout: CompiledLayout, index: number) => ( + // + // )) + // ) : ( + // // Empty state placeholders + // [...Array(Math.min(4, template.layoutCount))].map((_, index) => ( + //
+ // No preview + //
+ // )) + // )} + //
+ + + //
+ // {isSelected && ( + //
+ // Selected + //
+ // )} + //
{ - onSelectTemplate(template.id); - }} + className={`${isSelected ? 'border-2 border-blue-500' : ''} cursor-pointer flex flex-col justify-between relative hover:shadow-lg transition-all duration-200 group overflow-hidden`} + onClick={() => onSelectTemplate(template.id)} > + + + + Layouts- {template.layoutCount} +
-
-

- {template.name} -

- -
- - {/* Layout previews */}
@@ -61,36 +115,37 @@ export const CustomTemplateCard = memo(({ template, onSelectTemplate, selectedTe
)) - ) : previewLayouts && previewLayouts?.length > 0 ? ( - // Actual layout previews - using memoized component - previewLayouts?.slice(0, 4).map((layout: CompiledLayout, index: number) => ( - - )) - ) : ( - // Empty state placeholders - [...Array(Math.min(4, template.layoutCount))].map((_, index) => ( -
- No preview -
- )) + ) : previewLayouts.length > 0 && ( + // Actual layout previews + previewLayouts.slice(0, 4).map((layout: CompiledLayout, index: number) => { + const LayoutComponent = layout.component; + return ( +
+
+
+ +
+
+ ); + }) )}
- {isSelected && ( -
- Selected -
- )} +
+

+ {template.name} +

+ + +
); }); diff --git a/servers/nextjs/app/(presentation-generator)/outline/components/OutlineContent.tsx b/servers/nextjs/app/(presentation-generator)/outline/components/OutlineContent.tsx index 35544dd4..cbc7c40f 100644 --- a/servers/nextjs/app/(presentation-generator)/outline/components/OutlineContent.tsx +++ b/servers/nextjs/app/(presentation-generator)/outline/components/OutlineContent.tsx @@ -91,8 +91,9 @@ const OutlineContent: React.FC = ({ )} {/* Outlines content */} + {outlines && outlines.length > 0 && ( -
+
{ const { presentation_id, outlines } = useSelector( @@ -57,9 +58,10 @@ const OutlinePage: React.FC = () => { > Outline & Content + Select Template diff --git a/servers/nextjs/app/(presentation-generator)/outline/components/TemplateSelection.tsx b/servers/nextjs/app/(presentation-generator)/outline/components/TemplateSelection.tsx index 0edfd63d..5b5244c7 100644 --- a/servers/nextjs/app/(presentation-generator)/outline/components/TemplateSelection.tsx +++ b/servers/nextjs/app/(presentation-generator)/outline/components/TemplateSelection.tsx @@ -1,7 +1,8 @@ "use client"; import React, { useEffect } from "react"; -import { templates, TemplateLayoutsWithSettings } from "@/app/presentation-templates"; +import { templates } from "@/app/presentation-templates"; +import { TemplateLayoutsWithSettings } from "@/app/presentation-templates/utils"; import { Card } from "@/components/ui/card"; import { TemplateWithData } from "@/app/presentation-templates/utils"; import { CustomTemplates, useCustomTemplateSummaries } from "@/app/hooks/useCustomTemplates"; @@ -34,37 +35,26 @@ const TemplateSelection: React.FC = ({ const { templates: customTemplates, loading: customLoading } = useCustomTemplateSummaries(); - - - - return (
{/* In Built Templates */}

In Built Templates

-
+
{templates.map((template: TemplateLayoutsWithSettings) => { const previewLayouts = template.layouts.slice(0, 4); return ( onSelectTemplate(template)} > + + Layouts- {template.layouts.length} + +
-
-

- {template.name} -

- -
- -

- {template.description} -

-
{previewLayouts.map((layout: TemplateWithData, index: number) => { const LayoutComponent = layout.component; @@ -72,12 +62,11 @@ const TemplateSelection: React.FC = ({
@@ -86,12 +75,63 @@ const TemplateSelection: React.FC = ({ })}
- {typeof selectedTemplate !== 'string' && selectedTemplate?.id === template.id && ( -
- Selected +
+
+ +

+ {template.name} +

+

+ {template.description} +

- )} + +
+ // onSelectTemplate(template)} + // > + //
+ //
+ //

+ // {template.name} + //

+ + //
+ + //

+ // {template.description} + //

+ + //
+ // {previewLayouts.map((layout: TemplateWithData, index: number) => { + // const LayoutComponent = layout.component; + // return ( + //
+ //
+ //
+ // + //
+ //
+ // ); + // })} + //
+ //
+ // {typeof selectedTemplate !== 'string' && selectedTemplate?.id === template.id && ( + //
+ // Selected + //
+ // )} + // ); })}
@@ -115,7 +155,7 @@ const TemplateSelection: React.FC = ({

) : ( -
+
{customTemplates.map((template: CustomTemplates) => ( { }; return ( - + { onConfigChange={handleConfigChange} />
*/} -
+
{ return (
-
-

+
+

AI Presentation

Choose a design, set preferences, and generate polished slides.