New feature on the account creation:
It automatically stores who created the code and adds the registered user to a group administrated by that creator
This commit is contained in:
@@ -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,
|
||||
<input
|
||||
type={type}
|
||||
name={name}
|
||||
disabled={disabled}
|
||||
onChange={(e) => 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}
|
||||
/>
|
||||
|
||||
@@ -57,6 +57,7 @@ export interface Group {
|
||||
name: string;
|
||||
participants: string[];
|
||||
id: string;
|
||||
disableEditing?: boolean;
|
||||
}
|
||||
|
||||
export type Type = "student" | "teacher" | "admin" | "owner" | "developer";
|
||||
|
||||
@@ -69,7 +69,7 @@ const CreatePanel = ({user, users, group, onCreate}: CreateDialogProps) => {
|
||||
return (
|
||||
<div className="flex flex-col gap-12 mt-4 w-full px-4 py-2">
|
||||
<div className="flex flex-col gap-8">
|
||||
<Input name="name" type="text" label="Name" defaultValue={name} onChange={setName} required />
|
||||
<Input name="name" type="text" label="Name" defaultValue={name} onChange={setName} required disabled={group?.disableEditing} />
|
||||
<div className="flex flex-col gap-3 w-full">
|
||||
<label className="font-normal text-base text-mti-gray-dim">Participants</label>
|
||||
<div className="flex gap-8 w-full">
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
31
src/utils/registration.ts
Normal file
31
src/utils/registration.ts
Normal file
@@ -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;
|
||||
};
|
||||
Reference in New Issue
Block a user