Merge pull request #106 from presenton/feat/hot_reload_layout_preview

feat/hot reload layout preview
This commit is contained in:
Shiva Raj Badu 2025-07-20 20:33:24 +05:45 committed by GitHub
commit ac3cdeee2c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 34 additions and 23 deletions

View file

@ -16,6 +16,10 @@ http {
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1; # Required for WebSocket
proxy_set_header Upgrade $http_upgrade; # WebSocket header
proxy_set_header Connection "upgrade"; # WebSocket header
proxy_set_header Host $host;
proxy_read_timeout 30m;
proxy_connect_timeout 30m;
}

View file

@ -1,5 +1,5 @@
"use client";
import { LayoutDashboard, Settings } from "lucide-react";
import { LayoutDashboard, Settings, Upload } from "lucide-react";
import React from "react";
import Link from "next/link";
import { RootState } from "@/store/store";
@ -11,6 +11,7 @@ const HeaderNav = () => {
return (
<div className="flex items-center gap-2">
<Link
href="/dashboard"
prefetch={false}

View file

@ -21,11 +21,11 @@ export default function MarkdownEditor({ content, onChange }: { content: string;
});
// Update editor content when the content prop changes (for streaming)
useEffect(() => {
if (editor && content !== editor.storage.markdown.getMarkdown()) {
editor.commands.setContent(content);
}
}, [content, editor]);
// useEffect(() => {
// if (editor && content !== editor.storage.markdown.getMarkdown()) {
// editor.commands.setContent(content);
// }
// }, [content, editor]);
return (
<div className="relative">

View file

@ -66,16 +66,11 @@ export function OutlineItem({
transform: CSS.Transform.toString(transform),
transition,
}
const handleSlideDelete = () => {
if (isStreaming) return;
dispatch(deleteSlideOutline({ index: index - 1 }))
}
return (
<div className="mb-2 bg-[#F9F9F9]">
{/* Main Title Row */}

View file

@ -43,7 +43,7 @@ const page = () => {
<div className='relative'>
<Header />
<div className='flex flex-col items-center justify-center py-8'>
<h1 className='text-3xl font-semibold font-instrument_sans'>Create Presentation </h1>
<h1 className='text-3xl font-semibold font-instrument_sans'>Create Presentation </h1>
{/* <p className='text-sm text-gray-500'>We will generate a presentation for you</p> */}
</div>

View file

@ -3,7 +3,6 @@ import { promises as fs } from 'fs'
import path from 'path'
import { GroupSetting } from '@/app/layout-preview/types'
export async function GET() {
try {
// Get the path to the presentation-layouts directory

View file

@ -5,7 +5,7 @@ import { useGroupLayoutLoader } from '../hooks/useGroupLayoutLoader'
import LoadingStates from '../components/LoadingStates'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { ArrowLeft, Home } from 'lucide-react'
import { ArrowLeft, Home, Wifi, WifiOff, RefreshCw } from 'lucide-react'
const GroupLayoutPreview = () => {
const params = useParams()
@ -63,6 +63,7 @@ const GroupLayoutPreview = () => {
<p className="text-gray-600 mt-2">
{layoutGroup.layouts.length} layout{layoutGroup.layouts.length !== 1 ? 's' : ''} {layoutGroup.settings.description}
</p>
</div>
</div>
</header>

View file

@ -5,7 +5,7 @@ import { useLayoutLoader } from './hooks/useLayoutLoader'
import LoadingStates from './components/LoadingStates'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { ExternalLink } from 'lucide-react'
import { ExternalLink, Wifi, WifiOff, RefreshCw } from 'lucide-react'
const LayoutPreview = () => {
const { layoutGroups, layouts, loading, error, retry } = useLayoutLoader()
@ -35,6 +35,7 @@ const LayoutPreview = () => {
<p className="text-gray-600 mt-2">
{layoutGroups.length} groups {layouts.length} layouts
</p>
</div>
</div>

View file

@ -1,6 +1,14 @@
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: false,
images: {
remotePatterns: [

View file

@ -7,9 +7,8 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"get:version": "next --version"
},
"lint": "next lint"
},
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
@ -38,9 +37,11 @@
"@tiptap/extension-underline": "^2.0.0",
"@tiptap/react": "^2.11.5",
"@tiptap/starter-kit": "^2.11.5",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"jsonrepair": "^3.12.0",
"lucide-react": "^0.447.0",
"marked": "^15.0.11",
@ -56,6 +57,7 @@
"tailwind-scrollbar-hide": "^2.0.0",
"tailwindcss-animate": "^1.0.7",
"tiptap-markdown": "^0.8.10",
"ws": "^8.18.0",
"uuid": "^11.1.0",
"zod": "^4.0.5"
},
@ -66,6 +68,7 @@
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/uuid": "^10.0.0",
"@types/ws": "^8.5.13",
"cypress": "^14.3.3",
"tailwindcss": "^3.4.1",
"typescript": "^5"

View file

@ -7,10 +7,10 @@ export const layoutName = 'Type1 Slide'
export const layoutDescription = 'A clean two-column layout with title and description on the left and a featured image on the right.'
const type1SlideSchema = z.object({
title: z.string().min(3).max(100).default('Sample Title').meta({
title: z.string().min(3).max(100).default('Hot NOT Reload Working!').meta({
description: "Main title of the slide",
}),
description: z.string().min(10).max(500).default('Your description content goes here. This layout provides a clean and professional way to present content with supporting imagery.').meta({
description: z.string().min(10).max(500).default('This is a test of the hot reload system! If you can see this text, hot reload is working perfectly. Changes should appear instantly without page refresh.').meta({
description: "Main description text",
}),
image: ImageSchema.default({
@ -30,7 +30,6 @@ interface Type1SlideLayoutProps {
}
const Type1SlideLayout: React.FC<Type1SlideLayoutProps> = ({ data: slideData }) => {
return (
<div
className=" w-full rounded-sm max-w-[1280px] shadow-lg px-3 sm:px-12 lg:px-20 py-[10px] sm:py-[40px] lg:py-[86px] max-h-[720px] flex items-center aspect-video bg-white relative z-20 mx-auto"
@ -40,12 +39,12 @@ const Type1SlideLayout: React.FC<Type1SlideLayoutProps> = ({ data: slideData })
<div className="flex flex-col w-full items-start justify-center space-y-1 md:space-y-2 lg:space-y-6">
{/* Title */}
<h1 className="text-2xl sm:text-3xl lg:text-4xl xl:text-5xl font-bold text-gray-900 leading-tight">
{slideData?.title || 'Sample Title'}
nice {slideData?.title || ' This is the title of slide'}
</h1>
{/* Description */}
<p className="text-base sm:text-lg lg:text-xl text-gray-700 leading-relaxed">
{slideData?.description || 'Your description content goes here. This layout provides a clean and professional way to present content with supporting imagery.'}
{slideData?.description || 'This is a test of the hot reload system! If you can see this text, hot reload is working perfectly. Changes should appear instantly without page refresh.'}
</p>
</div>