feat(nextjs/dashboard): slide data rendered

This commit is contained in:
shiva raj badu 2025-07-12 19:03:48 +05:45
commit 94b8503843
11 changed files with 81 additions and 41 deletions

View file

@ -20,7 +20,7 @@ services:
- CUSTOM_LLM_API_KEY=${CUSTOM_LLM_API_KEY}
- CUSTOM_MODEL=${CUSTOM_MODEL}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- SQL_URL=${SQL_URL}
- DATABASE_URL=${DATABASE_URL}
production-gpu:
# image: ghcr.io/presenton/presenton:latest
@ -50,7 +50,7 @@ services:
- CUSTOM_LLM_API_KEY=${CUSTOM_LLM_API_KEY}
- CUSTOM_MODEL=${CUSTOM_MODEL}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- SQL_URL=${SQL_URL}
- DATABASE_URL=${DATABASE_URL}
development:
build:
@ -74,7 +74,7 @@ services:
- CUSTOM_LLM_API_KEY=${CUSTOM_LLM_API_KEY}
- CUSTOM_MODEL=${CUSTOM_MODEL}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- SQL_URL=${SQL_URL}
- DATABASE_URL=${DATABASE_URL}
development-gpu:
build:
@ -105,4 +105,4 @@ services:
- CUSTOM_LLM_API_KEY=${CUSTOM_LLM_API_KEY}
- CUSTOM_MODEL=${CUSTOM_MODEL}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- SQL_URL=${SQL_URL}
- DATABASE_URL=${DATABASE_URL}

View file

@ -144,8 +144,7 @@ class GeneratePresentationHandler(FetchAssetsOnPresentationGenerationMixin):
f"http://localhost/api/slide-metadata",
json={
"id": self.presentation_id,
# "theme": self.theme["name"],
# "customColors": self.theme["colors"],
},
) as response:
export_request_body = await response.json()
@ -153,6 +152,7 @@ class GeneratePresentationHandler(FetchAssetsOnPresentationGenerationMixin):
print("-" * 40)
print("Exporting Presentation")
export_request_body["presentation_id"] = self.presentation_id
print(export_request_body)
export_request = ExportAsRequest(**export_request_body)
presentation_and_path = await ExportAsPptxHandler(export_request).post(
@ -167,7 +167,7 @@ class GeneratePresentationHandler(FetchAssetsOnPresentationGenerationMixin):
async with session.post(
f"http://localhost/api/export-as-pdf",
json={
"url": f"http://localhost/pdf-maker?id={self.presentation_id}",
"id": self.presentation_id,
"title": presentation_content.title,
},
) as response:

View file

@ -1,5 +1,6 @@
from sqlmodel import select, exists
from api.models import LogMetadata
from api.routers.presentation.models import PresentationWithOneSlide
from api.services.logging import LoggingService
from api.sql_models import PresentationSqlModel, SlideSqlModel
from api.services.database import get_sql_session
@ -18,8 +19,19 @@ class GetPresentationsHandler:
)
)
).all()
presentations.sort(key=lambda x: x.created_at, reverse=True)
presentations_with_slide = []
for presentation in presentations:
slide = sql_session.exec(
select(SlideSqlModel)
.where(SlideSqlModel.presentation == presentation.id)
.where(SlideSqlModel.index == 0)
).first()
presentations_with_slide.append(
PresentationWithOneSlide.from_presentation_and_slide(
presentation, slide
)
)
logging_service.logger.info(
logging_service.message(
@ -27,4 +39,4 @@ class GetPresentationsHandler:
),
extra=log_metadata.model_dump(),
)
return presentations
return presentations_with_slide

View file

@ -0,0 +1,14 @@
from typing import Optional
from api.services.logging import LoggingService
from api.models import LogMetadata
from api.utils.model_utils import list_available_custom_models
class ListAvailableCustomModelsHandler:
def __init__(self, url: Optional[str] = None, api_key: Optional[str] = None):
self.url = url
self.api_key = api_key
async def get(self, logging_service: LoggingService, log_metadata: LogMetadata):
return await list_available_custom_models(self.url, self.api_key)

View file

@ -177,3 +177,23 @@ class OllamaModelStatusResponse(BaseModel):
class OllamaSupportedModelsResponse(BaseModel):
models: List[OllamaModelMetadata]
class PresentationWithOneSlide(BaseModel):
id: str
created_at: datetime
theme: Optional[dict] = None
title: Optional[str] = None
slide: SlideSqlModel
@classmethod
def from_presentation_and_slide(
cls, presentation: PresentationSqlModel, slide: SlideSqlModel
):
return cls(
id=presentation.id,
created_at=presentation.created_at,
theme=presentation.theme,
title=presentation.title,
slide=slide,
)

View file

@ -1,7 +1,6 @@
from typing import Annotated, List, Optional
import uuid
from fastapi import APIRouter, BackgroundTasks, Body, File, Form, UploadFile
import openai
from api.models import SessionModel
from api.request_utils import RequestUtils
@ -35,6 +34,9 @@ from api.routers.presentation.handlers.generate_outlines import (
)
from api.routers.presentation.handlers.get_presentation import GetPresentationHandler
from api.routers.presentation.handlers.get_presentations import GetPresentationsHandler
from api.routers.presentation.handlers.list_available_custom_models import (
ListAvailableCustomModelsHandler,
)
from api.routers.presentation.handlers.list_ollama_pulled_models import (
ListPulledOllamaModelsHandler,
)
@ -80,13 +82,10 @@ from api.routers.presentation.models import (
SearchImageRequest,
UpdatePresentationThemeRequest,
PresentationUpdateRequest,
PresentationWithOneSlide,
)
from api.sql_models import PresentationSqlModel
from api.utils.model_utils import get_llm_client, list_available_custom_models
from api.utils.utils import handle_errors
from image_processor.images_finder import (
generate_image_google,
)
from ppt_generator.models.slide_model import SlideModel
route_prefix = "/api/v1/ppt"
@ -94,7 +93,7 @@ presentation_router = APIRouter(prefix=route_prefix)
@presentation_router.get(
"/user_presentations", response_model=List[PresentationSqlModel]
"/user_presentations", response_model=List[PresentationWithOneSlide]
)
async def get_user_presentations():
request_utils = RequestUtils(f"{route_prefix}/user_presentations")
@ -398,4 +397,10 @@ async def list_custom_models(
url: Annotated[Optional[str], Body()] = None,
api_key: Annotated[Optional[str], Body()] = None,
):
return await list_available_custom_models(url, api_key)
request_utils = RequestUtils(f"{route_prefix}/models/list/custom")
logging_service, log_metadata = await request_utils.initialize_logger()
return await handle_errors(
ListAvailableCustomModelsHandler(url, api_key).get,
logging_service,
log_metadata,
)

View file

@ -4,14 +4,14 @@ from sqlalchemy import create_engine
from sqlmodel import Session
sql_url = os.getenv("SQL_URL") or "sqlite:///" + os.path.join(
database_url = os.getenv("DATABASE_URL") or "sqlite:///" + os.path.join(
os.getenv("APP_DATA_DIRECTORY"), "fastapi.db"
)
connect_args = {}
if "sqlite" in sql_url:
if "sqlite" in database_url:
connect_args["check_same_thread"] = False
sql_engine = create_engine(sql_url, connect_args=connect_args)
sql_engine = create_engine(database_url, connect_args=connect_args)
@contextmanager

View file

@ -14,12 +14,13 @@ export interface PresentationResponse {
n_slides: number;
prompt: string;
summary: string | null;
theme: string;
titles: string[];
user_id: string;
vector_store: any;
theme: string;
titles: string[];
user_id: string;
vector_store: any;
thumbnail: string;
thumbnail: string;
slide: any;
}
export class DashboardApi {

View file

@ -35,6 +35,7 @@ const DashboardPage: React.FC = () => {
}
};
return (
<div className="min-h-screen bg-[#E9E8F8]">
<Header />

View file

@ -18,12 +18,14 @@ export const PresentationCard = ({
created_at,
thumbnail,
theme,
slide
}: {
id: string;
title: string;
created_at: string;
thumbnail: string;
theme: any;
slide: any
}) => {
const router = useRouter();
@ -127,23 +129,7 @@ export const PresentationCard = ({
>
<div className="absolute bg-transparent z-40 top-0 left-0 w-full h-full" />
<div className="transform scale-[0.2] flex justify-center items-center origin-top-left w-[500%] h-[500%]">
{renderSlideContent({
id: 'mock-slide-1',
type: 1,
index: 0,
design_index: 1,
properties: null,
images: ['/static/user_data/ee7cb066-86d0-45fc-adc9-15bf565eab30/images/af54ed41-483e-4983-aef0-b254aac48408.jpg'],
icons: [],
graph_id: null,
presentation: id,
content: {
title: title || 'Sample Presentation',
body: "This is a sample slide description to demonstrate the layout and styling. The content here helps visualize how actual presentation content would appear.",
infographics: [],
image_prompts: ['Sample image showing business growth']
},
}, 'English')}
{renderSlideContent(slide, 'English')}
</div>
</div>

View file

@ -103,6 +103,7 @@ export const PresentationGrid = ({
key={presentation.id}
{...presentation}
theme={presentation.theme}
slide={presentation.slide}
/>
))}