diff --git a/components/Modal/User/BillingPortal.tsx b/components/Modal/User/BillingPortal.tsx
deleted file mode 100644
index 214bfca..0000000
--- a/components/Modal/User/BillingPortal.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { useState } from "react";
-import SubmitButton from "@/components/SubmitButton";
-import { toast } from "react-hot-toast";
-import { useRouter } from "next/router";
-import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons";
-
-export default function PaymentPortal() {
- const [submitLoader, setSubmitLoader] = useState(false);
- const router = useRouter();
-
- const submit = () => {
- setSubmitLoader(true);
- const load = toast.loading("Redirecting to billing portal...");
-
- router.push(process.env.NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL as string);
- };
-
- return (
-
-
-
- To manage/cancel your subsciption, visit the billing portal.
-
-
-
-
-
- If you still need help or encountered any issues, feel free to reach
- out to us at:{" "}
-
- support@linkwarden.app
-
-
-
-
- );
-}
diff --git a/components/Modal/User/ChangePassword.tsx b/components/Modal/User/ChangePassword.tsx
deleted file mode 100644
index 552463c..0000000
--- a/components/Modal/User/ChangePassword.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import { Dispatch, SetStateAction, useEffect, useState } from "react";
-import { AccountSettings } from "@/types/global";
-import useAccountStore from "@/store/account";
-import { signOut, useSession } from "next-auth/react";
-import { faPenToSquare } from "@fortawesome/free-regular-svg-icons";
-import SubmitButton from "@/components/SubmitButton";
-import { toast } from "react-hot-toast";
-import TextInput from "@/components/TextInput";
-
-type Props = {
- togglePasswordFormModal: Function;
- setUser: Dispatch>;
- user: AccountSettings;
-};
-
-export default function ChangePassword({
- togglePasswordFormModal,
- setUser,
- user,
-}: Props) {
- const [newPassword, setNewPassword1] = useState("");
- const [newPassword2, setNewPassword2] = useState("");
-
- const [submitLoader, setSubmitLoader] = useState(false);
-
- const { account, updateAccount } = useAccountStore();
- const { update, data } = useSession();
-
- useEffect(() => {
- if (
- !(newPassword == "" || newPassword2 == "") &&
- newPassword === newPassword2
- ) {
- setUser({ ...user, newPassword });
- }
- }, [newPassword, newPassword2]);
-
- const submit = async () => {
- if (newPassword == "" || newPassword2 == "") {
- toast.error("Please fill all the fields.");
- }
-
- if (newPassword !== newPassword2)
- return toast.error("Passwords do not match.");
- else if (newPassword.length < 8)
- return toast.error("Passwords must be at least 8 characters.");
-
- setSubmitLoader(true);
-
- const load = toast.loading("Applying...");
-
- const response = await updateAccount({
- ...user,
- });
-
- toast.dismiss(load);
-
- if (response.ok) {
- toast.success("Settings Applied!");
-
- if (user.email !== account.email) {
- update({
- id: data?.user.id,
- });
-
- signOut();
- } else if (
- user.username !== account.username ||
- user.name !== account.name
- )
- update({
- id: data?.user.id,
- });
-
- setUser({ ...user, newPassword: undefined });
- togglePasswordFormModal();
- } else toast.error(response.data as string);
-
- setSubmitLoader(false);
- };
-
- return (
-
-
-
New Password
-
-
setNewPassword1(e.target.value)}
- placeholder="••••••••••••••"
- type="password"
- />
-
-
- Confirm New Password
-
-
- setNewPassword2(e.target.value)}
- placeholder="••••••••••••••"
- type="password"
- />
-
-
-
-
- );
-}
diff --git a/components/Modal/User/PrivacySettings.tsx b/components/Modal/User/PrivacySettings.tsx
deleted file mode 100644
index ce61782..0000000
--- a/components/Modal/User/PrivacySettings.tsx
+++ /dev/null
@@ -1,248 +0,0 @@
-import { Dispatch, SetStateAction, useEffect, useState } from "react";
-import Checkbox from "../../Checkbox";
-import useAccountStore from "@/store/account";
-import {
- AccountSettings,
- MigrationFormat,
- MigrationRequest,
-} from "@/types/global";
-import { signOut, useSession } from "next-auth/react";
-import { faPenToSquare } from "@fortawesome/free-regular-svg-icons";
-import SubmitButton from "../../SubmitButton";
-import { toast } from "react-hot-toast";
-import Link from "next/link";
-import ClickAwayHandler from "@/components/ClickAwayHandler";
-
-type Props = {
- toggleSettingsModal: Function;
- setUser: Dispatch>;
- user: AccountSettings;
-};
-
-export default function PrivacySettings({
- toggleSettingsModal,
- setUser,
- user,
-}: Props) {
- const { update, data } = useSession();
- const { account, updateAccount } = useAccountStore();
-
- const [importDropdown, setImportDropdown] = useState(false);
- const [submitLoader, setSubmitLoader] = useState(false);
-
- const [whitelistedUsersTextbox, setWhiteListedUsersTextbox] = useState(
- user.whitelistedUsers.join(", ")
- );
-
- useEffect(() => {
- setUser({
- ...user,
- whitelistedUsers: stringToArray(whitelistedUsersTextbox),
- });
- }, [whitelistedUsersTextbox]);
-
- useEffect(() => {
- setUser({ ...user, newPassword: undefined });
- }, []);
-
- const stringToArray = (str: string) => {
- const stringWithoutSpaces = str.replace(/\s+/g, "");
-
- const wordsArray = stringWithoutSpaces.split(",");
-
- return wordsArray;
- };
-
- const importBookmarks = async (e: any, format: MigrationFormat) => {
- const file: File = e.target.files[0];
-
- if (file) {
- var reader = new FileReader();
- reader.readAsText(file, "UTF-8");
- reader.onload = async function (e) {
- const load = toast.loading("Importing...");
-
- const request: string = e.target?.result as string;
-
- const body: MigrationRequest = {
- format,
- data: request,
- };
-
- const response = await fetch("/api/migration", {
- method: "POST",
- body: JSON.stringify(body),
- });
-
- const data = await response.json();
-
- toast.dismiss(load);
-
- toast.success("Imported the Bookmarks! Reloading the page...");
-
- setImportDropdown(false);
-
- setTimeout(() => {
- location.reload();
- }, 2000);
- };
- reader.onerror = function (e) {
- console.log("Error:", e);
- };
- }
- };
-
- const submit = async () => {
- setSubmitLoader(true);
-
- const load = toast.loading("Applying...");
-
- const response = await updateAccount({
- ...user,
- });
-
- toast.dismiss(load);
-
- if (response.ok) {
- toast.success("Settings Applied!");
-
- if (user.email !== account.email) {
- update({
- id: data?.user.id,
- });
-
- signOut();
- } else if (
- user.username !== account.username ||
- user.name !== account.name
- )
- update({
- id: data?.user.id,
- });
-
- setUser({ ...user, newPassword: undefined });
- toggleSettingsModal();
- } else toast.error(response.data as string);
- setSubmitLoader(false);
- };
-
- return (
-
-
-
- Profile Visibility
-
-
-
setUser({ ...user, isPrivate: !user.isPrivate })}
- />
-
-
- This will limit who can find and add you to other Collections.
-
-
- {user.isPrivate && (
-
-
- Whitelisted Users
-
-
- Please provide the Username of the users you wish to grant
- visibility to your profile. Separated by comma.
-
-
- )}
-
-
-
-
Import Data
-
-
-
-
-
-
- Export Data
-
-
-
-
-
-
-
- );
-}
diff --git a/components/Modal/User/ProfileSettings.tsx b/components/Modal/User/ProfileSettings.tsx
deleted file mode 100644
index 0bb48eb..0000000
--- a/components/Modal/User/ProfileSettings.tsx
+++ /dev/null
@@ -1,195 +0,0 @@
-import { Dispatch, SetStateAction, useEffect, useState } from "react";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faClose } from "@fortawesome/free-solid-svg-icons";
-import useAccountStore from "@/store/account";
-import { AccountSettings } from "@/types/global";
-import { signOut, useSession } from "next-auth/react";
-import { resizeImage } from "@/lib/client/resizeImage";
-import { faPenToSquare } from "@fortawesome/free-regular-svg-icons";
-import SubmitButton from "../../SubmitButton";
-import ProfilePhoto from "../../ProfilePhoto";
-import { toast } from "react-hot-toast";
-import TextInput from "@/components/TextInput";
-
-type Props = {
- toggleSettingsModal: Function;
- setUser: Dispatch>;
- user: AccountSettings;
-};
-
-const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER;
-
-export default function ProfileSettings({
- toggleSettingsModal,
- setUser,
- user,
-}: Props) {
- const { update, data } = useSession();
- const { account, updateAccount } = useAccountStore();
- const [profileStatus, setProfileStatus] = useState(true);
-
- const [submitLoader, setSubmitLoader] = useState(false);
-
- const handleProfileStatus = (e: boolean) => {
- setProfileStatus(!e);
- };
-
- const handleImageUpload = async (e: any) => {
- const file: File = e.target.files[0];
-
- const fileExtension = file.name.split(".").pop()?.toLowerCase();
- const allowedExtensions = ["png", "jpeg", "jpg"];
-
- if (allowedExtensions.includes(fileExtension as string)) {
- const resizedFile = await resizeImage(file);
-
- if (
- resizedFile.size < 1048576 // 1048576 Bytes == 1MB
- ) {
- const reader = new FileReader();
-
- reader.onload = () => {
- setUser({ ...user, profilePic: reader.result as string });
- };
-
- reader.readAsDataURL(resizedFile);
- } else {
- toast.error("Please select a PNG or JPEG file thats less than 1MB.");
- }
- } else {
- toast.error("Invalid file format.");
- }
- };
-
- useEffect(() => {
- setUser({ ...user, newPassword: undefined });
- }, []);
-
- const submit = async () => {
- setSubmitLoader(true);
-
- const load = toast.loading("Applying...");
-
- const response = await updateAccount({
- ...user,
- });
-
- toast.dismiss(load);
-
- if (response.ok) {
- toast.success("Settings Applied!");
-
- if (user.email !== account.email) {
- update({
- id: data?.user.id,
- });
-
- signOut();
- } else if (
- user.username !== account.username ||
- user.name !== account.name
- )
- update({
- id: data?.user.id,
- });
-
- setUser({ ...user, newPassword: undefined });
- toggleSettingsModal();
- } else toast.error(response.data as string);
- setSubmitLoader(false);
- };
-
- return (
-
-
-
-
- Profile Photo
-
-
-
- {profileStatus && (
-
- setUser({
- ...user,
- profilePic: "",
- })
- }
- className="absolute top-1 left-1 w-5 h-5 flex items-center justify-center border p-1 border-slate-200 dark:border-neutral-700 rounded-full bg-white dark:bg-neutral-800 text-center select-none cursor-pointer duration-100 hover:text-red-500"
- >
-
-
- )}
-
-
-
-
-
-
-
-
-
-
- Display Name
-
-
setUser({ ...user, name: e.target.value })}
- />
-
-
-
-
Username
-
setUser({ ...user, username: e.target.value })}
- />
-
-
- {emailEnabled ? (
-
-
Email
-
setUser({ ...user, email: e.target.value })}
- />
-
- ) : undefined}
-
- {user.email !== account.email ? (
-
- You will need to log back in after you apply this Email.
-
- ) : undefined}
-
-
-
-
-
- );
-}
diff --git a/components/Modal/User/index.tsx b/components/Modal/User/index.tsx
deleted file mode 100644
index 54b1ba3..0000000
--- a/components/Modal/User/index.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import { Tab } from "@headlessui/react";
-import { AccountSettings } from "@/types/global";
-import { useState } from "react";
-import ChangePassword from "./ChangePassword";
-import ProfileSettings from "./ProfileSettings";
-import PrivacySettings from "./PrivacySettings";
-import BillingPortal from "./BillingPortal";
-
-type Props = {
- toggleSettingsModal: Function;
- activeUser: AccountSettings;
- className?: string;
- defaultIndex?: number;
-};
-
-const STRIPE_BILLING_PORTAL_URL =
- process.env.NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL;
-
-export default function UserModal({
- className,
- defaultIndex,
- toggleSettingsModal,
- activeUser,
-}: Props) {
- const [user, setUser] = useState(activeUser);
-
- return (
-
-
-
-
- selected
- ? "px-2 py-1 bg-sky-200 dark:bg-sky-800 dark:text-white duration-100 rounded-md outline-none"
- : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
- }
- >
- Profile Settings
-
-
-
- selected
- ? "px-2 py-1 bg-sky-200 dark:bg-sky-800 dark:text-white duration-100 rounded-md outline-none"
- : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
- }
- >
- Privacy Settings
-
-
-
- selected
- ? "px-2 py-1 bg-sky-200 dark:bg-sky-800 dark:text-white duration-100 rounded-md outline-none"
- : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
- }
- >
- Password
-
-
- {STRIPE_BILLING_PORTAL_URL ? (
-
- selected
- ? "px-2 py-1 bg-sky-200 dark:bg-sky-800 duration-100 rounded-md outline-none"
- : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
- }
- >
- Billing
-
- ) : undefined}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {STRIPE_BILLING_PORTAL_URL ? (
-
-
-
- ) : undefined}
-
-
-
- );
-}
diff --git a/components/ModalManagement.tsx b/components/ModalManagement.tsx
index 1958fe3..aa7790d 100644
--- a/components/ModalManagement.tsx
+++ b/components/ModalManagement.tsx
@@ -2,12 +2,10 @@ import useModalStore from "@/store/modals";
import Modal from "./Modal";
import LinkModal from "./Modal/Link";
import {
- AccountSettings,
CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags,
} from "@/types/global";
import CollectionModal from "./Modal/Collection";
-import UserModal from "./Modal/User";
import { useEffect } from "react";
import { useRouter } from "next/router";
@@ -49,15 +47,5 @@ export default function ModalManagement() {
/>
);
- else if (modal && modal.modal === "ACCOUNT")
- return (
-
-
-
- );
else return <>>;
}
diff --git a/lib/api/controllers/links/postLink.ts b/lib/api/controllers/links/postLink.ts
index a9afe16..33b4ba2 100644
--- a/lib/api/controllers/links/postLink.ts
+++ b/lib/api/controllers/links/postLink.ts
@@ -2,7 +2,7 @@ import { prisma } from "@/lib/api/db";
import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
import getTitle from "@/lib/api/getTitle";
import archive from "@/lib/api/archive";
-import { Collection, Link, UsersAndCollections } from "@prisma/client";
+import { Collection, UsersAndCollections } from "@prisma/client";
import getPermission from "@/lib/api/getPermission";
import createFolder from "@/lib/api/storage/createFolder";
diff --git a/store/modals.ts b/store/modals.ts
index 047bc28..71c336f 100644
--- a/store/modals.ts
+++ b/store/modals.ts
@@ -1,17 +1,10 @@
import {
- AccountSettings,
CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags,
} from "@/types/global";
import { create } from "zustand";
type Modal =
- | {
- modal: "ACCOUNT";
- state: boolean;
- active: AccountSettings;
- defaultIndex?: number;
- }
| {
modal: "LINK";
state: boolean;