140 lines
5.8 KiB
JavaScript
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>
|
|
)
|
|
}
|