enzostvs's picture
enzostvs HF Staff
Upload 172 files
9cd6ddb verified
import { useEffect, useRef, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { Icons } from "@/components/svg/icons";
import { IconItem } from "@/types/editor";
import { Input } from "@/components/input";
import {
useResults,
useSingleSearch,
} from "@/components/search/hooks/useSearch";
import { ListItem } from "@/components/editor-icons/comps/list/list-item";
import { Empty } from "@/components/empty";
import { ArrowLeftIcon } from "@heroicons/react/solid";
import { ArrowRightIcon } from "@heroicons/react/solid";
import { useClickAway } from "react-use";
import classNames from "classnames";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTrash } from "@fortawesome/free-solid-svg-icons";
export const IconPicker = ({
icon,
onSelect,
children,
}: {
onSelect: (i?: string) => void;
icon?: string;
children?: React.ReactNode;
}) => {
const [open, setOpen] = useState(false);
const svgRef = useRef<any>(null);
const container = useRef<HTMLDivElement>(null);
const intl = useIntl();
const [viewBox, setViewBox] = useState<string>("0 0 24 24");
const [search, setSearch] = useState<any>("");
useSingleSearch(search);
const { results, page, maxPage, totalItems, setPage } = useResults(21);
const findIcon = Icons?.find((i: IconItem) => icon === i.name);
const IconComponent = findIcon?.component as any;
useEffect(() => {
return setViewBox(
svgRef?.current?.getAttribute("viewBox") ?? "0 0 200 200"
);
}, [icon]);
useClickAway(container, () => setOpen(false));
return (
<div ref={container} className="relative">
<div
className="border border-dark-300 rounded-lg w-10 h-10 flex items-center justify-center hover:bg-green hover:bg-opacity-40 hover:border-green cursor-pointer"
onClick={() => setOpen(!open)}
>
<svg
width={16}
height={16}
fill="white"
viewBox={viewBox}
style={{ minWidth: 16, minHeight: 16 }}
>
<IconComponent ref={svgRef as any} />
</svg>
</div>
<div
className={classNames(
"w-full fixed lg:absolute lg:w-[420px] p-6 min-h-[350px] rounded-lg bg-dark-default left-0 bottom-0 lg:left-12 lg:top-0 transform lg:-translate-y-1/2 shadow-xl border-2 border-dark-200 border-opacity-20 z-[11]",
{
"opacity-0 pointer-events-none": !open,
}
)}
>
<Input
value={search}
type="text"
placeholder="Search for an icon"
className="bg-dark-600 rounded p-3 text-sm text-white placeholder-dark-200"
onChange={setSearch as any}
/>
<div className="flex jlg:items-start flex-wrap justify-start mt-3 gap-2 lg:gap-3">
{results?.map((result: any, key: number) => (
<ListItem
key={key}
icon={result}
fill={result?.defaultColor}
onSelect={(icon) => {
// if (icon?.isPremium && !user?.id) return setOpen(true);
// onSelect(icon);
onSelect(icon.name);
}}
/>
))}
{results?.length === 0 && (
<Empty
title="Clyde is disappointed..."
description="...there is no icon that matches your search :("
action={() => {
// if (!user?.id) return login();
// send to api a request;
}}
button="Ask for a new Icon"
/>
)}
</div>
{results?.length > 0 && (
<div className="flex items-center justify-between gap-4 mt-10">
<button
disabled={page <= 1}
className="w-full lg:w-auto group border-2 border-darkGreen bg-darkGreen text-white font-medium tracking-wide px-3.5 py-2 text-sm flex items-center justify-center gap-2 rounded-lg hover:bg-opacity-90 hover:border-opacity-0 disabled:bg-dark-100 disabled:bg-opacity-20 disabled:border-dark-100 disabled:border-opacity-0 disabled:text-dark-200 disabled:cursor-not-allowed"
onClick={() => setPage(page - 1)}
>
<ArrowLeftIcon className="w-4 text-white group-disabled:text-dark-200" />
</button>
<div className="hidden items-center justify-center gap-2 lg:flex">
<p className="text-dark-100 font-medium text-sm">
<FormattedMessage
id="iconsEditor.editor.listIcons.pagination.total"
values={{
page: () => page,
maxPage: () => maxPage,
}}
/>
</p>
</div>
<button
disabled={page === maxPage}
className="w-full lg:w-auto group border-2 border-darkGreen bg-darkGreen text-white font-medium tracking-wide px-3.5 py-2 text-sm flex items-center justify-center gap-2 rounded-lg hover:bg-opacity-90 hover:border-opacity-0 disabled:bg-dark-100 disabled:bg-opacity-20 disabled:border-dark-100 disabled:border-opacity-0 disabled:text-dark-200 disabled:cursor-not-allowed"
onClick={page >= maxPage ? () => {} : () => setPage(page + 1)}
>
<ArrowRightIcon className="w-4 text-white group-disabled:text-dark-200" />
</button>
</div>
)}
</div>
</div>
);
};