feat(Nextjs): Custom Layout delete endpoint & ui implemented
This commit is contained in:
parent
d9a46fdff3
commit
8495d2b8d1
5 changed files with 63 additions and 7 deletions
|
|
@ -73,6 +73,11 @@ class GetLayoutsResponse(BaseModel):
|
|||
message: Optional[str] = None
|
||||
|
||||
|
||||
class DeleteLayoutResponse(BaseModel):
|
||||
success: bool
|
||||
message: Optional[str] = None
|
||||
|
||||
|
||||
class PresentationSummary(BaseModel):
|
||||
presentation_id: str
|
||||
layout_count: int
|
||||
|
|
@ -917,4 +922,40 @@ async def get_presentations_summary(
|
|||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Internal server error while retrieving presentations summary: {str(e)}"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
# ENDPOINT : Delete a layout
|
||||
@LAYOUT_MANAGEMENT_ROUTER.delete(
|
||||
"/delete-layouts/{presentation_id}",
|
||||
response_model=DeleteLayoutResponse,
|
||||
responses={
|
||||
200: {"model": DeleteLayoutResponse, "description": "Layout deleted successfully"},
|
||||
404: {"model": ErrorResponse, "description": "Presentation Layouts not found"},
|
||||
500: {"model": ErrorResponse, "description": "Internal server error"}
|
||||
}
|
||||
)
|
||||
async def delete_layouts(presentation_id: str, session: AsyncSession = Depends(get_async_session)):
|
||||
try:
|
||||
# Validate presentation_id format (basic UUID check)
|
||||
if not presentation_id or len(presentation_id.strip()) == 0:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Presentation ID cannot be empty"
|
||||
)
|
||||
# Delete Presentation with all layouts
|
||||
await session.execute(delete(PresentationLayoutCodeModel).where(PresentationLayoutCodeModel.presentation_id == presentation_id))
|
||||
await session.commit()
|
||||
return DeleteLayoutResponse(
|
||||
success=True,
|
||||
message=f"Successfully deleted layout(s) for presentation {presentation_id}"
|
||||
)
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
print(f"Error deleting layouts for presentation {presentation_id}: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Internal server error while deleting layouts: {str(e)}"
|
||||
)
|
||||
Binary file not shown.
|
|
@ -275,7 +275,7 @@ const ImageEditor = ({
|
|||
</TabsTrigger>
|
||||
</TabsList>
|
||||
{/* Generate Tab */}
|
||||
<TabsContent value="generate" className="mt-4 space-y-4">
|
||||
<TabsContent value="generate" className="mt-4 space-y-4 overflow-y-auto hide-scrollbar h-[85vh]">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h3 className="text-sm font-medium mb-1">Current Prompt</h3>
|
||||
|
|
@ -333,7 +333,7 @@ const ImageEditor = ({
|
|||
<h3 className="text-sm font-medium mb-2">
|
||||
Previous Generated Images
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 gap-4 h-[400px] overflow-y-auto hide-scrollbar">
|
||||
<div className="grid grid-cols-2 gap-4 ">
|
||||
{previousGeneratedImages.map((image) => (
|
||||
<div
|
||||
onClick={() => handleImageChange(image.path)}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,8 @@ const compileCustomLayout = (layoutCode: string, React: any, z: any) => {
|
|||
.replace(/import\s+.*\s+from\s+['"]zod['"];?/g, "")
|
||||
// remove every zod import (any style)
|
||||
.replace(/import\s+.*\s+from\s+['"]zod['"];?/g, "")
|
||||
.replace(/const\s+[^=]*=\s*require\(['"]zod['"]\);?/g, "");
|
||||
.replace(/const\s+[^=]*=\s*require\(['"]zod['"]\);?/g, "")
|
||||
.replace(/Looking at this HTML structure, I can see it's a slide layout with a header, title, description, and a 2x2 grid of images with captions, plus footer elements.?/g, "")
|
||||
const compiled = Babel.transform(cleanCode, {
|
||||
presets: [
|
||||
["react", { runtime: "classic" }],
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ import { useParams, useRouter } from "next/navigation";
|
|||
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, Trash2 } from "lucide-react";
|
||||
import { useLayout } from "@/app/(presentation-generator)/context/LayoutContext";
|
||||
const GroupLayoutPreview = () => {
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const slug = params.slug as string;
|
||||
|
||||
const { getFullDataByGroup, loading } = useLayout();
|
||||
const { getFullDataByGroup, loading,refetch } = useLayout();
|
||||
const layoutGroup = getFullDataByGroup(slug);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -36,7 +36,17 @@ const GroupLayoutPreview = () => {
|
|||
if (!layoutGroup || layoutGroup.length === 0) {
|
||||
return <LoadingStates type="empty" />;
|
||||
}
|
||||
|
||||
const deleteLayouts = async () => {
|
||||
const presentationId = slug.replace('custom-','');
|
||||
refetch();
|
||||
router.back();
|
||||
const response = await fetch(`/api/v1/ppt/layout-management/delete-layouts/${presentationId}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
if (response.ok) {
|
||||
router.push("/layout-preview");
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
{/* Header */}
|
||||
|
|
@ -62,6 +72,9 @@ const GroupLayoutPreview = () => {
|
|||
<Home className="w-4 h-4" />
|
||||
All Groups
|
||||
</Button>
|
||||
{slug.includes('custom-') && <button className=" border border-red-200 flex justify-center items-center gap-2 text-red-700 px-4 py-1 rounded-md" onClick={() => {
|
||||
deleteLayouts();
|
||||
}}><Trash2 className="w-4 h-4" />Delete</button>}
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
|
|
@ -73,6 +86,7 @@ const GroupLayoutPreview = () => {
|
|||
{layoutGroup[0].groupName}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue