presenton/servers/nextjs/store/slices/presentationGeneration.ts
2025-07-17 16:25:59 +05:45

459 lines
13 KiB
TypeScript

import { Slide } from "@/app/(presentation-generator)/types/slide";
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface Series {
data: number[];
name?: string;
}
interface DataLabel {
dataLabelPosition: "Outside" | "Inside";
dataLabelAlignment: "Base" | "Center" | "End";
}
export interface ChartSettings {
showLegend: boolean;
showGrid: boolean;
showAxisLabel: boolean;
showDataLabel: boolean;
dataLabel: DataLabel;
}
export interface SlideOutline {
title?: string;
body?: string;
}
export interface Chart {
id: string;
name: string;
type: string;
style: ChartSettings | {} | null;
unit?: string | null;
presentation: string;
postfix: string;
data: {
categories: string[];
series: Series[];
};
}
export interface PresentationData {
id: string;
language: string;
layout: {
name: string;
ordered: boolean;
slides: any[];
};
n_slides: number;
title: string;
slides: any;
}
interface PresentationGenerationState {
presentation_id: string | null;
documents: string[];
images: string[];
isLoading: boolean;
isStreaming: boolean | null;
outlines: SlideOutline[];
error: string | null;
presentationData: PresentationData | null;
}
const initialState: PresentationGenerationState = {
presentation_id: null,
documents: [],
images: [],
outlines: [],
isLoading: false,
isStreaming: null,
error: null,
presentationData: null,
};
const presentationGenerationSlice = createSlice({
name: "presentationGeneration",
initialState,
reducers: {
setStreaming: (state, action: PayloadAction<boolean>) => {
state.isStreaming = action.payload;
},
// Loading
setLoading: (state, action: PayloadAction<boolean>) => {
state.isLoading = action.payload;
},
// Presentation ID
setPresentationId: (state, action: PayloadAction<string>) => {
state.presentation_id = action.payload;
state.error = null;
},
// Error
setError: (state, action: PayloadAction<string>) => {
state.error = action.payload;
state.isLoading = false;
},
// Clear presentation data
clearPresentationData: (state) => {
state.presentation_id = null;
state.error = null;
state.isLoading = false;
},
// Set documents
setDocs: (state, action: PayloadAction<string[]>) => {
state.documents = action.payload;
},
// Set images
setImgs: (state, action: PayloadAction<string[]>) => {
state.images = action.payload;
},
// Set outlines
setOutlines: (state, action: PayloadAction<SlideOutline[]>) => {
state.outlines = action.payload;
},
// Set presentation data
setPresentationData: (state, action: PayloadAction<PresentationData>) => {
state.presentationData = action.payload;
},
deleteSlideOutline: (state, action: PayloadAction<{ index: number }>) => {
if (state.outlines) {
// Remove the slide at the given index
state.outlines = state.outlines.filter(
(_, idx) => idx !== action.payload.index
);
}
},
// SLIDE OPERATIONS
addSlide: (
state,
action: PayloadAction<{ slide: Slide; index: number }>
) => {
if (state.presentationData?.slides) {
// Insert the new slide at the specified index
state.presentationData.slides.splice(
action.payload.index,
0,
action.payload.slide
);
// Update indices for all slides to ensure they remain sequential
state.presentationData.slides = state.presentationData.slides.map(
(slide: any, idx: number) => ({
...slide,
index: idx,
})
);
}
},
deletePresentationSlide: (state, action: PayloadAction<number>) => {
if (state.presentationData) {
state.presentationData.slides.splice(action.payload, 1);
state.presentationData.slides = state.presentationData.slides.map(
(slide: any, idx: number) => ({
...slide,
index: idx,
})
);
}
},
updateSlide: (
state,
action: PayloadAction<{ index: number; slide: Slide }>
) => {
if (
state.presentationData &&
state.presentationData.slides[action.payload.index]
) {
state.presentationData.slides[action.payload.index] =
action.payload.slide;
}
},
updateSlideVariant: (
state,
action: PayloadAction<{ index: number; variant: number }>
) => {
if (
state.presentationData &&
state.presentationData.slides[action.payload.index]
) {
state.presentationData.slides[action.payload.index].design_index =
action.payload.variant;
}
},
updateSlideTitle: (
state,
action: PayloadAction<{ index: number; title: string }>
) => {
if (state.presentationData?.slides[action.payload.index]) {
state.presentationData.slides[action.payload.index].content.title =
action.payload.title;
}
},
updateSlideDescription: (
state,
action: PayloadAction<{ index: number; description: string }>
) => {
if (state.presentationData?.slides[action.payload.index]) {
state.presentationData.slides[
action.payload.index
].content.description = action.payload.description;
}
},
updateSlideBodyString: (
state,
action: PayloadAction<{ index: number; body: string }>
) => {
if (state.presentationData?.slides[action.payload.index]) {
state.presentationData.slides[action.payload.index].content.body =
action.payload.body;
}
},
updateSlideBodyHeading: (
state,
action: PayloadAction<{ index: number; bodyIdx: number; heading: string }>
) => {
if (state.presentationData?.slides[action.payload.index]) {
state.presentationData.slides[action.payload.index].content.body[
action.payload.bodyIdx
// @ts-ignore
].heading = action.payload.heading;
}
},
updateSlideBodyDescription: (
state,
action: PayloadAction<{
index: number;
bodyIdx: number;
description: string;
}>
) => {
if (state.presentationData?.slides[action.payload.index]) {
state.presentationData.slides[action.payload.index].content.body[
action.payload.bodyIdx
// @ts-ignore
].description = action.payload.description;
}
},
updateSlideImage: (
state,
action: PayloadAction<{ index: number; imageIdx: number; image: string }>
) => {
if (state.presentationData?.slides[action.payload.index]?.images) {
state.presentationData.slides[action.payload.index].images![
action.payload.imageIdx
] = action.payload.image;
}
},
updateSlideIcon: (
state,
action: PayloadAction<{ index: number; iconIdx: number; icon: string }>
) => {
if (state.presentationData?.slides[action.payload.index]?.icons) {
state.presentationData.slides[action.payload.index].icons![
action.payload.iconIdx
] = action.payload.icon;
}
},
updateSlideChart: (
state,
action: PayloadAction<{ index: number; chart: Chart }>
) => {
if (state.presentationData?.slides[action.payload.index]) {
state.presentationData.slides[action.payload.index].content.graph =
action.payload.chart;
}
},
updateSlideChartSettings: (
state,
action: PayloadAction<{ index: number; chartSettings: ChartSettings }>
) => {
if (state.presentationData?.slides[action.payload.index]) {
const defaultSettings: ChartSettings = {
showLegend: false,
showGrid: false,
showAxisLabel: true,
showDataLabel: true,
dataLabel: {
dataLabelPosition: "Outside",
dataLabelAlignment: "Center",
},
};
state.presentationData.slides[
action.payload.index
].content.graph.style = {
...defaultSettings,
...action.payload.chartSettings,
};
}
},
addSlideBodyItem: (
state,
action: PayloadAction<{
index: number;
item: { heading: string; description: string };
}>
) => {
if (state.presentationData?.slides[action.payload.index]?.content.body) {
// @ts-ignore
state.presentationData.slides[action.payload.index].content.body.push(
action.payload.item
);
}
},
addSlideImage: (
state,
action: PayloadAction<{ index: number; image: string }>
) => {
if (state.presentationData?.slides[action.payload.index]?.images) {
state.presentationData.slides[action.payload.index].images!.push(
action.payload.image
);
}
},
deleteSlideImage: (
state,
action: PayloadAction<{ index: number; imageIdx: number }>
) => {
if (state.presentationData?.slides[action.payload.index]?.images) {
state.presentationData.slides[action.payload.index].images!.splice(
action.payload.imageIdx,
1
);
}
},
updateSlideProperties: (
state,
action: PayloadAction<{ index: number; itemIdx: number; properties: any }>
) => {
if (state.presentationData?.slides[action.payload.index]) {
// Initialize properties object if it doesn't exist
if (!state.presentationData.slides[action.payload.index].properties) {
state.presentationData.slides[action.payload.index].properties = {};
}
// Assign the properties to the specific item index
state.presentationData.slides[action.payload.index].properties[
action.payload.itemIdx
] = action.payload.properties;
}
},
// Infographics
addInfographics: (
state,
action: PayloadAction<{ slideIndex: number; item: any }>
) => {
if (state.presentationData?.slides[action.payload.slideIndex]?.content) {
// @ts-ignore
state.presentationData.slides[
action.payload.slideIndex
].content.infographics.push(action.payload.item);
}
},
deleteInfographics: (
state,
action: PayloadAction<{ slideIndex: number; itemIdx: number }>
) => {
if (state.presentationData?.slides[action.payload.slideIndex]?.content) {
// @ts-ignore
state.presentationData.slides[
action.payload.slideIndex
].content.infographics.splice(action.payload.itemIdx, 1);
}
},
updateInfographicsTitle: (
state,
action: PayloadAction<{
slideIndex: number;
itemIdx: number;
title: string;
}>
) => {
if (state.presentationData?.slides[action.payload.slideIndex]?.content) {
// @ts-ignore
state.presentationData.slides[
action.payload.slideIndex
].content.infographics[action.payload.itemIdx].title =
action.payload.title;
}
},
updateInfographicsDescription: (
state,
action: PayloadAction<{
slideIndex: number;
itemIdx: number;
description: string;
}>
) => {
if (state.presentationData?.slides[action.payload.slideIndex]?.content) {
// @ts-ignore
state.presentationData.slides[
action.payload.slideIndex
].content.infographics[action.payload.itemIdx].description =
action.payload.description;
}
},
updateInfographicsChart: (
state,
action: PayloadAction<{ slideIndex: number; itemIdx: number; chart: any }>
) => {
if (state.presentationData?.slides[action.payload.slideIndex]?.content) {
// @ts-ignore
state.presentationData.slides[
action.payload.slideIndex
].content.infographics[action.payload.itemIdx].chart =
action.payload.chart;
}
},
deleteSlideBodyItem: (
state,
action: PayloadAction<{ index: number; itemIdx: number }>
) => {
if (state.presentationData?.slides[action.payload.index]?.content.body) {
// @ts-ignore
state.presentationData.slides[action.payload.index].content.body.splice(
action.payload.itemIdx,
1
);
}
},
},
});
export const {
setStreaming,
setLoading,
setPresentationId,
setError,
clearPresentationData,
setDocs,
setImgs,
deleteSlideOutline,
setPresentationData,
setOutlines,
// slides operations
addSlide,
updateSlide,
updateSlideVariant,
updateSlideChart,
updateSlideChartSettings,
updateSlideTitle,
updateSlideDescription,
updateSlideBodyString,
updateSlideBodyHeading,
updateSlideBodyDescription,
updateSlideImage,
updateSlideIcon,
deletePresentationSlide,
addSlideBodyItem,
addSlideImage,
deleteSlideImage,
deleteSlideBodyItem,
updateSlideProperties,
// infographics
addInfographics,
deleteInfographics,
updateInfographicsTitle,
updateInfographicsDescription,
updateInfographicsChart,
} = presentationGenerationSlice.actions;
export default presentationGenerationSlice.reducer;