diff --git a/components/EditButton.tsx b/components/EditButton.tsx deleted file mode 100644 index 8286061..0000000 --- a/components/EditButton.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from "react"; -import { useTranslation } from "next-i18next"; -import clsx from "clsx"; - -type Props = { - onClick: Function; - className?: string; -}; - -function EditButton({ onClick, className }: Props) { - const { t } = useTranslation(); - - return ( - onClick()} - className={clsx( - "group-hover:opacity-100 opacity-0 duration-100 btn-square btn-xs btn btn-ghost absolute bi-pencil-fill text-neutral cursor-pointer -right-7 text-xs", - className - )} - title={t("edit")} - > - ); -} - -export default EditButton; diff --git a/components/LinkDetails.tsx b/components/LinkDetails.tsx index ae9779c..b6aade5 100644 --- a/components/LinkDetails.tsx +++ b/components/LinkDetails.tsx @@ -26,22 +26,26 @@ import { IconWeight } from "@phosphor-icons/react"; import Image from "next/image"; import clsx from "clsx"; import toast from "react-hot-toast"; -import EditButton from "./EditButton"; import CollectionSelection from "./InputSelect/CollectionSelection"; import TagSelection from "./InputSelect/TagSelection"; import unescapeString from "@/lib/client/unescapeString"; import IconPopover from "./IconPopover"; +import TextInput from "./TextInput"; type Props = { className?: string; activeLink: LinkIncludingShortenedCollectionAndTags; standalone?: boolean; + mode?: "view" | "edit"; + setMode?: Function; }; export default function LinkDetails({ className, activeLink, standalone, + mode = "view", + setMode, }: Props) { const [link, setLink] = useState(activeLink); @@ -144,21 +148,13 @@ export default function LinkDetails({ const updateLink = useUpdateLink(); - const [fieldToEdit, setFieldToEdit] = useState< - "name" | "collection" | "tags" | "description" | null - >(null); - const submit = async (e?: any) => { e?.preventDefault(); const { updatedAt: b, ...oldLink } = activeLink; const { updatedAt: a, ...newLink } = link; - console.log(oldLink); - console.log(newLink); - if (JSON.stringify(oldLink) === JSON.stringify(newLink)) { - setFieldToEdit(null); return; } @@ -172,7 +168,7 @@ export default function LinkDetails({ toast.error(error.message); } else { toast.success(t("updated")); - setFieldToEdit(null); + setMode && setMode("view"); console.log(data); setLink(data); } @@ -204,7 +200,7 @@ export default function LinkDetails({ >
) : link.preview === "unavailable" ? ( -
+
) : ( -
+
)} -
-
- -
-
- setIconPopover(true)} - /> -
- {/* #006796 */} - {iconPopover && ( - setLink({ ...link, color })} - weight={(link.iconWeight || "regular") as IconWeight} - setWeight={(iconWeight: string) => - setLink({ ...link, iconWeight }) - } - iconName={link.icon as string} - setIconName={(icon: string) => setLink({ ...link, icon })} - reset={() => - setLink({ - ...link, - color: "", - icon: "", - iconWeight: "", - }) - } - className="top-12" - onClose={() => { - setIconPopover(false); - submit(); - }} - /> + }} + className="hidden" + /> + +
)}
+ {standalone ? ( +
+ setIconPopover(true)} /> +
+ ) : ( +
+
+ setIconPopover(true)} + /> +
+ {iconPopover && ( + setLink({ ...link, color })} + weight={(link.iconWeight || "regular") as IconWeight} + setWeight={(iconWeight: string) => + setLink({ ...link, iconWeight }) + } + iconName={link.icon as string} + setIconName={(icon: string) => setLink({ ...link, icon })} + reset={() => + setLink({ + ...link, + color: "", + icon: "", + iconWeight: "", + }) + } + className="top-12" + onClose={() => { + setIconPopover(false); + submit(); + }} + /> + )} +
+ )} +
- {fieldToEdit !== "name" ? ( -
+ {mode === "view" && ( +

{link.name || t("untitled")} - setFieldToEdit("name")} - className="top-0" - />

- ) : fieldToEdit === "name" ? ( -
- setLink({ ...link, name: e.target.value })} - /> -
- ) : undefined} + )} {link.url && ( <> @@ -360,20 +348,32 @@ export default function LinkDetails({ )} + {mode === "edit" && ( + <> +
+ +
+

+ {t("name")} +

+ setLink({ ...link, name: e.target.value })} + placeholder={t("placeholder_example_link")} + className="bg-base-200" + /> +
+ + )} +
-
+

{t("collection")} - {fieldToEdit !== "collection" && ( - setFieldToEdit("collection")} - className="bottom-0" - /> - )}

- {fieldToEdit !== "collection" ? ( + {mode === "view" ? (
- ) : fieldToEdit === "collection" ? ( + ) : ( - ) : undefined} + )}

-
+

{t("tags")} - {fieldToEdit !== "tags" && ( - setFieldToEdit("tags")} - className="bottom-0" - /> - )}

- {fieldToEdit !== "tags" ? ( + {mode === "view" ? (
{link.tags[0] ? ( link.tags.map((tag) => @@ -464,26 +456,18 @@ export default function LinkDetails({ label: e.name, value: e.id, }))} - autoFocus - onBlur={submit} /> )}

-
+

{t("description")} - {fieldToEdit !== "description" && ( - setFieldToEdit("description")} - className="bottom-0" - /> - )}

- {fieldToEdit !== "description" ? ( + {mode === "view" ? (
{link.description ? (

{link.description}

@@ -499,134 +483,165 @@ export default function LinkDetails({ } placeholder={t("link_description_placeholder")} className="resize-none w-full rounded-md p-2 h-32 border-neutral-content bg-base-200 focus:border-primary border-solid border outline-none duration-100" - autoFocus - onBlur={submit} /> )}
-
+ {mode === "view" && ( +
+
-

- {link.url ? t("preserved_formats") : t("file")} -

- -
- {monolithAvailable(link) ? ( - <> - -
- - ) : undefined} - - {screenshotAvailable(link) ? ( - <> - -
- - ) : undefined} - - {pdfAvailable(link) ? ( - <> - -
- - ) : undefined} - - {readabilityAvailable(link) ? ( - <> - -
- - ) : undefined} - - {!isReady() && !atLeastOneFormatAvailable() ? ( -
- + {link.url ? t("preserved_formats") : t("file")} +

-

- {t("preservation_in_queue")} -

-

{t("check_back_later")}

+
+ {monolithAvailable(link) ? ( + <> + +
+ + ) : undefined} + + {screenshotAvailable(link) ? ( + <> + +
+ + ) : undefined} + + {pdfAvailable(link) ? ( + <> + +
+ + ) : undefined} + + {readabilityAvailable(link) ? ( + <> + +
+ + ) : undefined} + + {!isReady() && !atLeastOneFormatAvailable() ? ( +
+ + +

+ {t("preservation_in_queue")} +

+

+ {t("check_back_later")} +

+
+ ) : link.url && !isReady() && atLeastOneFormatAvailable() ? ( +
+ +

{t("there_are_more_formats")}

+

+ {t("check_back_later")} +

+
+ ) : undefined} + + {link.url && ( + +

+ {t("view_latest_snapshot")} +

+ + + )}
- ) : link.url && !isReady() && atLeastOneFormatAvailable() ? ( -
- -

{t("there_are_more_formats")}

-

{t("check_back_later")}

+
+ )} + + {mode === "view" ? ( + <> +
+ +

+ {t("saved")}{" "} + {new Date(link.createdAt || "").toLocaleDateString("en-US", { + month: "short", + day: "numeric", + year: "numeric", + })}{" "} + at{" "} + {new Date(link.createdAt || "").toLocaleTimeString("en-US", { + hour: "numeric", + minute: "numeric", + })} +

+ + ) : ( + <> +
+
+
- ) : undefined} - - {link.url && ( - -

{t("view_latest_snapshot")}

- - - )} -
- -
- -

- {t("saved")}{" "} - {new Date(link.createdAt || "").toLocaleDateString("en-US", { - month: "short", - day: "numeric", - year: "numeric", - })}{" "} - at{" "} - {new Date(link.createdAt || "").toLocaleTimeString("en-US", { - hour: "numeric", - minute: "numeric", - })} -

+ + )}
diff --git a/components/LinkViews/LinkComponents/LinkActions.tsx b/components/LinkViews/LinkComponents/LinkActions.tsx index f041c11..f8f1a29 100644 --- a/components/LinkViews/LinkComponents/LinkActions.tsx +++ b/components/LinkViews/LinkComponents/LinkActions.tsx @@ -4,14 +4,13 @@ import { LinkIncludingShortenedCollectionAndTags, } from "@/types/global"; import usePermissions from "@/hooks/usePermissions"; -import EditLinkModal from "@/components/ModalContent/EditLinkModal"; import DeleteLinkModal from "@/components/ModalContent/DeleteLinkModal"; import { dropdownTriggerer } from "@/lib/client/utils"; import { useTranslation } from "next-i18next"; import { useUser } from "@/hooks/store/user"; import { useDeleteLink, useGetLink, useUpdateLink } from "@/hooks/store/links"; import toast from "react-hot-toast"; -import LinkDetailModal from "@/components/ModalContent/LinkDetailModal"; +import LinkModal from "@/components/ModalContent/LinkModal"; import { useRouter } from "next/router"; type Props = { @@ -34,7 +33,7 @@ export default function LinkActions({ const getLink = useGetLink(); const [editLinkModal, setEditLinkModal] = useState(false); - const [linkDetailModal, setLinkDetailModal] = useState(false); + const [linkModal, setLinkModal] = useState(false); const [deleteLinkModal, setDeleteLinkModal] = useState(false); const { data: user = {} } = useUser(); @@ -96,7 +95,7 @@ export default function LinkActions({ className={`absolute ${position || "top-3 right-3"} ${ alignToTop ? "" : "dropdown-end" } z-20`} - onClick={() => setLinkDetailModal(true)} + onClick={() => setLinkModal(true)} >
@@ -144,7 +143,7 @@ export default function LinkActions({ tabIndex={0} onClick={() => { (document?.activeElement as HTMLElement)?.blur(); - setLinkDetailModal(true); + setLinkModal(true); }} className="whitespace-nowrap" > @@ -217,9 +216,13 @@ export default function LinkActions({
)} {editLinkModal && ( - setEditLinkModal(false)} - activeLink={link} + onPin={pinLink} + onUpdateArchive={updateArchive} + onDelete={() => setDeleteLinkModal(true)} + link={link} + activeMode="edit" /> )} {deleteLinkModal && ( @@ -228,10 +231,9 @@ export default function LinkActions({ activeLink={link} /> )} - {linkDetailModal && ( - setLinkDetailModal(false)} - onEdit={() => setEditLinkModal(true)} + {linkModal && ( + setLinkModal(false)} onPin={pinLink} onUpdateArchive={updateArchive} onDelete={() => setDeleteLinkModal(true)} diff --git a/components/ModalContent/EditLinkModal.tsx b/components/ModalContent/EditLinkModal.tsx deleted file mode 100644 index 6d17b1b..0000000 --- a/components/ModalContent/EditLinkModal.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import React, { useEffect, useState } from "react"; -import CollectionSelection from "@/components/InputSelect/CollectionSelection"; -import TagSelection from "@/components/InputSelect/TagSelection"; -import TextInput from "@/components/TextInput"; -import unescapeString from "@/lib/client/unescapeString"; -import { - ArchivedFormat, - LinkIncludingShortenedCollectionAndTags, -} from "@/types/global"; -import Link from "next/link"; -import Modal from "../Modal"; -import { useTranslation } from "next-i18next"; -import { useUpdateLink } from "@/hooks/store/links"; -import toast from "react-hot-toast"; -import IconPicker from "../IconPicker"; -import { IconWeight } from "@phosphor-icons/react"; -import Image from "next/image"; -import { previewAvailable } from "@/lib/shared/getArchiveValidity"; - -type Props = { - onClose: Function; - activeLink: LinkIncludingShortenedCollectionAndTags; -}; - -export default function EditLinkModal({ onClose, activeLink }: Props) { - const { t } = useTranslation(); - const [link, setLink] = - useState(activeLink); - - let shortenedURL; - try { - shortenedURL = new URL(link.url || "").host.toLowerCase(); - } catch (error) { - console.log(error); - } - - const [submitLoader, setSubmitLoader] = useState(false); - - const updateLink = useUpdateLink(); - - const setCollection = (e: any) => { - if (e?.__isNew__) e.value = null; - setLink({ - ...link, - collection: { id: e?.value, name: e?.label, ownerId: e?.ownerId }, - }); - }; - - const setTags = (e: any) => { - const tagNames = e.map((e: any) => ({ name: e.label })); - setLink({ ...link, tags: tagNames }); - }; - - useEffect(() => { - setLink(activeLink); - }, []); - - const submit = async () => { - if (!submitLoader) { - setSubmitLoader(true); - - const load = toast.loading(t("updating")); - - await updateLink.mutateAsync(link, { - onSettled: (data, error) => { - toast.dismiss(load); - - if (error) { - toast.error(error.message); - } else { - onClose(); - toast.success(t("updated")); - } - }, - }); - - setSubmitLoader(false); - } - }; - - return ( - -

{t("edit_link")}

- -
- - {link.url && ( - - -

{shortenedURL}

- - )} - -
-

{t("name")}

- setLink({ ...link, name: e.target.value })} - placeholder={t("placeholder_example_link")} - className="bg-base-200" - /> -
- -
-
-
-

{t("collection")}

- {link.collection.name && ( - - )} -
- -
-

{t("tags")}

- ({ - label: e.name, - value: e.id, - }))} - /> -
- -
-

{t("description")}

-