final polishing

This commit is contained in:
daniel31x13 2024-02-13 05:54:18 -05:00
parent a3c487d074
commit 155c77cbc4
8 changed files with 239 additions and 231 deletions

View File

@ -27,11 +27,7 @@ type Props = {
editMode?: boolean; editMode?: boolean;
}; };
export default function LinkCard({ export default function LinkCard({ link, flipDropdown, editMode }: Props) {
link,
flipDropdown,
editMode,
}: Props) {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
const { account } = useAccountStore(); const { account } = useAccountStore();
@ -96,17 +92,21 @@ export default function LinkCard({
const [showInfo, setShowInfo] = useState(false); const [showInfo, setShowInfo] = useState(false);
const selectedStyle = selectedLinks.some((selectedLink) => selectedLink.id === link.id) ? "border-primary bg-base-300" : "border-neutral-content"; const selectedStyle = selectedLinks.some(
const selectable = editMode && (permissions === true || permissions?.canCreate || permissions?.canDelete); (selectedLink) => selectedLink.id === link.id
const hoverStyles = !selectable ? "cursor-not-allowed" : "cursor-pointer"; )
? "border-primary bg-base-300"
: "border-neutral-content";
const selectable =
editMode &&
(permissions === true || permissions?.canCreate || permissions?.canDelete);
return ( return (
<div <div
ref={ref} ref={ref}
className={`${selectedStyle} ${hoverStyles} border border-solid border-neutral-content bg-base-200 shadow-md hover:shadow-none duration-100 rounded-2xl relative`} className={`${selectedStyle} border border-solid border-neutral-content bg-base-200 shadow-md hover:shadow-none duration-100 rounded-2xl relative`}
onClick={() => selectable && handleCheckboxClick(link)} onClick={() => selectable && handleCheckboxClick(link)}
> >
{!editMode ? ( {!editMode ? (
<> <>
<Link <Link
@ -134,9 +134,7 @@ export default function LinkCard({
) : ( ) : (
<div className="duration-100 h-40 bg-opacity-80 skeleton rounded-none"></div> <div className="duration-100 h-40 bg-opacity-80 skeleton rounded-none"></div>
)} )}
<div <div className="absolute top-0 left-0 right-0 bottom-0 rounded-t-2xl flex items-center justify-center shadow rounded-md">
className="absolute top-0 left-0 right-0 bottom-0 rounded-t-2xl flex items-center justify-center shadow rounded-md"
>
<LinkIcon link={link} /> <LinkIcon link={link} />
</div> </div>
</div> </div>
@ -190,7 +188,9 @@ export default function LinkCard({
</p> </p>
{link.tags[0] && ( {link.tags[0] && (
<> <>
<p className="text-neutral text-lg mt-3 font-semibold">Tags</p> <p className="text-neutral text-lg mt-3 font-semibold">
Tags
</p>
<hr className="divider my-2 last:hidden border-t border-neutral-content h-[1px]" /> <hr className="divider my-2 last:hidden border-t border-neutral-content h-[1px]" />
@ -226,9 +226,7 @@ export default function LinkCard({
</> </>
) : ( ) : (
<> <>
<div <div className="rounded-2xl cursor-pointer">
className="rounded-2xl cursor-pointer"
>
<div className="relative rounded-t-2xl h-40 overflow-hidden"> <div className="relative rounded-t-2xl h-40 overflow-hidden">
{previewAvailable(link) ? ( {previewAvailable(link) ? (
<Image <Image
@ -249,9 +247,7 @@ export default function LinkCard({
) : ( ) : (
<div className="duration-100 h-40 bg-opacity-80 skeleton rounded-none"></div> <div className="duration-100 h-40 bg-opacity-80 skeleton rounded-none"></div>
)} )}
<div <div className="absolute top-0 left-0 right-0 bottom-0 rounded-t-2xl flex items-center justify-center shadow rounded-md">
className="absolute top-0 left-0 right-0 bottom-0 rounded-t-2xl flex items-center justify-center shadow rounded-md"
>
<LinkIcon link={link} /> <LinkIcon link={link} />
</div> </div>
</div> </div>
@ -305,7 +301,9 @@ export default function LinkCard({
</p> </p>
{link.tags[0] && ( {link.tags[0] && (
<> <>
<p className="text-neutral text-lg mt-3 font-semibold">Tags</p> <p className="text-neutral text-lg mt-3 font-semibold">
Tags
</p>
<hr className="divider my-2 last:hidden border-t border-neutral-content h-[1px]" /> <hr className="divider my-2 last:hidden border-t border-neutral-content h-[1px]" />

View File

@ -76,16 +76,20 @@ export default function LinkCardCompact({
const [showInfo, setShowInfo] = useState(false); const [showInfo, setShowInfo] = useState(false);
const selectedStyle = selectedLinks.some((selectedLink) => selectedLink.id === link.id) ? "border border-primary bg-base-300" : "border-transparent"; const selectedStyle = selectedLinks.some(
const selectable = editMode && (permissions === true || permissions?.canCreate || permissions?.canDelete); (selectedLink) => selectedLink.id === link.id
const hoverStyles = !selectable ? "cursor-not-allowed" : "cursor-pointer"; )
? "border border-primary bg-base-300"
: "border-transparent";
const selectable =
editMode &&
(permissions === true || permissions?.canCreate || permissions?.canDelete);
return ( return (
<> <>
<div <div
className={`${selectedStyle} ${hoverStyles} border relative items-center flex ${!showInfo && !isPWA() className={`${selectedStyle} border relative items-center flex ${
? "hover:bg-base-300 p-3" !showInfo && !isPWA() ? "hover:bg-base-300 p-3" : "py-3"
: "py-3"
} duration-200 rounded-lg`} } duration-200 rounded-lg`}
onClick={() => selectable && handleCheckboxClick(link)} onClick={() => selectable && handleCheckboxClick(link)}
> >
@ -150,7 +154,9 @@ export default function LinkCardCompact({
{showInfo && ( {showInfo && (
<div> <div>
<div className="pb-3 mt-1 px-3"> <div className="pb-3 mt-1 px-3">
<p className="text-neutral text-lg font-semibold">Description</p> <p className="text-neutral text-lg font-semibold">
Description
</p>
<hr className="divider my-2 last:hidden border-t border-neutral-content h-[1px]" /> <hr className="divider my-2 last:hidden border-t border-neutral-content h-[1px]" />
<p> <p>
@ -192,12 +198,9 @@ export default function LinkCardCompact({
</div> </div>
)} )}
</> </>
) : ) : (
(
<> <>
<div <div className="flex items-center cursor-pointer">
className="flex items-center cursor-pointer"
>
<div className="shrink-0"> <div className="shrink-0">
<LinkIcon link={link} width="sm:w-12 w-8 mt-1 sm:mt-0" /> <LinkIcon link={link} width="sm:w-12 w-8 mt-1 sm:mt-0" />
</div> </div>
@ -215,7 +218,9 @@ export default function LinkCardCompact({
{link.url ? ( {link.url ? (
<div className="flex items-center gap-1 w-fit text-neutral truncate"> <div className="flex items-center gap-1 w-fit text-neutral truncate">
<i className="bi-link-45deg text-lg" /> <i className="bi-link-45deg text-lg" />
<p className="truncate w-full select-none">{shortendURL}</p> <p className="truncate w-full select-none">
{shortendURL}
</p>
</div> </div>
) : ( ) : (
<div className="badge badge-primary badge-sm my-1 select-none"> <div className="badge badge-primary badge-sm my-1 select-none">

View File

@ -23,7 +23,7 @@ export default function BulkDeleteLinksModal({ onClose }: Props) {
toast.dismiss(load); toast.dismiss(load);
response.ok && if (response.ok) {
toast.success( toast.success(
`Deleted ${selectedLinks.length} Link${ `Deleted ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : "" selectedLinks.length > 1 ? "s" : ""
@ -32,6 +32,7 @@ export default function BulkDeleteLinksModal({ onClose }: Props) {
setSelectedLinks([]); setSelectedLinks([]);
onClose(); onClose();
} else toast.error(response.data as string);
}; };
return ( return (

View File

@ -44,24 +44,25 @@ export default function BulkEditLinksModal({ onClose }: Props) {
if (response.ok) { if (response.ok) {
toast.success(`Updated!`); toast.success(`Updated!`);
setSelectedLinks([]);
onClose(); onClose();
} else toast.error(response.data as string); } else toast.error(response.data as string);
setSelectedLinks([]);
setSubmitLoader(false); setSubmitLoader(false);
onClose();
return response; return response;
} }
}; };
return ( return (
<Modal toggleModal={onClose}> <Modal toggleModal={onClose}>
<p className="text-xl font-thin">Edit Link</p> <p className="text-xl font-thin">
Edit {selectedLinks.length} Link{selectedLinks.length > 1 ? "s" : ""}
</p>
<div className="divider mb-3 mt-1"></div> <div className="divider mb-3 mt-1"></div>
<div className="mt-5"> <div className="mt-5">
<div className="grid sm:grid-cols-2 gap-3"> <div className="grid sm:grid-cols-2 gap-3">
<div> <div>
<p className="mb-2">Collection</p> <p className="mb-2">Move to Collection</p>
<CollectionSelection <CollectionSelection
showDefaultValue={false} showDefaultValue={false}
onChange={setCollection} onChange={setCollection}
@ -69,11 +70,11 @@ export default function BulkEditLinksModal({ onClose }: Props) {
</div> </div>
<div> <div>
<p className="mb-2">Tags</p> <p className="mb-2">Add Tags</p>
<TagSelection onChange={setTags} /> <TagSelection onChange={setTags} />
</div> </div>
</div> </div>
<div className="mt-3"> <div className="ml-auto w-1/2 p-3">
<label className="flex items-center gap-2 "> <label className="flex items-center gap-2 ">
<input <input
type="checkbox" type="checkbox"

View File

@ -121,7 +121,8 @@ export default function Index() {
const bulkDeleteLinks = async () => { const bulkDeleteLinks = async () => {
const load = toast.loading( const load = toast.loading(
`Deleting ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" `Deleting ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : ""
}...` }...`
); );
@ -133,7 +134,8 @@ export default function Index() {
response.ok && response.ok &&
toast.success( toast.success(
`Deleted ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" `Deleted ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : ""
}!` }!`
); );
}; };
@ -143,7 +145,8 @@ export default function Index() {
<div <div
className="h-[60rem] p-5 flex gap-3 flex-col" className="h-[60rem] p-5 flex gap-3 flex-col"
style={{ style={{
backgroundImage: `linear-gradient(${activeCollection?.color}20 10%, ${settings.theme === "dark" ? "#262626" : "#f3f4f6" backgroundImage: `linear-gradient(${activeCollection?.color}20 10%, ${
settings.theme === "dark" ? "#262626" : "#f3f4f6"
} 13rem, ${settings.theme === "dark" ? "#171717" : "#ffffff"} 100%)`, } 13rem, ${settings.theme === "dark" ? "#171717" : "#ffffff"} 100%)`,
}} }}
> >
@ -309,14 +312,18 @@ export default function Index() {
<div className="flex justify-between items-center gap-5"> <div className="flex justify-between items-center gap-5">
<p>Showing {activeCollection?._count?.links} results</p> <p>Showing {activeCollection?._count?.links} results</p>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{links.length > 0 && (permissions === true || permissions?.canUpdate || permissions?.canDelete) && ( {links.length > 0 &&
(permissions === true ||
permissions?.canUpdate ||
permissions?.canDelete) && (
<div <div
role="button" role="button"
onClick={() => { onClick={() => {
setEditMode(!editMode); setEditMode(!editMode);
setSelectedLinks([]); setSelectedLinks([]);
}} }}
className={`btn btn-square btn-sm btn-ghost ${editMode className={`btn btn-square btn-sm btn-ghost ${
editMode
? "bg-primary/20 hover:bg-primary/20" ? "bg-primary/20 hover:bg-primary/20"
: "hover:bg-neutral/20" : "hover:bg-neutral/20"
}`} }`}
@ -352,8 +359,7 @@ export default function Index() {
</div> </div>
)} )}
<div className="flex gap-3"> <div className="flex gap-3">
{(permissions === true || {(permissions === true || permissions?.canUpdate) && (
permissions?.canUpdate) && (
<button <button
onClick={() => setBulkEditLinksModal(true)} onClick={() => setBulkEditLinksModal(true)}
className="btn btn-sm btn-accent text-white w-fit ml-auto" className="btn btn-sm btn-accent text-white w-fit ml-auto"
@ -362,8 +368,7 @@ export default function Index() {
Edit Edit
</button> </button>
)} )}
{(permissions === true || {(permissions === true || permissions?.canDelete) && (
permissions?.canDelete) && (
<button <button
onClick={(e) => { onClick={(e) => {
(document?.activeElement as HTMLElement)?.blur(); (document?.activeElement as HTMLElement)?.blur();
@ -422,7 +427,6 @@ export default function Index() {
<BulkDeleteLinksModal <BulkDeleteLinksModal
onClose={() => { onClose={() => {
setBulkDeleteLinksModal(false); setBulkDeleteLinksModal(false);
setEditMode(false);
}} }}
/> />
)} )}
@ -430,7 +434,6 @@ export default function Index() {
<BulkEditLinksModal <BulkEditLinksModal
onClose={() => { onClose={() => {
setBulkEditLinksModal(false); setBulkEditLinksModal(false);
setEditMode(false);
}} }}
/> />
)} )}

View File

@ -28,7 +28,7 @@ export default function Links() {
const [bulkEditLinksModal, setBulkEditLinksModal] = useState(false); const [bulkEditLinksModal, setBulkEditLinksModal] = useState(false);
const [editMode, setEditMode] = useState(false); const [editMode, setEditMode] = useState(false);
const collectivePermissions = useCollectivePermissions( const collectivePermissions = useCollectivePermissions(
links.map((link) => link.collectionId as number) selectedLinks.map((link) => link.collectionId as number)
); );
useLinks({ sort: sortBy }); useLinks({ sort: sortBy });
@ -43,7 +43,8 @@ export default function Links() {
const bulkDeleteLinks = async () => { const bulkDeleteLinks = async () => {
const load = toast.loading( const load = toast.loading(
`Deleting ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" `Deleting ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : ""
}...` }...`
); );
@ -55,7 +56,8 @@ export default function Links() {
response.ok && response.ok &&
toast.success( toast.success(
`Deleted ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" `Deleted ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : ""
}!` }!`
); );
}; };
@ -69,7 +71,7 @@ export default function Links() {
// @ts-ignore // @ts-ignore
const LinkComponent = linkView[viewMode]; const LinkComponent = linkView[viewMode];
console.log(collectivePermissions) console.log(collectivePermissions);
return ( return (
<MainLayout> <MainLayout>
<div className="p-5 flex flex-col gap-5 w-full h-full"> <div className="p-5 flex flex-col gap-5 w-full h-full">
@ -81,14 +83,15 @@ export default function Links() {
/> />
<div className="mt-2 flex items-center justify-end gap-2"> <div className="mt-2 flex items-center justify-end gap-2">
{links.length > 0 && (collectivePermissions === true || collectivePermissions?.canUpdate || collectivePermissions?.canDelete) && ( {links.length > 0 && (
<div <div
role="button" role="button"
onClick={() => { onClick={() => {
setEditMode(!editMode); setEditMode(!editMode);
setSelectedLinks([]); setSelectedLinks([]);
}} }}
className={`btn btn-square btn-sm btn-ghost ${editMode className={`btn btn-square btn-sm btn-ghost ${
editMode
? "bg-primary/20 hover:bg-primary/20" ? "bg-primary/20 hover:bg-primary/20"
: "hover:bg-neutral/20" : "hover:bg-neutral/20"
}`} }`}
@ -163,7 +166,6 @@ export default function Links() {
<BulkDeleteLinksModal <BulkDeleteLinksModal
onClose={() => { onClose={() => {
setBulkDeleteLinksModal(false); setBulkDeleteLinksModal(false);
setEditMode(false);
}} }}
/> />
)} )}
@ -171,7 +173,6 @@ export default function Links() {
<BulkEditLinksModal <BulkEditLinksModal
onClose={() => { onClose={() => {
setBulkEditLinksModal(false); setBulkEditLinksModal(false);
setEditMode(false);
}} }}
/> />
)} )}

View File

@ -29,11 +29,9 @@ export default function PinnedLinks() {
const [bulkEditLinksModal, setBulkEditLinksModal] = useState(false); const [bulkEditLinksModal, setBulkEditLinksModal] = useState(false);
const [editMode, setEditMode] = useState(false); const [editMode, setEditMode] = useState(false);
const collectivePermissions = useCollectivePermissions( const collectivePermissions = useCollectivePermissions(
links.map((link) => link.collectionId as number) selectedLinks.map((link) => link.collectionId as number)
); );
useLinks({ sort: sortBy });
const handleSelectAll = () => { const handleSelectAll = () => {
if (selectedLinks.length === links.length) { if (selectedLinks.length === links.length) {
setSelectedLinks([]); setSelectedLinks([]);
@ -44,7 +42,8 @@ export default function PinnedLinks() {
const bulkDeleteLinks = async () => { const bulkDeleteLinks = async () => {
const load = toast.loading( const load = toast.loading(
`Deleting ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" `Deleting ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : ""
}...` }...`
); );
@ -56,7 +55,8 @@ export default function PinnedLinks() {
response.ok && response.ok &&
toast.success( toast.success(
`Deleted ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" `Deleted ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : ""
}!` }!`
); );
}; };
@ -80,14 +80,15 @@ export default function PinnedLinks() {
description={"Pinned Links from your Collections"} description={"Pinned Links from your Collections"}
/> />
<div className="mt-2 flex items-center justify-end gap-2"> <div className="mt-2 flex items-center justify-end gap-2">
{links.length > 0 && (collectivePermissions === true || collectivePermissions?.canUpdate || collectivePermissions?.canDelete) && ( {!(links.length === 0) && (
<div <div
role="button" role="button"
onClick={() => { onClick={() => {
setEditMode(!editMode); setEditMode(!editMode);
setSelectedLinks([]); setSelectedLinks([]);
}} }}
className={`btn btn-square btn-sm btn-ghost ${editMode className={`btn btn-square btn-sm btn-ghost ${
editMode
? "bg-primary/20 hover:bg-primary/20" ? "bg-primary/20 hover:bg-primary/20"
: "hover:bg-neutral/20" : "hover:bg-neutral/20"
}`} }`}
@ -174,7 +175,6 @@ export default function PinnedLinks() {
<BulkDeleteLinksModal <BulkDeleteLinksModal
onClose={() => { onClose={() => {
setBulkDeleteLinksModal(false); setBulkDeleteLinksModal(false);
setEditMode(false);
}} }}
/> />
)} )}
@ -182,7 +182,6 @@ export default function PinnedLinks() {
<BulkEditLinksModal <BulkEditLinksModal
onClose={() => { onClose={() => {
setBulkEditLinksModal(false); setBulkEditLinksModal(false);
setEditMode(false);
}} }}
/> />
)} )}

View File

@ -119,7 +119,8 @@ export default function Index() {
const bulkDeleteLinks = async () => { const bulkDeleteLinks = async () => {
const load = toast.loading( const load = toast.loading(
`Deleting ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" `Deleting ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : ""
}...` }...`
); );
@ -131,7 +132,8 @@ export default function Index() {
response.ok && response.ok &&
toast.success( toast.success(
`Deleted ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" `Deleted ${selectedLinks.length} Link${
selectedLinks.length > 1 ? "s" : ""
}!` }!`
); );
}; };
@ -190,7 +192,8 @@ export default function Index() {
</p> </p>
<div className="relative"> <div className="relative">
<div <div
className={`dropdown dropdown-bottom font-normal ${activeTag?.name.length && activeTag?.name.length > 8 className={`dropdown dropdown-bottom font-normal ${
activeTag?.name.length && activeTag?.name.length > 8
? "dropdown-end" ? "dropdown-end"
: "" : ""
}`} }`}
@ -239,21 +242,20 @@ export default function Index() {
</div> </div>
<div className="flex gap-2 items-center mt-2"> <div className="flex gap-2 items-center mt-2">
{links.length > 0 && (collectivePermissions === true || collectivePermissions?.canUpdate || collectivePermissions?.canDelete) && (
<div <div
role="button" role="button"
onClick={() => { onClick={() => {
setEditMode(!editMode); setEditMode(!editMode);
setSelectedLinks([]); setSelectedLinks([]);
}} }}
className={`btn btn-square btn-sm btn-ghost ${editMode className={`btn btn-square btn-sm btn-ghost ${
editMode
? "bg-primary/20 hover:bg-primary/20" ? "bg-primary/20 hover:bg-primary/20"
: "hover:bg-neutral/20" : "hover:bg-neutral/20"
}`} }`}
> >
<i className="bi-pencil-fill text-neutral text-xl"></i> <i className="bi-pencil-fill text-neutral text-xl"></i>
</div> </div>
)}
<SortDropdown sortBy={sortBy} setSort={setSortBy} /> <SortDropdown sortBy={sortBy} setSort={setSortBy} />
<ViewDropdown viewMode={viewMode} setViewMode={setViewMode} /> <ViewDropdown viewMode={viewMode} setViewMode={setViewMode} />
</div> </div>
@ -320,7 +322,6 @@ export default function Index() {
<BulkDeleteLinksModal <BulkDeleteLinksModal
onClose={() => { onClose={() => {
setBulkDeleteLinksModal(false); setBulkDeleteLinksModal(false);
setEditMode(false);
}} }}
/> />
)} )}
@ -328,7 +329,6 @@ export default function Index() {
<BulkEditLinksModal <BulkEditLinksModal
onClose={() => { onClose={() => {
setBulkEditLinksModal(false); setBulkEditLinksModal(false);
setEditMode(false);
}} }}
/> />
)} )}