feat(Nextjs): Stream scroll in outline stream
This commit is contained in:
parent
e6b69229e3
commit
f4775fecc1
6 changed files with 26 additions and 9 deletions
|
|
@ -6,6 +6,7 @@ import { useDispatch, useSelector } from "react-redux"
|
|||
import { deleteSlideOutline, setOutlines, SlideOutline } from "@/store/slices/presentationGeneration"
|
||||
import ToolTip from "@/components/ToolTip"
|
||||
import MarkdownEditor from "../../components/MarkdownEditor"
|
||||
import { useEffect } from "react"
|
||||
|
||||
|
||||
interface OutlineItemProps {
|
||||
|
|
@ -24,6 +25,19 @@ export function OutlineItem({
|
|||
} = useSelector((state: RootState) => state.presentationGeneration);
|
||||
const dispatch = useDispatch()
|
||||
|
||||
useEffect(() => {
|
||||
if (isStreaming && slideOutline.body) {
|
||||
const outlineItem = document.getElementById(`outline-item-${index}`);
|
||||
if (outlineItem) {
|
||||
outlineItem.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "center",
|
||||
inline: "nearest",
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [outlines.length]);
|
||||
|
||||
const handleSlideChange = (newOutline: SlideOutline) => {
|
||||
if (isStreaming) return;
|
||||
const newData = outlines?.map((each, idx) => {
|
||||
|
|
@ -60,6 +74,8 @@ export function OutlineItem({
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="mb-2 bg-[#F9F9F9]">
|
||||
{/* Main Title Row */}
|
||||
|
|
@ -84,7 +100,7 @@ export function OutlineItem({
|
|||
</div>
|
||||
|
||||
{/* Main Title Input - Add onFocus handler */}
|
||||
<div className="flex flex-col basis-full gap-2">
|
||||
<div id={`outline-item-${index}`} className="flex flex-col basis-full gap-2">
|
||||
<input
|
||||
type="text"
|
||||
value={slideOutline.title || ''}
|
||||
|
|
|
|||
|
|
@ -242,12 +242,15 @@ const OutlinePage = () => {
|
|||
if (!presentation_id) {
|
||||
return (
|
||||
<Wrapper>
|
||||
<div className="max-w-[1000px] mx-auto px-4 sm:px-6 pb-6">
|
||||
<div className="max-w-[1000px] min-h-screen flex justify-center items-center mx-auto px-4 sm:px-6 pb-6">
|
||||
<div className="mt-4 sm:mt-8 font-instrument_sans text-center">
|
||||
<h4 className="text-lg sm:text-xl font-medium mb-4">
|
||||
No Presentation ID Found
|
||||
</h4>
|
||||
<p className="text-gray-600">Please start a new presentation.</p>
|
||||
<p className="text-gray-600 mb-4">Please start a new presentation.</p>
|
||||
<Button onClick={() => router.push("/upload")} className="bg-[#5146E5] w-full rounded-xl text-base sm:text-lg py-4 sm:py-6 transition-all duration-300 font-roboto font-semibold hover:bg-[#5146E5]/80 text-white mt-4 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
Start New Presentation
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Wrapper>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import NewSlide from "../../components/slide_layouts/NewSlide";
|
|||
import { getEmptySlideContent } from "../../utils/NewSlideContent";
|
||||
import useLayoutSchema from "../../hooks/useLayoutSchema";
|
||||
import dynamic from "next/dynamic";
|
||||
import FirstSlideLayout from "@/components/layouts/FirstSlideLayout";
|
||||
|
||||
interface SlideContentProps {
|
||||
slide: Slide;
|
||||
|
|
@ -117,7 +116,7 @@ const SlideContent = ({
|
|||
|
||||
const renderLayout = (slide: any) => {
|
||||
const layoutName = idMapFileNames[slide.layoutId];
|
||||
const Layout = dynamic(() => import(`@/components/layouts/${layoutName}.tsx`));
|
||||
const Layout = dynamic(() => import(`@/components/layouts/${layoutName}`)) as React.ComponentType<{ data: any }>;
|
||||
return <Layout data={slide.content} />
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ const bulletPointSlideSchema = z.object({
|
|||
})
|
||||
export const Schema = bulletPointSlideSchema
|
||||
|
||||
console.log(z.toJSONSchema(Schema))
|
||||
|
||||
export type BulletPointSlideData = z.infer<typeof bulletPointSlideSchema>
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const conclusionSlideSchema = z.object({
|
|||
description: "Optional call to action or next steps",
|
||||
}),
|
||||
contactInfo: z.object({
|
||||
email: z.string().email().optional().meta({
|
||||
email: z.email().optional().meta({
|
||||
description: "Contact email",
|
||||
}),
|
||||
phone: z.string().min(5).max(50).optional().meta({
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ const teamSlideSchema = z.object({
|
|||
bio: z.string().min(10).max(300).optional().meta({
|
||||
description: "Brief biography or description",
|
||||
}),
|
||||
email: z.email().optional().meta({
|
||||
email: z.string().email().optional().meta({
|
||||
description: "Contact email",
|
||||
}),
|
||||
linkedin: z.url().optional().meta({
|
||||
linkedin: z.string().url().optional().meta({
|
||||
description: "LinkedIn profile URL",
|
||||
})
|
||||
})).min(1).max(6).default([
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue