Skip to content

Commit

Permalink
completed instructor profile
Browse files Browse the repository at this point in the history
  • Loading branch information
abinth11 committed Jul 23, 2023
1 parent 3144502 commit 00723e2
Show file tree
Hide file tree
Showing 15 changed files with 379 additions and 115 deletions.
20 changes: 20 additions & 0 deletions client/src/api/endpoints/instructor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
updateProfileService,
changePasswordService,
} from "../services/instructor";
import { PasswordInfo } from "../types/student/student";
import END_POINTS from "../../constants/endpoints";

export const changePassword = (passwordInfo: PasswordInfo) => {
return changePasswordService(
END_POINTS.INSTRUCTOR_CHANGE_PASSWORD,
passwordInfo
);
};

export const updateProfile = (profileInfo: FormData) => {
return updateProfileService(
END_POINTS.INSTRUCTOR_UPDATE_PROFILE,
profileInfo
);
};
28 changes: 28 additions & 0 deletions client/src/api/services/instructor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import CONSTANTS_COMMON from "../../constants/common";
import api from "../middlewares/protectedInterceptor";
import { PasswordInfo} from "../types/student/student";

export const changePasswordService = async (
endpoint: string,
passwordInfo: PasswordInfo
) => {
const response = await api.patch(
`${CONSTANTS_COMMON.API_BASE_URL}/${endpoint}`,
passwordInfo
);
return response;
};

export const updateProfileService = async (
endpoint: string,
profileInfo: FormData
) => {
const response = await api.put(
`${CONSTANTS_COMMON.API_BASE_URL}/${endpoint}`,
profileInfo
);
return response;
};



3 changes: 2 additions & 1 deletion client/src/api/types/apiResponses/apiResponseInstructors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export interface InstructorApiResponse {
dateJoined: string
__v: number
rejected: boolean
rejectedReason: string
rejectedReason: string,
profileUrl:string;
}

interface Certificate {
Expand Down
18 changes: 18 additions & 0 deletions client/src/api/types/instructor/instructor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface PasswordInfo {
currentPassword: string;
newPassword: string;
}
export interface UpdateProfileInfo {
firstName?: string;
lastName?: string;
email?: string;
mobile?: string;
profilePic?: File | null;
qualification?:string;
subjects?:string;
experience?:string;
skills?:string;
about?:string;

}

8 changes: 4 additions & 4 deletions client/src/components/pages/instructors/InsructorProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const InstructorProfile: React.FC = (props: Props) => {
<h2 className='text-3xl font-semibold text-customFontColorBlack'>
Edit profile info
</h2>
</div>
</div>
</div>
<div className='flex flex-col md:flex-row gap-x-10 h-full pb-10'>
<div className='flex flex-col md:flex-row gap-x-10 h-full pb-20'>
<div className='border md:w-7/12 w-full h-full rounded-md bg-white border-gray-300'>
<div className='flex justify-between'>
<h3 className='pl-5 pt-5 text-lg text-customFontColorBlack font-semibold'>
Expand All @@ -54,8 +54,8 @@ const InstructorProfile: React.FC = (props: Props) => {
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};

Expand Down
2 changes: 1 addition & 1 deletion client/src/components/pages/instructors/PasswordForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";
import { useFormik } from "formik";
import { changePassword } from "../../../api/endpoints/student";
import { changePassword } from "../../../api/endpoints/instructor";
import { toast } from "react-toastify";
import { PasswordInfo } from "../../../api/types/student/student";
import { PasswordValidationSchema } from "../../../validations/student";
Expand Down
212 changes: 148 additions & 64 deletions client/src/components/pages/instructors/ProfileForm.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
import { useState, useEffect } from "react";
import { useFormik } from "formik";
import { toast } from "react-toastify";
import { updateProfile } from "../../../api/endpoints/student";
import { UpdateProfileInfo } from "../../../api/types/student/student";
import { updateProfile } from "../../../api/endpoints/instructor";
import { UpdateProfileInfo } from "../../../api/types/instructor/instructor";
import { Avatar } from "@material-tailwind/react";
import { useSelector, useDispatch } from "react-redux";
import {
selectStudent,
selectIsFetchingStudent,
selectStudentError,
fetchStudentData,
} from "../../../redux/reducers/studentSlice";
import { getProfileUrl } from "../../../api/endpoints/student";
import { getIndividualInstructors } from "../../../api/endpoints/instructorManagement";
import { InstructorApiResponse } from "../../../api/types/apiResponses/apiResponseInstructors";

interface Props {
editMode:boolean;
setEditMode:(val:boolean)=>void
editMode: boolean;
setEditMode: (val: boolean) => void;
}
const ProfileForm:React.FC<Props> = ({editMode,setEditMode}) => {
const ProfileForm: React.FC<Props> = ({ editMode, setEditMode }) => {
const [previewImage, setPreviewImage] = useState<string | null>(null);
const studentInfo = useSelector(selectStudent)?.studentDetails;
let isFetching = useSelector(selectIsFetchingStudent);
const [loading, setLoading] = useState(false);
const [profileLoading, setProfileLoading] = useState(false);
const [instructor, setInstructor] = useState<InstructorApiResponse | null>(
null
);
const [profileUrl, setProfileUrl] = useState<string>("");
const error = useSelector(selectStudentError);
const [updated, setUpdated] = useState(false);
const dispatch = useDispatch();

const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
Expand All @@ -41,30 +34,54 @@ const ProfileForm:React.FC<Props> = ({editMode,setEditMode}) => {
formik.setFieldValue("profilePic", null);
}
};
const fetchUrl = async () => {
const fetchInstructor = async () => {
try {
setLoading(true);
const response = await getProfileUrl();
setProfileUrl(response.data);
setLoading(false);
} catch (error: any) {
toast.error(error?.data?.message, {
position: toast.POSITION.BOTTOM_RIGHT,
});
setProfileLoading(true);
const response = await getIndividualInstructors("fromProfile");
setInstructor(response?.data?.data);
setProfileLoading(false);
} catch (error) {
setProfileLoading(false);
}
};
useEffect(() => {
fetchUrl();
dispatch(fetchStudentData());
}, [updated]);

useEffect(() => {
if (!studentInfo) {
setLoading(true);
} else {
setLoading(false);
if (instructor) {
formik.setValues({
email: instructor.email || "",
firstName: instructor.firstName || "",
lastName: instructor.lastName || "",
mobile: instructor.mobile || "",
qualification: instructor?.qualification || "",
// subjects: instructor?.subjects || "",
experience: instructor?.experience || "",
skills: instructor?.skills || "",
about: instructor?.about || "",
});
}
}, [studentInfo]);
setProfileUrl(instructor?.profileUrl ?? "");
}, [instructor]);

useEffect(() => {
fetchInstructor();
}, [updated]);

const formik = useFormik({
initialValues: {
email: instructor?.email || "",
firstName: instructor?.firstName || "",
lastName: instructor?.lastName || "",
mobile: instructor?.mobile || "",
qualification: instructor?.qualification || "",
// subjects: instructor?.subjects || "",
experience: instructor?.experience || "",
skills: instructor?.skills || "",
about: instructor?.about || "",
},
onSubmit: (values) => {
handleSubmit(values);
},
});

const handleSubmit = async (profileInfo: UpdateProfileInfo) => {
try {
Expand All @@ -76,9 +93,12 @@ const ProfileForm:React.FC<Props> = ({editMode,setEditMode}) => {
formData.append("firstName", profileInfo.firstName || "");
formData.append("lastName", profileInfo.lastName || "");
formData.append("mobile", profileInfo.mobile || "");
formData.append("qualification",profileInfo.qualification||"")
formData.append("experience",profileInfo.experience||"")
formData.append("skills",profileInfo.skills||"")

const response = await updateProfile(formData);
// formik.resetForm();
// formik.resetForm();
setPreviewImage(null);
const fileInput = document.getElementById(
"file_input"
Expand All @@ -99,37 +119,13 @@ const ProfileForm:React.FC<Props> = ({editMode,setEditMode}) => {
}
};

const formik = useFormik({
initialValues: {
email: studentInfo?.email || "",
firstName: studentInfo?.firstName || "",
lastName: studentInfo?.lastName || "",
mobile: studentInfo?.mobile || "",
},
onSubmit: (values) => {
handleSubmit(values);
},
});

// if (isFetching) {
// return <div>Loading...</div>;
// }
if (loading) {
if (profileLoading) {
return <div>Loading...</div>;
}

// if (error) {
// return <div>Error: {error}</div>;
// }

// if (!studentInfo) {
// return <div>loading...</div>
// }

return (
<form onSubmit={formik.handleSubmit}>
<div>
</div>
<form onSubmit={formik.handleSubmit} >
<div></div>
<div className='p-5 flex '>
<Avatar
src={previewImage || profileUrl || "../profile.jpg"}
Expand Down Expand Up @@ -241,6 +237,94 @@ const ProfileForm:React.FC<Props> = ({editMode,setEditMode}) => {
Mobile
</label>
</div>
<div className='relative z-0 w-full mb-6 group'>
<input
type='text'
name='qualification'
id='floating_qualification'
disabled={!editMode}
value={formik.values.qualification}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
className='block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-300 appearance-none dark:text-white dark:border-gray-600 dark:focus:border-blue-500 focus:outline-none focus:ring-0 focus:border-blue-600 peer'
placeholder=' '
required
/>
<label
htmlFor='floating_qualification'
className={`peer-focus:font-medium absolute text-sm text-gray-500 dark:text-gray-400 duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] ${
formik.values.qualification ? "peer-placeholder-shown:scale-100" : ""
} peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6`}
>
Qualifications
</label>
</div>
{/* <div className='relative z-0 w-full mb-6 group'>
<input
type='text'
name='subjects'
id='floating_subject'
disabled={!editMode}
value={formik.values.mobile}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
className='block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-300 appearance-none dark:text-white dark:border-gray-600 dark:focus:border-blue-500 focus:outline-none focus:ring-0 focus:border-blue-600 peer'
placeholder=' '
required
/>
<label
htmlFor='floating_subjects'
className={`peer-focus:font-medium absolute text-sm text-gray-500 dark:text-gray-400 duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] ${
formik.values.mobile ? "peer-placeholder-shown:scale-100" : ""
} peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6`}
>
Subjects
</label>
</div> */}
<div className='relative z-0 w-full mb-6 group'>
<input
type='text'
name='experience'
id='floating_experience'
disabled={!editMode}
value={formik.values.experience}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
className='block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-300 appearance-none dark:text-white dark:border-gray-600 dark:focus:border-blue-500 focus:outline-none focus:ring-0 focus:border-blue-600 peer'
placeholder=' '
required
/>
<label
htmlFor='floating_experience'
className={`peer-focus:font-medium absolute text-sm text-gray-500 dark:text-gray-400 duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] ${
formik.values.experience ? "peer-placeholder-shown:scale-100" : ""
} peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6`}
>
Experience
</label>
</div>
<div className='relative z-0 w-full mb-6 group'>
<input
type='text'
name='skills'
id='floating_skills'
disabled={!editMode}
value={formik.values.skills}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
className='block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-300 appearance-none dark:text-white dark:border-gray-600 dark:focus:border-blue-500 focus:outline-none focus:ring-0 focus:border-blue-600 peer'
placeholder=' '
required
/>
<label
htmlFor='floating_skills'
className={`peer-focus:font-medium absolute text-sm text-gray-500 dark:text-gray-400 duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] ${
formik.values.skills ? "peer-placeholder-shown:scale-100" : ""
} peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6`}
>
Skills
</label>
</div>
<div className='relative pt-10 pr-1'>
{editMode && (
<button
Expand Down
4 changes: 3 additions & 1 deletion client/src/constants/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ const END_POINTS = {
UNBLOCK_STUDENT:"api/students/unblock-student",
GET_BLOCKED_STUDENTS:"api/students/get-all-blocked-students",
ADMIN_DASHBOARD_DATA:"api/admin/dashboard-details",
GET_GRAPH_DATA_ADMIN:"api/admin/graph-data"
GET_GRAPH_DATA_ADMIN:"api/admin/graph-data",
INSTRUCTOR_CHANGE_PASSWORD:"api/instructors/change-password",
INSTRUCTOR_UPDATE_PROFILE:"api/instructors/update-profile"
}
export default END_POINTS
Loading

0 comments on commit 00723e2

Please sign in to comment.