diff --git a/servers/nextjs/app/(presentation-generator)/components/ImageEditor.tsx b/servers/nextjs/app/(presentation-generator)/components/ImageEditor.tsx index 0fbeffbb..b5575409 100644 --- a/servers/nextjs/app/(presentation-generator)/components/ImageEditor.tsx +++ b/servers/nextjs/app/(presentation-generator)/components/ImageEditor.tsx @@ -37,6 +37,7 @@ import { PopoverTrigger, } from "@/components/ui/popover"; import ToolTip from "@/components/ToolTip"; +import { BASE_URL } from "@/utils/constant"; interface ImageEditorProps { initialImage: string | null; @@ -90,7 +91,7 @@ const ImageEditor = ({ (properties && properties[imageIdx] && properties[imageIdx].initialObjectFit) || - "cover" + "cover" ); const imageRef = useRef(null); const imageContainerRef = useRef(null); @@ -569,30 +570,30 @@ const ImageEditor = ({
{isGenerating || previewImages.length === 0 ? Array.from({ length: 4 }).map((_, index) => ( - - )) + + )) : previewImages.map((image, index) => ( -
handleImageChange(image as string)} - className="aspect-[4/3] w-full overflow-hidden rounded-lg border cursor-pointer" - > - {`Preview -
- ))} +
handleImageChange(image as string)} + className="aspect-[4/3] w-full overflow-hidden rounded-lg border cursor-pointer" + > + {`Preview +
+ ))}
@@ -626,25 +627,25 @@ const ImageEditor = ({
{isSearching ? Array.from({ length: 6 }).map((_, index) => ( - - )) + + )) : searchedImages.map((imgSrc, index) => ( -
handleImageChange(imgSrc)} - className="aspect-[4/3] cursor-pointer group relative rounded-lg overflow-hidden" - > - {`Search -
-
- ))} +
handleImageChange(imgSrc)} + className="aspect-[4/3] cursor-pointer group relative rounded-lg overflow-hidden" + > + {`Search +
+
+ ))}
diff --git a/servers/nextjs/app/(presentation-generator)/components/info_graphics/AllInfoGraphics.tsx b/servers/nextjs/app/(presentation-generator)/components/info_graphics/AllInfoGraphics.tsx deleted file mode 100644 index 432f06a7..00000000 --- a/servers/nextjs/app/(presentation-generator)/components/info_graphics/AllInfoGraphics.tsx +++ /dev/null @@ -1,789 +0,0 @@ -import React, { useState } from "react"; - -import { - Sheet, - SheetContent, - SheetFooter, - SheetHeader, - SheetTitle, -} from "@/components/ui/sheet"; -import { Slider } from "@/components/ui/slider"; -import { Label } from "@/components/ui/label"; -import { Input } from "@/components/ui/input"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { Button } from "@/components/ui/button"; -import { useDispatch, useSelector } from "react-redux"; -import { updateInfographicsChart } from "@/store/slices/presentationGeneration"; -import { RootState } from "@/store/store"; -import { getPercentage, ICON_LIST, IconMapper } from "../../utils/IconList"; - -type Chart = { - chart_type: string; - icon?: string; - value: { - number_type: string; - numerator?: number; - denominator?: number; - percentage?: number; - numerical?: number; - suffix?: string; - }; -}; -const colors = [ - "#6453ff", - "#22c1dd", - "#ff6453", - "#ffc122", - "#22ddc1", - "#c122ff", - "#dd22ff", - "#ff22c1", - "#c1ff22", - "#22ffc1", -]; - -const CHART_TYPES = [ - { value: "progress-dial", label: "Progress Dial" }, - { value: "radial-progress", label: "Radial Progress" }, - { value: "progress-ring", label: "Progress Ring" }, - { value: "progress-bar", label: "Progress Bar" }, - { value: "icon-infographic", label: "Icon Infographic" }, -]; - -const AllInfoGraphics = ({ - slideIndex, - itemIndex, - chart, -}: { - slideIndex: number; - itemIndex: number; - chart: Chart; -}) => { - const dispatch = useDispatch(); - - const [isEditingOpen, setIsEditingOpen] = useState(false); - const [lineWeight, setLineWeight] = useState(20); - const [selectedIcon, setSelectedIcon] = useState(chart.icon || "star"); - const [chartType, setChartType] = useState(chart.chart_type); - - // State for both percentage and fraction - const [percentageValue, setPercentageValue] = useState( - chart.value.number_type === "fraction" - ? getPercentage(chart.value.numerator!, chart.value.denominator!) - : chart.value.percentage || 0 - ); - const [numerator, setNumerator] = useState(chart.value.numerator || 0); - const [denominator, setDenominator] = useState( - chart.value.denominator || 100 - ); - const [numberType, setNumberType] = useState(chart.value.number_type); - const { currentColors } = useSelector((state: RootState) => state.theme); - - const handlePercentageChange = (value: number) => { - const newValue = Math.min(1000, Math.max(0, value)); - setPercentageValue(newValue); - - if (numberType === "fraction") { - // Update numerator based on percentage while keeping denominator same - const newNumerator = Math.round((newValue / 100) * denominator); - setNumerator(newNumerator); - } - }; - - const handleFractionChange = (num: number | null, den: number | null) => { - // Ensure we have valid numbers - const validNum = num !== null ? Math.max(0, num) : numerator; - const validDen = den !== null ? Math.max(1, den) : denominator; - - setNumerator(validNum); - setDenominator(validDen); - - // Calculate and update percentage - const newPercentage = getPercentage(validNum, validDen); - setPercentageValue(newPercentage); - }; - - const handlePercentageInputChange = ( - e: React.ChangeEvent - ) => { - const value = e.target.value; - if (value === "") { - setPercentageValue(0); // Keep internal state at 0 - return; - } - handlePercentageChange(Number(value)); - }; - - const handlePercentageBlur = (e: React.FocusEvent) => { - if (e.target.value === "") { - handlePercentageChange(0); - } - }; - - const handleNumeratorChange = (e: React.ChangeEvent) => { - const value = e.target.value; - if (value === "") { - setNumerator(0); // Keep internal state at 0 - return; - } - handleFractionChange(Number(value), null); - }; - - const handleNumeratorBlur = (e: React.FocusEvent) => { - if (e.target.value === "") { - handleFractionChange(0, null); - } - }; - - const handleDenominatorChange = (e: React.ChangeEvent) => { - const value = e.target.value; - if (value === "") { - setDenominator(1); // Keep internal state at 1 - return; - } - handleFractionChange(null, Number(value)); - }; - - const handleDenominatorBlur = (e: React.FocusEvent) => { - if (e.target.value === "") { - handleFractionChange(null, 1); - } - }; - - const handleContentEdit = (e: React.FormEvent) => { - const content = e.currentTarget.textContent || ""; - - // Check if content is in fraction format (e.g., "3/4") - if (content.includes("/")) { - const [num, den] = content.split("/").map((n) => parseInt(n)); - if (!isNaN(num) && !isNaN(den) && den !== 0) { - setNumberType("fraction"); - handleFractionChange(num, den); - } - } - // Check if content is in percentage format (e.g., "75%") - else { - const value = parseInt(content.replace("%", "")); - if (!isNaN(value)) { - setNumberType("percentage"); - handlePercentageChange(value); - } - } - }; - - const handleSave = () => { - const chartData = { - chart_type: chartType, - value: { - number_type: numberType, - }, - } as Chart; - - // Add icon if it's an icon infographic - if (chartType === "icon-infographic") { - chartData.icon = selectedIcon; - } - - // Add values based on number type - if (numberType === "fraction") { - chartData.value.numerator = numerator; - chartData.value.denominator = denominator; - } else if (numberType === "percentage") { - chartData.value.percentage = percentageValue; - } - dispatch( - updateInfographicsChart({ - slideIndex: slideIndex, - itemIdx: itemIndex, - chart: chartData, - }) - ); - - setIsEditingOpen(false); - }; - const handleSheetClose = () => { - handleSave(); - setIsEditingOpen(false); - }; - - const handleInfographicClick = (e: React.MouseEvent) => { - e.stopPropagation(); - if (chartType !== "text") { - setIsEditingOpen(true); - } - }; - - return ( - <> -
- {chartType === "progress-dial" && ( - - )} - {chartType === "radial-progress" && ( - - )} - {chartType === "progress-ring" && ( - - )} - {chartType === "progress-bar" && ( - - )} - {chartType === "icon-infographic" && ( - - )} - {chartType === "text" && ( - - )} -
- - - - - Chart Settings - - -
-
- - -
- -
-
- - -
- -
- -
-
- { - handlePercentageChange(value[0]); - }} - /> -
-
- -
-
-
- -
- -
- - / - -
- = {percentageValue.toFixed(1)}% -
-
-
-
- - {chartType === "icon-infographic" && ( -
- -
- {Object.entries(ICON_LIST).map(([key, Icon]) => ( - - ))} -
-
- )} -
- - - -
-
- - ); -}; - -export default AllInfoGraphics; - -export function IconGraphics({ - color, - icon, - percentage, -}: { - color: string; - icon: string; - percentage?: number; -}) { - const percentageValue = percentage && percentage > 100 ? 100 : percentage; - const radius = 110; - const circumference = 2 * Math.PI * radius; - const gap = percentageValue === 100 ? 0 : 10; // No gap at 100% - const adjustedCircumference = circumference - gap; - - return ( -
- - - {percentageValue !== 0 && ( - = 100 ? "butt" : "round"} - stroke="currentColor" - fill="transparent" - r={radius} - cx="120" - cy="120" - strokeDasharray={`${adjustedCircumference}`} - strokeDashoffset={ - ((100 - percentageValue!) / 100) * adjustedCircumference + gap - } - /> - )} - -
- {IconMapper(false, icon)} -
-
- ); -} - -export function ProgressDial({ - color, - percentage, -}: { - color: string; - percentage?: number; -}) { - // Calculate needle rotation based on percentage - const needleRotation = Math.round((percentage! / 100) * 180 - 90); - - return ( -
- - {/* Background arc */} - - - {/* Needle */} - - - {/* Center circle */} - - -
- ); -} - -export function RadialProgress({ - strokeWidth, - color, - percentage, - numerator, - denominator, - onContentEdit, - numberType = "percentage", -}: { - strokeWidth: number; - color: string; - percentage?: number; - numerator?: number; - denominator?: number; - onContentEdit?: (e: React.FormEvent) => void; - numberType?: string; -}) { - const percentageValue = - percentage && percentage > 100 ? 100 : percentage ?? 0; - const radius = 90; - const arcLength = Math.PI * radius; - const strokeDasharray = arcLength; - - const correctionFactor = percentageValue === 100 ? 1 : 0.98; - const strokeDashoffset = - arcLength * (1 - (percentageValue / 100) * correctionFactor); - - return ( -
- - {/* Background half-circle */} - - - {/* Foreground half-circle */} - - - -
-

{ - const selection = window.getSelection(); - const range = document.createRange(); - range.selectNodeContents(e.currentTarget); - selection?.removeAllRanges(); - selection?.addRange(range); - }} - onInput={onContentEdit} - style={{ color }} - className="text-[24px] focus-visible:outline-none leading-[32px] font-bold" - > - {numberType === "fraction" && numerator && denominator - ? `${numerator}/${denominator}` - : `${percentageValue}%`} -

-
-
- ); -} - -export function ProgressRing({ - color, - percentage, - numerator, - denominator, - lineWeight = 20, - onContentEdit, - numberType = "percentage", -}: { - color: string; - percentage?: number; - numerator?: number; - denominator?: number; - lineWeight?: number; - onContentEdit?: (e: React.FormEvent) => void; - numberType?: string; -}) { - const percentageValue = percentage && percentage > 100 ? 100 : percentage; - const radius = 110; - const circumference = 2 * Math.PI * radius; - const gap = percentageValue === 100 ? 0 : 10; // No gap at 100% - const adjustedCircumference = circumference - gap; - - return ( -
- - - {percentageValue !== 0 && ( - - )} - -
-

{ - const selection = window.getSelection(); - const range = document.createRange(); - range.selectNodeContents(e.currentTarget); - selection?.removeAllRanges(); - selection?.addRange(range); - }} - onInput={onContentEdit} - contentEditable - suppressContentEditableWarning - style={{ color: color }} - className="text-base md:text-[24px] focus-visible:outline-none leading-[32px] font-bold" - > - {numberType === "fraction" && numerator && denominator - ? `${numerator}/${denominator}` - : `${percentage}%`} -

-
-
- ); -} - -export function ProgressBar({ - progressBg, - color, - percentage, - lineWeight = 20, -}: { - progressBg: string; - color: string; - percentage?: number; - lineWeight?: number; -}) { - const percentageValue = percentage && percentage > 100 ? 100 : percentage; - return ( -
-
-
- ); -} -export function TextInfographic({ - dispatch, - iconBg, - slideIndex, - itemIndex, - item, - suffix, - numerical, -}: { - dispatch: any; - slideIndex: number; - itemIndex: number; - item: any; - suffix: string; - numerical: number; - iconBg: string; -}) { - const updateChart = ({ - slideIndex, - itemIdx, - chart, - }: { - slideIndex: number; - itemIdx: number; - chart: any; - }) => { - dispatch(updateInfographicsChart({ slideIndex, itemIdx, chart })); - }; - const formatNumber = (value: number) => { - if (isNaN(value)) { - return value; - } - const absValue = Math.abs(value); - if (absValue >= 1000000000) { - return `${(absValue / 1000000000).toFixed(0)}B`; - } else if (absValue >= 1000000) { - return `${(absValue / 1000000).toFixed(0)}M`; - } else if (absValue >= 1000) { - return `${(absValue / 1000).toFixed(0)}k`; - } - return absValue.toString(); - }; - return ( -
-
-

{ - updateChart({ - slideIndex, - itemIdx: itemIndex, - chart: { - chart_type: item.chart_type, - value: { - number_type: item.value.number_type, - numerical: e.currentTarget.innerText, - suffix: item.value.suffix, - }, - }, - }); - }} - contentEditable={true} - suppressContentEditableWarning - className="text-base md:text-[24px] focus-visible:outline-none leading-[40px] font-bold" - > - {formatNumber(numerical)} -

-

{ - updateChart({ - slideIndex, - itemIdx: itemIndex, - chart: { - chart_type: item.chart_type, - value: { - number_type: item.value.number_type, - numerical: item.value.numerical, - suffix: e.currentTarget.innerText, - }, - }, - }); - }} - contentEditable={true} - suppressContentEditableWarning - className="text-base md:text-[20px] cursor-text focus-visible:outline-none leading-[24px] font-bold" - > - {suffix.toString().replace(/\*\*/g, "")} -

-
-
- ); -} diff --git a/servers/nextjs/app/(presentation-generator)/components/info_graphics/MiniInfoGraphics.tsx b/servers/nextjs/app/(presentation-generator)/components/info_graphics/MiniInfoGraphics.tsx deleted file mode 100644 index 30079e5a..00000000 --- a/servers/nextjs/app/(presentation-generator)/components/info_graphics/MiniInfoGraphics.tsx +++ /dev/null @@ -1,359 +0,0 @@ -import React, { useState } from "react"; -import { useSelector } from "react-redux"; -import { RootState } from "@/store/store"; -import { IconMapper } from "../../utils/IconList"; - -type Chart = { - chart_type: string; - icon?: string; - value: { - number_type: string; - numerator?: number; - denominator?: number; - percentage?: number; - numerical?: number; - suffix?: string; - }; -}; - -const colors = [ - "#6453ff", - "#22c1dd", - "#ff6453", - "#ffc122", - "#22ddc1", - "#c122ff", - "#dd22ff", - "#ff22c1", - "#c1ff22", - "#22ffc1", -]; - -const MiniInfoGraphics = ({ - slideIndex, - itemIndex, - chart, -}: { - slideIndex: number; - itemIndex: number; - chart: Chart; -}) => { - const { currentColors } = useSelector((state: RootState) => state.theme); - - const percentage = - chart.value.number_type === "fraction" && - chart.value.numerator && - chart.value.denominator - ? (chart.value.numerator / chart.value.denominator) * 100 - : chart.value.percentage || 0; - - return ( -
- {chart.chart_type === "progress-dial" && ( - - )} - {chart.chart_type === "radial-progress" && ( - - )} - {chart.chart_type === "progress-ring" && ( - - )} - {chart.chart_type === "progress-bar" && ( - - )} - {chart.chart_type === "icon-infographic" && ( - - )} - {chart.chart_type === "text" && ( - - )} -
- ); -}; - -export default MiniInfoGraphics; - -function MiniIconGraphics({ - color, - icon, - percentage, -}: { - color: string; - icon: string; - percentage: number; -}) { - const percentageValue = percentage > 100 ? 100 : percentage; - const radius = 20; - const circumference = 2 * Math.PI * radius; - const gap = percentageValue === 100 ? 0 : 2; - const adjustedCircumference = circumference - gap; - - return ( -
- - - {percentageValue !== 0 && ( - - )} - -
- {IconMapper(true, icon)} -
-
- ); -} - -function MiniProgressDial({ - color, - percentage, -}: { - color: string; - percentage: number; -}) { - const percentageValue = percentage > 100 ? 100 : percentage; - const needleRotation = Math.round((percentageValue / 100) * 180 - 90); - - return ( -
- - - - - -
- ); -} - -function MiniRadialProgress({ - color, - percentage, - numerator, - denominator, - numberType, -}: { - color: string; - percentage: number; - numerator?: number; - denominator?: number; - numberType: string; -}) { - const percentageValue = percentage > 100 ? 100 : percentage; - const radius = 20; - const arcLength = Math.PI * radius; - const offset = - percentageValue === 100 ? 0 : arcLength * (1 - percentageValue / 100); - - return ( -
- - - - -
-

- {numberType === "fraction" && numerator && denominator - ? `${numerator}/${denominator}` - : `${percentage}%`} -

-
-
- ); -} - -function MiniProgressRing({ - color, - percentage, - numerator, - denominator, - numberType, -}: { - color: string; - percentage: number; - numerator?: number; - denominator?: number; - numberType: string; -}) { - const percentageValue = percentage > 100 ? 100 : percentage; - const radius = 20; - const circumference = 2 * Math.PI * radius; - const gap = percentageValue === 100 ? 0 : 2; - const adjustedCircumference = circumference - gap; - - return ( -
- - - {percentageValue !== 0 && ( - - )} - -
-

- {numberType === "fraction" && numerator && denominator - ? `${numerator}/${denominator}` - : `${percentage}%`} -

-
-
- ); -} - -function MiniProgressBar({ - color, - percentage, -}: { - color: string; - percentage: number; -}) { - const percentageValue = percentage > 100 ? 100 : percentage; - return ( -
-
-
- ); -} - -function MiniTextInfographic({ - iconBg, - numerical, -}: { - iconBg: string; - numerical: number; -}) { - const formatNumber = (value: number) => { - if (isNaN(value)) { - return value; - } - const absValue = Math.abs(value); - if (absValue >= 1000000000) { - return `${(absValue / 1000000000).toFixed(0)}B`; - } else if (absValue >= 1000000) { - return `${(absValue / 1000000).toFixed(0)}M`; - } else if (absValue >= 1000) { - return `${(absValue / 1000).toFixed(0)}k`; - } - return absValue.toString(); - }; - return ( -
-

{formatNumber(numerical)}

-
- ); -} diff --git a/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type10Mini.tsx b/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type10Mini.tsx deleted file mode 100644 index 2bd4341a..00000000 --- a/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type10Mini.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react' -import AllInfoGraphics from '../info_graphics/AllInfoGraphics'; -import MiniInfoGraphics from '../info_graphics/MiniInfoGraphics'; -import MiniTypeWriter from './MiniTypeWriter'; - -type Type10MiniProps = { - slideIndex: number; - title: string; - description?: string; - design_index: number; - infographics: { - title: string; - description: string; - chart: { - chart_type: string; - value: { - number_type: string; - numerical: number; - suffix: string; - numerator?: number; - denominator?: number; - percentage?: number; - } - } - }[]; -} - -const Type10Mini = ({ slideIndex, title, description, infographics, design_index }: Type10MiniProps) => { - - if (infographics.length === 1) { - return ( -
-
-
-

- -

- {description &&

- -

} -
-
- -

- -

-
-
-
- ) - } else { - - - return ( -
-
-

- -

- {description &&

- -

} -
-
- {infographics.map((item, index) => ( -
- -

- -

-

- -

-
- ))} -
-
- ) - } -} - -export default Type10Mini diff --git a/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type11Mini.tsx b/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type11Mini.tsx deleted file mode 100644 index 812115cf..00000000 --- a/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type11Mini.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { RootState } from '@/store/store'; -import React from 'react' -import { useSelector } from 'react-redux'; - -type Type11MiniProps = { - title: string; - description?: string; - infographics: { - title: string; - description: string; - chart: { - chart_type: string; - value: { - number_type: string; - numerical: number; - suffix: string; - } - } - }[]; -} - -const Type11Mini = ({ title, description, infographics }: Type11MiniProps) => { - const { currentColors } = useSelector((state: RootState) => state.theme); - - return ( -
-
-

{title}

- {description &&

{description}

} -
-
- {infographics.map((item, index) => ( -
-
-

{item.chart.value.numerical}

-
-

{item.title}

-
- ))} -
-
- ) -} - -export default Type11Mini diff --git a/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type12Mini.tsx b/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type12Mini.tsx deleted file mode 100644 index 09c0a780..00000000 --- a/servers/nextjs/app/(presentation-generator)/components/mini-slides/Type12Mini.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import React, { useEffect, useRef } from "react"; -import MiniTypeWriter from "./MiniTypeWriter"; -import { useSelector } from "react-redux"; -import { RootState } from "@/store/store"; -import mermaid from "mermaid"; - -interface Type12MiniProps { - title: string; - description: string; - mermaidCode: string; - slideIndex: number; - isFullSizeGraph: boolean; -} -const Type12Mini = ({ - title, - description, - mermaidCode, - slideIndex, - isFullSizeGraph, -}: Type12MiniProps) => { - const { currentColors, currentTheme } = useSelector( - (state: RootState) => state.theme - ); - const mermaidRef = useRef(null); - const hasInitialized = useRef(false); - - // Initialize Mermaid once - useEffect(() => { - if (!hasInitialized.current) { - mermaid.initialize({ - startOnLoad: false, - theme: "base", - themeVariables: { - primaryColor: currentColors.slideBox, - primaryTextColor: currentColors.slideTitle, - primaryBorderColor: currentColors.slideBox, - lineColor: currentColors.chartColors[0], - secondaryColor: currentColors.slideHeading, - fontFamily: currentColors.fontFamily || "Inter", - background: currentColors.background || "#ffffff", - }, - }); - hasInitialized.current = true; - } - }, [currentColors]); - - // Render the diagram on code/theme change - useEffect(() => { - if (typeof window !== "undefined" && mermaidCode && mermaidRef.current) { - const uniqueId = `mermaid-${slideIndex}-mini`; - mermaid - .render(uniqueId, mermaidCode) - .then(({ svg }) => { - if (mermaidRef.current) { - mermaidRef.current.innerHTML = svg; - - // Optional: apply inline styling after render - const svgEl = mermaidRef.current.querySelector("svg"); - if (svgEl) { - svgEl.style.width = "90px"; - svgEl.style.maxWidth = "100%"; - svgEl.style.background = currentColors.background || "#ffffff"; - svgEl.style.color = currentColors.slideTitle || "#000000"; - svgEl.style.fontFamily = currentColors.fontFamily || "Inter"; - } - } - }) - .catch((err) => { - console.error("Mermaid render error:", err); - }); - } - }, [mermaidCode, slideIndex, currentColors]); - return ( -
-
-
- -
-
-
-
- {/* */} -
- {/*
- -
*/} -
- -
-
- {/*
- - - -
{description}
-
*/} -
- ); -}; - -export default Type12Mini; diff --git a/servers/nextjs/app/(presentation-generator)/components/slide_config.tsx b/servers/nextjs/app/(presentation-generator)/components/slide_config.tsx index 6d2de097..5798ccb3 100644 --- a/servers/nextjs/app/(presentation-generator)/components/slide_config.tsx +++ b/servers/nextjs/app/(presentation-generator)/components/slide_config.tsx @@ -30,12 +30,10 @@ import { XAxis, } from "recharts"; import { ResponsiveContainer } from "recharts"; -import Type10Layout from "./slide_layouts/Type10Layout"; -import Type10Mini from "./mini-slides/Type10Mini"; + import { ThemeColors } from "../store/themeSlice"; import { isDarkColor } from "../utils/others"; -import Type12Layout from "./slide_layouts/Type12Layout"; -import Type12Mini from "./mini-slides/Type12Mini"; + import { formatTooltipValue, formatYAxisTick, @@ -149,29 +147,7 @@ export const renderSlideContent = (slide: Slide, language: string) => { graphData={slide.content.graph} /> ); - case 10: - case 11: - return ( - - ); - case 12: - return ( - - ); + default: return null; @@ -258,27 +234,7 @@ export const renderMiniSlideContent = (slide: Slide) => { slideIndex={slide.index} /> ); - case 10: - case 11: - return ( - - ); - case 12: - return ( - - ); + default: return null; } @@ -433,14 +389,14 @@ export const renderChart = ( dataKey={serie.name || `Series ${index + 1}`} stroke={chartColors[index % chartColors.length]} style={{ cursor: "pointer" }} - // label={(chartSettings?.showDataLabel && localChartData.data.series.length === 1) ? { - // position: chartSettings?.dataLabel.dataLabelPosition === "Outside" ? "top" : "center", - // formatter: (value: number) => formatYAxisTick(value), - // fill: chartSettings?.dataLabel.dataLabelPosition === "Outside" ? theme.slideTitle : '#ffffff', - // fontWeight: 'bold', - // fontSize: '12px', - // fontFamily: theme.fontFamily - // } : undefined} + // label={(chartSettings?.showDataLabel && localChartData.data.series.length === 1) ? { + // position: chartSettings?.dataLabel.dataLabelPosition === "Outside" ? "top" : "center", + // formatter: (value: number) => formatYAxisTick(value), + // fill: chartSettings?.dataLabel.dataLabelPosition === "Outside" ? theme.slideTitle : '#ffffff', + // fontWeight: 'bold', + // fontSize: '12px', + // fontFamily: theme.fontFamily + // } : undefined} /> ))} @@ -602,27 +558,27 @@ export const renderChart = ( label={ chartSettings?.showDataLabel ? { - position: - chartSettings?.dataLabel.dataLabelPosition === + position: + chartSettings?.dataLabel.dataLabelPosition === "Outside" - ? "top" - : chartSettings?.dataLabel.dataLabelAlignment === - "Base" + ? "top" + : chartSettings?.dataLabel.dataLabelAlignment === + "Base" ? "insideBottom" : chartSettings?.dataLabel.dataLabelAlignment === "Center" - ? "center" - : "insideTop", - formatter: (value: number) => formatYAxisTick(value), - fill: - chartSettings?.dataLabel.dataLabelPosition === + ? "center" + : "insideTop", + formatter: (value: number) => formatYAxisTick(value), + fill: + chartSettings?.dataLabel.dataLabelPosition === "Outside" - ? theme.slideTitle - : "#ffffff", - fontWeight: "bold", - fontSize: "14px", - fontFamily: theme.fontFamily, - } + ? theme.slideTitle + : "#ffffff", + fontWeight: "bold", + fontSize: "14px", + fontFamily: theme.fontFamily, + } : undefined } /> diff --git a/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type10Layout.tsx b/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type10Layout.tsx deleted file mode 100644 index b922f51e..00000000 --- a/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type10Layout.tsx +++ /dev/null @@ -1,277 +0,0 @@ -import React from "react"; -import EditableText from "../EditableText"; -import ElementMenu from "../ElementMenu"; -import { MoreVertical, Plus } from "lucide-react"; -import { useDispatch, useSelector } from "react-redux"; -import { - addInfographics, - deleteInfographics, - updateSlideVariant, -} from "@/store/slices/presentationGeneration"; -import AllInfoGraphics from "../info_graphics/AllInfoGraphics"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@radix-ui/react-popover"; -import { RootState } from "@/store/store"; -import SlideFooter from "./SlideFooter"; - -type Type10LayoutProps = { - title: string; - slideIndex: number; - slideId: string | null; - description: string; - design_index: number; - infographics: { - title: string; - description: string; - chart: { - chart_type: string; - value: { - number_type: string; - numerical: number; - suffix: string; - numerator?: number; - denominator?: number; - percentage?: number; - }; - }; - }[]; -}; - -const Type10Layout = ({ - title, - slideIndex, - slideId, - infographics, - description, - design_index, -}: Type10LayoutProps) => { - const { currentColors } = useSelector((state: RootState) => state.theme); - const dispatch = useDispatch(); - - const handleDeleteItem = (index: number) => { - dispatch( - deleteInfographics({ - slideIndex: slideIndex, - itemIdx: index, - }) - ); - }; - const handleAddItem = () => { - dispatch( - addInfographics({ - slideIndex: slideIndex, - item: { - title: "Enter Title", - description: "Enter Description", - chart: { - chart_type: infographics[0].chart.chart_type, - value: { - percentage: 80, - number_type: "percentage", - }, - }, - }, - }) - ); - }; - const handleVariantChange = (newVariant: number) => { - dispatch(updateSlideVariant({ index: slideIndex, variant: newVariant })); - }; - - const VariantMenu = () => ( - - - - - - - - - - ); - - if (infographics.length === 1) { - return ( -
-
-
- - {description && ( - - )} -
-
-
- {infographics.length < 3 && ( - - )} - - -
- -
-
-
- -
- ); - } else { - return ( -
-
- - {description && ( - - )} -
-
- - {/* hover border and icon */} -
- {infographics.length < 3 && ( - - )} - - {infographics.map((item: any, index: number) => { - return ( -
- - -
- - -
-
- ); - })} -
- -
- ); - } -}; - -export default Type10Layout; diff --git a/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type11Layout.tsx b/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type11Layout.tsx deleted file mode 100644 index 50b27ef4..00000000 --- a/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type11Layout.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import React, { useState } from 'react' -import EditableText from '../EditableText' -import { Plus } from 'lucide-react'; -import ElementMenu from '../ElementMenu'; -import { addInfographics, deleteInfographics, updateInfographicsChart } from '@/store/slices/presentationGeneration'; -import { useDispatch, useSelector } from 'react-redux'; -import { RootState } from '@/store/store'; - -type Type11LayoutProps = { - title: string; - slideIndex: number; - slideId: string; - description?: string; - infographics: { - title: string; - description: string; - chart: { - chart_type: string; - value: { - number_type: string; - numerical: number; - suffix: string; - } - } - }[]; -} - -const Type11Layout = ({ - title, - slideIndex, - slideId, - description, - infographics -}: Type11LayoutProps) => { - const dispatch = useDispatch(); - const { currentColors } = useSelector((state: RootState) => state.theme); - - // const percentageColors = ['#ff00ef', '#6453ff', '#f00000'] - - - const handleDeleteItem = (index: number) => { - dispatch(deleteInfographics({ - slideIndex: slideIndex, - itemIdx: index - })) - - } - const handleAddItem = () => { - dispatch(addInfographics({ - slideIndex: slideIndex, - item: { - title: 'Enter Title', - description: 'Enter Description', - chart: { - chart_type: infographics[0].chart.chart_type, - value: { - percentage: 80, - number_type: 'percentage', - } - } - } - })) - - } - const updateChart = ({ slideIndex, itemIdx, chart }: { slideIndex: number, itemIdx: number, chart: any }) => { - dispatch(updateInfographicsChart({ slideIndex, itemIdx, chart })) - } - - return ( -
-
- - {description && } -
-
-
- - - {infographics.map((item, index) => ( -
- -
- -
-

{ - updateChart({ - slideIndex, itemIdx: index, chart: { - chart_type: item.chart.chart_type, - value: { - number_type: item.chart.value.number_type, - numerical: parseInt(e.currentTarget.innerText), - suffix: item.chart.value.suffix - } - } - }) - }} contentEditable suppressContentEditableWarning data-slide-element data-slide-index={slideIndex} data-element-type="text" data-is-align={true} data-element-id={`slide-${slideIndex}-value-${index}`} className='text-[24px] focus-visible:outline-none leading-[40px] font-bold'>{item.chart.value.numerical}

-

{ - updateChart({ - slideIndex, itemIdx: index, chart: { - chart_type: item.chart.chart_type, - value: { - number_type: item.chart.value.number_type, - numerical: item.chart.value.numerical, - suffix: e.currentTarget.innerText - } - } - }) - }} contentEditable suppressContentEditableWarning data-slide-element data-slide-index={slideIndex} data-element-type="text" data-is-align={true} data-element-id={`slide-${slideIndex}-subtitle-${index}`} className='text-[20px] focus-visible:outline-none leading-[24px] font-bold'>{item.chart.value.suffix.toString().replace(/\*\*/g, '')}

-
- -
-
- - -
-
- ))} -
-
- ) -} - -export default Type11Layout diff --git a/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type12Layout.tsx b/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type12Layout.tsx deleted file mode 100644 index 8e64b734..00000000 --- a/servers/nextjs/app/(presentation-generator)/components/slide_layouts/Type12Layout.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React, { useEffect, useRef } from "react"; -import EditableText from "../EditableText"; -import { useSelector } from "react-redux"; -import SlideFooter from "./SlideFooter"; -import { RootState } from "@/store/store"; -import mermaid from "mermaid"; - -const Type12Layout = ({ - title, - description, - slideId, - mermaidCode, - slideIndex, - isFullSizeGraph, -}: { - title: string; - description?: string; - slideId: string | null; - mermaidCode: string; - slideIndex: number; - isFullSizeGraph: boolean; -}) => { - const { currentColors, currentTheme } = useSelector( - (state: RootState) => state.theme - ); - - const mermaidRef = useRef(null); - const hasInitialized = useRef(false); - - // Initialize Mermaid once - useEffect(() => { - // if (!hasInitialized.current) { - - mermaid.initialize({ - startOnLoad: false, - theme: "base", - themeVariables: { - primaryColor: currentColors.slideBox, - primaryTextColor: currentColors.slideTitle, - primaryBorderColor: currentColors.slideBox, - lineColor: currentColors.chartColors[0], - secondaryColor: currentColors.slideHeading, - fontFamily: currentColors.fontFamily || "Inter", - background: currentColors.slideBg || "#ffffff", - }, - }); - hasInitialized.current = true; - // } - }, [currentColors]); - - // Render the diagram on code/theme change - useEffect(() => { - if (typeof window !== "undefined" && mermaidCode && mermaidRef.current) { - const uniqueId = `mermaid-${slideIndex}`; - mermaid - .render(uniqueId, mermaidCode) - .then(({ svg }) => { - if (mermaidRef.current) { - mermaidRef.current.innerHTML = svg; - - // Optional: apply inline styling after render - const svgEl = mermaidRef.current.querySelector("svg"); - if (svgEl) { - svgEl.style.width = "600px"; - svgEl.style.maxWidth = "100%"; - svgEl.style.background = currentColors.slideBox || "#ffffff"; - svgEl.style.color = currentColors.slideTitle || "#000000"; - svgEl.style.fontFamily = currentColors.fontFamily || "Inter"; - } - } - }) - .catch((err) => { - console.error("Mermaid render error:", err); - }); - } - }, [mermaidCode, slideIndex, currentColors]); - - return ( -
- -
-
-
- -
-
- -
- ); -}; - -export default Type12Layout; diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx index 1196b50f..0ef673c0 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx @@ -27,6 +27,7 @@ import { jsonrepair } from "jsonrepair"; import { Button } from "@/components/ui/button"; import { AlertCircle } from "lucide-react"; import Help from "./Help"; +import { BASE_URL } from "@/utils/constant"; // Custom debounce function function useDebounce void>( @@ -128,7 +129,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { dispatch(setStreaming(true)); evtSource = new EventSource( - `${PresentationGenerationApi.BASE_URL}/ppt/generate/stream?presentation_id=${presentation_id}&session=${session}` + `${BASE_URL}/ppt/generate/stream?presentation_id=${presentation_id}&session=${session}` ); evtSource.onopen = () => { diff --git a/servers/nextjs/app/(presentation-generator)/services/api/presentation-generation.ts b/servers/nextjs/app/(presentation-generator)/services/api/presentation-generation.ts index ac2bf3bc..734ccf17 100644 --- a/servers/nextjs/app/(presentation-generator)/services/api/presentation-generation.ts +++ b/servers/nextjs/app/(presentation-generator)/services/api/presentation-generation.ts @@ -1,16 +1,16 @@ +import { BASE_URL } from "@/utils/constant"; import { getHeader, getHeaderForFormData } from "./header"; import { IconSearch, ImageGenerate, ImageSearch } from "./params"; export class PresentationGenerationApi { // static BASE_URL="https://api.presenton.ai"; // static BASE_URL="https://presentation-generator-fragrant-mountain-1643.fly.dev"; - static BASE_URL = process.env.NEXT_PUBLIC_FAST_API || 'http://localhost:8000'; // static BASE_URL = "http://localhost:48388"; static async getChapterDetails() { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/chapter-details`, + `${BASE_URL}/ppt/chapter-details`, { method: "GET", headers: getHeader(), @@ -40,7 +40,7 @@ export class PresentationGenerationApi { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/files/upload`, + `${BASE_URL}/ppt/files/upload`, { method: "POST", headers: getHeaderForFormData(), @@ -69,7 +69,7 @@ export class PresentationGenerationApi { }; try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/report/generate`, + `${BASE_URL}/ppt/report/generate`, { method: "POST", headers: getHeader(), @@ -94,7 +94,7 @@ export class PresentationGenerationApi { static async decomposeDocuments(documentKeys: string[], imageKeys: string[]) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/files/decompose`, + `${BASE_URL}/ppt/files/decompose`, { method: "POST", headers: getHeader(), @@ -124,7 +124,7 @@ export class PresentationGenerationApi { }) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/titles/generate`, + `${BASE_URL}/ppt/titles/generate`, { method: "POST", headers: getHeader(), @@ -151,7 +151,7 @@ export class PresentationGenerationApi { static async generatePresentation(presentationData: any) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/generate`, + `${BASE_URL}/ppt/generate`, { method: "POST", headers: getHeader(), @@ -180,7 +180,7 @@ export class PresentationGenerationApi { ) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/edit`, + `${BASE_URL}/ppt/edit`, { method: "POST", headers: getHeader(), @@ -209,7 +209,7 @@ export class PresentationGenerationApi { static async updatePresentationContent(body: any) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/slides/update`, + `${BASE_URL}/ppt/slides/update`, { method: "POST", headers: getHeader(), @@ -235,7 +235,7 @@ export class PresentationGenerationApi { static async generateData(presentationData: any) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/generate/data`, + `${BASE_URL}/ppt/generate/data`, { method: "POST", headers: getHeader(), @@ -259,7 +259,7 @@ export class PresentationGenerationApi { static async imageSearch(imageSearch: ImageSearch) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/image/search`, + `${BASE_URL}/ppt/image/search`, { method: "POST", headers: getHeader(), @@ -281,7 +281,7 @@ export class PresentationGenerationApi { static async generateImage(imageGenerate: ImageGenerate) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/image/generate`, + `${BASE_URL}/ppt/image/generate`, { method: "POST", headers: getHeader(), @@ -304,7 +304,7 @@ export class PresentationGenerationApi { static async searchIcons(iconSearch: IconSearch) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/icon/search`, + `${BASE_URL}/ppt/icon/search`, { method: "POST", headers: getHeader(), @@ -328,7 +328,7 @@ export class PresentationGenerationApi { static async updateDocuments(body: any) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/document/update`, + `${BASE_URL}/ppt/document/update`, { method: "POST", headers: getHeaderForFormData(), @@ -352,7 +352,7 @@ export class PresentationGenerationApi { static async exportAsPPTX(presentationData: any) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/presentation/export_as_pptx/`, + `${BASE_URL}/ppt/presentation/export_as_pptx/`, { method: "POST", headers: getHeader(), @@ -365,7 +365,7 @@ export class PresentationGenerationApi { return { ...data, - url: `${PresentationGenerationApi.BASE_URL}${data.url}`, + url: `${BASE_URL}${data.url}`, }; } else { throw new Error(`Failed to export as pptx: ${response.statusText}`); @@ -378,7 +378,7 @@ export class PresentationGenerationApi { static async exportAsPDF(presentationData: any) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/presentation/export_as_pdf/`, + `${BASE_URL}/ppt/presentation/export_as_pdf/`, { method: "POST", headers: getHeader(), @@ -400,7 +400,7 @@ export class PresentationGenerationApi { static async deleteSlide(presentation_id: string, slide_id: string) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/slide/delete?presentation_id=${presentation_id}&slide_id=${slide_id}`, + `${BASE_URL}/ppt/slide/delete?presentation_id=${presentation_id}&slide_id=${slide_id}`, { method: "DELETE", headers: getHeader(), @@ -421,7 +421,7 @@ export class PresentationGenerationApi { static async setThemeColors(presentation_id: string, theme: any) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/presentation/theme`, + `${BASE_URL}/ppt/presentation/theme`, { method: "POST", headers: getHeader(), @@ -464,7 +464,7 @@ export class PresentationGenerationApi { }) { try { const response = await fetch( - `${PresentationGenerationApi.BASE_URL}/ppt/create`, + `${BASE_URL}/ppt/create`, { method: "POST", headers: getHeader(), diff --git a/servers/nextjs/app/(presentation-generator)/utils/IconList.tsx b/servers/nextjs/app/(presentation-generator)/utils/IconList.tsx deleted file mode 100644 index 8f2c41a1..00000000 --- a/servers/nextjs/app/(presentation-generator)/utils/IconList.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import BabyIcon from "@/components/icons/Baby"; -import PersonIcon from "@/components/icons/Person"; -import HandIcon from "@/components/icons/Hand"; -import TreeIcon from "@/components/icons/Tree"; -import StarIcon from "@/components/icons/Star"; -import CornIcon from "@/components/icons/Corn"; -import MealIcon from "@/components/icons/Meal"; -import DrinkBottleIcon from "@/components/icons/DrinkBottle"; -import CupIcon from "@/components/icons/Cup"; -import DropletIcon from "@/components/icons/Droplet"; -import HouseIcon from "@/components/icons/House"; -import BuildingIcon from "@/components/icons/Building"; -import TentIcon from "@/components/icons/Tent"; -import CarIcon from "@/components/icons/Car"; -import BicycleIcon from "@/components/icons/Bicycle"; -import ClockIcon from "@/components/icons/Clock"; -import BanknoteIcon from "@/components/icons/Banknote"; -import BriefcaseIcon from "@/components/icons/Briefcase"; -import TruckIcon from "@/components/icons/Truck"; -import AirplaneIcon from "@/components/icons/Airplane"; -import LaptopIcon from "@/components/icons/Laptop"; -import MobilePhoneIcon from "@/components/icons/MobilePhone"; -import LightBulbIcon from "@/components/icons/LightBulb"; -import SpannerIcon from "@/components/icons/Spanner"; -import FireIcon from "@/components/icons/Fire"; -import MortarboardIcon from "@/components/icons/Mortarboard"; -import BookIcon from "@/components/icons/Book"; -import SyringeIcon from "@/components/icons/Syringe"; -import FirstAidIcon from "@/components/icons/FirstAid"; -import GlobeIcon from "@/components/icons/Globe"; -// First, let's create a constant object with all the icon mappings -export const ICON_LIST = { - person: PersonIcon, - female_person: PersonIcon, - male_person: PersonIcon, - baby: BabyIcon, - hand: HandIcon, - tree: TreeIcon, - star: StarIcon, - corn: CornIcon, - meal: MealIcon, - drink_bottle: DrinkBottleIcon, - cup: CupIcon, - droplet: DropletIcon, - house: HouseIcon, - building: BuildingIcon, - tent: TentIcon, - car: CarIcon, - bicycle: BicycleIcon, - clock: ClockIcon, - banknote: BanknoteIcon, - briefcase: BriefcaseIcon, - truck: TruckIcon, - airplane: AirplaneIcon, - laptop_computer: LaptopIcon, - mobile_phone: MobilePhoneIcon, - light_bulb: LightBulbIcon, - spanner: SpannerIcon, - fire: FireIcon, - mortarboard: MortarboardIcon, - book: BookIcon, - syringe: SyringeIcon, - first_aid: FirstAidIcon, - globe: GlobeIcon, -} as const; - -// Then modify IconMapper to use this list -export const IconMapper = (isMini = false, icon: string) => { - const IconComponent = ICON_LIST[icon as keyof typeof ICON_LIST]; - if (!IconComponent) return null; - return ; -}; - -export const getPercentage = (numerator: number, denominator: number) => { - if (denominator === 0) return 0; - - return Math.round((numerator / denominator) * 100); -}; diff --git a/servers/nextjs/app/(presentation-generator)/utils/NewSlideContent.ts b/servers/nextjs/app/(presentation-generator)/utils/NewSlideContent.ts index 1d664a29..40ae1336 100644 --- a/servers/nextjs/app/(presentation-generator)/utils/NewSlideContent.ts +++ b/servers/nextjs/app/(presentation-generator)/utils/NewSlideContent.ts @@ -143,241 +143,7 @@ export const getEmptySlideContent = ( ], }, }; - case 10: - return { - ...baseSlide, - type: 10, - // @ts-ignore - content: { - title: "New Title", - infographics: [ - { - title: "Enter Heading", - chart: { - chart_type: "progress-ring", - value: { - number_type: "fraction", - numerator: 4, - denominator: 5, - }, - }, - description: "Enter Description", - }, - { - title: "Enter Heading", - chart: { - chart_type: "progress-ring", - value: { - number_type: "percentage", - percentage: 40, - }, - }, - description: "Enter Description", - }, - ], - }, - }; - case 11: - return { - ...baseSlide, - type: 10, - // @ts-ignore - content: { - title: "New Title", - infographics: [ - { - title: "Enter Heading", - chart: { - chart_type: "text", - value: { - number_type: "numerical", - numerical: "50", - suffix: "quids", - }, - }, - description: "Enter Description", - }, - { - title: "Enter Heading", - chart: { - chart_type: "text", - value: { - number_type: "numerical", - numerical: "23.4", - suffix: "pence", - }, - }, - description: "Enter Description", - }, - ], - }, - }; - case 12: - return { - ...baseSlide, - type: 10, - // @ts-ignore - content: { - title: "New Title", - description: "Enter Description", - infographics: [ - { - title: "Enter Heading", - chart: { - chart_type: "icon-infographic", - icon: "hand", - value: { - number_type: "percentage", - percentage: 75, - }, - }, - description: "Enter Description", - }, - ], - }, - }; - case 13: - return { - ...baseSlide, - type: 10, - // @ts-ignore - content: { - title: "New Title", - description: "Enter Description", - infographics: [ - { - title: "Enter Heading", - chart: { - chart_type: "icon-infographic", - icon: "hand", - value: { - number_type: "percentage", - percentage: 75, - }, - }, - description: "Enter Description", - }, - { - title: "Enter Heading", - chart: { - chart_type: "icon-infographic", - icon: "baby", - value: { - number_type: "percentage", - percentage: 75, - }, - }, - description: "Enter Description", - }, - ], - }, - }; - case 14: - return { - ...baseSlide, - type: 10, - // @ts-ignore - content: { - title: "New Title", - description: "Enter Description", - infographics: [ - { - title: "Enter Heading", - chart: { - chart_type: "progress-ring", - value: { - number_type: "percentage", - percentage: 40, - }, - }, - description: "Enter Description", - }, - { - title: "Enter Heading", - chart: { - chart_type: "progress-ring", - value: { - number_type: "fraction", - numerator: 4, - denominator: 5, - }, - }, - description: "Enter Description", - }, - ], - }, - }; - case 15: - return { - ...baseSlide, - type: 10, - // @ts-ignore - content: { - title: "New Title", - description: "Enter Description", - infographics: [ - { - title: "Enter Heading", - chart: { - chart_type: "progress-dial", - value: { - number_type: "fraction", - numerator: 2, - denominator: 3, - }, - }, - description: "Enter Description", - }, - { - title: "Enter Heading", - chart: { - chart_type: "progress-dial", - value: { - number_type: "percentage", - percentage: 40, - }, - }, - description: "Enter Description", - }, - ], - }, - }; - - case 16: - return { - ...baseSlide, - type: 10, - // @ts-ignore - content: { - title: "New Title", - description: "Enter Description", - infographics: [ - { - title: "Enter Heading", - chart: { - chart_type: "progress-bar", - value: { - number_type: "percentage", - percentage: 40, - }, - }, - description: "Enter Description", - }, - { - title: "Enter Heading", - chart: { - chart_type: "progress-bar", - value: { - number_type: "fraction", - numerator: 4, - denominator: 5, - }, - }, - description: "Enter Description", - }, - ], - }, - }; + default: return baseSlide; } diff --git a/servers/nextjs/app/(presentation-generator)/utils/metadataCollector.ts b/servers/nextjs/app/(presentation-generator)/utils/metadataCollector.ts deleted file mode 100644 index 5b9d4847..00000000 --- a/servers/nextjs/app/(presentation-generator)/utils/metadataCollector.ts +++ /dev/null @@ -1,340 +0,0 @@ -interface ElementPosition { - left: number; - top: number; - width: number; - height: number; -} - -interface FontStyles { - name: string; - size: number; - weight: string; - color: string; -} - - - -interface TextMetadata { - - position: ElementPosition; - paragraphs: Array<{ - text: string; - font: FontStyles; - }>; -} - -interface PictureMetadata { - - position: ElementPosition; - picture:{ - is_network: boolean; - path: string; - } - border_radius: number; -} - -interface GraphMetadata { - - position: ElementPosition; - categoryFont: FontStyles; - valueFont: FontStyles; - legendFont: FontStyles; - graphData: { - type: string; - data: any; // Replace with your specific graph data structure - }; -} - -interface FilledBoxMetadata { - - position: ElementPosition; - type: 1 | 5 | 9; // 1 for rectangle, 2 for circle - fill: { - color:string; - }; - stroke:{ - color:string; - thickness:number; - }, - shadow:{ - radius:number; - color:string; - offset:number; - opacity:number; - angle:number; - }, - -} - -interface LineMetadata { - - position: ElementPosition; - lineType: 1; - thickness: string; - color: string; -} - -interface SlideBoxMetadata { - - position: ElementPosition; - -} - -type ElementMetadata = TextMetadata | PictureMetadata | GraphMetadata | FilledBoxMetadata | LineMetadata | SlideBoxMetadata; - -interface SlideMetadata { - slideIndex: number; - backgroundColor:string; - elements: ElementMetadata[]; -} - -const FIXED_SLIDE_WIDTH = 1280; // Standard slide width -const FIXED_SLIDE_HEIGHT = 720; // Standard slide height - - -// Add this helper function before collectSlideMetadata -const rgbToHex = (color: string): string => { - // Handle empty or invalid colors - if (!color || color === 'transparent' || color === 'none') return '#000000'; - - // If already hex, return as is - if (color.startsWith('#')) return color; - - // Extract RGB/RGBA values - const matches = color.match(/\d+/g); - if (!matches) return '#000000'; - - // Convert to hex - const r = parseInt(matches[0]); - const g = parseInt(matches[1]); - const b = parseInt(matches[2]); - - return [r, g, b] - .map(x => x.toString(16).padStart(2, '0')) - .join(''); -}; - - - -export const collectSlideMetadata = (): SlideMetadata[] => { - const slidesMetadata: SlideMetadata[] = []; - - const slideContainers = document.querySelectorAll('[data-element-type="slide-container"]'); - - slideContainers.forEach((container) => { - const containerEl = container as HTMLElement; - const containerRect = containerEl.getBoundingClientRect(); - const slideIndex = parseInt(containerEl.getAttribute('data-slide-index') || '0'); - - // Get container computed styles - const containerComputedStyle = window.getComputedStyle(containerEl); - - const slideMetadata: SlideMetadata = { - slideIndex, - backgroundColor: rgbToHex(containerComputedStyle.backgroundColor), - elements: [] - }; - - const elements = containerEl.querySelectorAll('[data-slide-element]:not([data-element-type="slide-container"])'); - - elements.forEach((element) => { - const el = element as HTMLElement; - const elementRect = el.getBoundingClientRect(); - const computedStyle = window.getComputedStyle(el); - - // Calculate position relative to slide container - const position: ElementPosition = { - left: Math.round(elementRect.left - containerRect.left), - top: Math.round(elementRect.top - containerRect.top), - width: Math.round(elementRect.width), - height: Math.round(elementRect.height) - }; - - - const elementType = el.getAttribute('data-element-type'); - if (!elementType) return; - - // Get computed font styles after Tailwind has been applied - const fontStyles: FontStyles = { - // name: computedStyle.fontFamily.replace(/['"]/g, ''), - name:"Inter", - size: parseInt(computedStyle.fontSize), - weight: computedStyle.fontWeight, - color: rgbToHex(computedStyle.color) - }; - - switch (elementType) { - case 'text': - slideMetadata.elements.push({ - position, - paragraphs: [{ - text: el.textContent || '', - font: fontStyles - }] - }); - break; - - case 'picture': - // Handle both img elements and elements containing img - let imgEl: HTMLImageElement | null; - if (el.tagName.toLowerCase() === 'img') { - imgEl = el as HTMLImageElement; - } else { - imgEl = el.querySelector('img'); - } - - if (imgEl) { - slideMetadata.elements.push({ - - position, - picture:{ - - is_network: imgEl.src.startsWith('http'), - path: imgEl.src || imgEl.getAttribute('data-image-path') || '', - }, - border_radius: parseInt(computedStyle.borderRadius) - }); - } - break; - - case 'graph': - slideMetadata.elements.push({ - position, - categoryFont: { - name: computedStyle.fontFamily.replace(/['"]/g, ''), - size: parseInt(computedStyle.fontSize) , - weight: computedStyle.fontWeight, - color: computedStyle.color - }, - valueFont: fontStyles, - legendFont: fontStyles, - graphData: { - type: el.getAttribute('data-graph-type') || 'bar', - data: JSON.parse(el.getAttribute('data-graph-data') || '{}') - } - }); - break; - - case 'filledbox':{ - const boxShadow = computedStyle.boxShadow; - - // Default shadow properties - let shadowRadius = 0; - let shadowColor = '#000000'; - let shadowOffsetX = 0; - let shadowOffsetY = 0; - let shadowOpacity = 0; - - if (boxShadow && boxShadow !== 'none') { - // Regex to parse box-shadow values: "offset-x offset-y blur-radius spread-radius color" - const boxShadowRegex = /rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]+)?\)?\s+(-?\d+px)\s+(-?\d+px)\s+(-?\d+px)\s+(-?\d+px)|(-?\d+px)\s+(-?\d+px)\s+(-?\d+px)\s+(-?\d+px)\s+rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]+)?\)?/; - - const match = boxShadow.match(boxShadowRegex); - - if (!match) return null; - - // Extract values based on format - shadowColor =rgbToHex( match[1] - ? "rgb(" + match[1] + ", " + match[2] + ", " + match[3] + ")" - : "rgb(" + match[13] + ", " + match[14] + ", " + match[15] + ")"); - shadowOpacity = parseInt(match[4] || match[16] || '1'); - shadowOffsetX = parseInt(match[5] || match[9]); - shadowOffsetY = parseInt(match[6] || match[10]); - shadowRadius = parseInt(match[7] || match[11]); - - } - - slideMetadata.elements.push({ - position, - type: computedStyle.borderRadius === '9999px' || computedStyle.borderRadius === '50%' ? 9 : 5, - fill: { - color: rgbToHex(computedStyle.backgroundColor), - }, - border_radius: parseInt(computedStyle.borderRadius) || 0, - stroke: { - color: rgbToHex(computedStyle.borderColor), - thickness: parseInt(computedStyle.borderWidth) || 0, - }, - shadow: { - radius: shadowRadius, - color: shadowColor, - offset: Math.sqrt(shadowOffsetX ** 2 + shadowOffsetY ** 2), // Total offset length - opacity: shadowOpacity, - angle: Math.round((Math.atan2(shadowOffsetY, shadowOffsetX) * 180) / Math.PI), // Shadow angle in degrees - }, - - }); - break; -} - - case 'line': - slideMetadata.elements.push({ - - position, - lineType: 1, - thickness: computedStyle.borderWidth || computedStyle.height, - color: rgbToHex(computedStyle.borderColor || computedStyle.backgroundColor) - }); - break; - case 'slide-box': { - const boxShadow = computedStyle.boxShadow; - console.log('slide-box', boxShadow, 'slide-box'); - - // Default shadow properties - let shadowRadius = 0; - let shadowColor = '#000000'; - let shadowOffsetX = 0; - let shadowOffsetY = 0; - let shadowOpacity = 0; - - if (boxShadow && boxShadow !== 'none') { - // Regex to parse box-shadow values: "offset-x offset-y blur-radius spread-radius color" - const boxShadowRegex = /rgba\((\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)\)\s*(-?\d+)px\s*(-?\d+)px\s*(-?\d+)px\s*(-?\d+)px/; - const match = boxShadow.match(boxShadowRegex); - - if (match) { - const [_, r, g, b, opacity, xOffset, yOffset, blurRadius, spreadRadius] = match; - console.log('rgb',`rgb(${r},${g},${b})`); - shadowOpacity=parseInt(opacity); - shadowRadius=parseInt(blurRadius); - shadowColor= rgbToHex(`rgba(${r},${g},${b},1)`) - shadowOffsetX=parseInt(xOffset); - - shadowOffsetY=parseInt(yOffset); - - - } - } - - slideMetadata.elements.push({ - position, - type: computedStyle.borderRadius === '9999px' || computedStyle.borderRadius === '50%' ? 9 : 5, - fill: { - color: rgbToHex(computedStyle.backgroundColor), - }, - border_radius: parseInt(computedStyle.borderRadius) || 0, - stroke: { - color: rgbToHex(computedStyle.borderColor), - thickness: parseInt(computedStyle.borderWidth) || 0, - }, - shadow: { - radius: shadowRadius, - color: shadowColor, - offset: Math.sqrt(shadowOffsetX ** 2 + shadowOffsetY ** 2), // Total offset length - opacity: shadowOpacity, - angle: Math.round((Math.atan2(shadowOffsetY, shadowOffsetX) * 180) / Math.PI), // Shadow angle in degrees - }, - - }); - break; -} - - - } - }); - - slidesMetadata.push(slideMetadata); - }); - - return slidesMetadata; -}; \ No newline at end of file diff --git a/servers/nextjs/app/dashboard/api/dashboard.ts b/servers/nextjs/app/dashboard/api/dashboard.ts index 4c179dbf..f95280e6 100644 --- a/servers/nextjs/app/dashboard/api/dashboard.ts +++ b/servers/nextjs/app/dashboard/api/dashboard.ts @@ -2,6 +2,7 @@ import { getHeader, getHeaderForFormData, } from "@/app/(presentation-generator)/services/api/header"; +import { BASE_URL } from "@/utils/constant"; export interface PresentationResponse { id: string; @@ -22,11 +23,11 @@ export interface PresentationResponse { export class DashboardApi { // static BASE_URL = "http://localhost:48388"; - static BASE_URL = process.env.NEXT_PUBLIC_FAST_API || 'http://localhost:8000'; + static async getPresentations(): Promise { try { const response = await fetch( - `${DashboardApi.BASE_URL}/ppt/user_presentations`, + `${BASE_URL}/ppt/user_presentations`, { method: "GET", headers: getHeader(), @@ -48,7 +49,7 @@ export class DashboardApi { static async getPresentation(id: string) { try { const response = await fetch( - `${DashboardApi.BASE_URL}/ppt/presentation?presentation_id=${id}`, + `${BASE_URL}/ppt/presentation?presentation_id=${id}`, { method: "GET", headers: getHeader(), @@ -67,7 +68,7 @@ export class DashboardApi { static async deletePresentation(presentation_id: string) { try { const response = await fetch( - `${DashboardApi.BASE_URL}/ppt/delete?presentation_id=${presentation_id}`, + `${BASE_URL}/ppt/delete?presentation_id=${presentation_id}`, { method: "DELETE", headers: getHeader(), @@ -90,7 +91,7 @@ export class DashboardApi { formData.append("thumbnail", file); try { const response = await fetch( - `${DashboardApi.BASE_URL}/ppt/presentation/thumbnail`, + `${BASE_URL}/ppt/presentation/thumbnail`, { method: "POST", headers: getHeaderForFormData(), diff --git a/servers/nextjs/app/privacy-policy/page.tsx b/servers/nextjs/app/privacy-policy/page.tsx deleted file mode 100644 index 4f178fe1..00000000 --- a/servers/nextjs/app/privacy-policy/page.tsx +++ /dev/null @@ -1,377 +0,0 @@ -import React from 'react' -import { Metadata } from 'next' -import MarkdownRenderer from '../(presentation-generator)/documents-preview/components/MarkdownRenderer'; - -export const metadata: Metadata = { - title: 'Presenton Privacy Policy | Data Protection Guidelines', - description: 'Learn how Present On protects your privacy and personal data. Our privacy policy outlines data collection, usage, security measures and your rights as a user.', -} - -export default function PrivacyPolicyPage() { - return ( - //
- //

Privacy Policy

- //

Last updated: November 29, 2024

- //

This Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your information when You use the Service and tells You about Your privacy rights and how the law protects You.

- //

We use Your Personal data to provide and improve the Service. By using the Service, You agree to the collection and use of information in accordance with this Privacy Policy.

- - //

Interpretation and Definitions

- //

Interpretation

- - //

- // The words of which the initial letter is capitalized have meanings defined under the following conditions. The following definitions shall have the same meaning regardless of whether they appear in singular or in plural. - //

- - //

Definitions

- //

- // For the purposes of this Privacy Policy: - //

- //
    - //
  • - //

    Account means a unique account created for You to access our Service or parts of our Service.

    - //
  • - //
  • - //

    Affiliate means an entity that controls, is controlled by or is under common control with a party, where "control" means ownership of 50% or more of the shares, equity interest or other securities entitled to vote for election of directors or other managing authority.

    - //
  • - //
  • - //

    Company (referred to as either "the Company", "We", "Us" or "Our" in this Agreement) refers to Present On.

    - //
  • - //
  • - //

    Cookies are small files that are placed on Your computer, mobile device or any other device by a website, containing the details of Your browsing history on that website among its many uses.

    - //
  • - //
  • - //

    Country refers to: Nepal

    - //
  • - //
  • - //

    Device means any device that can access the Service such as a computer, a cellphone or a digital tablet.

    - //
  • - //
  • - //

    Personal Data is any information that relates to an identified or identifiable individual.

    - //
  • - //
  • - //

    Service refers to the Website.

    - //
  • - //
  • - //

    Service Provider means any natural or legal person who processes the data on behalf of the Company. It refers to third-party companies or individuals employed by the Company to facilitate the Service, to provide the Service on behalf of the Company, to perform services related to the Service or to assist the Company in analyzing how the Service is used.

    - //
  • - //
  • - //

    Third-party Social Media Service refers to any website or any social network website through which a User can log in or create an account to use the Service.

    - //
  • - //
  • - //

    Usage Data refers to data collected automatically, either generated by the use of the Service or from the Service infrastructure itself (for example, the duration of a page visit).

    - //
  • - //
  • - //

    Website refers to Present On, accessible from https://presenton.ai

    - //
  • - //
  • - //

    You means the individual accessing or using the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.

    - //
  • - //
- //

Collecting and Using Your Personal Data

- //

Types of Data Collected

- //

Personal Data

- //

- // While using Our Service, We may ask You to provide Us with certain personally identifiable information that can be used to contact or identify You. Personally identifiable information may include, but is not limited to: - //

- //
    - //
  • - //

    Email address

    - //
  • - //
  • - //

    First name and last name

    - //
  • - //
  • - //

    Address, State, Province, ZIP/Postal code, City

    - //
  • - //
  • - //

    Usage Data

    - //
  • - //
- //

Usage Data

- //

- // Usage Data is collected automatically when using the Service. - //

- //

- // Usage Data may include information such as Your Device's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that You visit, the time and date of Your visit, the time spent on those pages, unique device identifiers and other diagnostic data. - //

- //

- // When You access the Service by or through a mobile device, We may collect certain information automatically, including, but not limited to, the type of mobile device You use, Your mobile device unique ID, the IP address of Your mobile device, Your mobile operating system, the type of mobile Internet browser You use, unique device identifiers and other diagnostic data. - //

- //

- // We may also collect information that Your browser sends whenever You visit our Service or when You access the Service by or through a mobile device. - //

- //

Information from Third-Party Social Media Services

- //

- // The Company allows You to create an account and log in to use the Service through the following Third-party Social Media Services: - //

- //
    - //
  • Google
  • - //
  • Facebook
  • - //
  • Instagram
  • - //
  • Twitter
  • - //
  • LinkedIn
  • - //
- //

- // If You decide to register through or otherwise grant us access to a Third-Party Social Media Service, We may collect Personal data that is already associated with Your Third-Party Social Media Service's account, such as Your name, Your email address, Your activities or Your contact list associated with that account. - //

- //

- // You may also have the option of sharing additional information with the Company through Your Third-Party Social Media Service's account. If You choose to provide such information and Personal Data, during registration or otherwise, You are giving the Company permission to use, share, and store it in a manner consistent with this Privacy Policy. - //

- //

Tracking Technologies and Cookies

- //

- // We use Cookies and similar tracking technologies to track the activity on Our Service and store certain information. Tracking technologies used are beacons, tags, and scripts to collect and track information and to improve and analyze Our Service. The technologies We use may include: - //

- //
    - //
  • - //

    Cookies or Browser Cookies. A cookie is a small file placed on Your Device. You can instruct Your browser to refuse all Cookies or to indicate when a Cookie is being sent. However, if You do not accept Cookies, You may not be able to use some parts of our Service. Unless you have adjusted Your browser setting so that it will refuse Cookies, our Service may use Cookies.

    - //
  • - //
  • - //

    Web Beacons. Certain sections of our Service and our emails may contain small electronic files known as web beacons (also referred to as clear gifs, pixel tags, and single-pixel gifs) that permit the Company, for example, to count users who have visited those pages or opened an email and for other related website statistics (for example, recording the popularity of a certain section and verifying system and server integrity).

    - //
  • - //
- //

- // Cookies can be "Persistent" or "Session" Cookies. Persistent Cookies remain on Your personal computer or mobile device when You go offline, while Session Cookies are deleted as soon as You close Your web browser. You can learn more about cookies on TermsFeed website article. - //

- //

- // We use both Session and Persistent Cookies for the purposes set out below: - //

- //
    - //
  • - //

    Necessary / Essential Cookies

    - //

    Type: Session Cookies

    - //

    Administered by: Us

    - //

    Purpose: These Cookies are essential to provide You with services available through the Website and to enable You to use some of its features. They help to authenticate users and prevent fraudulent use of user accounts. Without these Cookies, the services that You have asked for cannot be provided, and We only use these Cookies to provide You with those services.

    - //
  • - //
  • - //

    Cookies Policy / Notice Acceptance Cookies

    - //

    Type: Persistent Cookies

    - //

    Administered by: Us

    - //

    Purpose: These Cookies identify if users have accepted the use of cookies on the Website.

    - //
  • - //
  • - //

    Functionality Cookies

    - //

    Type: Persistent Cookies

    - //

    Administered by: Us

    - //

    Purpose: These Cookies allow us to remember choices You make when You use the Website, such as remembering your login details or language preference. The purpose of these Cookies is to provide You with a more personal experience and to avoid You having to re-enter your preferences every time You use the Website.

    - //
  • - //
- //

- // For more information about the cookies we use and your choices regarding cookies, please visit our Cookies Policy or the Cookies section of our Privacy Policy. - //

- //

Use of Your Personal Data

- //

- // The Company may use Personal Data for the following purposes: - //

- //
    - //
  • - //

    To provide and maintain our Service, including to monitor the usage of our Service.

    - //
  • - //
  • - //

    To manage Your Account: to manage Your registration as a user of the Service. The Personal Data You provide can give You access to different functionalities of the Service that are available to You as a registered user.

    - //
  • - //
  • - //

    For the performance of a contract: the development, compliance and undertaking of the purchase contract for the products, items or services You have purchased or of any other contract with Us through the Service.

    - //
  • - //
  • - //

    To contact You: To contact You by email, telephone calls, SMS, or other equivalent forms of electronic communication, such as a mobile application's push notifications regarding updates or informative communications related to the functionalities, products or contracted services, including the security updates, when necessary or reasonable for their implementation.

    - //
  • - //
  • - //

    To provide You with news, special offers and general information about other goods, services and events which we offer that are similar to those that you have already purchased or enquired about unless You have opted not to receive such information.

    - //
  • - //
  • - //

    To manage Your requests: To attend and manage Your requests to Us.

    - //
  • - //
  • - //

    For business transfers: We may use Your information to evaluate or conduct a merger, divestiture, restructuring, reorganization, dissolution, or other sale or transfer of some or all of Our assets, whether as a going concern or as part of bankruptcy, liquidation, or similar proceeding, in which Personal Data held by Us about our Service users is among the assets transferred.

    - //
  • - //
  • - //

    For other purposes: We may use Your information for other purposes, such as data analysis, identifying usage trends, determining the effectiveness of our promotional campaigns and to evaluate and improve our Service, products, services, marketing and your experience.

    - //
  • - //
- //

- // We may share Your personal information in the following situations: - //

- //
    - //
  • - //

    With Service Providers: We may share Your personal information with Service Providers to monitor and analyze the use of our Service, to contact You.

    - //
  • - //
  • - //

    For business transfers: We may share or transfer Your personal information in connection with, or during negotiations of, any merger, sale of Company assets, financing, or acquisition of all or a portion of Our business to another company.

    - //
  • - //
  • - //

    With Affiliates: We may share Your information with Our affiliates, in which case we will require those affiliates to honor this Privacy Policy. Affiliates include Our parent company and any other subsidiaries, joint venture partners or other companies that We control or that are under common control with Us.

    - //
  • - //
  • - //

    With business partners: We may share Your information with Our business partners to offer You certain products, services or promotions.

    - //
  • - //
  • - //

    With other users: when You share personal information or otherwise interact in the public areas with other users, such information may be viewed by all users and may be publicly distributed outside. If You interact with other users or register through a Third-Party Social Media Service, Your contacts on the Third-Party Social Media Service may see Your name, profile, pictures and description of Your activity. Similarly, other users will be able to view descriptions of Your activity, communicate with You and view Your profile.

    - //
  • - //
  • - //

    With Your consent: We may disclose Your personal information for any other purpose with Your consent.

    - //
  • - //
- //

Retention of Your Personal Data

- //

- // The Company will retain Your Personal Data only for as long as is necessary for the purposes set out in this Privacy Policy. We will retain and use Your Personal Data to the extent necessary to comply with our legal obligations (for example, if we are required to retain your data to comply with applicable laws), resolve disputes, and enforce our legal agreements and policies. - //

- //

- // The Company will also retain Usage Data for internal analysis purposes. Usage Data is generally retained for a shorter period of time, except when this data is used to strengthen the security or to improve the functionality of Our Service, or We are legally obligated to retain this data for longer time periods. - //

- //

Transfer of Your Personal Data

- //

- // Your information, including Personal Data, is processed at the Company's operating offices and in any other places where the parties involved in the processing are located. It means that this information may be transferred to — and maintained on — computers located outside of Your state, province, country or other governmental jurisdiction where the data protection laws may differ than those from Your jurisdiction. - //

- //

- // Your consent to this Privacy Policy followed by Your submission of such information represents Your agreement to that transfer. - //

- //

- // The Company will take all steps reasonably necessary to ensure that Your data is treated securely and in accordance with this Privacy Policy and no transfer of Your Personal Data will take place to an organization or a country unless there are adequate controls in place including the security of Your data and other personal information. - //

- //

Delete Your Personal Data

- //

- // You have the right to delete or request that We assist in deleting the Personal Data that We have collected about You. - //

- //

- // Our Service may give You the ability to delete certain information about You from within the Service. - //

- //

- // You may update, amend, or delete Your information at any time by signing in to Your Account, if you have one, and visiting the account settings section that allows you to manage Your personal information. You may also contact Us to request access to, correct, or delete any personal information that You have provided to Us. - //

- //

- // Please note, however, that We may need to retain certain information when we have a legal obligation or lawful basis to do so. - //

- //

Disclosure of Your Personal Data

- //

Business Transactions

- //

- // If the Company is involved in a merger, acquisition or asset sale, Your Personal Data may be transferred. We will provide notice before Your Personal Data is transferred and becomes subject to a different Privacy Policy. - //

- //

Law enforcement

- //

- // Under certain circumstances, the Company may be required to disclose Your Personal Data if required to do so by law or in response to valid requests by public authorities (e.g. a court or a government agency). - //

- //

Other legal requirements

- //

- // The Company may disclose Your Personal Data in the good faith belief that such action is necessary to: - //

- //
    - //
  • Comply with a legal obligation
  • - //
  • Protect and defend the rights or property of the Company
  • - //
  • Prevent or investigate possible wrongdoing in connection with the Service
  • - //
  • Protect the personal safety of Users of the Service or the public
  • - //
  • Protect against legal liability
  • - //
- //

Security of Your Personal Data

- //

- // The security of Your Personal Data is important to Us, but remember that no method of transmission over the Internet, or method of electronic storage is 100% secure. While We strive to use commercially acceptable means to protect Your Personal Data, We cannot guarantee its absolute security. - //

- //

Children's Privacy

- //

- // Our Service does not address anyone under the age of 13. We do not knowingly collect personally identifiable information from anyone under the age of 13. If You are a parent or guardian and You are aware that Your child has provided Us with Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the age of 13 without verification of parental consent, We take steps to remove that information from Our servers. - //

- //

- // If We need to rely on consent as a legal basis for processing Your information and Your country requires consent from a parent, We may require Your parent's consent before We collect and use that information. - //

- //

Links to Other Websites

- //

- // Our Service may contain links to other websites that are not operated by Us. If You click on a third party link, You will be directed to that third party's site. We strongly advise You to review the Privacy Policy of every site You visit. - //

- //

- // We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services. - //

- //

Changes to this Privacy Policy

- //

- // We may update Our Privacy Policy from time to time. We will notify You of any changes by posting the new Privacy Policy on this page. - //

- //

- // We will let You know via email and/or a prominent notice on Our Service, prior to the change becoming effective and update the "Last updated" date at the top of this Privacy Policy. - //

- //

- // You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page. - //

- //

Contact Us

- //

- // If you have any questions about this Privacy Policy, You can contact us: - //

- // - //
-
- - -Kinu Tech Pvt. Ltd. ("Presenton," "we," "us," or "our") is committed to safeguarding your privacy. This Privacy Policy describes how we collect, use, disclose, and protect your personal information in connection with our services. By accessing or using our services, you agree to this Privacy Policy. -## 1. Scope -This Privacy Policy applies to all personal data collected through our website, applications, and any related services. -## 2. Information We Collect -### Personal Information -- **Identity Data:** Name, username, or similar identifiers. -- **Contact Data:** Email address, phone numbers. -- **Financial Data:** Payment card details (processed via Stripe). -- **Transaction Data:** Details about payments and services. -- **Technical Data:** IP address, login data, browser type, time zone, browser plug-in types, and platform. -- **Profile Data:** Preferences, feedback, and survey responses. -- **Usage Data:** Information on how you use our website and services. -- **Marketing and Communications Data:** Your preferences in receiving marketing from us and third parties. -## 3. How We Collect Data -- **Direct Interactions:** Account creation, purchase of services, feedback forms. -- **Automated Technologies:** Cookies, server logs, and analytics tools (via Google Analytics). -- **Third Parties:** Identity and contact data from third-party platforms like Supabase. -## 4. Legal Basis for Processing -We process your personal data under the following legal grounds: -- **Consent:** When you provide consent for marketing. -- **Contractual Necessity:** To fulfill our service agreement with you. -- **Legal Obligation:** To comply with applicable laws. -- **Legitimate Interests:** Improving our services and user experience. -## 5. How We Use Your Data -We use your data for: -- Account setup and maintenance -- Processing transactions -- Customer support -- Improving our platform and services -- Marketing and promotional communications -## 6. Sharing Your Information -We may share your information with: -- **Service Providers:** For hosting, payment processing (Stripe), and analytics. -- **Professional Advisers:** Lawyers, bankers, auditors. -- **Regulatory Authorities:** As required by law. -- **Business Transfers:** As part of mergers, acquisitions, or sales. -## 7. International Transfers -Your data may be transferred to countries outside your location. We ensure adequate data protection measures are in place, such as standard contractual clauses. -## 8. Data Security -We implement advanced security measures, including: -- **Encryption:** Protecting personal data during transmission. -- **Access Controls:** Limiting access to personal information. -- **Monitoring:** Regular security audits and vulnerability assessments. -## 9. Data Retention -We retain your data for as long as necessary to fulfill our services and comply with legal obligations. Upon request, we will delete your data in accordance with applicable laws. -## 10. Cookies and Tracking -Our website uses cookies for: -- Functionality: Remembering your preferences. -- Performance: Analyzing usage to improve our site. -- Targeting: Providing personalized advertising based on browsing activity. -You may control cookies through browser settings, but disabling them may affect your experience. -## 11. Your Privacy Rights -Depending on your location, you may have the right to: -- Access, correct, or delete your personal data. -- Object to or restrict processing. -- Withdraw consent where processing is based on consent. -- Request data portability. -To exercise these rights, contact us at [suraj@presenton.ai](mailto:suraj@presenton.ai). -## 12. Children's Privacy -Our services are not intended for individuals under 13 years old. We do not knowingly collect data from children. -## 13. Policy Updates -We may update this Privacy Policy to reflect changes in technology or legislation. Changes will be notified via email or site notifications. -## 14. Contact Us -For any questions or concerns about this Privacy Policy, please contact: -- **Suraj Jha** -- Email: [suraj@presenton.ai](mailto:suraj@presenton.ai) -## 15. Governing Law and Dispute Resolution -This Privacy Policy is governed by the laws of [Specify Jurisdiction]. Any disputes arising under this policy will be resolved in accordance with local regulations. `} /> -
- ); -} \ No newline at end of file diff --git a/servers/nextjs/app/terms-and-conditions/page.tsx b/servers/nextjs/app/terms-and-conditions/page.tsx deleted file mode 100644 index ba63955a..00000000 --- a/servers/nextjs/app/terms-and-conditions/page.tsx +++ /dev/null @@ -1,191 +0,0 @@ -import React from 'react' -import { Metadata } from 'next' -import MarkdownRenderer from '../(presentation-generator)/documents-preview/components/MarkdownRenderer' - -export const metadata: Metadata = { - title: 'Terms and Conditions | Presenton.ai', - description: ' Read our terms and conditions to understand our legal policies, user rights, service terms, and privacy guidelines for using our AI presentation platform.', -} - -const page = () => { - return ( - //
- // [data-custom-class='body'], [data-custom-class='body'] * { - // background: transparent !important; - // } - // [data-custom-class='title'], [data-custom-class='title'] * { - // font-family: Arial !important; - // font-size: 26px !important; - // color: #000000 !important; - // } - // [data-custom-class='subtitle'], [data-custom-class='subtitle'] * { - // font-family: Arial !important; - // color: #595959 !important; - // font-size: 14px !important; - // } - // [data-custom-class='heading_1'], [data-custom-class='heading_1'] * { - // font-family: Arial !important; - // font-size: 19px !important; - // color: #000000 !important; - // } - // [data-custom-class='heading_2'], [data-custom-class='heading_2'] * { - // font-family: Arial !important; - // font-size: 17px !important; - // color: #000000 !important; - // } - // [data-custom-class='body_text'], [data-custom-class='body_text'] * { - // color: #595959 !important; - // font-size: 14px !important; - // font-family: Arial !important; - // } - // [data-custom-class='link'], [data-custom-class='link'] * { - // color: #3030F1 !important; - // font-size: 14px !important; - // font-family: Arial !important; - // word-break: break-word !important; - // } - // - - - //
- //
TERMS AND CONDITIONS

Last updated November 29, 2024



AGREEMENT TO OUR LEGAL TERMS

We are Kinu Tech ("Company," "we," "us," "our").

We operate the website https://presenton.ai (the "Site"), as well as any other related products and services that refer or link to these legal terms (the "Legal Terms") (collectively, the "Services").

You can contact us by email at __________ or by mail to __________, ____________________.

These Legal Terms constitute a legally binding agreement made between you, whether personally or on behalf of an entity ("you"), and Kinu Tech, concerning your access to and use of the Services. You agree that by accessing the Services, you have read, understood, and agreed to be bound by all of these Legal Terms. IF YOU DO NOT AGREE WITH ALL OF THESE LEGAL TERMS, THEN YOU ARE EXPRESSLY PROHIBITED FROM USING THE SERVICES AND YOU MUST DISCONTINUE USE IMMEDIATELY.

Supplemental terms and conditions or documents that may be posted on the Services from time to time are hereby expressly incorporated herein by reference. We reserve the right, in our sole discretion, to make changes or modifications to these Legal Terms from time to time. We will alert you about any changes by updating the "Last updated" date of these Legal Terms, and you waive any right to receive specific notice of each such change. It is your responsibility to periodically review these Legal Terms to stay informed of updates. You will be subject to, and will be deemed to have been made aware of and to have accepted, the changes in any revised Legal Terms by your continued use of the Services after the date such revised Legal Terms are posted.

All users who are minors in the jurisdiction in which they reside (generally under the age of 18) must have the permission of, and be directly supervised by, their parent or guardian to use the Services. If you are a minor, you must have your parent or guardian read and agree to these Legal Terms prior to you using the Services.

We recommend that you print a copy of these Legal Terms for your records.


TABLE OF CONTENTS



1. OUR SERVICES

The information provided when using the Services is not intended for distribution to or use by any person or entity in any jurisdiction or country where such distribution or use would be contrary to law or regulation or which would subject us to any registration requirement within such jurisdiction or country. Accordingly, those persons who choose to access the Services from other locations do so on their own initiative and are solely responsible for compliance with local laws, if and to the extent local laws are applicable.

The Services are not tailored to comply with industry-specific regulations (Health Insurance Portability and Accountability Act (HIPAA), Federal Information Security Management Act (FISMA), etc.), so if your interactions would be subjected to such laws, you may not use the Services. You may not use the Services in a way that would violate the Gramm-Leach-Bliley Act (GLBA).

2. INTELLECTUAL PROPERTY RIGHTS

Our intellectual property

We are the owner or the licensee of all intellectual property rights in our Services, including all source code, databases, functionality, software, website designs, audio, video, text, photographs, and graphics in the Services (collectively, the "Content"), as well as the trademarks, service marks, and logos contained therein (the "Marks").

Our Content and Marks are protected by copyright and trademark laws (and various other intellectual property rights and unfair competition laws) and treaties in the United States and around the world.

The Content and Marks are provided in or through the Services "AS IS" for your personal, non-commercial use or internal business purpose only.

Your use of our Services

Subject to your compliance with these Legal Terms, including the "PROHIBITED ACTIVITIES" section below, we grant you a non-exclusive, non-transferable, revocable license to:
  • access the Services; and
  • download or print a copy of any portion of the Content to which you have properly gained access,
solely for your personal, non-commercial use or internal business purpose.

Except as set out in this section or elsewhere in our Legal Terms, no part of the Services and no Content or Marks may be copied, reproduced, - // aggregated, republished, uploaded, posted, publicly displayed, encoded, - // translated, transmitted, distributed, sold, licensed, or otherwise exploited - // for any commercial purpose whatsoever, without our express prior written - // permission.

If you wish to make any use of the Services, Content, or Marks other than as set out in this section or elsewhere in our Legal Terms, please address your request to: __________. If we ever grant you the permission to post, reproduce, or publicly display any part of our Services or Content, you must identify us as the owners or licensors of the Services, Content, or Marks and ensure that any copyright or proprietary notice appears or is visible on posting, reproducing, or displaying our Content.

We reserve all rights not expressly granted to you in and to the Services, Content, and Marks.

Any breach of these Intellectual Property Rights will constitute a material breach of our Legal Terms and your right to use our Services will terminate immediately.

Your submissions

Please review this section and the "PROHIBITED ACTIVITIES" section carefully prior to using our Services to understand the (a) rights you give us and (b) obligations you have when you post or upload any content through the Services.

Submissions: By directly sending us any question, comment, suggestion, idea, feedback, or other information about the Services ("Submissions"), you agree to assign to us all intellectual property rights in such Submission. You agree that we shall own this Submission and be entitled to its unrestricted use and dissemination for any lawful purpose, commercial or otherwise, without acknowledgment or compensation to you.

You are responsible for what you post or upload: By sending us Submissions through any part of the Services you:
  • confirm that you have read and agree with our "PROHIBITED ACTIVITIES" and will not post, send, publish, upload, or transmit through the Services any Submission that is illegal, harassing, hateful, harmful, defamatory, obscene, bullying, abusive, discriminatory, threatening to any person or group, sexually explicit, false, inaccurate, deceitful, or misleading;
  • to the extent permissible by applicable law, waive any and all moral rights to any such Submission;
  • warrant that any such Submission are original to you or that you have the necessary rights and licenses to submit such Submissions and that you have full authority to grant us the above-mentioned rights in relation to your Submissions; and
  • warrant and represent that your Submissions do not constitute confidential information.
You are solely responsible for your Submissions and you expressly agree to reimburse us for any and all losses that we may suffer because of your breach of (a) this section, (b) any third party’s intellectual property rights, or (c) applicable law.

3. USER REPRESENTATIONS

By using the Services, you represent and warrant that: (1) all registration information you submit - // will be true, accurate, current, and complete; (2) you will maintain the accuracy of such information and promptly update such registration information as necessary; (3) you have the legal capacity and you agree to comply with these Legal Terms; (4) you are not a - // minor in the jurisdiction in which you reside, or if a minor, you have - // received parental permission to use the Services; (5) you will not access the Services through automated or non-human means, whether through a bot, script or - // otherwise; (6) you will not use the Services for any illegal or unauthorized purpose; and (7) your use of the Services will not violate any applicable law or regulation.

If you provide any information that is untrue, inaccurate, not current, or incomplete, we have the right to suspend or terminate your account and refuse any and all current or future use of the Services (or any portion thereof).

4. USER REGISTRATION

You may be required to register to use the Services. You agree to keep your password confidential and will be responsible for all use of your account and password. We reserve the right to remove, reclaim, or change a username you select if we determine, in our sole discretion, that such username is inappropriate, obscene, or otherwise objectionable.

5. PURCHASES AND PAYMENT

We accept the following forms of payment:

-  Visa

You agree to provide current, complete, and accurate purchase and account information for all purchases made via the Services. You further agree to promptly update account and payment information, including email address, payment method, and payment card expiration date, so that we can complete your transactions and contact you as needed. Sales tax will be added to the price of purchases as deemed required by us. We may change prices at any time. All payments shall be in US dollars.

You agree to pay all charges at the prices then in effect for your purchases and any applicable shipping fees, and you authorize us to charge your chosen payment provider for any such amounts upon placing your order. We reserve the right to correct any errors or mistakes in pricing, even if we have already requested or received payment.

We reserve the right to refuse any order placed through the Services. We may, in our sole discretion, limit or cancel quantities purchased per person, per household, or per order. These restrictions may include orders placed by or under the same customer account, the same payment method, and/or orders that use the same billing or shipping address. We reserve the right to limit or prohibit orders that, in our sole judgment, appear to be placed by dealers, resellers, or distributors.

6. SUBSCRIPTIONS

Billing and Renewal

Your subscription will continue and automatically renew unless canceled. You consent to our charging your payment method on a recurring basis without requiring your prior approval for each recurring charge, until such time as you cancel the applicable order. The length of your billing cycle will depend on the type of subscription plan you choose when you subscribed to the Services.

Free Trial

We offer a __________-day free trial to new users who register with the Services. The account will be charged according to the user's chosen subscription at the end of the free trial.

Cancellation

All purchases are non-refundable. You can cancel your subscription at any time by logging into your account. Your cancellation will take effect at the end of the current paid term. If you have any questions or are unsatisfied with our Services, please email us at __________.

Fee Changes

We may, from time to time, make changes to the subscription fee and will communicate any price changes to you in accordance with applicable law.

7. PROHIBITED ACTIVITIES

You may not access or use the Services for any purpose other than that for which we make the Services available. The Services may not be used in connection with any commercial endeavors except those that are specifically endorsed or approved by us.

As a user of the Services, you agree not to:
  • Systematically retrieve data or other content from the Services to create or compile, directly or indirectly, a collection, compilation, database, or directory without written permission from us.
  • Trick, defraud, or mislead us and other users, especially in any attempt to learn sensitive account information such as user passwords.
  • Circumvent, disable, or otherwise interfere with security-related features of the Services, including features that prevent or restrict the use or copying of any Content or enforce limitations on the use of the Services and/or the Content contained therein.
  • Disparage, tarnish, or otherwise harm, in our opinion, us and/or the Services.
  • Use any information obtained from the Services in order to harass, abuse, or harm another person.
  • Make improper use of our support services or submit false reports of abuse or misconduct.
  • Use the Services in a manner inconsistent with any applicable laws or regulations.
  • Engage in unauthorized framing of or linking to the Services.
  • Upload or transmit (or attempt to upload or to transmit) viruses, Trojan horses, or other material, including excessive use of capital letters and spamming (continuous posting of repetitive text), that interferes with any party’s uninterrupted use and enjoyment of the Services or modifies, impairs, disrupts, alters, or interferes with the use, features, functions, operation, or maintenance of the Services.
  • Engage in any automated use of the system, such as using scripts to send comments or messages, or using any data mining, robots, or similar data gathering and extraction tools.
  • Delete the copyright or other proprietary rights notice from any Content.
  • Attempt to impersonate another user or person or use the username of another user.
  • Upload or transmit (or attempt to upload or to transmit) any material that acts as a passive or active information collection or transmission mechanism, including without limitation, clear graphics interchange formats ("gifs"), 1×1 pixels, web bugs, cookies, or other similar devices (sometimes referred to as "spyware" or "passive collection mechanisms" or "pcms").
  • Interfere with, disrupt, or create an undue burden on the Services or the networks or services connected to the Services.
  • Harass, annoy, intimidate, or threaten any of our employees or agents engaged in providing any portion of the Services to you.
  • Attempt to bypass any measures of the Services designed to prevent or restrict access to the Services, or any portion of the Services.
  • Copy or adapt the Services' software, including but not limited to Flash, PHP, HTML, JavaScript, or other code.
  • Except as permitted by applicable law, decipher, decompile, disassemble, or reverse engineer any of the software comprising or in any way making up a part of the Services.
  • Except as may be the result of standard search engine or Internet browser usage, use, launch, develop, or distribute any automated system, including without limitation, any spider, robot, cheat utility, scraper, or offline reader that accesses the Services, or use or launch any unauthorized script or other software.
  • Use a buying agent or purchasing agent to make purchases on the Services.
  • Make any unauthorized use of the Services, including collecting usernames and/or email addresses of users by electronic or other means for the purpose of sending unsolicited email, or creating user accounts by automated means or under false pretenses.
  • Use the Services as part of any effort to compete with us or otherwise use the Services and/or the Content for any revenue-generating endeavor or commercial enterprise.

8. USER GENERATED CONTRIBUTIONS

The Services does not offer users to submit or post content. We may provide you with the opportunity to create, submit, post, display, transmit, perform, publish, distribute, or broadcast content and materials to us or on the Services, including but not limited to text, writings, video, audio, photographs, graphics, comments, suggestions, or personal information or other material (collectively, "Contributions"). Contributions may be viewable by other users of the Services and through third-party websites. As such, any Contributions you transmit may be treated in accordance with the Services' Privacy Policy. When you create or make available any Contributions, you thereby represent and warrant that:
 
 
 
  • The creation, distribution, transmission, public display, or performance, and the accessing, downloading, or copying of your Contributions do not and will not infringe the proprietary rights, including but not limited to the copyright, patent, trademark, trade secret, or moral rights of any third party.
  • You are the creator and owner of or have the necessary licenses, rights, consents, releases, and permissions to use and to authorize us, the Services, and other users of the Services to use your Contributions in any manner contemplated by the Services and these Legal Terms.
  • You have the written consent, release, and/or permission of each and every identifiable individual person in your Contributions to use the name or likeness of each and every such identifiable individual person to enable inclusion and use of your Contributions in any manner contemplated by the Services and these Legal Terms.
  • Your Contributions are not false, inaccurate, or misleading. 
  • Your Contributions are not unsolicited or unauthorized advertising, promotional materials, pyramid schemes, chain letters, spam, mass mailings, or other forms of solicitation.
  • Your Contributions are not obscene, lewd, lascivious, filthy, violent, harassing, libelous, slanderous, or otherwise objectionable (as determined by us). 
  • Your Contributions do not ridicule, mock, disparage, intimidate, or abuse anyone.
  • Your Contributions are not used to harass or threaten (in the legal sense of those terms) any other person and to promote violence against a specific person or class of people.
  • Your Contributions do not violate any applicable law, regulation, or rule.
  • Your Contributions do not violate the privacy or publicity rights of any third party.
  • Your Contributions do not violate any applicable law concerning child pornography, or otherwise intended to protect the health or well-being of minors.
  • Your Contributions do not include any offensive comments that are connected to race, national origin, gender, sexual preference, or physical handicap.
  • Your Contributions do not otherwise violate, or link to material that violates, any provision of these Legal Terms, or any applicable law or regulation.
Any use of the Services in violation of the foregoing violates these Legal Terms and may result in, among other things, termination or suspension of your rights to use the Services.

9. CONTRIBUTION LICENSE

You and Services agree that we may access, store, process, and use any information and personal data that you provide following the terms of the Privacy Policy and your choices (including settings).

By submitting suggestions or other feedback regarding the Services, you agree that we can use and share such feedback for any purpose without compensation to you.

We do not assert any ownership over your Contributions. You retain full ownership of all of your Contributions and any intellectual property rights or other proprietary rights associated with your Contributions. We are not liable for any statements or representations in your Contributions provided by you in any area on the Services. You are solely responsible for your Contributions to the Services and you expressly agree to exonerate us from any and all responsibility and to refrain from any legal action against us regarding your Contributions.

10. GUIDELINES FOR REVIEWS

We may provide you areas on the Services to leave reviews or ratings. When posting a review, you must comply with the following criteria: (1) you should have firsthand experience with the person/entity being reviewed; (2) your reviews should not contain offensive profanity, or abusive, racist, offensive, or hateful language; (3) your reviews should not contain discriminatory references based on religion, race, gender, national origin, age, marital status, sexual orientation, or disability; (4) your reviews should not contain references to illegal activity; (5) you should not be affiliated with competitors if posting negative reviews; (6) you should not make any conclusions as to the legality of conduct; (7) you may not post any false or misleading statements; and (8) you may not organize a campaign encouraging others to post reviews, whether positive or negative.

We may accept, reject, or remove reviews in our sole discretion. We have absolutely no obligation to screen reviews or to delete reviews, even if anyone considers reviews objectionable or inaccurate. Reviews are not endorsed by us, and do not necessarily represent our opinions or the views of any of our affiliates or partners. We do not assume liability for any review or for any claims, liabilities, or losses resulting from any review. By posting a review, you hereby grant to us a perpetual, non-exclusive, worldwide, royalty-free, fully paid, assignable, and sublicensable right and license to reproduce, modify, translate, transmit by any means, display, perform, and/or distribute all content relating to review.

11. SERVICES MANAGEMENT

We reserve the right, but not the obligation, to: (1) monitor the Services for violations of these Legal Terms; (2) take appropriate legal action against anyone who, in our sole discretion, violates the law or these Legal Terms, including without limitation, reporting such user to law enforcement authorities; (3) in our sole discretion and without limitation, refuse, restrict access to, limit the availability of, or disable (to the extent technologically feasible) any of your Contributions or any portion thereof; (4) in our sole discretion and without limitation, notice, or liability, to remove from the Services or otherwise disable all files and content that are excessive in size or are in any way burdensome to our systems; and (5) otherwise manage the Services in a manner designed to protect our rights and property and to facilitate the proper functioning of the Services.

12. PRIVACY POLICY

We care about data privacy and security. Please review our Privacy Policy: https://presenton.ai/privacy-policy. By using the Services, you agree to be bound by our Privacy Policy, which is incorporated into these Legal Terms. Please be advised the Services are hosted in India. If you access the Services from any other region of the world with laws or other requirements governing personal data collection, use, or disclosure that differ from applicable laws in India, then through your continued use of the Services, you are transferring your data to India, and you expressly consent to have your data transferred to and processed in India.

13. TERM AND TERMINATION

These Legal Terms shall remain in full force and effect while you use the Services. WITHOUT LIMITING ANY OTHER PROVISION OF THESE LEGAL TERMS, WE RESERVE THE RIGHT TO, IN OUR SOLE DISCRETION AND WITHOUT NOTICE OR LIABILITY, DENY ACCESS TO AND USE OF THE SERVICES (INCLUDING BLOCKING CERTAIN IP ADDRESSES), TO ANY PERSON FOR ANY REASON OR FOR NO REASON, INCLUDING WITHOUT LIMITATION FOR BREACH OF ANY REPRESENTATION, WARRANTY, OR COVENANT CONTAINED IN THESE LEGAL TERMS OR OF ANY APPLICABLE LAW OR REGULATION. WE MAY TERMINATE YOUR USE OR PARTICIPATION IN THE SERVICES OR DELETE YOUR ACCOUNT AND ANY CONTENT OR INFORMATION THAT YOU POSTED AT ANY TIME, WITHOUT WARNING, IN OUR SOLE DISCRETION.

If we terminate or suspend your account for any reason, you are prohibited from registering and creating a new account under your name, a fake or borrowed name, or the name of any third party, even if you may be acting on behalf of the third party. In addition to terminating or suspending your account, we reserve the right to take appropriate legal action, including without limitation pursuing civil, criminal, and injunctive redress.

14. MODIFICATIONS AND INTERRUPTIONS

We reserve the right to change, modify, or remove the contents of the Services at any time or for any reason at our sole discretion without notice. However, we have no obligation to update any information on our Services. We will not be liable to you or any third party for any modification, price change, suspension, or discontinuance of the Services.

We cannot guarantee the Services will be available at all times. We may experience hardware, software, or other problems or need to perform maintenance related to the Services, resulting in interruptions, delays, or errors. We reserve the right to change, revise, update, suspend, discontinue, or otherwise modify the Services at any time or for any reason without notice to you. You agree that we have no liability whatsoever for any loss, damage, or inconvenience caused by your inability to access or use the Services during any downtime or discontinuance of the Services. Nothing in these Legal Terms will be construed to obligate us to maintain and support the Services or to supply any corrections, updates, or releases in connection therewith.

15. GOVERNING LAW

These Legal Terms shall be governed by and defined following the laws of __________. Kinu Tech and yourself irrevocably consent that the courts of __________ shall have exclusive jurisdiction to resolve any dispute which may arise in connection with these Legal Terms.

16. DISPUTE RESOLUTION

Informal Negotiations

To expedite resolution and control the cost of any dispute, controversy, or claim related to these Legal Terms (each a "Dispute" and collectively, the "Disputes") brought by either you or us (individually, a "Party" and collectively, the "Parties"), the Parties agree to first attempt to negotiate any Dispute (except those Disputes expressly provided below) informally for at least __________ days before initiating arbitration. Such informal negotiations commence upon written notice from one Party to the other Party.

Binding Arbitration

Any dispute arising out of or in connection with these Legal Terms, including any question regarding its existence, validity, or termination, shall be referred to and finally resolved by the International Commercial Arbitration Court under the European Arbitration Chamber (Belgium, Brussels, Avenue Louise, 146) according to the Rules of this ICAC, which, as a result of referring to it, is considered as the part of this clause. The number of arbitrators shall be __________. The seat, or legal place, or arbitration shall be __________. The language of the proceedings shall be __________. The governing law of these Legal Terms shall be substantive law of __________.

Restrictions

The Parties agree that any arbitration shall be limited to the Dispute between the Parties individually. To the full extent permitted by law, (a) no arbitration shall be joined with any other proceeding; (b) there is no right or authority for any Dispute to be arbitrated on a class-action basis or to utilize class action procedures; and (c) there is no right or authority for any Dispute to be brought in a purported representative capacity on behalf of the general public or any other persons.

Exceptions to Informal Negotiations and Arbitration

The Parties agree that the following Disputes are not subject to the above provisions concerning informal negotiations binding arbitration: (a) any Disputes seeking to enforce or protect, or concerning the validity of, any of the intellectual property rights of a Party; (b) any Dispute related to, or arising from, allegations of theft, piracy, invasion of privacy, or unauthorized use; and (c) any claim for injunctive relief. If this provision is found to be illegal or unenforceable, then neither Party will elect to arbitrate any Dispute falling within that portion of this provision found to be illegal or unenforceable and such Dispute shall be decided by a court of competent jurisdiction within the courts listed for jurisdiction above, and the Parties agree to submit to the personal jurisdiction of that court.

17. CORRECTIONS

There may be information on the Services that contains typographical errors, inaccuracies, or omissions, including descriptions, pricing, availability, and various other information. We reserve the right to correct any errors, inaccuracies, or omissions and to change or update the information on the Services at any time, without prior notice.

18. DISCLAIMER

THE SERVICES ARE PROVIDED ON AN AS-IS AND AS-AVAILABLE BASIS. YOU AGREE THAT YOUR USE OF THE SERVICES WILL BE AT YOUR SOLE RISK. TO THE FULLEST EXTENT PERMITTED BY LAW, WE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, IN CONNECTION WITH THE SERVICES AND YOUR USE THEREOF, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. WE MAKE NO WARRANTIES OR REPRESENTATIONS ABOUT THE ACCURACY OR COMPLETENESS OF THE SERVICES' CONTENT OR THE CONTENT OF ANY WEBSITES OR MOBILE APPLICATIONS LINKED TO THE SERVICES AND WE WILL ASSUME NO LIABILITY OR RESPONSIBILITY FOR ANY (1) ERRORS, MISTAKES, OR INACCURACIES OF CONTENT AND MATERIALS, (2) PERSONAL INJURY OR PROPERTY DAMAGE, OF ANY NATURE WHATSOEVER, RESULTING FROM YOUR ACCESS TO AND USE OF THE SERVICES, (3) ANY UNAUTHORIZED ACCESS TO OR USE OF OUR SECURE SERVERS AND/OR ANY AND ALL PERSONAL INFORMATION AND/OR FINANCIAL INFORMATION STORED THEREIN, (4) ANY INTERRUPTION OR CESSATION OF TRANSMISSION TO OR FROM THE SERVICES, (5) ANY BUGS, VIRUSES, TROJAN HORSES, OR THE LIKE WHICH MAY BE TRANSMITTED TO OR THROUGH THE SERVICES BY ANY THIRD PARTY, AND/OR (6) ANY ERRORS OR OMISSIONS IN ANY CONTENT AND MATERIALS OR FOR ANY LOSS OR DAMAGE OF ANY KIND INCURRED AS A RESULT OF THE USE OF ANY CONTENT POSTED, TRANSMITTED, OR OTHERWISE MADE AVAILABLE VIA THE SERVICES. WE DO NOT WARRANT, ENDORSE, GUARANTEE, OR ASSUME RESPONSIBILITY FOR ANY PRODUCT OR SERVICE ADVERTISED OR OFFERED BY A THIRD PARTY THROUGH THE SERVICES, ANY HYPERLINKED WEBSITE, OR ANY WEBSITE OR MOBILE APPLICATION FEATURED IN ANY BANNER OR OTHER ADVERTISING, AND WE WILL NOT BE A PARTY TO OR IN ANY WAY BE RESPONSIBLE FOR MONITORING ANY TRANSACTION BETWEEN YOU AND ANY THIRD-PARTY PROVIDERS OF PRODUCTS OR SERVICES. AS WITH THE PURCHASE OF A PRODUCT OR SERVICE THROUGH ANY MEDIUM OR IN ANY ENVIRONMENT, YOU SHOULD USE YOUR BEST JUDGMENT AND EXERCISE CAUTION WHERE APPROPRIATE.

19. LIMITATIONS OF LIABILITY

IN NO EVENT WILL WE OR OUR DIRECTORS, EMPLOYEES, OR AGENTS BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL, OR PUNITIVE DAMAGES, INCLUDING LOST PROFIT, LOST REVENUE, LOSS OF DATA, OR OTHER DAMAGES ARISING FROM YOUR USE OF THE SERVICES, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED HEREIN, OUR LIABILITY TO YOU FOR ANY CAUSE WHATSOEVER AND REGARDLESS OF THE FORM OF THE ACTION, WILL AT ALL TIMES BE LIMITED TO THE LESSER OF THE AMOUNT PAID, IF ANY, BY YOU TO US OR . CERTAIN US STATE LAWS AND INTERNATIONAL LAWS DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIES OR THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES. IF THESE LAWS APPLY TO YOU, SOME OR ALL OF THE ABOVE DISCLAIMERS OR LIMITATIONS MAY NOT APPLY TO YOU, AND YOU MAY HAVE ADDITIONAL RIGHTS.

20. INDEMNIFICATION

You agree to - // defend, indemnify, and hold us harmless, including our subsidiaries, - // affiliates, and all of our respective officers, agents, partners, and - // employees, from and against any loss, damage, liability, claim, or demand, including - // reasonable attorneys’ fees and expenses, made by any third party due to or - // arising out of: (1) use of the Services; (2) breach of these Legal Terms; (3) any breach of your representations and warranties set forth in these Legal Terms; (4) your violation of the rights of a third party, including but not limited to intellectual property rights; or (5) any overt harmful act toward any other user of the Services with whom you connected via the Services. Notwithstanding the foregoing, we reserve the right, at your expense, to assume the exclusive defense and control of any matter for which you are required to indemnify us, and you agree to cooperate, at your expense, with our defense of such claims. We will use reasonable efforts to notify you of any such claim, action, or proceeding which is subject to this indemnification upon becoming aware of it.

21. USER DATA

We will maintain - // certain data that you transmit to the Services for the purpose of managing the - // performance of the Services, as well as data relating to your use of the Services. Although we perform regular routine backups - // of data, you are solely responsible for all data that you transmit or that - // relates to any activity you have undertaken using the Services. You agree - // that we shall have no liability to you for any loss or corruption of any such - // data, and you hereby waive any right of action against us arising from any such - // loss or corruption of such data.

22. ELECTRONIC COMMUNICATIONS, TRANSACTIONS, AND SIGNATURES

Visiting the Services, sending us emails, and completing online forms constitute electronic communications. You consent to receive electronic communications, and you agree that all agreements, notices, disclosures, and other communications we provide to you electronically, via email and on the Services, satisfy any legal requirement that such communication be in writing. YOU HEREBY AGREE TO THE USE OF ELECTRONIC SIGNATURES, CONTRACTS, ORDERS, AND OTHER RECORDS, AND TO ELECTRONIC DELIVERY OF NOTICES, POLICIES, AND RECORDS OF TRANSACTIONS INITIATED OR COMPLETED BY US OR VIA THE SERVICES. You hereby waive any rights or requirements under any statutes, regulations, rules, ordinances, or other laws in any jurisdiction which require an original signature or delivery or retention of non-electronic records, or to payments or the granting of credits by any means other than electronic means.

23. CALIFORNIA USERS AND RESIDENTS

If any complaint - // with us is not satisfactorily resolved, you can contact the Complaint - // Assistance Unit of the Division of Consumer Services of the California - // Department of Consumer Affairs in writing at 1625 North Market Blvd., Suite N - // 112, Sacramento, California 95834 or by telephone at (800) 952-5210 or (916) - // 445-1254.

24. MISCELLANEOUS

These Legal Terms and any policies or operating rules posted by us on the Services or in respect to the Services constitute the entire agreement and understanding between you and us. Our failure to exercise or enforce any right or provision of these Legal Terms shall not operate as a waiver of such right or provision. These Legal Terms operate to the fullest extent permissible by law. We may assign any or all of our rights and obligations to others at any time. We shall not be responsible or liable for any loss, damage, delay, or failure to act caused by any cause beyond our reasonable control. If any provision or part of a provision of these Legal Terms is determined to be unlawful, void, or unenforceable, that provision or part of the provision is deemed severable from these Legal Terms and does not affect the validity and enforceability of any remaining provisions. There is no joint venture, partnership, employment or agency relationship created between you and us as a result of these Legal Terms or use of the Services. You agree that these Legal Terms will not be construed against us by virtue of having drafted them. You hereby waive any and all defenses you may have based on the electronic form of these Legal Terms and the lack of signing by the parties hereto to execute these Legal Terms.

25. CONTACT US

In order to resolve a complaint regarding the Services or to receive further information regarding use of the Services, please contact us at:

Kinu Tech
 
- //
- - // ` - // }}> - - //
-
- - -Welcome to Presenton, provided by Kinu Tech Pvt. Ltd. ("We," "Us," "Our"). By using our services, you agree to comply with and be bound by the following terms and conditions. -## 1. Company Information -- **Entity Name:** Kinu Tech Pvt. Ltd. -## 2. Service Description -Presenton uses AI technology to assist users in creating data presentations. Our platform streamlines the process to enhance productivity and efficiency. -## 3. User Responsibilities -Users must: -- Provide accurate information during account registration. -- Maintain the confidentiality of login credentials. -- Use the service in compliance with applicable laws. -- Be responsible for any content uploaded to the platform. -## 4. Payment Terms -- **Payment Methods:** All payments are processed through Stripe. -- **Refund Policy:** All payments are final. We do not offer refunds. -- **Billing:** Users are responsible for providing up-to-date billing information. -## 5. User Restrictions -Users are prohibited from: -- Attempting to hack or interfere with our system’s security. -- Using the service for any unlawful activities. -- Engaging in actions that may harm the platform or other users. -## 6. Intellectual Property -Users retain ownership of any intellectual property rights to content they create using our service. We do not claim ownership of user-generated content. -## 7. Termination of Service -We reserve the right to terminate service: -- If a user fails to make the required payments. -- For violations of these terms or applicable laws. -## 8. Liability Limitations -Kinu Tech Pvt. Ltd. is not liable for: -- Indirect, incidental, or consequential damages arising from the use of our services. -- Unauthorized access or use of our servers and personal data. -## 9. Dispute Resolution -Any disputes arising under these terms will be resolved through [standard dispute resolution method, e.g., arbitration, negotiation]. -## 10. Governing Law -These terms are governed by the laws of Nepal. Any legal actions will be conducted within this jurisdiction. -## 11. Amendments -We may update these terms periodically. Any changes will be communicated to users via email. Your continued use of the service constitutes acceptance of the new terms. -## 12. Contact Information -For questions regarding these terms, please contact us at: -- **Email:** [suraj@presenton.ai](mailto:suraj@presenton.ai) ---- - - -`} /> -
- ) -} - -export default page diff --git a/servers/nextjs/utils/constant.ts b/servers/nextjs/utils/constant.ts new file mode 100644 index 00000000..7519c5bf --- /dev/null +++ b/servers/nextjs/utils/constant.ts @@ -0,0 +1 @@ +export const BASE_URL = process.env.NEXT_PUBLIC_FAST_API || 'http://localhost:8000'; \ No newline at end of file