canvas-backend/src/Home.jsx
2025-02-12 18:57:58 +06:00

140 lines
5.8 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 { useParams } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { generateToken, getUser } 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 AuthContext from './components/Context/authContext/AuthContext';
import { useToast } from './hooks/use-toast';
import useProject from './hooks/useProject';
export const Home = () => {
const { activeObject, setActiveObject } = useContext(ActiveObjectContext);
const { canvas, selectedPanel } = useContext(CanvasContext);
const { user, setUser } = useContext(AuthContext);
const params = useParams();
const navigate = useNavigate();
const getToken = () => localStorage.getItem('canvas_token');
const { id } = params;
const { toast } = useToast();
// Fetch token only if it doesn't exist
const { data, isLoading } = useQuery({
queryKey: ['get-token'],
queryFn: () => generateToken(id),
});
// Fetch project data only if token and id exist
const { projectData, isLoading: projectLoading } = useProject();
// Fetch user related data only if token exists
const { data: userData, isLoading: userLoading } = useQuery({
queryKey: ['user'],
queryFn: async () => await getUser(),
enabled: !!getToken() && user?.length === 0,
})
// update the data into context
useEffect(() => {
if (userData?.status === 200 && !userLoading) {
setUser([userData?.user])
}
}, [userData, userLoading, setUser]);
useEffect(() => {
const token = getToken(); // Get latest token
if (!token && !isLoading) {
navigate("/unAuthenticated");
}
if (token && !isLoading && data?.status === 201) {
navigate("/");
}
if (projectData?.status === 500 && id) {
navigate("/");
toast({ variant: "destructive", title: projectData?.status, description: "No project found" });
}
if (!projectData && canvas) {
canvas.clear();
canvas.renderAll();
canvas.setBackgroundColor("#ffffff", canvas.renderAll.bind(canvas));
setActiveObject(null);
}
if (projectData && projectData?.status === 200 && !projectLoading && canvas && (selectedPanel === "project" || selectedPanel === "") && id) {
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();
});
}
}
}
}, [navigate, isLoading, data, projectData, id, toast, canvas, selectedPanel, projectLoading, setActiveObject]);
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">
{!isLoading &&
<>
<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-10 flex justify-center items-center h-20 bg-white border-t border-gray-200 shadow-md w-fit">
<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'>
<Sidebar />
</div>
</div>
)
}