custom icons fully implemented for collections

This commit is contained in:
daniel31x13 2024-08-20 19:25:35 -04:00
parent 6df2e44213
commit bf1a6efd2e
11 changed files with 127 additions and 56 deletions

View File

@ -17,6 +17,8 @@ import toast from "react-hot-toast";
import { useTranslation } from "next-i18next";
import { useCollections, useUpdateCollection } from "@/hooks/store/collections";
import { useUpdateUser, useUser } from "@/hooks/store/user";
import Icon from "./Icon";
import { IconWeight } from "@phosphor-icons/react";
interface ExtendedTreeItem extends TreeItem {
data: Collection;
@ -256,7 +258,7 @@ const renderItem = (
: "hover:bg-neutral/20"
} duration-100 flex gap-1 items-center pr-2 pl-1 rounded-md`}
>
{Icon(item as ExtendedTreeItem, onExpand, onCollapse)}
{Dropdown(item as ExtendedTreeItem, onExpand, onCollapse)}
<Link
href={`/collections/${collection.id}`}
@ -266,10 +268,21 @@ const renderItem = (
<div
className={`py-1 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize`}
>
<i
className="bi-folder-fill text-2xl drop-shadow"
style={{ color: collection.color }}
></i>
{collection.icon ? (
<Icon
icon={collection.icon}
size={30}
weight={(collection.iconWeight || "regular") as IconWeight}
color={collection.color || "#0ea5e9"}
className="-mr-[0.15rem]"
/>
) : (
<i
className="bi-folder-fill text-2xl"
style={{ color: collection.color || "#0ea5e9" }}
></i>
)}
<p className="truncate w-full">{collection.name}</p>
{collection.isPublic && (
@ -288,7 +301,7 @@ const renderItem = (
);
};
const Icon = (
const Dropdown = (
item: ExtendedTreeItem,
onExpand: (id: ItemId) => void,
onCollapse: (id: ItemId) => void
@ -332,6 +345,8 @@ const buildTreeFromCollections = (
name: collection.name,
description: collection.description,
color: collection.color,
icon: collection.icon,
iconWeight: collection.iconWeight,
isPublic: collection.isPublic,
ownerId: collection.ownerId,
createdAt: collection.createdAt,

View File

@ -20,6 +20,8 @@ import { useGetLink } from "@/hooks/store/links";
import LinkIcon from "./LinkViews/LinkComponents/LinkIcon";
import CopyButton from "./CopyButton";
import { useRouter } from "next/router";
import Icon from "./Icon";
import { IconWeight } from "@phosphor-icons/react";
type Props = {
className?: string;
@ -163,10 +165,19 @@ export default function LinkDetails({ className, link }: Props) {
>
<p>{link.collection.name}</p>
<div className="absolute right-0 px-2 bg-base-200">
<i
className="bi-folder-fill text-xl"
style={{ color: link.collection.color }}
></i>
{link.collection.icon ? (
<Icon
icon={link.collection.icon}
size={30}
weight={(link.collection.iconWeight || "regular") as IconWeight}
color={link.collection.color || "#0ea5e9"}
/>
) : (
<i
className="bi-folder-fill text-2xl"
style={{ color: link.collection.color || "#0ea5e9" }}
></i>
)}
</div>
</Link>
</div>

View File

@ -1,7 +1,9 @@
import Icon from "@/components/Icon";
import {
CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags,
} from "@/types/global";
import { IconWeight } from "@phosphor-icons/react";
import Link from "next/link";
import React from "react";
@ -22,10 +24,19 @@ export default function LinkCollection({
className="flex items-center gap-1 max-w-full w-fit hover:opacity-70 duration-100 select-none"
title={collection?.name}
>
<i
className="bi-folder-fill text-lg drop-shadow"
style={{ color: collection?.color }}
></i>
{link.collection.icon ? (
<Icon
icon={link.collection.icon}
size={20}
weight={(link.collection.iconWeight || "regular") as IconWeight}
color={link.collection.color || "#0ea5e9"}
/>
) : (
<i
className="bi-folder-fill text-lg"
style={{ color: link.collection.color || "#0ea5e9" }}
></i>
)}
<p className="truncate capitalize">{collection?.name}</p>
</Link>
</>

View File

@ -6,7 +6,6 @@ import { useTranslation } from "next-i18next";
import { useUpdateCollection } from "@/hooks/store/collections";
import toast from "react-hot-toast";
import IconPicker from "../IconPicker";
import Icon from "../Icon";
import { IconWeight } from "@phosphor-icons/react";
type Props = {

View File

@ -1,12 +1,13 @@
import React, { useEffect, useState } from "react";
import TextInput from "@/components/TextInput";
import { HexColorPicker } from "react-colorful";
import { Collection } from "@prisma/client";
import Modal from "../Modal";
import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import { useTranslation } from "next-i18next";
import { useCreateCollection } from "@/hooks/store/collections";
import toast from "react-hot-toast";
import IconPicker from "../IconPicker";
import { IconWeight } from "@phosphor-icons/react";
type Props = {
onClose: Function;
@ -72,10 +73,32 @@ export default function NewCollectionModal({ onClose, parent }: Props) {
<div className="divider mb-3 mt-1"></div>
<div className="flex flex-col gap-3">
<div className="flex flex-col sm:flex-row gap-3">
<div className="w-full">
<p className="mb-2">{t("name")}</p>
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-3">
<div className="flex gap-3 items-end">
<IconPicker
color={collection.color || "#0ea5e9"}
setColor={(color: string) =>
setCollection({ ...collection, color })
}
weight={(collection.iconWeight || "regular") as IconWeight}
setWeight={(iconWeight: string) =>
setCollection({ ...collection, iconWeight })
}
iconName={collection.icon as string}
setIconName={(icon: string) =>
setCollection({ ...collection, icon })
}
reset={() =>
setCollection({
...collection,
color: "#0ea5e9",
icon: "",
iconWeight: "",
})
}
/>
<div className="w-full">
<p className="mb-2">{t("name")}</p>
<TextInput
className="bg-base-200"
value={collection.name}
@ -84,31 +107,6 @@ export default function NewCollectionModal({ onClose, parent }: Props) {
setCollection({ ...collection, name: e.target.value })
}
/>
<div>
<p className="w-full mb-2">{t("color")}</p>
<div className="color-picker flex justify-between items-center">
<HexColorPicker
color={collection.color as string}
onChange={(color) =>
setCollection({ ...collection, color })
}
/>
<div className="flex flex-col gap-2 items-center w-32">
<i
className={"bi-folder-fill text-5xl"}
style={{ color: collection.color as string }}
></i>
<div
className="btn btn-ghost btn-xs"
onClick={() =>
setCollection({ ...collection, color: "#0ea5e9" })
}
>
{t("reset")}
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -16,6 +16,8 @@ import LinkActions from "./LinkViews/LinkComponents/LinkActions";
import { useTranslation } from "next-i18next";
import { useCollections } from "@/hooks/store/collections";
import { useGetLink } from "@/hooks/store/links";
import { IconWeight } from "@phosphor-icons/react";
import Icon from "./Icon";
type LinkContent = {
title: string;
@ -203,10 +205,21 @@ export default function ReadableView({ link }: Props) {
href={`/collections/${link?.collection.id}`}
className="flex items-center gap-1 cursor-pointer hover:opacity-60 duration-100 mr-2 z-10"
>
<i
className="bi-folder-fill drop-shadow text-2xl"
style={{ color: link?.collection.color as string }}
></i>
{link.collection.icon ? (
<Icon
icon={link.collection.icon}
size={30}
weight={
(link.collection.iconWeight || "regular") as IconWeight
}
color={link.collection.color || "#0ea5e9"}
/>
) : (
<i
className="bi-folder-fill text-2xl"
style={{ color: link.collection.color || "#0ea5e9" }}
></i>
)}
<p
title={link?.collection.name}
className="text-lg truncate max-w-[12rem]"

View File

@ -18,8 +18,6 @@ export default async function updateCollection(
if (!(collectionIsAccessible?.ownerId === userId))
return { response: "Collection is not accessible.", status: 401 };
console.log(data);
if (data.parentId) {
if (data.parentId !== ("root" as any)) {
const findParentCollection = await prisma.collection.findUnique({
@ -61,6 +59,8 @@ export default async function updateCollection(
name: data.name.trim(),
description: data.description,
color: data.color,
icon: data.icon,
iconWeight: data.iconWeight,
isPublic: data.isPublic,
parent:
data.parentId && data.parentId !== ("root" as any)

View File

@ -42,6 +42,8 @@ export default async function postCollection(
name: collection.name.trim(),
description: collection.description,
color: collection.color,
icon: collection.icon,
iconWeight: collection.iconWeight,
parent: collection.parentId
? {
connect: {

View File

@ -24,6 +24,8 @@ import { useCollections } from "@/hooks/store/collections";
import { useUser } from "@/hooks/store/user";
import { useLinks } from "@/hooks/store/links";
import Links from "@/components/LinkViews/Links";
import Icon from "@/components/Icon";
import { IconWeight } from "@phosphor-icons/react";
export default function Index() {
const { t } = useTranslation();
@ -110,10 +112,21 @@ export default function Index() {
{activeCollection && (
<div className="flex gap-3 items-start justify-between">
<div className="flex items-center gap-2">
<i
className="bi-folder-fill text-3xl drop-shadow"
style={{ color: activeCollection?.color as string }}
></i>
{activeCollection.icon ? (
<Icon
icon={activeCollection.icon}
size={45}
weight={
(activeCollection.iconWeight || "regular") as IconWeight
}
color={activeCollection.color || "#0ea5e9"}
/>
) : (
<i
className="bi-folder-fill text-3xl"
style={{ color: activeCollection.color || "#0ea5e9" }}
></i>
)}
<p className="sm:text-3xl text-2xl capitalize w-full py-1 break-words hyphens-auto font-thin">
{activeCollection?.name}

View File

@ -0,0 +1,9 @@
/*
Warnings:
- Made the column `color` on table `Collection` required. This step will fail if there are existing NULL values in that column.
*/
-- AlterTable
ALTER TABLE "Collection" ALTER COLUMN "color" SET NOT NULL,
ALTER COLUMN "color" SET DEFAULT '#0ea5e9';

View File

@ -96,7 +96,7 @@ model Collection {
description String @default("")
icon String?
iconWeight String?
color String?
color String @default("#0ea5e9")
parentId Int?
parent Collection? @relation("SubCollections", fields: [parentId], references: [id])
subCollections Collection[] @relation("SubCollections")