added custom icons for links

This commit is contained in:
daniel31x13 2024-08-24 15:50:29 -04:00
parent bf1a6efd2e
commit fae9e95fa9
7 changed files with 72 additions and 40 deletions

View File

@ -8,13 +8,14 @@ import { IconWeight } from "@phosphor-icons/react";
import IconGrid from "./IconGrid"; import IconGrid from "./IconGrid";
type Props = { type Props = {
alignment?: "left" | "right"; alignment?: string;
color: string; color: string;
setColor: Function; setColor: Function;
iconName?: string; iconName?: string;
setIconName: Function; setIconName: Function;
weight: "light" | "regular" | "bold" | "fill" | "duotone" | "thin"; weight: "light" | "regular" | "bold" | "fill" | "duotone" | "thin";
setWeight: Function; setWeight: Function;
hideDefaultIcon?: boolean;
reset: Function; reset: Function;
className?: string; className?: string;
}; };
@ -27,6 +28,7 @@ const IconPicker = ({
setIconName, setIconName,
weight, weight,
setWeight, setWeight,
hideDefaultIcon,
className, className,
reset, reset,
}: Props) => { }: Props) => {
@ -47,6 +49,8 @@ const IconPicker = ({
weight={(weight || "regular") as IconWeight} weight={(weight || "regular") as IconWeight}
color={color || "#0ea5e9"} color={color || "#0ea5e9"}
/> />
) : !iconName && hideDefaultIcon ? (
<p className="p-1">{t("set_custom_icon")}</p>
) : ( ) : (
<i <i
className="bi-folder-fill text-6xl" className="bi-folder-fill text-6xl"
@ -59,7 +63,8 @@ const IconPicker = ({
onClose={() => setIconPicker(false)} onClose={() => setIconPicker(false)}
className={ className={
className + className +
" fade-in bg-base-200 border border-neutral-content p-2 h-44 w-[22.5rem] rounded-lg backdrop-blur-sm bg-opacity-90 top-20 left-0 lg:-translate-x-1/3" " fade-in bg-base-200 border border-neutral-content p-2 h-44 w-[22.5rem] rounded-lg backdrop-blur-sm bg-opacity-90 " +
(alignment || " lg:-translate-x-1/3 top-20 left-0 ")
} }
> >
<div className="flex gap-2 h-full w-full"> <div className="flex gap-2 h-full w-full">

View File

@ -127,7 +127,9 @@ export default function LinkDetails({ className, link }: Props) {
return ( return (
<div className={className} data-vaul-no-drag> <div className={className} data-vaul-no-drag>
<LinkIcon link={link} className="mx-auto" /> <div className="mx-auto w-fit">
<LinkIcon link={link} hideBackground />
</div>
{link.name && <p className="text-xl text-center mt-2">{link.name}</p>} {link.name && <p className="text-xl text-center mt-2">{link.name}</p>}

View File

@ -2,34 +2,24 @@ import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
import Image from "next/image"; import Image from "next/image";
import isValidUrl from "@/lib/shared/isValidUrl"; import isValidUrl from "@/lib/shared/isValidUrl";
import React from "react"; import React from "react";
import Icon from "@/components/Icon";
import { IconWeight } from "@phosphor-icons/react";
import clsx from "clsx";
export default function LinkIcon({ export default function LinkIcon({
link, link,
className, className,
size, hideBackground,
}: { }: {
link: LinkIncludingShortenedCollectionAndTags; link: LinkIncludingShortenedCollectionAndTags;
className?: string; className?: string;
size?: "small" | "medium"; hideBackground?: boolean;
}) { }) {
let iconClasses: string = let iconClasses: string = clsx(
"bg-white shadow rounded-md border-[2px] flex item-center justify-center border-white select-none z-10 " + "rounded-md flex item-center justify-center select-none z-10 w-12 h-12",
(className || ""); !hideBackground && "bg-white backdrop-blur-lg bg-opacity-50 p-1",
className
let dimension; );
switch (size) {
case "small":
dimension = " w-8 h-8";
break;
case "medium":
dimension = " w-12 h-12";
break;
default:
size = "medium";
dimension = " w-12 h-12";
break;
}
const url = const url =
isValidUrl(link.url || "") && link.url ? new URL(link.url) : undefined; isValidUrl(link.url || "") && link.url ? new URL(link.url) : undefined;
@ -38,14 +28,22 @@ export default function LinkIcon({
return ( return (
<> <>
{link.type === "url" && url ? ( {link.icon ? (
<Icon
icon={link.icon}
size={30}
weight={(link.iconWeight || "regular") as IconWeight}
color={link.color || "#0ea5e9"}
className={iconClasses}
/>
) : link.type === "url" && url ? (
showFavicon ? ( showFavicon ? (
<Image <Image
src={`https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=${link.url}&size=32`} src={`https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=${link.url}&size=32`}
width={64} width={64}
height={64} height={64}
alt="" alt=""
className={iconClasses + dimension} className={iconClasses}
draggable="false" draggable="false"
onError={() => { onError={() => {
setShowFavicon(false); setShowFavicon(false);
@ -53,22 +51,22 @@ export default function LinkIcon({
/> />
) : ( ) : (
<LinkPlaceholderIcon <LinkPlaceholderIcon
iconClasses={iconClasses + dimension} iconClasses={iconClasses}
size={size}
icon="bi-link-45deg" icon="bi-link-45deg"
hideBackground={hideBackground}
/> />
) )
) : link.type === "pdf" ? ( ) : link.type === "pdf" ? (
<LinkPlaceholderIcon <LinkPlaceholderIcon
iconClasses={iconClasses + dimension} iconClasses={iconClasses}
size={size}
icon="bi-file-earmark-pdf" icon="bi-file-earmark-pdf"
hideBackground={hideBackground}
/> />
) : link.type === "image" ? ( ) : link.type === "image" ? (
<LinkPlaceholderIcon <LinkPlaceholderIcon
iconClasses={iconClasses + dimension} iconClasses={iconClasses}
size={size}
icon="bi-file-earmark-image" icon="bi-file-earmark-image"
hideBackground={hideBackground}
/> />
) : // : link.type === "monolith" ? ( ) : // : link.type === "monolith" ? (
// <LinkPlaceholderIcon // <LinkPlaceholderIcon
@ -84,20 +82,18 @@ export default function LinkIcon({
const LinkPlaceholderIcon = ({ const LinkPlaceholderIcon = ({
iconClasses, iconClasses,
size,
icon, icon,
hideBackground,
}: { }: {
iconClasses: string; iconClasses: string;
size?: "small" | "medium";
icon: string; icon: string;
hideBackground?: boolean;
}) => { }) => {
return ( return (
<div <div className={clsx(iconClasses, "aspect-square text-4xl text-[#0ea5e9]")}>
className={`${
size === "small" ? "text-2xl" : "text-4xl"
} text-black aspect-square ${iconClasses}`}
>
<i className={`${icon} m-auto`}></i> <i className={`${icon} m-auto`}></i>
</div> </div>
); );
}; };
// `text-black aspect-square text-4xl ${iconClasses}`

View File

@ -111,7 +111,7 @@ export default function LinkCardCompact({
} }
> >
<div className="shrink-0"> <div className="shrink-0">
<LinkIcon link={link} className="w-12 h-12 text-4xl" /> <LinkIcon link={link} hideBackground />
</div> </div>
<div className="w-[calc(100%-56px)] ml-2"> <div className="w-[calc(100%-56px)] ml-2">

View File

@ -9,6 +9,8 @@ import Modal from "../Modal";
import { useTranslation } from "next-i18next"; import { useTranslation } from "next-i18next";
import { useUpdateLink } from "@/hooks/store/links"; import { useUpdateLink } from "@/hooks/store/links";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import IconPicker from "../IconPicker";
import { IconWeight } from "@phosphor-icons/react";
type Props = { type Props = {
onClose: Function; onClose: Function;
@ -138,6 +140,29 @@ export default function EditLinkModal({ onClose, activeLink }: Props) {
className="resize-none w-full rounded-md p-2 border-neutral-content bg-base-200 focus:border-sky-300 dark:focus:border-sky-600 border-solid border outline-none duration-100" className="resize-none w-full rounded-md p-2 border-neutral-content bg-base-200 focus:border-sky-300 dark:focus:border-sky-600 border-solid border outline-none duration-100"
/> />
</div> </div>
<div>
<IconPicker
hideDefaultIcon
color={link.color || "#0ea5e9"}
setColor={(color: string) => 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: "",
})
}
alignment="-top-10 translate-x-20"
/>
</div>
</div> </div>
</div> </div>

View File

@ -96,6 +96,9 @@ export default async function updateLinkById(
data: { data: {
name: data.name, name: data.name,
description: data.description, description: data.description,
icon: data.icon,
iconWeight: data.iconWeight,
color: data.color,
collection: { collection: {
connect: { connect: {
id: data.collection.id, id: data.collection.id,

View File

@ -379,5 +379,6 @@
"fill": "Fill", "fill": "Fill",
"duotone": "Duotone", "duotone": "Duotone",
"light_icon": "Light", "light_icon": "Light",
"search": "Search" "search": "Search",
"set_custom_icon": "Set Custom Icon"
} }