diff --git a/src/components/Low/Input.tsx b/src/components/Low/Input.tsx index b44950b9..54860157 100644 --- a/src/components/Low/Input.tsx +++ b/src/components/Low/Input.tsx @@ -6,11 +6,12 @@ interface Props { label?: string; placeholder?: string; defaultValue?: string; + disabled?: boolean; name: string; onChange: (value: string) => void; } -export default function Input({type, label, placeholder, name, required = false, defaultValue, onChange}: Props) { +export default function Input({type, label, placeholder, name, required = false, defaultValue, disabled = false, onChange}: Props) { const [showPassword, setShowPassword] = useState(false); if (type === "password") { @@ -53,9 +54,10 @@ export default function Input({type, label, placeholder, name, required = false, onChange(e.target.value)} placeholder={placeholder} - className="px-8 py-6 text-sm font-normal placeholder:text-mti-gray-cool bg-white rounded-full border border-mti-gray-platinum focus:outline-none" + className="px-8 py-6 text-sm font-normal placeholder:text-mti-gray-cool disabled:bg-mti-gray-platinum/40 disabled:text-mti-gray-dim disabled:cursor-not-allowed bg-white rounded-full border border-mti-gray-platinum focus:outline-none" required={required} defaultValue={defaultValue} /> diff --git a/src/interfaces/user.ts b/src/interfaces/user.ts index c97f125e..15040ef1 100644 --- a/src/interfaces/user.ts +++ b/src/interfaces/user.ts @@ -57,6 +57,7 @@ export interface Group { name: string; participants: string[]; id: string; + disableEditing?: boolean; } export type Type = "student" | "teacher" | "admin" | "owner" | "developer"; diff --git a/src/pages/(admin)/Lists/GroupList.tsx b/src/pages/(admin)/Lists/GroupList.tsx index f7e3bed4..64f460de 100644 --- a/src/pages/(admin)/Lists/GroupList.tsx +++ b/src/pages/(admin)/Lists/GroupList.tsx @@ -69,7 +69,7 @@ const CreatePanel = ({user, users, group, onCreate}: CreateDialogProps) => { return (
- +
diff --git a/src/pages/api/register.ts b/src/pages/api/register.ts index e4cf53f8..b947c0e0 100644 --- a/src/pages/api/register.ts +++ b/src/pages/api/register.ts @@ -5,6 +5,7 @@ import {sessionOptions} from "@/lib/session"; import {withIronSessionApiRoute} from "iron-session/next"; import {getFirestore, doc, setDoc, query, collection, where, getDocs} from "firebase/firestore"; import {DemographicInformation, Type} from "@/interfaces/user"; +import {addUserToGroupOnCreation} from "@/utils/registration"; const auth = getAuth(app); const db = getFirestore(app); @@ -36,7 +37,7 @@ async function login(req: NextApiRequest, res: NextApiResponse) { return; } - const codeData = codeDocs[0].data() as {code: string; type: Type}; + const codeData = codeDocs[0].data() as {code: string; type: Type; creator: string}; createUserWithEmailAndPassword(auth, email, password) .then(async (userCredentials) => { @@ -55,6 +56,7 @@ async function login(req: NextApiRequest, res: NextApiResponse) { await setDoc(doc(db, "users", userId), user); await setDoc(codeDocs[0].ref, {userId: userId}, {merge: true}); + await addUserToGroupOnCreation(userId, codeData.type, codeData.creator); req.session.user = {...user, id: userId}; await req.session.save(); diff --git a/src/pages/api/user.ts b/src/pages/api/user.ts index 92cd6ffb..41474d5e 100644 --- a/src/pages/api/user.ts +++ b/src/pages/api/user.ts @@ -2,7 +2,7 @@ import {PERMISSIONS} from "@/constants/userPermissions"; import {app, adminApp} from "@/firebase"; import {User} from "@/interfaces/user"; import {sessionOptions} from "@/lib/session"; -import {collection, deleteDoc, doc, getDoc, getDocs, getFirestore, query, where} from "firebase/firestore"; +import {collection, deleteDoc, doc, getDoc, getDocs, getFirestore, query, setDoc, where} from "firebase/firestore"; import {getAuth} from "firebase-admin/auth"; import {withIronSessionApiRoute} from "iron-session/next"; import {NextApiRequest, NextApiResponse} from "next"; @@ -49,18 +49,24 @@ async function del(req: NextApiRequest, res: NextApiResponse) { return; } + const userCodeDocs = await getDocs(query(collection(db, "codes"), where("userId", "==", id))); + const userParticipantGroup = await getDocs(query(collection(db, "groups"), where("participants", "array-contains", id))); + const userGroupAdminDocs = await getDocs(query(collection(db, "groups"), where("admin", "==", id))); + const userStatsDocs = await getDocs(query(collection(db, "stats"), where("user", "==", id))); + + await Promise.all([ + ...userCodeDocs.docs.map(async (x) => await deleteDoc(x.ref)), + ...userGroupAdminDocs.docs.map(async (x) => await deleteDoc(x.ref)), + ...userStatsDocs.docs.map(async (x) => await deleteDoc(x.ref)), + ...userParticipantGroup.docs.map( + async (x) => await setDoc(x.ref, {participants: x.data().participants.filter((y: string) => y !== id)}, {merge: true}), + ), + ]); + await auth.deleteUser(id); await deleteDoc(doc(db, "users", id)); res.json({ok: true}); - - const statsQuery = query(collection(db, "stats"), where("user", "==", targetUser.id)); - const statsSnapshot = await getDocs(statsQuery); - await Promise.all( - statsSnapshot.docs.map(async (doc) => { - return await deleteDoc(doc.ref); - }), - ); } async function get(req: NextApiRequest, res: NextApiResponse) { diff --git a/src/utils/registration.ts b/src/utils/registration.ts new file mode 100644 index 00000000..22954048 --- /dev/null +++ b/src/utils/registration.ts @@ -0,0 +1,31 @@ +import {collection, doc, getDoc, getDocs, getFirestore, query, setDoc, where} from "firebase/firestore"; +import {app} from "@/firebase"; +import {Group, Type, User} from "@/interfaces/user"; +import {uuidv4} from "@firebase/util"; + +const db = getFirestore(app); + +export const addUserToGroupOnCreation = async (userId: string, type: Type, creatorId: string) => { + const creatorDoc = await getDoc(doc(db, "users", creatorId)); + if (!creatorDoc.exists()) return false; + + const creator = {...creatorDoc.data(), id: creatorDoc.id} as User; + + const creatorGroupsDocs = await getDocs(query(collection(db, "groups"), where("admin", "==", creator.id))); + const typeGroup = creatorGroupsDocs.docs.find((x) => (x.data() as Group).name === (type === "student" ? "Students" : "Teachers")); + + if (typeGroup && typeGroup.exists()) { + await setDoc(typeGroup.ref, {participants: [...typeGroup.data().participants, userId]}, {merge: true}); + return true; + } + + const groupId = uuidv4(); + await setDoc(doc(db, "groups", groupId), { + admin: creatorId, + name: type === "student" ? "Students" : "Teachers", + id: groupId, + participants: [userId], + disableEditing: true, + } as Group); + return true; +};