added settings modal UI
This commit is contained in:
parent
a5d0d08c93
commit
e3862188de
|
@ -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}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ export default function () {
|
|||
<Modal toggleModal={toggleDeleteCollectionModal}>
|
||||
<DeleteCollection
|
||||
collection={activeCollection}
|
||||
toggleCollectionModal={toggleDeleteCollectionModal}
|
||||
toggleDeleteCollectionModal={toggleDeleteCollectionModal}
|
||||
/>
|
||||
</Modal>
|
||||
) : null}
|
||||
|
|
|
@ -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[];
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
import { create } from "zustand";
|
||||
import { Tag } from "@prisma/client";
|
||||
import tags from "@/pages/api/routes/tags";
|
||||
|
||||
type TagStore = {
|
||||
tags: Tag[];
|
||||
|
|
Ŝarĝante…
Reference in New Issue