canvas_frontend_dev/src/Home.jsx
2025-03-01 14:20:45 +06:00

125 lines
5.3 KiB
JavaScript

import { useContext, useEffect } from 'react'
import ActiveObjectContext from './components/Context/activeObject/ObjectContext';
import { TopBar } from './components/Panel/TopBar';
import { ActionButtons } from './components/ActionButtons';
import { Sidebar } from './components/Layouts/LeftSidebar';
import EditorPanel from './components/Panel/EditorPanel';
import Canvas from './components/Canvas/Canvas';
import CanvasCapture from './components/CanvasCapture';
import { useQuery } from '@tanstack/react-query';
import { generateToken } from './api/authApi';
import { useNavigate } from "react-router-dom";
import { Toaster } from '@/components/ui/toaster';
import { Loader } from 'lucide-react';
import CanvasContext from './components/Context/canvasContext/CanvasContext';
import { useToast } from './hooks/use-toast';
import useProject from './hooks/useProject';
export const Home = () => {
const { activeObject } = useContext(ActiveObjectContext);
const { canvas, selectedPanel } = useContext(CanvasContext);
const navigate = useNavigate();
const getToken = () => localStorage.getItem('canvas_token');
const path = location.pathname;
const { toast } = useToast();
// Fetch project data only if token and id exist
const { projectData, isLoading: projectLoading } = useProject();
// Fetch token only if it doesn't exist
const { data, isLoading } = useQuery({
queryKey: ['get-token'],
queryFn: () => generateToken(),
enabled: !!getToken(),
});
useEffect(() => {
const checkToken = () => {
const token = getToken();
if (!token) {
navigate("/login");
}
};
checkToken(); // Run immediately on mount
window.addEventListener("storage", checkToken);
return () => {
window.removeEventListener("storage", checkToken);
};
}, [navigate]);
// to load the project data into canvas when the project is selected or the page is refreshed
useEffect(() => {
if (projectData?.status === 500) {
navigate("/");
toast({ variant: "destructive", title: projectData?.status, description: "No project found" });
}
if (projectData && projectData?.status === 200 && !projectLoading && canvas && (selectedPanel === "project" || selectedPanel === "") && path !== "/") {
if (canvas?._objects?.length === 0) {
const isEmpty = (obj) => Object.values(obj).length === 0;
if (!isEmpty(projectData?.data?.object)) {
canvas.loadFromJSON(projectData?.data?.object, () => {
// Ensure background image fills the canvas
if (canvas.backgroundImage) {
canvas.backgroundImage.scaleToWidth(canvas.width);
canvas.backgroundImage.scaleToHeight(canvas.height);
}
canvas.renderAll();
});
}
}
}
}, [projectData, toast, canvas, selectedPanel, projectLoading, path, navigate, isLoading])
return (
<div className='relative flex flex-col'>
{
isLoading ?
<div className='flex justify-center items-center h-screen'>
<p><Loader className="animate-spin mx-auto" /></p>
</div> :
<>
<div className="flex h-screen overflow-hidden relative">
<Toaster />
{
activeObject &&
<div className="absolute left-0 xl:left-[90px] lg:left-[90px] md:left-[90px] sm:left-[80px] right-0 xl:right-[90px] lg:right-[90px] md:right-[90px] sm:right-[80px] z-[9999] rounded-md p-1 h-fit bg-white border-t border-gray-200 shadow-md my-1 w-[80%] mx-auto">
<TopBar />
</div>
}
<div className="absolute z-[999] right-0 xl:bottom-0 lg:bottom-0 md:bottom-0 sm:bottom-0 bottom-16 flex justify-center items-center h-20 bg-white border-t border-gray-200 shadow-md w-fit">
<p></p>
<ActionButtons />
</div>
<div className="h-full mr-1 hidden xl:block lg:block md:block sm:block">
<Sidebar />
</div>
<div className="absolute ml-0 xl:ml-20 lg:ml-20 md:ml-20 z-[999] top-[15%]">
<EditorPanel />
</div>
<div className="flex-1 flex flex-col h-full overflow-hidden my-2">
<div className="flex-1 overflow-auto">
<Canvas />
</div>
{/* canvas capture part */}
<CanvasCapture />
</div>
</div>
<div className='h-full z-[999] block xl:hidden lg:hidden md:hidden sm:hidden border'>
<Sidebar />
</div>
</>
}
</div>
)
}