From d34205b4c6cbf96ebfbaaf99343342f12b4c6325 Mon Sep 17 00:00:00 2001 From: Nishad Shirsat <103021375+nishad-ayanworks@users.noreply.github.com> Date: Mon, 18 Sep 2023 16:38:52 +0530 Subject: [PATCH] refactor: edit organization for private/public option (#277) * feat:public profile features Signed-off-by: pranalidhanavade * feat:changes in edit organization details model Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade Signed-off-by: @nishad.shirsat Co-authored-by: pranalidhanavade --- .../Authentication/SignInUserPassword.tsx | 6 +- src/components/Profile/EditUserProfile.tsx | 135 +++++++---- src/components/Profile/interfaces/index.ts | 1 + .../organization/EditOrgdetailsModal.tsx | 228 ++++++++++++------ 4 files changed, 244 insertions(+), 126 deletions(-) diff --git a/src/components/Authentication/SignInUserPassword.tsx b/src/components/Authentication/SignInUserPassword.tsx index 8ad30e955..df06a4ab4 100644 --- a/src/components/Authentication/SignInUserPassword.tsx +++ b/src/components/Authentication/SignInUserPassword.tsx @@ -8,17 +8,17 @@ import { Form, Formik, } from 'formik'; +import React, { useState } from 'react'; import { apiStatusCodes, storageKeys } from '../../config/CommonConstant'; import { getUserProfile, loginUser, passwordEncryption, setToLocalStorage } from '../../api/Auth'; import { Alert } from 'flowbite-react'; import type { AxiosResponse } from 'axios'; import CustomSpinner from '../CustomSpinner'; +import FooterBar from './FooterBar'; +import NavBar from './NavBar'; import SignInUserPasskey from './SignInUserPasskey'; import { getSupabaseClient } from '../../supabase'; -import NavBar from './NavBar'; -import FooterBar from './FooterBar'; -import React, { useState } from 'react'; interface emailValue { email: string; diff --git a/src/components/Profile/EditUserProfile.tsx b/src/components/Profile/EditUserProfile.tsx index 29969e217..578de1d89 100644 --- a/src/components/Profile/EditUserProfile.tsx +++ b/src/components/Profile/EditUserProfile.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { SetStateAction, useEffect, useState } from "react"; import type { UserProfile } from "./interfaces"; import { getFromLocalStorage, getUserProfile, updateUserProfile } from "../../api/Auth"; import { IMG_MAX_HEIGHT, IMG_MAX_WIDTH, apiStatusCodes, imageSizeAccepted, storageKeys } from "../../config/CommonConstant"; @@ -14,7 +14,8 @@ interface Values { profileImg: string; firstName: string; lastName: string; - email:string; + email: string; + radio1: string | boolean; } interface ILogoImage { @@ -37,13 +38,16 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile } firstName: userProfileInfo?.firstName || "", lastName: userProfileInfo?.lastName || "", email: userProfileInfo?.email || "", - + radio1: userProfileInfo?.publicProfile?.toString() + }) const [logoImage, setLogoImage] = useState({ logoFile: '', imagePreviewUrl: userProfileInfo?.profileImg || "", fileName: '' }) + + useEffect(() => { @@ -52,8 +56,8 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile } profileImg: userProfileInfo?.profileImg || "", firstName: userProfileInfo.firstName || '', lastName: userProfileInfo.lastName || '', - email: userProfileInfo?.email, - + email: userProfileInfo?.email, + radio1: userProfileInfo?.publicProfile.toString() }); setLogoImage({ @@ -121,7 +125,7 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile } ...logoImage, imagePreviewUrl: '', }); - + const reader = new FileReader() const file = event?.target?.files @@ -146,9 +150,6 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile } const updateUserDetails = async (values: Values) => { - console.log(`Image::`, logoImage?.imagePreviewUrl); - - setLoading(true) const userData = { @@ -156,8 +157,8 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile } firstName: values.firstName, lastName: values.lastName, email: values.email, - profileImg: logoImage?.imagePreviewUrl as string || values?.profileImg - + profileImg: logoImage?.imagePreviewUrl as string || values?.profileImg, + publicProfile:values?.radio1 } const resUpdateUserDetails = await updateUserProfile(userData) @@ -172,14 +173,14 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile } const validationSchema = yup.object().shape({ firstName: yup.string() - .required("First Name is required") - .min(2, 'First name must be at least 2 characters') - .max(255, 'First name must be at most 255 characters'), + .required("First Name is required") + .min(2, 'First name must be at least 2 characters') + .max(255, 'First name must be at most 255 characters'), lastName: yup.string() - .required("Last Name is required") - .min(2, 'Last name must be at least 2 characters') - .max(255, 'Last name must be at most 255 characters') + .required("Last Name is required") + .min(2, 'Last name must be at least 2 characters') + .max(255, 'Last name must be at most 255 characters') }); @@ -192,17 +193,19 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile } - ) => { + ) => { if (!values.firstName || !values.lastName) { return; } - + values['radio1'] = values?.radio1 === 'true' ? true : false updateUserDetails(values); toggleEditProfile(); + }} - + validationSchema={validationSchema}> {(formikHandlers): JSX.Element => (
) : ( - )} + )}

@@ -251,25 +254,25 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile }

+ type="button" + className="absolute top-0 right-0 w-6 h-6 m-2 " + onClick={toggleEditProfile} + > + + + + + + + + @@ -317,6 +320,48 @@ const UpdateUserProfile = ({ toggleEditProfile, userProfileInfo, updateProfile } } +
+
+
+
+ + Private + Only the connected organization can see you organization details + +
+
+
+
+ + Public + Your profile and organization details can be seen by everyone +
+
+
diff --git a/src/components/Profile/interfaces/index.ts b/src/components/Profile/interfaces/index.ts index 799a152b5..0fae36cb1 100644 --- a/src/components/Profile/interfaces/index.ts +++ b/src/components/Profile/interfaces/index.ts @@ -55,4 +55,5 @@ export interface UserProfile { lastName: string isEmailVerified: boolean keycloakUserId: string + publicProfile:boolean } \ No newline at end of file diff --git a/src/components/organization/EditOrgdetailsModal.tsx b/src/components/organization/EditOrgdetailsModal.tsx index e7312d0cc..68689b54d 100644 --- a/src/components/organization/EditOrgdetailsModal.tsx +++ b/src/components/organization/EditOrgdetailsModal.tsx @@ -5,15 +5,18 @@ import { Field, Form, Formik, FormikHelpers } from 'formik'; import { IMG_MAX_HEIGHT, IMG_MAX_WIDTH, apiStatusCodes, imageSizeAccepted } from '../../config/CommonConstant' import { calculateSize, dataURItoBlob } from "../../utils/CompressImage"; import { useEffect, useState } from "react"; + import { AlertComponent } from "../AlertComponent"; import type { AxiosResponse } from 'axios'; +import type { Organisation } from "./interfaces"; +import React from "react"; // import { asset } from '../../lib/data.js'; import { updateOrganization } from "../../api/organization"; -import type { Organisation } from "./interfaces"; interface Values { name: string; description: string; + radio1: string | boolean; } interface ILogoImage { @@ -26,58 +29,67 @@ interface EditOrgdetailsModalProps { openModal: boolean; setMessage: (message: string) => void; setOpenModal: (flag: boolean) => void; - onEditSucess?:() =>void; - orgData: Organisation | null; - } + onEditSucess?: () => void; + orgData: Organisation | null; -const EditOrgdetailsModal = (props: EditOrgdetailsModalProps)=> { +} + +const EditOrgdetailsModal = (props: EditOrgdetailsModalProps) => { const [logoImage, setLogoImage] = useState({ logoFile: "", imagePreviewUrl: props?.orgData?.logoUrl || "", - fileName: '' + fileName: '', + }) const [loading, setLoading] = useState(false) const [isImageEmpty, setIsImageEmpty] = useState(true) + const [isPublic, setIsPublic] = useState(true) const [initialOrgData, setOrgData] = useState({ name: props?.orgData?.name || "", description: props?.orgData?.description || "", + radio1: props?.orgData?.publicProfile?.toString() || "" }) useEffect(() => { - + if (props.orgData) { - setOrgData({ - name: props.orgData.name || '', - description: props.orgData.description || '', - }); - - setLogoImage({ - logoFile: "", - imagePreviewUrl: props.orgData.logoUrl || "", - fileName: '' - }); + setOrgData({ + name: props.orgData.name || '', + description: props.orgData.description || '', + radio1: props?.orgData?.publicProfile.toString() + }); + + setLogoImage({ + logoFile: "", + imagePreviewUrl: props.orgData.logoUrl || "", + fileName: '' + }); } - }, [props.orgData]); - + }, [props]); + const [erroMsg, setErrMsg] = useState(null) const [imgError, setImgError] = useState('') useEffect(() => { - setOrgData({ - name: '', - description: '', - }) - setLogoImage({ - ...logoImage, - logoFile: "", - imagePreviewUrl: "" - }) + if (props.openModal === false) { + setOrgData({ + name: '', + description: '', + radio1: '' + }) + + setLogoImage({ + ...logoImage, + logoFile: "", + imagePreviewUrl: "" + }) + } }, [props.openModal]) @@ -155,33 +167,34 @@ const EditOrgdetailsModal = (props: EditOrgdetailsModalProps)=> { } } - const submitUpdateOrganization = async (values: Values) => { - setLoading(true) + const submitUpdateOrganization = async (values: Values) => { - const orgData = { - orgId: props?.orgData?.id, - name: values.name, - description: values.description, - logo: logoImage?.imagePreviewUrl as string || props?.orgData?.logoUrl, - website: "" - } + setLoading(true) - const resUpdateOrg = await updateOrganization(orgData) + const orgData = { + orgId: props?.orgData?.id, + name: values.name, + description: values.description, + logo: logoImage?.imagePreviewUrl as string || props?.orgData?.logoUrl, + website: "", + isPublic: isPublic + } - const { data } = resUpdateOrg as AxiosResponse - setLoading(false) + const resUpdateOrg = await updateOrganization(orgData) - if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { - if(props?.onEditSucess){ - props?.onEditSucess() - } - props.setOpenModal(false) - window.location.reload(); - } else { - setErrMsg(resUpdateOrg as string) + const { data } = resUpdateOrg as AxiosResponse + setLoading(false) + + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + if (props?.onEditSucess) { + props?.onEditSucess() } + props.setOpenModal(false) + } else { + setErrMsg(resUpdateOrg as string) } - + } + return ( { setLogoImage({ @@ -195,19 +208,16 @@ const EditOrgdetailsModal = (props: EditOrgdetailsModalProps)=> { }> Edit Organization - { + onAlertClose={() => { setErrMsg(null) }} - /> + /> { description: yup .string() .min(2, 'Organization name must be at least 2 characters') - .max(255, 'Organization name must be at most 255 characters') + .max(600, 'Organization name must be at most 255 characters') .required('Description is required') })} validateOnBlur @@ -232,7 +242,6 @@ const EditOrgdetailsModal = (props: EditOrgdetailsModalProps)=> { ) => { submitUpdateOrganization(values) - }} > {(formikHandlers): JSX.Element => ( @@ -249,21 +258,21 @@ const EditOrgdetailsModal = (props: EditOrgdetailsModalProps)=> { { - (typeof (logoImage.logoFile) === "string" && props?.orgData?.logoUrl) ? - Jese picture - : typeof (logoImage.logoFile) === "string" ? - : + (typeof (logoImage.logoFile) === "string" && props?.orgData?.logoUrl) ? Jese picture + : typeof (logoImage.logoFile) === "string" ? + : + Jese picture } @@ -278,7 +287,7 @@ const EditOrgdetailsModal = (props: EditOrgdetailsModalProps)=> {
+ +
{ {formikHandlers?.errors?.description} }
+
+
+
+ + +
+
+ +
+
+
+ setIsPublic(false)} + id="private" + name="private" + /> + Private + Only the connected organization can see you organization details + +
+
+
+
+ setIsPublic(true)} + checked={isPublic === true} + id="public" + name="public" + /> + + Public + Your profile and organization details can be seen by everyone +
+
)}