diff --git a/src/components/Diagnostic.tsx b/src/components/Diagnostic.tsx
index 943d90e7..a221f1d2 100644
--- a/src/components/Diagnostic.tsx
+++ b/src/components/Diagnostic.tsx
@@ -22,8 +22,8 @@ interface Props {
export default function Diagnostic({onFinish}: Props) {
const [focus, setFocus] = useState<"academic" | "general">();
- const [levels, setLevels] = useState({reading: -1, listening: -1, writing: -1, speaking: -1});
- const [desiredLevels, setDesiredLevels] = useState({reading: 9, listening: 9, writing: 9, speaking: 9});
+ const [levels, setLevels] = useState({reading: -1, listening: -1, writing: -1, speaking: -1, level: 0});
+ const [desiredLevels, setDesiredLevels] = useState({reading: 9, listening: 9, writing: 9, speaking: 9, level: 9});
const router = useRouter();
@@ -51,7 +51,7 @@ export default function Diagnostic({onFinish}: Props) {
axios
.patch("/api/users/update", {
focus,
- levels: Object.values(levels).includes(-1) ? {reading: 0, listening: 0, writing: 0, speaking: 0} : levels,
+ levels: Object.values(levels).includes(-1) ? {reading: 0, listening: 0, writing: 0, speaking: 0, level: 0} : levels,
desiredLevels,
isFirstLogin: false,
})
diff --git a/src/dashboards/Student.tsx b/src/dashboards/Student.tsx
index ec67cff7..369249f7 100644
--- a/src/dashboards/Student.tsx
+++ b/src/dashboards/Student.tsx
@@ -191,11 +191,12 @@ export default function StudentDashboard({user}: Props) {
{module === "listening" && }
{module === "writing" && }
{module === "speaking" && }
+ {module === "level" && }
{capitalize(module)}
- Level {user.levels[module]} / Level {user.desiredLevels[module]}
+ Level {user.levels[module] || 0} / Level {user.desiredLevels[module] || 9}
diff --git a/src/pages/api/users/update.ts b/src/pages/api/users/update.ts
index 7b6ea5f3..e82fdf58 100644
--- a/src/pages/api/users/update.ts
+++ b/src/pages/api/users/update.ts
@@ -4,14 +4,14 @@ import {app, storage} from "@/firebase";
import {getFirestore, collection, getDocs, getDoc, doc, setDoc, query, where} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session";
-import {User} from "@/interfaces/user";
+import {Group, User} from "@/interfaces/user";
import {getDownloadURL, getStorage, ref, uploadBytes} from "firebase/storage";
import {getAuth, signInWithEmailAndPassword, updateEmail, updatePassword} from "firebase/auth";
import {errorMessages} from "@/constants/errors";
import moment from "moment";
import ShortUniqueId from "short-unique-id";
import {Payment} from "@/interfaces/paypal";
-import { toFixedNumber } from "@/utils/number";
+import {toFixedNumber} from "@/utils/number";
const db = getFirestore(app);
const auth = getAuth(app);
@@ -22,10 +22,10 @@ export default withIronSessionApiRoute(handler, sessionOptions);
// but if it is not inserted as a string, some UI components will not work (Invalid Date)
const addPaymentRecord = async (data: any) => {
await setDoc(doc(db, "payments", data.id), data);
-}
+};
const managePaymentRecords = async (user: User, userId: string | undefined): Promise => {
try {
- if(user.type === 'corporate' && userId) {
+ if (user.type === "corporate" && userId) {
const shortUID = new ShortUniqueId();
const data: Payment = {
id: shortUID.randomUUID(8),
@@ -38,34 +38,35 @@ const managePaymentRecords = async (user: User, userId: string | undefined): Pro
isPaid: false,
date: new Date().toISOString(),
};
-
+
const corporatePayments = await getDocs(query(collection(db, "payments"), where("corporate", "==", userId)));
- if(corporatePayments.docs.length === 0) {
+ if (corporatePayments.docs.length === 0) {
await addPaymentRecord(data);
return true;
}
-
+
const hasPaymentPaidAndExpiring = corporatePayments.docs.filter((doc) => {
const data = doc.data();
- return data.isPaid
- && moment().isAfter(moment(user.subscriptionExpirationDate).subtract(30, "days"))
- && moment().isBefore(moment(user.subscriptionExpirationDate));
+ return (
+ data.isPaid &&
+ moment().isAfter(moment(user.subscriptionExpirationDate).subtract(30, "days")) &&
+ moment().isBefore(moment(user.subscriptionExpirationDate))
+ );
});
- if(hasPaymentPaidAndExpiring.length > 0) {
+ if (hasPaymentPaidAndExpiring.length > 0) {
await addPaymentRecord(data);
return true;
}
}
return false;
- } catch(e) {
+ } catch (e) {
// if this process fails it should not stop the rest of the process
console.log(e);
return false;
}
-
-}
+};
async function handler(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) {
@@ -108,6 +109,18 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const credential = await signInWithEmailAndPassword(auth, req.session.user.email, updatedUser.password);
await updateEmail(credential.user, updatedUser.email);
+
+ const groups = ((await getDocs(collection(db, "groups"))).docs.map((x) => ({...x.data(), id: x.id})) as Group[]).filter((x) =>
+ x.participants.includes(req.session.user!.id),
+ );
+
+ groups.forEach(async (group) => {
+ await setDoc(
+ doc(db, "groups", group.id),
+ {participants: group.participants.filter((x) => x !== req.session.user!.id)},
+ {merge: true},
+ );
+ });
} catch {
res.status(400).json({error: "E002", message: errorMessages.E002});
return;
diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx
index 0c0ed4cc..f81a0fc3 100644
--- a/src/pages/profile.tsx
+++ b/src/pages/profile.tsx
@@ -19,6 +19,8 @@ import {shouldRedirectHome} from "@/utils/navigation.disabled";
import moment from "moment";
import {BsCamera, BsCameraFill} from "react-icons/bs";
import {USER_TYPE_LABELS} from "@/resources/user";
+import useGroups from "@/hooks/useGroups";
+import useUsers from "@/hooks/useUsers";
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
const user = req.session.user;
@@ -52,28 +54,32 @@ export const getServerSideProps = withIronSessionSsr(({req, res}) => {
interface Props {
user: User;
- mutateUser: Function,
+ mutateUser: Function;
}
-function UserProfile({
- user,
- mutateUser,
-}: Props) {
- const [bio, setBio] = useState(user.bio || '');
- const [name, setName] = useState(user.name || '');
- const [email, setEmail] = useState(user.email || '');
+function UserProfile({user, mutateUser}: Props) {
+ const [bio, setBio] = useState(user.bio || "");
+ const [name, setName] = useState(user.name || "");
+ const [email, setEmail] = useState(user.email || "");
const [password, setPassword] = useState("");
const [newPassword, setNewPassword] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [profilePicture, setProfilePicture] = useState(user.profilePicture);
- const [country, setCountry] = useState(user.demographicInformation?.country || '');
- const [phone, setPhone] = useState(user.demographicInformation?.phone || '');
+ const [country, setCountry] = useState(user.demographicInformation?.country || "");
+ const [phone, setPhone] = useState(user.demographicInformation?.phone || "");
const [gender, setGender] = useState(user.demographicInformation?.gender || undefined);
- const [employment, setEmployment] = useState(user.type === "corporate" ? undefined : user.demographicInformation?.employment);
+ const [employment, setEmployment] = useState(
+ user.type === "corporate" ? undefined : user.demographicInformation?.employment,
+ );
const [position, setPosition] = useState(user.type === "corporate" ? user.demographicInformation?.position : undefined);
- const [companyName, setCompanyName] = useState(user.type === 'agent' ? user.agentInformation?.companyName : undefined);
- const [commercialRegistration, setCommercialRegistration] = useState(user.type === 'agent' ? user.agentInformation?.commercialRegistration : undefined);
+ const [companyName, setCompanyName] = useState(user.type === "agent" ? user.agentInformation?.companyName : undefined);
+ const [commercialRegistration, setCommercialRegistration] = useState(
+ user.type === "agent" ? user.agentInformation?.commercialRegistration : undefined,
+ );
+
+ const {groups} = useGroups();
+ const {users} = useUsers();
const profilePictureInput = useRef(null);
const expirationDateColor = (date: Date) => {
@@ -120,6 +126,19 @@ function UserProfile({
return;
}
+ if (email !== user?.email) {
+ const userAdmins = groups.filter((x) => x.participants.includes(user.id)).map((x) => x.admin);
+ const message =
+ users.filter((x) => userAdmins.includes(x.id) && x.type === "corporate").length > 0
+ ? "If you change your e-mail address, you will lose all benefits from your university/institute. Are you sure you want to continue?"
+ : "Are you sure you want to update your e-mail address?";
+
+ if (!confirm(message)) {
+ setIsLoading(false);
+ return;
+ }
+ }
+
const request = await axios.post("/api/users/update", {
bio,
name,
@@ -176,7 +195,7 @@ function UserProfile({
setPassword(e)}
@@ -358,10 +377,10 @@ function UserProfile({
{USER_TYPE_LABELS[user.type]}
- {user.type === 'agent' && (
+ {user.type === "agent" && (
}.png`})
@@ -394,9 +413,8 @@ function UserProfile({
);
}
-
export default function Home() {
- const {user, mutateUser } = useUser({redirectTo: "/login"});
+ const {user, mutateUser} = useUser({redirectTo: "/login"});
return (
<>
@@ -410,9 +428,7 @@ export default function Home() {
- {user &&
}
+ {user &&
}
>
);
-
-
-}
\ No newline at end of file
+}