custom icons fully implemented for collections
This commit is contained in:
parent
6df2e44213
commit
bf1a6efd2e
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
</>
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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]"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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';
|
|
@ -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")
|
||||
|
|
Ŝarĝante…
Reference in New Issue