add pin to hover view + add number of pins to dashboard + bug fixes
This commit is contained in:
@@ -14,12 +14,7 @@ export default function dashboardItem({
|
||||
</div>
|
||||
<div className="ml-4 flex flex-col justify-center">
|
||||
<p className="text-neutral text-xs tracking-wider">{name}</p>
|
||||
<p className="font-thin text-5xl text-primary mt-0.5 hidden sm:block md:hidden">
|
||||
{value < 1000 ? value : (value / 1000).toFixed(1) + "k"}
|
||||
</p>
|
||||
<p className="font-thin text-5xl text-primary mt-0.5 sm:hidden md:block">
|
||||
{value}
|
||||
</p>
|
||||
<p className="font-thin text-5xl text-primary mt-0.5">{value || 0}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,12 +7,12 @@ import usePermissions from "@/hooks/usePermissions";
|
||||
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 { useDeleteLink, useGetLink } from "@/hooks/store/links";
|
||||
import toast from "react-hot-toast";
|
||||
import LinkModal from "@/components/ModalContent/LinkModal";
|
||||
import { useRouter } from "next/router";
|
||||
import clsx from "clsx";
|
||||
import usePinLink from "@/lib/client/pinLink";
|
||||
|
||||
type Props = {
|
||||
link: LinkIncludingShortenedCollectionAndTags;
|
||||
@@ -27,41 +27,14 @@ export default function LinkActions({ link, className, btnStyle }: Props) {
|
||||
const permissions = usePermissions(link.collection.id as number);
|
||||
const getLink = useGetLink();
|
||||
|
||||
const pinLink = usePinLink();
|
||||
|
||||
const [editLinkModal, setEditLinkModal] = useState(false);
|
||||
const [linkModal, setLinkModal] = useState(false);
|
||||
const [deleteLinkModal, setDeleteLinkModal] = useState(false);
|
||||
|
||||
const { data: user = {} } = useUser();
|
||||
|
||||
const updateLink = useUpdateLink();
|
||||
const deleteLink = useDeleteLink();
|
||||
|
||||
const pinLink = async () => {
|
||||
const isAlreadyPinned = link?.pinnedBy && link.pinnedBy[0] ? true : false;
|
||||
|
||||
const load = toast.loading(t("updating"));
|
||||
|
||||
await updateLink.mutateAsync(
|
||||
{
|
||||
...link,
|
||||
pinnedBy: isAlreadyPinned ? [{ id: undefined }] : [{ id: user.id }],
|
||||
},
|
||||
{
|
||||
onSettled: (data, error) => {
|
||||
toast.dismiss(load);
|
||||
|
||||
if (error) {
|
||||
toast.error(error.message);
|
||||
} else {
|
||||
toast.success(
|
||||
isAlreadyPinned ? t("link_unpinned") : t("link_pinned")
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const updateArchive = async () => {
|
||||
const load = toast.loading(t("sending_request"));
|
||||
|
||||
@@ -103,7 +76,7 @@ export default function LinkActions({ link, className, btnStyle }: Props) {
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={`dropdown dropdown-left absolute ${
|
||||
className={`dropdown dropdown-end absolute ${
|
||||
className || "top-3 right-3"
|
||||
} z-20`}
|
||||
>
|
||||
@@ -117,7 +90,7 @@ export default function LinkActions({ link, className, btnStyle }: Props) {
|
||||
</div>
|
||||
<ul
|
||||
className={
|
||||
"dropdown-content z-[20] menu shadow bg-base-200 border border-neutral-content rounded-box mr-1"
|
||||
"dropdown-content z-[20] menu shadow bg-base-200 border border-neutral-content rounded-box mt-1"
|
||||
}
|
||||
>
|
||||
<li>
|
||||
@@ -126,7 +99,7 @@ export default function LinkActions({ link, className, btnStyle }: Props) {
|
||||
tabIndex={0}
|
||||
onClick={() => {
|
||||
(document?.activeElement as HTMLElement)?.blur();
|
||||
pinLink();
|
||||
pinLink(link);
|
||||
}}
|
||||
className="whitespace-nowrap"
|
||||
>
|
||||
@@ -216,7 +189,7 @@ export default function LinkActions({ link, className, btnStyle }: Props) {
|
||||
{editLinkModal && (
|
||||
<LinkModal
|
||||
onClose={() => setEditLinkModal(false)}
|
||||
onPin={pinLink}
|
||||
onPin={() => pinLink(link)}
|
||||
onUpdateArchive={updateArchive}
|
||||
onDelete={() => setDeleteLinkModal(true)}
|
||||
link={link}
|
||||
@@ -232,7 +205,7 @@ export default function LinkActions({ link, className, btnStyle }: Props) {
|
||||
{linkModal && (
|
||||
<LinkModal
|
||||
onClose={() => setLinkModal(false)}
|
||||
onPin={pinLink}
|
||||
onPin={() => pinLink(link)}
|
||||
onUpdateArchive={updateArchive}
|
||||
onDelete={() => setDeleteLinkModal(true)}
|
||||
link={link}
|
||||
|
||||
@@ -23,6 +23,7 @@ import { useUser } from "@/hooks/store/user";
|
||||
import { useGetLink, useLinks } from "@/hooks/store/links";
|
||||
import { useRouter } from "next/router";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
import LinkPin from "./LinkPin";
|
||||
|
||||
type Props = {
|
||||
link: LinkIncludingShortenedCollectionAndTags;
|
||||
@@ -36,13 +37,13 @@ export default function LinkCard({ link, columns, editMode }: Props) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const heightMap = {
|
||||
1: "h-48",
|
||||
2: "h-44",
|
||||
3: "h-40",
|
||||
4: "h-36",
|
||||
5: "h-32",
|
||||
6: "h-28",
|
||||
7: "h-24",
|
||||
1: "h-44",
|
||||
2: "h-40",
|
||||
3: "h-36",
|
||||
4: "h-32",
|
||||
5: "h-28",
|
||||
6: "h-24",
|
||||
7: "h-20",
|
||||
8: "h-20",
|
||||
};
|
||||
|
||||
@@ -216,7 +217,7 @@ export default function LinkCard({ link, columns, editMode }: Props) {
|
||||
<div>
|
||||
<hr className="divider mt-2 mb-1 last:hidden border-t border-neutral-content h-[1px]" />
|
||||
|
||||
<div className="flex justify-between text-xs text-neutral px-3 pb-1 gap-2">
|
||||
<div className="flex justify-between items-center text-xs text-neutral px-3 pb-1 gap-2">
|
||||
{show.collection && (
|
||||
<div className="cursor-pointer truncate">
|
||||
<LinkCollection link={link} collection={collection} />
|
||||
@@ -238,6 +239,10 @@ export default function LinkCard({ link, columns, editMode }: Props) {
|
||||
"top-3 right-3 group-hover:opacity-100 group-focus-within:opacity-100 opacity-0 duration-100"
|
||||
}
|
||||
/>
|
||||
<LinkPin
|
||||
link={link}
|
||||
className="absolute top-3 right-[3.25rem] group-hover:opacity-100 group-focus-within:opacity-100 opacity-0 duration-100"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,13 +35,13 @@ export default function LinkMasonry({ link, editMode, columns }: Props) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const heightMap = {
|
||||
1: "h-48",
|
||||
2: "h-44",
|
||||
3: "h-40",
|
||||
4: "h-36",
|
||||
5: "h-32",
|
||||
6: "h-28",
|
||||
7: "h-24",
|
||||
1: "h-44",
|
||||
2: "h-40",
|
||||
3: "h-36",
|
||||
4: "h-32",
|
||||
5: "h-28",
|
||||
6: "h-24",
|
||||
7: "h-20",
|
||||
8: "h-20",
|
||||
};
|
||||
|
||||
@@ -225,7 +225,7 @@ export default function LinkMasonry({ link, editMode, columns }: Props) {
|
||||
<div>
|
||||
<hr className="divider mt-2 mb-1 last:hidden border-t border-neutral-content h-[1px]" />
|
||||
|
||||
<div className="flex flex-wrap justify-between text-xs text-neutral px-3 pb-1 w-full gap-x-2">
|
||||
<div className="flex flex-wrap justify-between items-center text-xs text-neutral px-3 pb-1 w-full gap-x-2">
|
||||
{show.collection && (
|
||||
<div className="cursor-pointer truncate">
|
||||
<LinkCollection link={link} collection={collection} />
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
|
||||
import { useRouter } from "next/router";
|
||||
import clsx from "clsx";
|
||||
import usePinLink from "@/lib/client/pinLink";
|
||||
|
||||
type Props = {
|
||||
link: LinkIncludingShortenedCollectionAndTags;
|
||||
className?: string;
|
||||
btnStyle?: string;
|
||||
};
|
||||
|
||||
export default function LinkPin({ link, className, btnStyle }: Props) {
|
||||
const pinLink = usePinLink();
|
||||
const router = useRouter();
|
||||
|
||||
const isPublicRoute = router.pathname.startsWith("/public") ? true : false;
|
||||
const isAlreadyPinned = link?.pinnedBy && link.pinnedBy[0] ? true : false;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(className || "top-3 right-3 absolute", btnStyle)}
|
||||
onClick={() => pinLink(link)}
|
||||
>
|
||||
<div className="btn btn-sm btn-square text-neutral">
|
||||
<i
|
||||
title="Pin"
|
||||
className={clsx(
|
||||
"text-xl",
|
||||
isAlreadyPinned ? "bi-pin-fill" : "bi-pin"
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -130,7 +130,7 @@ export default function ViewDropdown({ viewMode, setViewMode }: Props) {
|
||||
className="range range-xs range-primary"
|
||||
step="1"
|
||||
/>
|
||||
<div className="flex w-full justify-between px-2 text-xs text-neutral">
|
||||
<div className="flex w-full justify-between px-2 text-xs text-neutral select-none">
|
||||
<span>|</span>
|
||||
<span>|</span>
|
||||
<span>|</span>
|
||||
|
||||
Reference in New Issue
Block a user