Spaces:
Running
Running
import { ArrowRightIcon, ArrowLeftIcon } from "@heroicons/react/solid"; | |
import { useContext, useRef } from "react"; | |
import { useResults } from "components/search/hooks/useSearch"; | |
import { ListItem } from "components/editor-icons/comps/list/list-item"; | |
import { IconItem } from "types/editor"; | |
import { Empty } from "components/empty"; | |
import { login, useUser } from "utils/auth"; | |
import { PremiumContext } from "components/premium/premium"; | |
import { Premium } from "@/components/premium"; | |
import classNames from "classnames"; | |
import { toBase64 } from "@/components/upload"; | |
import { FormattedMessage } from "react-intl"; | |
export const ListIcons = ({ | |
onSelect, | |
onCustomText, | |
onCustomUpload, | |
}: { | |
onSelect: (e: IconItem) => void; | |
onCustomText: () => void; | |
onCustomUpload: (s: string) => void; | |
}) => { | |
const { user } = useUser(); | |
const { setOpen } = useContext(PremiumContext); | |
const inputRef = useRef<HTMLInputElement>(null); | |
const { results, page, maxPage, totalItems, setPage } = useResults(); | |
const handleCustomUpload = (e: any) => { | |
const file = e.target.files[0]; | |
if (file) { | |
toBase64(file).then((res: any) => { | |
onCustomUpload(res); | |
}); | |
} | |
}; | |
return ( | |
<div> | |
<div className="flex flex-col lg:flex-row gap-y-3 lg:gap-y-0 items-start justify-between"> | |
<p className="font-bold tracking-wider text-base text-white"> | |
<FormattedMessage | |
id="iconsEditor.editor.listIcons.totalIcons" | |
values={{ total: () => totalItems }} | |
/> | |
</p> | |
<input | |
ref={inputRef} | |
type="file" | |
className="hidden" | |
onChange={handleCustomUpload} | |
/> | |
<div className="flex w-full lg:w-auto items-center justify-end gap-3"> | |
<button | |
className={classNames( | |
"w-full lg:w-auto px-3 py-2 hover:bg-opacity-70 text-xs font-semibold text-white rounded-md flex items-center justify-center lg:justify-start gap-2", | |
{ | |
"bg-dark-300": !user?.id, | |
"bg-darkGreen": user?.id, | |
} | |
)} | |
onClick={() => inputRef.current?.click()} | |
> | |
{!user && <Premium size="16" tooltip={true} />} | |
<FormattedMessage id="iconsEditor.editor.listIcons.uploadCustomIcon" /> | |
</button> | |
<button | |
className={classNames( | |
"w-full lg:w-auto px-3 py-2 hover:bg-opacity-70 text-xs font-semibold text-white rounded-md flex items-center justify-center lg:justify-start gap-2", | |
{ | |
"bg-dark-300": !user?.id, | |
"bg-yellow": user?.id, | |
} | |
)} | |
onClick={onCustomText} | |
> | |
{!user && <Premium size="16" tooltip={true} />} | |
<FormattedMessage id="iconsEditor.editor.listIcons.useCustomText" /> | |
</button> | |
</div> | |
</div> | |
<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); | |
}} | |
/> | |
))} | |
{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; | |
console.log("display Modal and call API"); | |
}} | |
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" /> | |
<FormattedMessage | |
id="iconsEditor.editor.listIcons.pagination.previous" | |
values={{ | |
span: (t) => <span className="hidden lg:inline">{t}</span>, | |
}} | |
/> | |
</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)} | |
> | |
<FormattedMessage | |
id="iconsEditor.editor.listIcons.pagination.next" | |
values={{ | |
span: (t) => <span className="hidden lg:inline">{t}</span>, | |
}} | |
/> | |
<ArrowRightIcon className="w-4 text-white group-disabled:text-dark-200" /> | |
</button> | |
</div> | |
)} | |
</div> | |
); | |
}; | |