From d262041f3368d8dd97b57e089b71d9fcf8d87572 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Fri, 24 May 2024 17:12:47 -0400 Subject: [PATCH] refactor code to improve readability and maintainability + redesigned announcement bar --- .../{Announcement.tsx => AnnouncementBar.tsx} | 0 components/DashboardItem.tsx | 6 +- components/LinkViews/Layouts/CardView.tsx | 2 +- components/LinkViews/LinkCard.tsx | 96 ++++++++++--------- .../LinkComponents/LinkTypeBadge.tsx | 6 +- components/LinkViews/LinkMasonry.tsx | 43 ++++----- components/ModalContent/DeleteLinkModal.tsx | 8 +- components/ModalContent/DeleteUserModal.tsx | 8 +- .../EmailChangeVerificationModal.tsx | 11 +-- components/ModalContent/NewTokenModal.tsx | 8 +- components/Navbar.tsx | 2 +- components/{ui => }/ToggleDarkMode.tsx | 0 components/ui/Button.tsx | 5 +- layouts/AuthRedirect.tsx | 2 + layouts/MainLayout.tsx | 2 +- .../users/userId/deleteUserById.ts | 9 +- pages/dashboard.tsx | 38 ++++---- pages/public/collections/[id].tsx | 2 +- pages/settings/account.tsx | 93 ++++++++++-------- pages/settings/billing.tsx | 6 +- pages/settings/delete.tsx | 19 ++-- 21 files changed, 191 insertions(+), 175 deletions(-) rename components/{Announcement.tsx => AnnouncementBar.tsx} (100%) rename components/{ui => }/ToggleDarkMode.tsx (100%) diff --git a/components/Announcement.tsx b/components/AnnouncementBar.tsx similarity index 100% rename from components/Announcement.tsx rename to components/AnnouncementBar.tsx diff --git a/components/DashboardItem.tsx b/components/DashboardItem.tsx index 60a5fe4..337fc36 100644 --- a/components/DashboardItem.tsx +++ b/components/DashboardItem.tsx @@ -9,12 +9,12 @@ export default function dashboardItem({ }) { return (
-
- +
+

{name}

-

{value}

+

{value}

); diff --git a/components/LinkViews/Layouts/CardView.tsx b/components/LinkViews/Layouts/CardView.tsx index 892e3ff..45ea8f8 100644 --- a/components/LinkViews/Layouts/CardView.tsx +++ b/components/LinkViews/Layouts/CardView.tsx @@ -13,7 +13,7 @@ export default function CardView({ isLoading?: boolean; }) { return ( -
+
{links.map((e, i) => { return (
!editMode && window.open(generateLinkHref(link, account), "_blank") } > -
- {previewAvailable(link) ? ( - { - const target = e.target as HTMLElement; - target.style.display = "none"; - }} - /> - ) : link.preview === "unavailable" ? ( -
- ) : ( -
- )} -
- -
-
- -
- -
-

- {unescapeString(link.name || link.description) || link.url} -

- - -
- -
- -
-
- {collection && ( - +
+
+ {previewAvailable(link) ? ( + { + const target = e.target as HTMLElement; + target.style.display = "none"; + }} + /> + ) : link.preview === "unavailable" ? ( +
+ ) : ( +
+ )} + {link.type !== "image" && ( +
+ +
)}
- + +
+
+ +
+
+

+ {unescapeString(link.name)} +

+ + +
+ +
+
+ +
+
+ {collection && ( + + )} +
+ +
+
diff --git a/components/LinkViews/LinkComponents/LinkTypeBadge.tsx b/components/LinkViews/LinkComponents/LinkTypeBadge.tsx index b7563e4..0088bae 100644 --- a/components/LinkViews/LinkComponents/LinkTypeBadge.tsx +++ b/components/LinkViews/LinkComponents/LinkTypeBadge.tsx @@ -25,14 +25,12 @@ export default function LinkTypeBadge({ onClick={(e) => { e.stopPropagation(); }} - className="flex gap-1 item-center select-none text-neutral mt-1 hover:opacity-70 duration-100" + className="flex gap-1 item-center select-none text-neutral hover:opacity-70 duration-100" >

{shortendURL}

) : ( -
- {link.type} -
+
{link.type}
); } diff --git a/components/LinkViews/LinkMasonry.tsx b/components/LinkViews/LinkMasonry.tsx index e3315a5..165c43f 100644 --- a/components/LinkViews/LinkMasonry.tsx +++ b/components/LinkViews/LinkMasonry.tsx @@ -30,7 +30,6 @@ type Props = { }; export default function LinkMasonry({ link, flipDropdown, editMode }: Props) { - const viewMode = localStorage.getItem("viewMode") || "card"; const { collections } = useCollectionStore(); const { account } = useAccountStore(); @@ -141,6 +140,9 @@ export default function LinkMasonry({ link, flipDropdown, editMode }: Props) { height={720} alt="" className="rounded-t-2xl select-none object-cover z-10 h-40 w-full shadow opacity-80 scale-105" + style={ + link.type !== "image" ? { filter: "blur(1px)" } : undefined + } draggable="false" onError={(e) => { const target = e.target as HTMLElement; @@ -150,28 +152,29 @@ export default function LinkMasonry({ link, flipDropdown, editMode }: Props) { ) : link.preview === "unavailable" ? null : (
)} + {link.type !== "image" && ( +
+ +
+ )}
{link.preview !== "unavailable" && (
)} -
-
-
- -
-

{unescapeString(link.name)}

+
+

+ {unescapeString(link.name)} +

- {link.description && ( -

{unescapeString(link.description)}

- )} - -
+ + + {link.description && ( +

+ {unescapeString(link.description)} +

+ )} {link.tags[0] && (
@@ -193,12 +196,8 @@ export default function LinkMasonry({ link, flipDropdown, editMode }: Props) {
-
-
- {collection && ( - - )} -
+
+ {collection && }
diff --git a/components/ModalContent/DeleteLinkModal.tsx b/components/ModalContent/DeleteLinkModal.tsx index 1a3a476..b884dab 100644 --- a/components/ModalContent/DeleteLinkModal.tsx +++ b/components/ModalContent/DeleteLinkModal.tsx @@ -4,6 +4,7 @@ import { LinkIncludingShortenedCollectionAndTags } from "@/types/global"; import toast from "react-hot-toast"; import Modal from "../Modal"; import { useRouter } from "next/router"; +import Button from "../ui/Button"; type Props = { onClose: Function; @@ -59,13 +60,10 @@ export default function DeleteLinkModal({ onClose, activeLink }: Props) { 'Delete' to bypass this confirmation in the future.

- +
); diff --git a/components/ModalContent/DeleteUserModal.tsx b/components/ModalContent/DeleteUserModal.tsx index cf1d3b9..3c4c1a5 100644 --- a/components/ModalContent/DeleteUserModal.tsx +++ b/components/ModalContent/DeleteUserModal.tsx @@ -1,6 +1,7 @@ import toast from "react-hot-toast"; import Modal from "../Modal"; import useUserStore from "@/store/admin/users"; +import Button from "../ui/Button"; type Props = { onClose: Function; @@ -38,13 +39,10 @@ export default function DeleteUserModal({ onClose, userId }: Props) {
- +
); diff --git a/components/ModalContent/EmailChangeVerificationModal.tsx b/components/ModalContent/EmailChangeVerificationModal.tsx index 20fe0ef..595b06f 100644 --- a/components/ModalContent/EmailChangeVerificationModal.tsx +++ b/components/ModalContent/EmailChangeVerificationModal.tsx @@ -30,12 +30,11 @@ export default function EmailChangeVerificationModal({ "Updating this field will change your billing email on Stripe as well."}

- {process.env.NEXT_PUBLIC_GOOGLE_ENABLED === "true" && ( -

- If you change your email address, any existing Google SSO - connections will be removed. -

- )} +

+ If you change your email address, any existing{" "} + {process.env.NEXT_PUBLIC_GOOGLE_ENABLED === "true" && "Google"} SSO + connections will be removed. +

Old Email

diff --git a/components/ModalContent/NewTokenModal.tsx b/components/ModalContent/NewTokenModal.tsx index 2092eaa..a8be992 100644 --- a/components/ModalContent/NewTokenModal.tsx +++ b/components/ModalContent/NewTokenModal.tsx @@ -5,6 +5,7 @@ import toast from "react-hot-toast"; import Modal from "../Modal"; import useTokenStore from "@/store/tokens"; import { dropdownTriggerer } from "@/lib/client/utils"; +import Button from "../ui/Button"; type Props = { onClose: Function; @@ -90,18 +91,19 @@ export default function NewTokenModal({ onClose }: Props) {

Expires in

-
{token.expires === TokenExpiry.sevenDays && "7 Days"} {token.expires === TokenExpiry.oneMonth && "30 Days"} {token.expires === TokenExpiry.twoMonths && "60 Days"} {token.expires === TokenExpiry.threeMonths && "90 Days"} {token.expires === TokenExpiry.never && "No Expiration"} -
+
-
-
- +
+ -
+
- + -
+
- -
+
diff --git a/pages/public/collections/[id].tsx b/pages/public/collections/[id].tsx index 289c4c4..836d57a 100644 --- a/pages/public/collections/[id].tsx +++ b/pages/public/collections/[id].tsx @@ -12,7 +12,7 @@ import Head from "next/head"; import useLinks from "@/hooks/useLinks"; import useLinkStore from "@/store/links"; import ProfilePhoto from "@/components/ProfilePhoto"; -import ToggleDarkMode from "@/components/ui/ToggleDarkMode"; +import ToggleDarkMode from "@/components/ToggleDarkMode"; import getPublicUserData from "@/lib/client/getPublicUserData"; import Image from "next/image"; import Link from "next/link"; diff --git a/pages/settings/account.tsx b/pages/settings/account.tsx index 05fe14c..8318171 100644 --- a/pages/settings/account.tsx +++ b/pages/settings/account.tsx @@ -13,6 +13,7 @@ import Link from "next/link"; import Checkbox from "@/components/Checkbox"; import { dropdownTriggerer } from "@/lib/client/utils"; import EmailChangeVerificationModal from "@/components/ModalContent/EmailChangeVerificationModal"; +import Button from "@/components/ui/Button"; const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER; @@ -203,37 +204,56 @@ export default function Account() {

Profile Photo

-
+
- {user.image && ( -
- setUser({ - ...user, - image: "", - }) - } - className="absolute top-1 left-1 btn btn-xs btn-circle btn-neutral btn-outline bg-base-100" + +
+
- )} -
- + + Edit + +
    +
  • + +
  • + {user.image && ( +
  • +
    + setUser({ + ...user, + image: "", + }) + } + > + Remove Photo +
    +
  • + )} +
@@ -293,16 +313,18 @@ export default function Account() {

Import your data from other platforms.

-
-

Import From

-
+ Import From + +
diff --git a/pages/settings/billing.tsx b/pages/settings/billing.tsx index 139c74b..c130fb3 100644 --- a/pages/settings/billing.tsx +++ b/pages/settings/billing.tsx @@ -21,6 +21,7 @@ export default function Billing() { Billing Portal @@ -30,10 +31,7 @@ export default function Billing() {

If you still need help or encountered any issues, feel free to reach out to us at:{" "} - + support@linkwarden.app

diff --git a/pages/settings/delete.tsx b/pages/settings/delete.tsx index 0c78932..a2ee3e6 100644 --- a/pages/settings/delete.tsx +++ b/pages/settings/delete.tsx @@ -4,6 +4,7 @@ import TextInput from "@/components/TextInput"; import CenteredForm from "@/layouts/CenteredForm"; import { signOut, useSession } from "next-auth/react"; import Link from "next/link"; +import Button from "@/components/ui/Button"; const keycloakEnabled = process.env.NEXT_PUBLIC_KEYCLOAK_ENABLED === "true"; const authentikEnabled = process.env.NEXT_PUBLIC_AUTHENTIK_ENABLED === "true"; @@ -135,20 +136,14 @@ export default function Delete() { ) : undefined} - +
);