import { __ } from "@wordpress/i18n";
import { useCallback, useMemo, memo, useState } from "@wordpress/element";
import { decodeEntities } from "@wordpress/html-entities";
import { RadioControl, Tooltip } from "@wordpress/components";
import { HeartIcon, HeartIconFull, ImportIcon, PreviewIcon, ProBadgeIcon, RotateIcon } from "./icons";
import { DEFAULTS, KEYBOARD_KEYS, API_ENDPOINTS } from "./constants";
import { FilterPart, HeaderWithFilter } from "./filter/filterPart";
import { currentBlockTitle } from "./controls";
const RenderFilterLabel = ({ label, number }) => {
return (
<>
{label}
{`(${number || 0})`}
>
);
};
const getPatternCategories = (categoryCounts, allCount) => {
return [
{
label: ,
value: "all",
},
...Object.keys(categoryCounts).map((blockName) => ({
label: ,
value: blockName,
})),
];
};
const Skeleton = (props) => {
const { type, size, loop, unit, c_s, classes } = props;
const getSize = () => {
let css = {};
switch (type) {
case "image":
case "circle":
css = {
width: size ? size + "px" : "300px",
height: size ? size + "px" : "300px",
};
break;
case "title":
css = {
width: `${size ? size : "100"}${unit ? unit : "%"}`,
};
break;
case "button":
css = { width: size ? size + "px" : "90px" };
break;
case "custom_size":
css = {
width: `${c_s.size1 ? c_s.size1 : "100"}${c_s.unit1 ? c_s.unit1 : "%"}`,
height: `${c_s.size2 ? c_s.size2 : "20"}${c_s.unit2 ? c_s.unit2 : "px"}`,
borderRadius: c_s.br ? c_s.br + "px" : "0px",
};
break;
default:
break;
}
return css;
};
return (
<>
{loop ? (
<>
{Array(parseInt(loop))
.fill("1")
.map((x, i) => {
return (
);
})}
>
) : (
)}
>
);
};
// Individual Card Component.
const PremadeCard = memo(({ data, wishListArr, setWListAction, reload, reloadId, onImport }) => {
const isInWishlist = wishListArr?.includes(String(data.ID));
const isLoading = reload && reloadId === data.ID;
const isPro = data.pro;
// const isPro = false;
const handleWishlistClick = useCallback(() => {
setWListAction(data.ID, isInWishlist ? "remove" : "");
}, [data.ID, isInWishlist, setWListAction]);
const handleImportClick = useCallback(() => {
if (!isPro) {
onImport(data.ID, data.pro);
}
}, [data.ID, data.pro, isPro, onImport]);
return (
{decodeEntities(data?.name || "")}
{
if (e.key === KEYBOARD_KEYS.ENTER || e.key === KEYBOARD_KEYS.SPACE) {
handleWishlistClick();
}
}}
aria-label={
isInWishlist
? __("Remove from wishlist", "easy-accordion-free")
: __("Add to wishlist", "easy-accordion-free")
}
>
{isInWishlist ? : }
{isPro ? (
{__("PRO", "easy-accordion-free")}
) : (
{
if (e.key === KEYBOARD_KEYS.ENTER || e.key === KEYBOARD_KEYS.SPACE) {
handleImportClick();
}
}}
aria-label={__("Import", "easy-accordion-free") + " " + data.name}
style={
isLoading
? {
pointerEvents: "none",
opacity: 0.6,
}
: {}
}
>
{isLoading ? (
) : (
<>
{__("Import", "easy-accordion-free")}
>
)}
)}
);
});
// Loading Skeleton Component.
const LoadingSkeleton = memo(() => (
{Array(25)
.fill(null)
.map((_, i) => (
))}
));
// Empty State Component.
const EmptyState = memo(() => (
{__("No Data found...", "easy-accordion-free")}
));
// Main Grid Component.
const PremadeGrid = memo(
({
premadeLists,
column,
searchQuery,
freePro,
showWishList,
wishListArr,
// localizedData,
setWListAction,
reload,
reloadId,
onImport,
loading,
}) => {
// Memoize filter function
const filteredLists = useMemo(() => {
return premadeLists.filter((data) => {
const searchMatch = !searchQuery || data.name?.toLowerCase().includes(searchQuery.toLowerCase());
const freeProMatch =
freePro === "all" || (freePro === "pro" && data.pro) || (freePro === "free" && !data.pro);
const wishListMatch = !showWishList || wishListArr?.includes(String(data.ID));
return searchMatch && freeProMatch && wishListMatch;
});
}, [premadeLists, searchQuery, freePro, showWishList, wishListArr]);
// Loading state.
if (loading) {
return ;
}
// Empty state
if (filteredLists.length === 0) {
return ;
}
// Grid with data
return (
{filteredLists.map((data) => (
))}
);
}
);
// Main StarterSites Component
const StarterSites = (props) => {
const {
filterValue,
state,
setState,
// useState,
// useEffect,
// useRef,
_changeVal,
filterByCategoryKey,
setWListAction,
wishListArr,
_fetchFile,
onClose,
currentBlockName,
isSingleBlock,
} = props;
const { current, designs, reload, reloadId, categoryCounts, freeCount, proCount, fetching, loading } = state;
// const localizedData = sp_eab_patterns_post_block_localize || {};
// Local state management.
const [column, setColumn] = useState(DEFAULTS.COLUMN);
const [searchQuery, setSearchQuery] = useState(DEFAULTS.SEARCH_QUERY);
const [trend, setTrend] = useState(DEFAULTS.TREND);
const [freePro, setFreePro] = useState(DEFAULTS.FREE_PRO);
const [showWishList, setShowWishList] = useState(false);
const totalCount = freeCount + proCount;
// Memoize sorted lists.
const premadeLists = useMemo(() => {
if (!current.length) return [];
const lists = [...current];
if (trend === "latest" || trend === "all") {
return lists.sort((a, b) => b.ID - a.ID);
}
if (trend === "popular" && lists[0]?.hit !== undefined) {
return lists.sort((a, b) => b.hit - a.hit);
}
return lists;
}, [current, trend]);
const allCategoryCount = premadeLists?.length;
const patternCategories = getPatternCategories(categoryCounts, totalCount);
// Handle filter changes.
const handleFilterChange = useCallback(
(type) => {
const filteredData = type === "all" ? designs : filterByCategoryKey(designs, type);
setState((prev) => ({
...prev,
designFilter: type,
current: filteredData,
}));
},
[designs, filterByCategoryKey, setState]
);
// Unified state change handler.
const changeStates = useCallback(
(type, value) => {
const handlers = {
freePro: () => setFreePro(value),
search: () => setSearchQuery(value),
column: () => setColumn(value),
wishlist: () => setShowWishList(value),
trend: () => setTrend(value),
filter: () => handleFilterChange(value),
};
handlers[type]?.();
},
[handleFilterChange]
);
// Memoize import handler.
const handleImport = useCallback(
(templateID, isPro) => {
_changeVal(templateID, isPro);
},
[_changeVal]
);
const freeProOptions = [
{
value: "all",
label: ,
},
{
value: "free",
label: ,
},
{
value: "pro",
label: ,
},
];
return (
<>
{isSingleBlock && (
)}
{!isSingleBlock && (
{
changeStates("freePro", v);
}}
/>
{
changeStates("filter", v);
}}
/>
)}
>
);
};
export default StarterSites;