added settings modal UI

This commit is contained in:
Daniel 2023-05-18 21:32:17 +03:30
parent a5d0d08c93
commit e3862188de
15 changed files with 74 additions and 24 deletions

View File

@ -5,12 +5,15 @@ import { ChangeEventHandler } from "react";
type Props = {
label: string;
state: boolean;
className?: string;
onClick: ChangeEventHandler<HTMLInputElement>;
};
export default function Checkbox({ label, state, onClick }: Props) {
export default function Checkbox({ label, state, className, onClick }: Props) {
return (
<label className="cursor-pointer flex items-center gap-2 text-sky-500">
<label
className={`cursor-pointer flex items-center gap-2 text-sky-500 ${className}`}
>
<input
type="checkbox"
checked={state}

View File

@ -46,7 +46,7 @@ export default function AddCollection({ toggleCollectionModal }: Props) {
return (
<div className="flex flex-col gap-3 sm:w-[35rem] w-80">
<p className="font-bold text-sky-300 mb-3 text-center">New Collection</p>
<p className="text-xl text-sky-500 mb-2 text-center">New Collection</p>
<div className="flex flex-col sm:flex-row gap-3">
<div className="w-full">

View File

@ -78,7 +78,7 @@ export default function AddLink({ toggleLinkModal }: Props) {
return (
<div className="flex flex-col gap-3 sm:w-[35rem] w-80">
<p className="font-bold text-sky-300 mb-2 text-center">New Link</p>
<p className="text-xl text-sky-500 mb-2 text-center">New Link</p>
<div className="grid sm:grid-cols-2 gap-3">
<div>

View File

@ -11,12 +11,12 @@ import useCollectionStore from "@/store/collections";
import { useRouter } from "next/router";
type Props = {
toggleCollectionModal: Function;
toggleDeleteCollectionModal: Function;
collection: ExtendedCollection;
};
export default function AddCollection({
toggleCollectionModal,
toggleDeleteCollectionModal,
collection,
}: Props) {
const [inputField, setInputField] = useState("");
@ -28,14 +28,14 @@ export default function AddCollection({
const submit = async () => {
const response = await removeCollection(collection.id);
if (response) {
toggleCollectionModal();
toggleDeleteCollectionModal();
router.push("/collections");
}
};
return (
<div className="flex flex-col gap-3 sm:w-[33rem] w-72">
<p className="font-bold text-sky-300 text-center">Delete Collection</p>
<p className="text-xl text-sky-500 mb-2 text-center">Delete Collection</p>
<p className="text-sky-900 select-none text-center">
To confirm, type "

View File

@ -54,7 +54,7 @@ export default function EditCollection({
return (
<div className="flex flex-col gap-3 sm:w-[35rem] w-80">
<p className="font-bold text-sky-300 mb-2 text-center">Edit Collection</p>
<p className="text-xl text-sky-500 mb-2 text-center">Edit Collection</p>
<div className="flex flex-col sm:flex-row gap-3">
<div className="w-full">
@ -297,7 +297,7 @@ export default function EditCollection({
<Modal toggleModal={toggleDeleteCollectionModal}>
<DeleteCollection
collection={activeCollection}
toggleCollectionModal={toggleDeleteCollectionModal}
toggleDeleteCollectionModal={toggleDeleteCollectionModal}
/>
</Modal>
) : null}

View File

@ -49,7 +49,7 @@ export default function EditLink({ toggleLinkModal, link }: Props) {
return (
<div className="flex flex-col gap-3 sm:w-96 w-80">
<p className="font-bold text-sky-300 mb-2 text-center">Edit Link</p>
<p className="text-xl text-sky-500 mb-2 text-center">Edit Link</p>
<p className="text-sky-700">
<b>{shortendURL}</b> | {link.title}
</p>

View File

@ -56,6 +56,7 @@ export default function () {
};
return (
// lg:ml-64 xl:ml-80
<div className="flex justify-between gap-2 items-center px-5 py-2 border-solid border-b-sky-100 border-b">
<div
onClick={toggleSidebar}

View File

@ -5,21 +5,28 @@
import { prisma } from "@/lib/api/db";
export default async function (email: string) {
export default async function (lookupEmail: string, isSelf: boolean) {
const user = await prisma.user.findUnique({
where: {
email,
email: lookupEmail,
},
});
const unsensitiveUserInfo = {
const data = isSelf
? {
// If user is requesting its data
id: user?.id,
name: user?.name,
email: user?.email,
}
: {
// If user is requesting someone elses data
id: user?.id,
name: user?.name,
email: user?.email,
createdAt: user?.createdAt,
};
const statusCode = user?.id ? 200 : 404;
return { response: unsensitiveUserInfo || null, status: statusCode };
return { response: data || null, status: statusCode };
}

View File

@ -8,18 +8,21 @@ import { useEffect } from "react";
import { useSession } from "next-auth/react";
import useTagStore from "@/store/tags";
import useLinkStore from "@/store/links";
import useAccountStore from "@/store/account";
export default function () {
const { status } = useSession();
const { status, data } = useSession();
const { setCollections } = useCollectionStore();
const { setTags } = useTagStore();
const { setLinks } = useLinkStore();
const { setAccount } = useAccountStore();
useEffect(() => {
if (status === "authenticated") {
setCollections();
setTags();
setLinks();
setAccount(data.user.email as string);
}
}, [status]);
}

View File

@ -15,9 +15,12 @@ export default async function (req: NextApiRequest, res: NextApiResponse) {
return res.status(401).json({ response: "You must be logged in." });
}
const lookupEmail = req.query.email as string;
const isSelf = session.user.email === lookupEmail ? true : false;
// get unsensitive user info by email
if (req.method === "GET") {
const users = await getUsers(req.query.email as string);
const users = await getUsers(lookupEmail, isSelf);
return res.status(users.status).json({ response: users.response });
}
}

View File

@ -175,7 +175,7 @@ export default function () {
<Modal toggleModal={toggleDeleteCollectionModal}>
<DeleteCollection
collection={activeCollection}
toggleCollectionModal={toggleDeleteCollectionModal}
toggleDeleteCollectionModal={toggleDeleteCollectionModal}
/>
</Modal>
) : null}

View File

@ -0,0 +1,4 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "collectionProtection" BOOLEAN NOT NULL DEFAULT true,
ADD COLUMN "profilePhotoPath" TEXT NOT NULL DEFAULT '',
ADD COLUMN "whitelistedUsers" TEXT[] DEFAULT ARRAY[]::TEXT[];

View File

@ -20,6 +20,9 @@ model User {
collections Collection[]
tags Tag[]
collectionsJoined UsersAndCollections[]
collectionProtection Boolean @default(true)
whitelistedUsers String[] @default([])
profilePhotoPath String @default("")
createdAt DateTime @default(now())
}

27
store/account.ts Normal file
View File

@ -0,0 +1,27 @@
// Copyright (C) 2022-present Daniel31x13 <daniel31x13@gmail.com>
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
import { create } from "zustand";
import { User } from "@prisma/client";
type AccountStore = {
account: User;
setAccount: (email: string) => void;
};
const useAccountStore = create<AccountStore>()((set) => ({
account: {} as User,
setAccount: async (email) => {
const response = await fetch(`/api/routes/users?email=${email}`);
const data = await response.json();
console.log(data);
if (response.ok) set({ account: data.response });
},
}));
export default useAccountStore;

View File

@ -5,7 +5,6 @@
import { create } from "zustand";
import { Tag } from "@prisma/client";
import tags from "@/pages/api/routes/tags";
type TagStore = {
tags: Tag[];