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()} | |
| > | |
| <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} | |
| > | |
| <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> | |
| ); | |
| }; | |