Spaces:
Running
Running
| import classNames from "classnames"; | |
| import { useState } from "react"; | |
| import { | |
| faChevronDown, | |
| faChevronRight, | |
| faTrash, | |
| faCaretDown, | |
| faCaretUp, | |
| } from "@fortawesome/free-solid-svg-icons"; | |
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | |
| import { ColorPicker } from "components/color-picker"; | |
| import { Range } from "components/range"; | |
| import { UploadImage } from "@/components/upload"; | |
| import { Switch } from "@/components/switch"; | |
| import { login, useUser } from "@/utils/auth"; | |
| import { Premium } from "@/components/premium"; | |
| import { PremiumOverlay } from "@/components/premium/overlay"; | |
| import { FormattedMessage, useIntl } from "react-intl"; | |
| import { Label } from "@/components/label"; | |
| export const ShapeSelected = ({ | |
| shape, | |
| handleChange, | |
| onDelete, | |
| }: { | |
| shape: any; | |
| handleChange: (s: any) => void; | |
| onDelete: () => void; | |
| }) => { | |
| const { user } = useUser(); | |
| const intl = useIntl(); | |
| const [open, setOpen] = useState(true); | |
| return ( | |
| <div | |
| className={classNames( | |
| "mt-5 bg-dark-600 w-full rounded-lg pl-4 py-4 pr-6 cursor-pointer transition-all border-2 border-dark-600 duration-200 hover:border-blue", | |
| { | |
| "border-blue": open, | |
| } | |
| )} | |
| > | |
| <div | |
| className="tracking-wider flex items-center justify-between gap-4" | |
| onClick={() => setOpen(!open)} | |
| > | |
| <p className="text-white font-semibold"> | |
| <FormattedMessage id="iconsEditor.editor.shape.update.title" /> | |
| </p> | |
| <div className="flex items-center justify-end gap-4"> | |
| <div | |
| className="bg-danger bg-opacity-60 rounded-lg text-white hover:bg-opacity-100 cursor-pointer w-8 h-8 flex items-center justify-center" | |
| onClick={(e: any) => { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| onDelete(); | |
| }} | |
| > | |
| <FontAwesomeIcon icon={faTrash} className="w-4" /> | |
| </div> | |
| <div className="w-4 flex items-center justify-end"> | |
| <FontAwesomeIcon | |
| icon={open ? faChevronDown : faChevronRight} | |
| className="text-dark-100 transition-all duration-200" | |
| /> | |
| </div> | |
| </div> | |
| </div> | |
| {open && ( | |
| <div className="border-t border-dark-400 pt-3 mt-4 grid grid-cols-2 gap-4"> | |
| <div className="w-full col-span-2"> | |
| <Label className="!mb-2"> | |
| <FormattedMessage id="iconsEditor.editor.customisation.rotation" /> | |
| </Label> | |
| <div className="flex items-center gap-3 w-full"> | |
| <p className="font-semibold uppercase text-dark-200 text-xs">Z</p> | |
| <Range | |
| value={shape?.position?.angle ?? 0} | |
| max={360} | |
| onChange={(value) => { | |
| const newShape = { | |
| ...shape, | |
| position: { ...shape.position, angle: Number(value) }, | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| <input | |
| type="number" | |
| className="w-full bg-dark-500 rounded px-2 py-2 text-sm text-white placeholder-dark-200 outline-none border-none" | |
| placeholder={intl.formatMessage({ | |
| id: "iconsEditor.editor.customisation.angle", | |
| })} | |
| value={shape?.position?.angle} | |
| onChange={({ target }) => { | |
| const newShape = { | |
| ...shape, | |
| position: { | |
| ...shape.position, | |
| angle: target.value | |
| ? Number(target.value) > 360 | |
| ? 360 | |
| : Number(target.value) | |
| : undefined, | |
| }, | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| </div> | |
| </div> | |
| {shape?.component === "Square" && ( | |
| <div className="w-full col-span-2"> | |
| <Label className="!mb-2"> | |
| <FormattedMessage id="iconsEditor.editor.customisation.radius" /> | |
| </Label> | |
| <div className="flex items-center gap-3 w-full"> | |
| <p className="font-semibold uppercase text-dark-200 text-xs"> | |
| Z | |
| </p> | |
| <Range | |
| value={shape?.radius ?? 0} | |
| max={120} | |
| onChange={(value) => { | |
| const newShape = { | |
| ...shape, | |
| radius: Number(value), | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| <input | |
| type="number" | |
| className="w-full bg-dark-500 rounded px-2 py-2 text-sm text-white placeholder-dark-200 outline-none border-none" | |
| placeholder={intl.formatMessage({ | |
| id: "iconsEditor.editor.customisation.angle", | |
| })} | |
| value={shape?.radius} | |
| onChange={({ target }) => { | |
| const newShape = { | |
| ...shape, | |
| radius: Number(target.value), | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| </div> | |
| </div> | |
| )} | |
| <div className="col-span-2"> | |
| <div className="flex items-center justify-start gap-3 mb-2.5 "> | |
| <Label className=""> | |
| <FormattedMessage | |
| id="iconsEditor.editor.customisation.gradientColor" | |
| values={{ | |
| span: (t) => ( | |
| <span className="text-xs opacity-40">{t}</span> | |
| ), | |
| }} | |
| /> | |
| </Label> | |
| <Switch | |
| value={!shape?.transparency} | |
| onChange={(transparency: boolean) => { | |
| const newShape = { | |
| ...shape, | |
| transparency: !transparency, | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| </div> | |
| <ColorPicker | |
| value={shape?.stringColor ?? shape?.colour} | |
| data={shape} | |
| onChange={(c: any, datas) => { | |
| let newShape = { ...shape, stringColor: c }; | |
| if (c.includes("gradient")) { | |
| const { colors, degrees } = datas; | |
| const gradientType = c?.startsWith("linear") | |
| ? "linearGradient" | |
| : "radialGradient"; | |
| const angle = c?.startsWith("linear") | |
| ? c?.replace("linear-gradient(", "")?.split("deg")?.[0] | |
| : 90; | |
| newShape["gradient"] = { | |
| ...newShape.gradient, | |
| enabled: true, | |
| colours: colors, | |
| angle, | |
| type: gradientType, | |
| }; | |
| } else { | |
| newShape = { | |
| ...newShape, | |
| colour: c, | |
| gradient: { | |
| ...shape?.gradient, | |
| enabled: false, | |
| }, | |
| }; | |
| } | |
| handleChange(newShape); | |
| }} | |
| /> | |
| </div> | |
| <div className="col-span-2 grid grid-cols-2 gap-4 relative"> | |
| <div className="col-span-2"> | |
| <div className="flex items-center justify-start gap-3 mb-2.5 "> | |
| <Label className=""> | |
| <FormattedMessage id="iconsEditor.editor.customisation.backgroundImage" /> | |
| </Label> | |
| <Switch | |
| value={shape?.image?.enabled} | |
| onChange={(enabled: boolean) => { | |
| const newShape = { | |
| ...shape, | |
| image: { | |
| ...shape.image, | |
| enabled, | |
| }, | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| </div> | |
| {shape?.image?.enabled && ( | |
| <UploadImage | |
| values={shape?.image?.urls} | |
| onChange={(urls: string) => { | |
| const newShape = { | |
| ...shape, | |
| image: { | |
| ...shape.image, | |
| urls, | |
| }, | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| )} | |
| </div> | |
| <div> | |
| <Label className="!mb-2.5"> | |
| <FormattedMessage id="iconsEditor.editor.customisation.border" /> | |
| </Label> | |
| <div className="flex items-start justify-start gap-5"> | |
| <div className="w-full"> | |
| <p className="font-semibold uppercase text-dark-200 text-xs mb-2"> | |
| <FormattedMessage id="iconsEditor.editor.customisation.width" /> | |
| </p> | |
| <input | |
| type="number" | |
| className="bg-dark-500 w-full rounded px-4 py-2 text-sm text-white placeholder-dark-200 outline-none border-none" | |
| placeholder={ | |
| intl.formatMessage({ | |
| id: "iconsEditor.editor.customisation.width", | |
| }) + "...px" | |
| } | |
| min={0} | |
| value={shape?.border?.width} | |
| onChange={({ target }) => { | |
| const newShape = { | |
| ...shape, | |
| border: { | |
| ...shape.border, | |
| width: target?.value | |
| ? Number(target.value) | |
| : undefined, | |
| }, | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| </div> | |
| <div> | |
| <p className="font-semibold uppercase text-dark-200 text-xs mb-2"> | |
| <FormattedMessage id="iconsEditor.editor.customisation.color" /> | |
| </p> | |
| <ColorPicker | |
| value={shape?.border?.colour} | |
| gradients={false} | |
| onChange={(c: any) => { | |
| const newShape = { | |
| ...shape, | |
| border: { | |
| ...shape.border, | |
| colour: c, | |
| }, | |
| }; | |
| handleChange(newShape); | |
| }} | |
| /> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| }; | |