diff --git a/src/components/ConfirmationModal.jsx b/src/components/ConfirmationModal.jsx index 2222e6f..449c2e4 100644 --- a/src/components/ConfirmationModal.jsx +++ b/src/components/ConfirmationModal.jsx @@ -9,28 +9,45 @@ export default function ConfirmationModal() { if (!state.confirmation) return null; return ( -
+
e.stopPropagation()} > -

+

{state.confirmationHeading}

-

{state.confirmationMsg}

- +

{state.confirmationMsg}

+
+ + +
); diff --git a/src/components/Profile/ProfileImageConfirmModal.jsx b/src/components/Profile/ProfileImageConfirmModal.jsx new file mode 100644 index 0000000..26cc199 --- /dev/null +++ b/src/components/Profile/ProfileImageConfirmModal.jsx @@ -0,0 +1,62 @@ +import { Dialog, Transition } from "@headlessui/react"; +import { Fragment } from "react"; + +export default function ProfileImageConfirmModal({ + modalOpen, + modalImage, + onConfirm, + onCancel, +}) { + return ( + + + +
+ +
+
+ + + Profile Preview +
+ + +
+
+
+
+
+
+
+ ); +} diff --git a/src/pages/Customer/Profile/CustomerProfilePage.jsx b/src/pages/Customer/Profile/CustomerProfilePage.jsx index 6619806..a67cb59 100644 --- a/src/pages/Customer/Profile/CustomerProfilePage.jsx +++ b/src/pages/Customer/Profile/CustomerProfilePage.jsx @@ -8,7 +8,11 @@ import MkdSDK from "@/utils/MkdSDK"; import { callCustomAPI } from "@/utils/callCustomAPI"; import Skeleton from "react-loading-skeleton"; import { formatDate } from "@/utils/date-time-utils"; -import { IMAGE_STATUS, NOTIFICATION_STATUS, NOTIFICATION_TYPE } from "@/utils/constants"; +import { + IMAGE_STATUS, + NOTIFICATION_STATUS, + NOTIFICATION_TYPE, +} from "@/utils/constants"; import SwitchBulkMode from "@/components/SwitchBulkMode"; import TwoFaDialog from "@/components/Profile/TwoFaDialog"; import EditProfileModal from "@/components/Profile/EditProfileModal"; @@ -18,6 +22,7 @@ import EditAboutModal from "@/components/Profile/EditAboutModal"; import { parseJsonSafely } from "@/utils/utils"; import EnableEmailDialog from "@/components/Profile/EnableEmailDialog"; import DeleteAccountModal from "@/components/Profile/DeleteAccountModal"; +import ProfileImageConfirmModal from "@/components/Profile/ProfileImageConfirmModal"; function getProfilePhotoMessage(image_status) { switch (image_status) { @@ -33,7 +38,8 @@ function getProfilePhotoMessage(image_status) { } export default function CustomerProfilePage() { - const { dispatch: globalDispatch, state: globalState } = useContext(GlobalContext); + const { dispatch: globalDispatch, state: globalState } = + useContext(GlobalContext); const [loading, setLoading] = useState(false); const [twoFa, setTwoFa] = useState(false); const [twoFaDialog, setTwoFaDialog] = useState(false); @@ -49,20 +55,29 @@ export default function CustomerProfilePage() { const [deleteAccountModal, setDeleteAccountModal] = useState(false); + const [showImagePreview, setShowImagePreview] = useState(false); + const [selectedImage, setSelectedImage] = useState(null); + let sdk = new MkdSDK(); - const changeProfilePic = async (e) => { - globalDispatch({ type: "START_LOADING" }); - const file = e.target.files; - const formData = new FormData(); - for (let i = 0; i < file.length; i++) { - formData.append("file", file[i]); + const changeProfilePic = (e) => { + const file = e.target.files && e.target.files[0]; + if (file) { + setSelectedImage(file); + setShowImagePreview(true); } + }; + + const handleConfirmUpload = async () => { + setShowImagePreview(false); + if (!selectedImage) return; + globalDispatch({ type: "START_LOADING" }); + const formData = new FormData(); + formData.append("file", selectedImage); try { const upload = await sdk.uploadImage(formData); - console.log("upload", upload); sdk.setTable("user"); - const result = await callCustomAPI( + await callCustomAPI( "edit-self", "post", { @@ -71,9 +86,16 @@ export default function CustomerProfilePage() { is_photo_approved: IMAGE_STATUS.IN_REVIEW, }, }, - "", + "" ); - globalDispatch({ type: "SET_USER_DATA", payload: { ...globalState.user, photo: upload.url, is_photo_approved: IMAGE_STATUS.IN_REVIEW } }); + globalDispatch({ + type: "SET_USER_DATA", + payload: { + ...globalState.user, + photo: upload.url, + is_photo_approved: IMAGE_STATUS.IN_REVIEW, + }, + }); // create notification sdk.setTable("notification"); await sdk.callRestAPI( @@ -86,7 +108,7 @@ export default function CustomerProfilePage() { type: NOTIFICATION_TYPE.EDIT_USER_PICTURE, status: NOTIFICATION_STATUS.NOT_ADDRESSED, }, - "POST", + "POST" ); } catch (err) { globalDispatch({ @@ -98,9 +120,15 @@ export default function CustomerProfilePage() { }); } globalDispatch({ type: "STOP_LOADING" }); + setSelectedImage(null); }; - const removeProfilePic = async (e) => { + const handleCancelUpload = () => { + setShowImagePreview(false); + setSelectedImage(null); + }; + + const removeProfilePic = async () => { try { sdk.setTable("user"); await callCustomAPI( @@ -112,9 +140,12 @@ export default function CustomerProfilePage() { is_photo_approved: null, }, }, - "", + "" ); - globalDispatch({ type: "SET_USER_DATA", payload: { ...globalState.user, photo: null, is_photo_approved: null } }); + globalDispatch({ + type: "SET_USER_DATA", + payload: { ...globalState.user, photo: null, is_photo_approved: null }, + }); } catch (err) { globalDispatch({ type: "SHOW_ERROR", @@ -137,14 +168,16 @@ export default function CustomerProfilePage() { two_factor_authentication: twoFa != 1 ? 1 : 0, }, }, - "", + "" ); setTwoFaDialog(false); globalDispatch({ type: "SHOW_CONFIRMATION", payload: { heading: "Success", - message: `Two factor Authentication ${twoFa == 1 ? "disabled" : "enabled"}`, + message: `Two factor Authentication ${ + twoFa == 1 ? "disabled" : "enabled" + }`, btn: "Ok got it", }, }); @@ -163,50 +196,66 @@ export default function CustomerProfilePage() { } return ( -
-
-
-
-

Your photo

- {getProfilePhotoMessage(globalState.user.is_photo_approved)} +
+
+
+
+

Your photo

+ + {getProfilePhotoMessage(globalState.user.is_photo_approved)} +
+ data-tour='photo-step' + className='flex items-center justify-between' + >
-
-

Profile status

-
+
+

Profile status

+
{![0, 1].includes(globalState.user.verificationStatus) && ( Get verified @@ -214,7 +263,11 @@ export default function CustomerProfilePage() {
-
+
setUpdateName(false)} modalOpen={updateName} @@ -284,6 +337,16 @@ export default function CustomerProfilePage() { isOpen={enableEmailDialog} closeModal={() => setEnableEmailDialog(false)} /> +
); } diff --git a/src/pages/Host/Profile/HostProfilePage.jsx b/src/pages/Host/Profile/HostProfilePage.jsx index 470ddc3..6f3d793 100644 --- a/src/pages/Host/Profile/HostProfilePage.jsx +++ b/src/pages/Host/Profile/HostProfilePage.jsx @@ -8,7 +8,11 @@ import MkdSDK from "@/utils/MkdSDK"; import { callCustomAPI } from "@/utils/callCustomAPI"; import Skeleton from "react-loading-skeleton"; import { formatDate } from "@/utils/date-time-utils"; -import { IMAGE_STATUS, NOTIFICATION_STATUS, NOTIFICATION_TYPE } from "@/utils/constants"; +import { + IMAGE_STATUS, + NOTIFICATION_STATUS, + NOTIFICATION_TYPE, +} from "@/utils/constants"; import SwitchBulkMode from "@/components/SwitchBulkMode"; import TwoFaDialog from "@/components/Profile/TwoFaDialog"; import EditProfileModal from "@/components/Profile/EditProfileModal"; @@ -18,6 +22,7 @@ import EditAboutModal from "@/components/Profile/EditAboutModal"; import { parseJsonSafely } from "@/utils/utils"; import EnableEmailDialog from "@/components/Profile/EnableEmailDialog"; import DeleteAccountModal from "@/components/Profile/DeleteAccountModal"; +import ProfileImageConfirmModal from "@/components/Profile/ProfileImageConfirmModal"; function getProfilePhotoMessage(image_status) { switch (image_status) { @@ -33,7 +38,8 @@ function getProfilePhotoMessage(image_status) { } export default function HostProfilePage() { - const { dispatch: globalDispatch, state: globalState } = useContext(GlobalContext); + const { dispatch: globalDispatch, state: globalState } = + useContext(GlobalContext); const [loading, setLoading] = useState(false); const [twoFa, setTwoFa] = useState(false); const [twoFaDialog, setTwoFaDialog] = useState(false); @@ -49,20 +55,29 @@ export default function HostProfilePage() { const [deleteAccountModal, setDeleteAccountModal] = useState(false); + const [showImagePreview, setShowImagePreview] = useState(false); + const [selectedImage, setSelectedImage] = useState(null); + let sdk = new MkdSDK(); - const changeProfilePic = async (e) => { - globalDispatch({ type: "START_LOADING" }); - const file = e.target.files; - const formData = new FormData(); - for (let i = 0; i < file.length; i++) { - formData.append("file", file[i]); + const changeProfilePic = (e) => { + const file = e.target.files && e.target.files[0]; + if (file) { + setSelectedImage(file); + setShowImagePreview(true); } + }; + + const handleConfirmUpload = async () => { + setShowImagePreview(false); + if (!selectedImage) return; + globalDispatch({ type: "START_LOADING" }); + const formData = new FormData(); + formData.append("file", selectedImage); try { const upload = await sdk.uploadImage(formData); - console.log("upload", upload); sdk.setTable("user"); - const result = await callCustomAPI( + await callCustomAPI( "edit-self", "post", { @@ -71,9 +86,16 @@ export default function HostProfilePage() { is_photo_approved: IMAGE_STATUS.IN_REVIEW, }, }, - "", + "" ); - globalDispatch({ type: "SET_USER_DATA", payload: { ...globalState.user, photo: upload.url, is_photo_approved: IMAGE_STATUS.IN_REVIEW } }); + globalDispatch({ + type: "SET_USER_DATA", + payload: { + ...globalState.user, + photo: upload.url, + is_photo_approved: IMAGE_STATUS.IN_REVIEW, + }, + }); // create notification sdk.setTable("notification"); await sdk.callRestAPI( @@ -86,7 +108,7 @@ export default function HostProfilePage() { type: NOTIFICATION_TYPE.EDIT_USER_PICTURE, status: NOTIFICATION_STATUS.NOT_ADDRESSED, }, - "POST", + "POST" ); } catch (err) { globalDispatch({ @@ -98,9 +120,15 @@ export default function HostProfilePage() { }); } globalDispatch({ type: "STOP_LOADING" }); + setSelectedImage(null); }; - const removeProfilePic = async (e) => { + const handleCancelUpload = () => { + setShowImagePreview(false); + setSelectedImage(null); + }; + + const removeProfilePic = async () => { try { sdk.setTable("user"); await callCustomAPI( @@ -112,9 +140,12 @@ export default function HostProfilePage() { is_photo_approved: null, }, }, - "", + "" ); - globalDispatch({ type: "SET_USER_DATA", payload: { ...globalState.user, photo: null, is_photo_approved: null } }); + globalDispatch({ + type: "SET_USER_DATA", + payload: { ...globalState.user, photo: null, is_photo_approved: null }, + }); } catch (err) { globalDispatch({ type: "SHOW_ERROR", @@ -137,14 +168,16 @@ export default function HostProfilePage() { two_factor_authentication: twoFa != 1 ? 1 : 0, }, }, - "", + "" ); setTwoFaDialog(false); globalDispatch({ type: "SHOW_CONFIRMATION", payload: { heading: "Success", - message: `Two factor Authentication ${twoFa == 1 ? "disabled" : "enabled"}`, + message: `Two factor Authentication ${ + twoFa == 1 ? "disabled" : "enabled" + }`, btn: "Ok got it", }, }); @@ -163,51 +196,67 @@ export default function HostProfilePage() { } return ( -
-
-
-
-

Your photo

- {getProfilePhotoMessage(globalState.user.is_photo_approved)} +
+
+
+
+

Your photo

+ + {getProfilePhotoMessage(globalState.user.is_photo_approved)} +
+ data-tour='photo-step' + className='flex items-center justify-between' + >
-
-

Profile status

-
+
+

Profile status

+
{![0, 1].includes(globalState.user.verificationStatus) && ( Get verified @@ -215,7 +264,11 @@ export default function HostProfilePage() {
- -
-
+ +
+
Manage Property Rules Template Add Property Rules Template @@ -299,6 +352,16 @@ export default function HostProfilePage() { isOpen={enableEmailDialog} closeModal={() => setEnableEmailDialog(false)} /> +
); }