"use client"; import type { RootState } from "@/core/redux/store"; import { setLocation, setProjectName, setProjectType, setUnitsOfMeasurement, UnitOption } from "@/core/redux/projectDetails"; import { useAppDispatch, useAppSelector } from "@/core/utils/hooks/useRedux"; import React, { useEffect, useMemo, useState } from "react"; import { useSelector } from "react-redux"; import AnimatedImages from "@/core/components/Icons/AnimatedImages"; import Filter from "@/core/components/Icons/Filter"; import Foundation from "@/core/components/Icons/Foundation"; import Info from "@/core/components/Icons/Info"; import ImgCard from "@/core/components/ImgCard"; import SelectDropdown from "@/core/components/SelectDropdown"; import Image from "next/image"; /* #region types and interfaces */ interface ProjectDetailsProps { isShown: boolean; } interface ImagesProps { uploadedImages: { url: string, date?: string, }[]; } type Tab = { name: string, icon: (fill: string) => React.ReactNode, }; type InputField = { label: string, value?: { label: string, value: string }[], type?: string, }; type ImageField = { name: string, }; /* #endregion */ /* #region dummy arrays */ const useAppData = () => { // Memoize tabs to avoid re-creating icon functions const tabs = useMemo(() => [ { name: "Info", icon: (fill: string | undefined) => }, { name: "Images", icon: (fill: string | undefined) => }, { name: "Materials", icon: (fill: string | undefined) => }, ], []); // Memoize infoFields to avoid re-creating the array on every render const infoFields = useMemo(() => [ { label: "Project name" }, { label: "Project type" }, { label: "Location" }, { label: "Units of measurement", value: [ { value: "1", label: "U.S. - inch, foot, mile, pounds" }, { value: "2", label: "EU - inch, foot, mile, pounds" }, ], type: "dropdown", }, ], []); // Memoize materials to avoid re-creating the array on every render const materials = useMemo(() => [ { image: "https://picsum.photos/200/300?random=1", label: "Wood", data: "$630 - 1 pcs.", }, { image: "https://picsum.photos/200/300?random=2", label: "Metal", data: "$630 - 1 pcs.", }, { image: "https://picsum.photos/200/300?random=3", label: "Plastic", data: "$630 - 1 pcs.", }, { image: "https://picsum.photos/200/300?random=4", label: "Glass", data: "$630 - 1 pcs.", }, ], []); return { tabs, infoFields, materials }; }; /* #endregion */ const InfoTab = () => { const dispatch = useAppDispatch(); const infoFields = useAppSelector(state => state.projectInfo.infoFields); const [isOpenedSelect, setIsOpenedSelect] = useState(false); const selectedMeasurement = (infoFields["Units of measurement"] as UnitOption[]).find( (unit) => unit.selected ) || { label: "", value: "" }; const handleSelectMeasurement = (item: UnitOption) => { dispatch(setUnitsOfMeasurement(item.value)); }; const handleFieldChange = (label: string, value: string) => { switch (label) { case "Project name": dispatch(setProjectName(value)); break; case "Project type": dispatch(setProjectType(value)); break; case "Location": dispatch(setLocation(value)); break; default: break; } }; return (
{Object.keys(infoFields).map((label) => (
{label === "Units of measurement" ? (
setIsOpenedSelect(!isOpenedSelect)} >
{"expand_more_bottom"}
) : ( handleFieldChange(label, e.target.value)} /> )}
))}
); }; const Images: React.FC = ({ uploadedImages }) => { const [activeImageType, setActiveImageType] = useState("Screenshots"); return (
{uploadedImages.length > 0 ? ( <>
{["Screenshots", "Realistic", "360°"].map((option) => (
setActiveImageType(option)} > {option}
))}
{uploadedImages.map((image) => ( ))}
) : (
No images yet🥲
)}
); }; const Materials = () => { const currentRoom = useAppSelector((state) => state.model.currentRoom); const materials = useAppData().materials; return (
{materials.length > 0 ? ( <>
{"room"} {currentRoom?.floor + "/" + currentRoom?.name}
Sort/filter
{materials.map((material) => (
{material.image}

{material.label}

{material.data}

')`, backgroundRepeat: "no-repeat", backgroundSize: "contain", }} />
))}
) : (
No materials yet🥲
)}
); }; const ProjectDetails: React.FC = (props) => { const [activeTab, setActiveTab] = useState("Info"); const [isVisible, setIsVisible] = useState(props.isShown); const tabs = useAppData().tabs; const uploadedImages = useSelector( (state: RootState) => state.imageUpload.uploadedImages ); const renderTabContent = ( uploadedImages: { url: string, date?: string }[] ) => { switch (activeTab) { case "Info": return ; case "Images": return ; case "Materials": return ; default: return null; } }; useEffect(() => { let timeoutId: NodeJS.Timeout; if (props.isShown) { setIsVisible(true); } else { timeoutId = setTimeout(() => { setIsVisible(false); }, 200); } return () => { clearTimeout(timeoutId); }; }, [props.isShown]); //timeout for animation return (
{tabs.map((tab) => (
setActiveTab(tab.name)} key={tab.name} >
{tab.icon(activeTab === tab.name ? "#FFFFFF" : "#131313")}

{tab.name}

))}
{renderTabContent(uploadedImages)}
); }; export default ProjectDetails;