File "Main.tsx"

Full Path: /home/rattkxnv/byattorney.com/wp-content/plugins/everest-forms/src/templates/components/Main.tsx
File size: 3.73 KB
MIME-type: text/x-java
Charset: utf-8

import React, { useState, useCallback, useMemo } from "react";
import { Box, Flex, Spinner, useBreakpointValue } from "@chakra-ui/react";
import Sidebar from "./Sidebar";
import TemplateList from "./TemplateList";
import { useQuery } from '@tanstack/react-query';
import apiFetch from "@wordpress/api-fetch";
import { templatesScriptData } from "../utils/global";
import { __ } from '@wordpress/i18n';

const { restURL, security } = templatesScriptData;

const fetchTemplates = async () => {
    const response = (await apiFetch({
        path: `${restURL}everest-forms/v1/templates`,
        method: "GET",
        headers: {
            "X-WP-Nonce": security,
        },
    })) as { templates: { category: string; templates: Template[] }[] };

    if (response && Array.isArray(response.templates)) {
        const allTemplates = response.templates.flatMap((category) => category.templates);
        return allTemplates;
    } else {
        throw new Error(__("Unexpected response format.", "everest-forms"));
    }
};

const Main: React.FC<{ filter: string }> = ({ filter }) => {
    const [state, setState] = useState({
        selectedCategory: __("All Forms", "everest-forms"),
        searchTerm: ""
    });

    const { selectedCategory, searchTerm } = state;

    const { data: templates = [], isLoading, error } = useQuery(['templates'], fetchTemplates);

    const categories = useMemo(() => {
        const categoriesSet = new Set<string>();
        templates.forEach(template => {
            template.categories.forEach(category => categoriesSet.add(category));
        });

        return [
            { name: __("All Forms", "everest-forms"), count: templates.length },
            ...Array.from(categoriesSet).map((category) => ({
                name: category,
                count: templates.filter(template => template.categories.includes(category)).length,
            }))
        ];
    }, [templates]);

    const filteredTemplates = useMemo(() => {
        return templates.filter(template =>
            (selectedCategory === __("All Forms", "everest-forms") || template.categories.includes(selectedCategory)) &&
            template.title.toLowerCase().includes(searchTerm.toLowerCase()) &&
            (filter === "All" || (filter === "Free" && !template.isPro) || (filter === "Premium" && template.isPro))
        );
    }, [selectedCategory, searchTerm, templates, filter]);

		const handleCategorySelect = useCallback((category) => {
			setState(prevState => ({ ...prevState, selectedCategory: category }));
		}, []);

    const handleSearchChange = useCallback((searchTerm) => {
        setState(prevState => ({ ...prevState, searchTerm }));
    }, []);

    const sidebarWidth = useBreakpointValue({ base: "100%", md: "250px" });

    if (isLoading) return (
        <Flex justify="center" align="center" height="100vh">
            <Spinner size="xl" />
        </Flex>
    );
    if (error) return <div>{(error as Error).message}</div>;

    return (
        <Box>
            <Flex direction={{ base: "column", md: "row" }}>
                <Box width={sidebarWidth} mr={{ base: 0, md: 4 }} mb={{ base: 4, md: 0 }}>
                    <Sidebar
                        categories={categories}
						selectedCategory={state.selectedCategory}
                        onCategorySelect={handleCategorySelect}
                        onSearchChange={handleSearchChange}
                    />
                </Box>
				<Box
				width="1px"
				bg="linear-gradient(90deg, #CDD0D8 0%, rgba(255, 255, 255, 0) 158.04%)"
				mx="4"
				marginRight="28px"
				/>
                <Box flex={1}>
                    <TemplateList selectedCategory={selectedCategory} templates={filteredTemplates} />
                </Box>
            </Flex>
        </Box>
    );
};

export default Main;