improved ux + coloring fix + improved dashboard ui

This commit is contained in:
Daniel
2023-08-28 14:03:06 -04:00
parent e47aef8123
commit 5015f79b81
7 changed files with 84 additions and 186 deletions
+13 -18
View File
@@ -32,16 +32,15 @@ export default async function updateLink(
const isCollectionOwner =
targetLink?.collection.ownerId === link.collection.ownerId &&
link.collection.ownerId === userId &&
targetLink?.collection.ownerId === userId;
link.collection.ownerId === userId;
const authorizedSwitchCollection =
!isCollectionOwner && targetLink?.collection.id === link.collection.id;
const unauthorizedSwitchCollection =
!isCollectionOwner && targetLink?.collection.id !== link.collection.id;
console.log(authorizedSwitchCollection);
console.log(isCollectionOwner);
// Makes sure collection members (non-owners) cannot move a link to/from a collection.
if (!authorizedSwitchCollection)
if (unauthorizedSwitchCollection)
return {
response: "You can't move a link to/from a collection you don't own.",
status: 401,
@@ -59,15 +58,11 @@ export default async function updateLink(
data: {
name: link.name,
description: link.description,
collection:
targetLink?.collection.ownerId === link.collection.ownerId &&
link.collection.ownerId === userId
? {
connect: {
id: link.collection.id,
},
}
: undefined,
collection: {
connect: {
id: link.collection.id,
},
},
tags: {
set: [],
connectOrCreate: link.tags.map((tag) => ({
@@ -104,14 +99,14 @@ export default async function updateLink(
},
});
if (targetLink.collection.id !== link.collection.id) {
if (targetLink?.collection.id !== link.collection.id) {
await moveFile(
`archives/${targetLink.collection.id}/${link.id}.pdf`,
`archives/${targetLink?.collection.id}/${link.id}.pdf`,
`archives/${link.collection.id}/${link.id}.pdf`
);
await moveFile(
`archives/${targetLink.collection.id}/${link.id}.png`,
`archives/${targetLink?.collection.id}/${link.id}.png`,
`archives/${link.collection.id}/${link.id}.png`
);
}
+1
View File
@@ -53,6 +53,7 @@ export default function Subscribe() {
<TextInput
placeholder="john"
value={inputedUsername}
className="bg-white"
onChange={(e) => setInputedUsername(e.target.value)}
/>
</div>
+47 -168
View File
@@ -2,15 +2,13 @@ import useCollectionStore from "@/store/collections";
import {
faChartSimple,
faChevronDown,
faThumbTack,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import MainLayout from "@/layouts/MainLayout";
import useLinkStore from "@/store/links";
import useTagStore from "@/store/tags";
import LinkCard from "@/components/LinkCard";
import Link from "next/link";
import CollectionCard from "@/components/CollectionCard";
import { Disclosure, Transition } from "@headlessui/react";
import { useEffect, useState } from "react";
import useLinks from "@/hooks/useLinks";
@@ -21,20 +19,6 @@ export default function Dashboard() {
const [numberOfLinks, setNumberOfLinks] = useState(0);
const [tagPinDisclosure, setTagPinDisclosure] = useState<boolean>(() => {
const storedValue =
typeof window !== "undefined" && localStorage.getItem("tagPinDisclosure");
return storedValue ? storedValue === "true" : true;
});
const [collectionPinDisclosure, setCollectionPinDisclosure] =
useState<boolean>(() => {
const storedValue =
typeof window !== "undefined" &&
localStorage.getItem("collectionPinDisclosure");
return storedValue ? storedValue === "true" : true;
});
const [linkPinDisclosure, setLinkPinDisclosure] = useState<boolean>(() => {
const storedValue =
typeof window !== "undefined" &&
@@ -54,20 +38,6 @@ export default function Dashboard() {
);
}, [collections]);
useEffect(() => {
localStorage.setItem(
"tagPinDisclosure",
tagPinDisclosure ? "true" : "false"
);
}, [tagPinDisclosure]);
useEffect(() => {
localStorage.setItem(
"collectionPinDisclosure",
collectionPinDisclosure ? "true" : "false"
);
}, [collectionPinDisclosure]);
useEffect(() => {
localStorage.setItem(
"linkPinDisclosure",
@@ -76,25 +46,22 @@ export default function Dashboard() {
}, [linkPinDisclosure]);
return (
// ml-80
<MainLayout>
<div className="p-5">
<div className="flex gap-3 items-center mb-5">
<div className="p-5 flex flex-col gap-5">
<div className="flex gap-3 items-center">
<div className="flex gap-2">
<FontAwesomeIcon
icon={faChartSimple}
className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow"
/>
<p className="sm:text-4xl text-3xl capitalize text-black dark:text-white">
<p className="sm:text-4xl text-3xl text-black dark:text-white">
Dashboard
</p>
</div>
</div>
<br />
<div className="flex flex-col md:flex-row md:items-center justify-evenly gap-2 mb-10">
<div className="flex items-baseline gap-2">
<div className="flex flex-col md:flex-row md:items-center gap-5">
<div className="flex flex-col justify-center items-center gap-2 md:w-full rounded-2xl p-10 border border-sky-100 dark:border-neutral-700">
<p className="font-bold text-6xl text-sky-500 dark:text-sky-300">
{numberOfLinks}
</p>
@@ -103,7 +70,7 @@ export default function Dashboard() {
</p>
</div>
<div className="flex items-baseline gap-2">
<div className="flex flex-col justify-center items-center gap-2 md:w-full rounded-2xl p-10 border border-sky-100 dark:border-neutral-700">
<p className="font-bold text-6xl text-sky-500 dark:text-sky-300">
{collections.length}
</p>
@@ -112,7 +79,7 @@ export default function Dashboard() {
</p>
</div>
<div className="flex items-baseline gap-2">
<div className="flex flex-col justify-center items-center gap-2 md:w-full rounded-2xl p-10 border border-sky-100 dark:border-neutral-700">
<p className="font-bold text-6xl text-sky-500 dark:text-sky-300">
{tags.length}
</p>
@@ -122,143 +89,55 @@ export default function Dashboard() {
</div>
</div>
{/* <hr className="my-5 border-sky-100" /> */}
<br />
<div className="flex justify-between items-center">
<div className="flex gap-2 items-center">
<FontAwesomeIcon
icon={faThumbTack}
className="w-5 h-5 text-sky-500 dark:text-sky-300 drop-shadow"
/>
<p className="text-2xl text-black dark:text-white">Pinned Links</p>
</div>
{links.some((e) => e.pinnedBy && e.pinnedBy[0]) ? (
<button
className="text-black dark:text-white flex items-center gap-2 cursor-pointer"
onClick={() => setLinkPinDisclosure(!linkPinDisclosure)}
>
{linkPinDisclosure ? "Show Less" : "Show More"}
<FontAwesomeIcon
icon={faChevronDown}
className={`w-4 h-4 text-black dark:text-white ${
linkPinDisclosure ? "rotate-reverse" : "rotate"
}`}
/>
</button>
) : undefined}
</div>
<div className="flex flex-col 2xl:flex-row items-start justify-evenly 2xl:gap-2">
{links.some((e) => e.pinnedBy && e.pinnedBy[0]) ? (
<Disclosure defaultOpen={linkPinDisclosure}>
<div className="flex flex-col gap-5 p-2 w-full mx-auto md:w-2/3">
<Disclosure.Button
onClick={() => {
setLinkPinDisclosure(!linkPinDisclosure);
}}
className="flex justify-between gap-2 items-baseline shadow active:shadow-inner dark:bg-neutral-700 duration-100 py-2 px-4 rounded-full"
>
<p className="text-black dark:text-white text-xl">
Pinned Links
</p>
<div className="text-black dark:text-white flex items-center gap-2">
{linkPinDisclosure ? "Hide" : "Show"}
<FontAwesomeIcon
icon={faChevronDown}
className={`w-4 h-4 text-black dark:text-white ${
linkPinDisclosure ? "rotate-reverse" : "rotate"
}`}
/>
</div>
</Disclosure.Button>
<Transition
enter="transition duration-100 ease-out"
enterFrom="transform opacity-0 -translate-y-3"
enterTo="transform opacity-100 translate-y-0"
leave="transition duration-100 ease-out"
leaveFrom="transform opacity-100 translate-y-0"
leaveTo="transform opacity-0 -translate-y-3"
>
<Disclosure.Panel className="grid grid-cols-1 xl:grid-cols-2 gap-5 w-full">
{links
.filter((e) => e.pinnedBy && e.pinnedBy[0])
.map((e, i) => (
<LinkCard key={i} link={e} count={i} />
))}
</Disclosure.Panel>
</Transition>
</div>
</Disclosure>
<div
className={`grid overflow-hidden 2xl:grid-cols-3 xl:grid-cols-2 grid-cols-1 gap-5 w-full ${
linkPinDisclosure ? "h-full" : "h-44"
}`}
>
{links
.filter((e) => e.pinnedBy && e.pinnedBy[0])
.map((e, i) => (
<LinkCard key={i} link={e} count={i} />
))}
</div>
) : (
<div className="border border-solid border-sky-100 dark:border-neutral-700 w-full mx-auto md:w-2/3 p-10 rounded-2xl">
<div className="border border-solid border-sky-100 dark:border-neutral-700 w-full mx-auto p-10 rounded-2xl">
<p className="text-center text-2xl text-black dark:text-white">
No Pinned Links
</p>
<p className="text-center text-black dark:text-white text-sm">
You can Pin Links by clicking on the three dots on each Link and
clicking &quot;Pin to Dashboard.&quot;
<p className="text-center text-gray-500 dark:text-gray-300 text-sm mt-2">
You can Pin your favorite Links by clicking on the three dots on
each Link and clicking{" "}
<span className="font-semibold">Pin to Dashboard</span>.
</p>
</div>
)}
{/* <Disclosure defaultOpen={collectionPinDisclosure}>
<div className="flex flex-col gap-5 p-2 w-full">
<Disclosure.Button
onClick={() => {
setCollectionPinDisclosure(!collectionPinDisclosure);
}}
className="flex justify-between gap-2 items-baseline shadow active:shadow-inner duration-100 py-2 px-4 rounded-full"
>
<p className="text-black text-xl">Pinned Collections</p>
<div className="text-black flex items-center gap-2">
{collectionPinDisclosure ? "Hide" : "Show"}
<FontAwesomeIcon
icon={faChevronDown}
className={`w-4 h-4 text-black ${
collectionPinDisclosure ? "rotate-reverse" : "rotate"
}`}
/>
</div>
</Disclosure.Button>
<Transition
enter="transition duration-100 ease-out"
enterFrom="transform opacity-0 -translate-y-3"
enterTo="transform opacity-100 translate-y-0"
leave="transition duration-100 ease-out"
leaveFrom="transform opacity-100 translate-y-0"
leaveTo="transform opacity-0 -translate-y-3"
>
<Disclosure.Panel className="flex flex-col gap-5 w-full">
{collections.slice(0, 5).map((e, i) => (
<CollectionCard key={i} collection={e} />
))}
</Disclosure.Panel>
</Transition>
</div>
</Disclosure> */}
{/* <Disclosure defaultOpen={tagPinDisclosure}>
<div className="flex flex-col gap-5 p-2 w-full">
<Disclosure.Button
onClick={() => {
setTagPinDisclosure(!tagPinDisclosure);
}}
className="flex justify-between gap-2 items-baseline shadow active:shadow-inner duration-100 py-2 px-4 rounded-full"
>
<p className="text-black text-xl">Pinned Tags</p>
<div className="text-black flex items-center gap-2">
{tagPinDisclosure ? "Hide" : "Show"}
<FontAwesomeIcon
icon={faChevronDown}
className={`w-4 h-4 text-black ${
tagPinDisclosure ? "rotate-reverse" : "rotate"
}`}
/>
</div>
</Disclosure.Button>
<Transition
enter="transition duration-100 ease-out"
enterFrom="transform opacity-0 -translate-y-3"
enterTo="transform opacity-100 translate-y-0"
leave="transition duration-100 ease-out"
leaveFrom="transform opacity-100 translate-y-0"
leaveTo="transform opacity-0 -translate-y-3"
>
<Disclosure.Panel className="flex gap-2 flex-wrap">
{tags.slice(0, 19).map((e, i) => (
<Link
href={`/tags/${e.id}`}
key={i}
className="px-2 py-1 bg-sky-200 rounded-full hover:opacity-60 duration-100 text-black"
>
{e.name}
</Link>
))}
</Disclosure.Panel>
</Transition>
</div>
</Disclosure> */}
</div>
</div>
</MainLayout>
+1
View File
@@ -64,6 +64,7 @@ export default function Forgot() {
type="email"
placeholder="johnny@example.com"
value={form.email}
className="bg-white"
onChange={(e) => setForm({ ...form, email: e.target.value })}
/>
</div>
+2
View File
@@ -62,6 +62,7 @@ export default function Login() {
<TextInput
placeholder="johnny"
value={form.username}
className="bg-white"
onChange={(e) => setForm({ ...form, username: e.target.value })}
/>
</div>
@@ -75,6 +76,7 @@ export default function Login() {
type="password"
placeholder="••••••••••••••"
value={form.password}
className="bg-white"
onChange={(e) => setForm({ ...form, password: e.target.value })}
/>
{emailEnabled && (
+5
View File
@@ -111,6 +111,7 @@ export default function Register() {
<TextInput
placeholder="Johnny"
value={form.name}
className="bg-white"
onChange={(e) => setForm({ ...form, name: e.target.value })}
/>
</div>
@@ -124,6 +125,7 @@ export default function Register() {
<TextInput
placeholder="john"
value={form.username}
className="bg-white"
onChange={(e) => setForm({ ...form, username: e.target.value })}
/>
</div>
@@ -139,6 +141,7 @@ export default function Register() {
type="email"
placeholder="johnny@example.com"
value={form.email}
className="bg-white"
onChange={(e) => setForm({ ...form, email: e.target.value })}
/>
</div>
@@ -153,6 +156,7 @@ export default function Register() {
type="password"
placeholder="••••••••••••••"
value={form.password}
className="bg-white"
onChange={(e) => setForm({ ...form, password: e.target.value })}
/>
</div>
@@ -166,6 +170,7 @@ export default function Register() {
type="password"
placeholder="••••••••••••••"
value={form.passwordConfirmation}
className="bg-white"
onChange={(e) =>
setForm({ ...form, passwordConfirmation: e.target.value })
}
+15
View File
@@ -47,6 +47,21 @@
animation: slide-up-animation 70ms;
}
.slide-down {
animation: slide-down-animation 70ms;
}
@keyframes slide-down-animation {
0% {
transform: translateY(-15%);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slide-up-animation {
0% {
transform: translateY(15%);