template-react-app/src/components/DevControlPanel.tsx

107 lines
3.3 KiB
TypeScript

import { useLocation } from "wouter";
import { floatingLanguageMenuStructure, main } from "../configure";
import { DevControlPanelProps } from "../types/devControlPanelTypes";
import { RoutingTree } from "../types/routesTypes";
import inDev from "../utils/inDev";
import ThemeButton from "./ThemeButton";
import { clearMultiplePathSlashes } from "../utils/StringTransformationUtils";
import { useTranslation } from "react-i18next";
import FloatingMenu from "./FloatingMenu";
/**
* Development Control Panel Component
*
* This component renders a development control panel for navigation and debugging.
* It includes a dynamic list of routes and a theme toggle button.
*
* @param {DevControlPanelProps} props - Properties passed to the DevControlPanel component.
* @returns {JSX.Element} A React component that renders the development control panel.
*/
const DevControlPanel = ({ routesTree }: DevControlPanelProps) => {
const [, setLocation] = useLocation();
const { t, i18n } = useTranslation();
// Function to update the current location, with debug logging
const _setLocation = (targetLocation: string) => {
inDev(() => console.log("DevControlPanel_setLocation", targetLocation));
setLocation(targetLocation);
};
// Function to generate a list of buttons for navigation based on the routing tree
const routesCrawler = (
routesTree: RoutingTree,
parentPath?: string,
): JSX.Element[] => {
return routesTree.map((route): JSX.Element => {
// Constructing path for the route button
const _path = clearMultiplePathSlashes(
parentPath ? "/" + parentPath + "/" + route.path : "/" + route.path,
);
// Debug logging for route information
inDev(() =>
console.log(
"%croutesCrawler_routes %s %s",
"color: lightblue",
route.name,
_path,
),
);
// Generating nested routes or single route buttons
if (route.nest) {
return (
<div className="indicator">
<span className="indicator-item indicator-center badge badge-primary">
{route.name}
</span>
<div key={_path} className="join">
{routesCrawler(route.nest, _path)}
</div>
</div>
);
} else {
return (
<button
key={_path}
className="btn btn-neutral join-item"
onClick={() => _setLocation(_path)}
>
{route.name}
</button>
);
}
});
};
// Render the development control panel with navigation buttons and theme toggle
return (
<div className="border border-base-content flex gap-4 p-4 absolute w-full bottom-0 bg-base-300 z-50">
<div className="px-5 mt-6">
{/* Displaying the program name and version */}
<div className="text-center">
{main.program_name} v{main.program_version}
<p>Base path is: {main.base_path}</p>
</div>
<div>
{/* Embedding the ThemeButton component for theme toggling */}
<ThemeButton />
</div>
</div>
{/* Rendering the dynamically generated route navigation buttons */}
<div className="space-y-2 space-x-2 mb-6">{routesCrawler(routesTree)}</div>
<div className="px-5 mt-6">
<p>{t("welcome")}</p>
<p>Lang: {i18n.language}</p>
</div>
<FloatingMenu
menuStructure={floatingLanguageMenuStructure}
className="flex gap-2 flex-col"
tooltipClassName="tooltip tooltip-right"
/>
</div>
);
};
export default DevControlPanel;