From e0282001a3650b05ffc4c919d0d78e3f9f1b23aa Mon Sep 17 00:00:00 2001 From: amiparadis250 Date: Tue, 16 Jul 2024 13:16:21 +0200 Subject: [PATCH] fixing profile update --- src/app/(profile)/profile-edit/page.tsx | 106 ++++++++++++++++++----- src/components/EditProfile.tsx | 77 ++++++++++++---- src/components/InputBox.tsx | 3 +- src/components/profile/About.tsx | 14 +-- src/components/profile/ProfileHeader.tsx | 5 +- src/validations/userProfileSchema.ts | 10 ++- 6 files changed, 171 insertions(+), 44 deletions(-) diff --git a/src/app/(profile)/profile-edit/page.tsx b/src/app/(profile)/profile-edit/page.tsx index efb989c..3ba43f7 100644 --- a/src/app/(profile)/profile-edit/page.tsx +++ b/src/app/(profile)/profile-edit/page.tsx @@ -3,25 +3,34 @@ import React, { useEffect, useState, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { AppDispatch, RootState } from '@/redux/store'; import { getUserProfile, updateUserProfile } from '@/redux/slices/profileSlice'; -import Header from '@/components/Header'; -import Footer from '@/components/Footer'; -import InputBox from '@/components/InputBox'; + import { toast } from 'react-toastify'; import { showToast } from '@/helpers/toast'; import { useForm, SubmitHandler, useWatch } from 'react-hook-form'; -import { zodResolver } from '@hookform/resolvers/zod'; + import updateSchema from '@/validations/userProfileSchema'; import { useRouter } from 'next/navigation'; import type { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; + +import InputBox from '@/components/InputBox'; +import UpdatePasswords from '@/components/updatepassword'; +import Header from '@/components/Header'; +import Footer from '@/components/Footer'; +import { User, Cake, Award } from 'lucide-react' type FormSchemaType = z.infer; const UserProfileForm: React.FC = () => { + const route = useRouter(); + const [showlModal, setShowmodal] = useState(false); const dispatch = useDispatch(); const { user, loading, error } = useSelector( (state: RootState) => state.userProfile, ); - + const handleshow = () => { + setShowmodal(!showlModal); + }; const { register, handleSubmit, @@ -34,6 +43,7 @@ const UserProfileForm: React.FC = () => { firstName: '', lastName: '', phone: '', + address:'', birthDate: '', preferredLanguage: '', whereYouLive: '', @@ -68,7 +78,7 @@ const UserProfileForm: React.FC = () => { }, [user, setValue]); const handleImageChange = (e: React.ChangeEvent) => { - if (e.target.files && e.target.files.length === 1) { + if (e.target.files && e.target?.files?.length === 1) { const file = e.target.files[0]; setImageFile(file); const reader = new FileReader(); @@ -83,22 +93,36 @@ const UserProfileForm: React.FC = () => { fileInputRef.current?.click(); }; - const onSubmit: SubmitHandler = async (data) => { - if (!imageFile && !profileImage) { - toast.error( - 'Please select a profile image before updating your profile.', - ); - return; + const getExistingImage = async (): Promise => { + if (!user?.User?.profileImage) return null; + + try { + const response = await fetch(user.User.profileImage); + const blob = await response.blob(); + return new File([blob], 'profile_image.jpg', { type: blob.type }); + } catch (error) { + console.error('Error fetching existing image:', error); + return null; } + }; + const onSubmit: SubmitHandler = async (data) => { const formDataToSend = new FormData(); Object.entries(data).forEach(([key, value]) => { formDataToSend.append(key, value as string); }); + let imageToUpload: File | null = null; + if (imageFile) { - formDataToSend.append('profileImage', imageFile); + imageToUpload = imageFile; + } else { + imageToUpload = await getExistingImage(); + } + + if (imageToUpload) { + formDataToSend.append('profileImage', imageToUpload); } try { @@ -106,17 +130,16 @@ const UserProfileForm: React.FC = () => { const response = await dispatch(updateUserProfile(formDataToSend)); setIsLoading(false); if (updateUserProfile.fulfilled.match(response)) { - // Update only the User value in localStorage const currentProfile = JSON.parse( localStorage.getItem('profile') || '{}', ); if (response.payload && response.payload.User) { currentProfile.User = response.payload.User; - console.log('currentProfile', currentProfile); localStorage.setItem('profile', JSON.stringify(currentProfile)); } toast.success('Profile updated successfully'); + route.push('/profile'); } else if (updateUserProfile.rejected.match(response)) { const errorMessage: any = response.payload && @@ -147,9 +170,31 @@ const UserProfileForm: React.FC = () => { if (!user) { return
No user data available. Please try refreshing the page.
; } - + const getCurrentDate = () => { + const today = new Date(); + const year = today.getFullYear() - 10; + const month = String(today.getMonth() + 1).padStart(2, '0'); + const day = String(today.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + }; + function convertToNormalDate(isoTimestamp:any) { + const date = new Date(isoTimestamp); + const options:any = { year: 'numeric', month: 'long', day: 'numeric' }; + return date.toLocaleDateString('en-US', options); + } + function formatDate(dateString: string) { + // Parse the date string into a Date object + const date = new Date(dateString); + const year = date.getFullYear(); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const day = date.getDate().toString().padStart(2, '0'); + const formattedDate = `${day}-${month}-${year}`; + + return formattedDate; + } + return ( -
+
@@ -162,6 +207,10 @@ const UserProfileForm: React.FC = () => { src={profileImage} alt="Profile" onClick={handleImageClick} + onError={(e) => { + e.currentTarget.src = '/unknown.jpg'; + }} + /> { d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> - {watchedValues.birthDate || 'YYYY-MM-DD'} + {convertToNormalDate(watchedValues.birthDate) || watchedValues.birthDate || 'YYYY-MM-DD'}
  • { {watchedValues.phone || 'Contact Number'}
  • +
  • + +
  • @@ -302,6 +359,8 @@ const UserProfileForm: React.FC = () => { placeholder="Birth date" {...register('birthDate')} error={errors.birthDate?.message} + + max={getCurrentDate()} />
    @@ -309,8 +368,7 @@ const UserProfileForm: React.FC = () => { nameuse="Address" type="text" placeholder="Address" - {...register('whereYouLive')} - error={errors.whereYouLive?.message} + error ={errors.address?.message} />
    @@ -349,10 +407,11 @@ const UserProfileForm: React.FC = () => {
    +
    + +
    + +
    ); diff --git a/src/components/EditProfile.tsx b/src/components/EditProfile.tsx index a97e450..f8e50a6 100644 --- a/src/components/EditProfile.tsx +++ b/src/components/EditProfile.tsx @@ -15,7 +15,8 @@ import type { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import InputBox from '@/components/InputBox'; -import UpdatePasswords from './updatepassword'; +import UpdatePasswords from '@/components/updatepassword'; + type FormSchemaType = z.infer; const UserProfileForm: React.FC = () => { @@ -40,6 +41,7 @@ const UserProfileForm: React.FC = () => { firstName: '', lastName: '', phone: '', + address:'', birthDate: '', preferredLanguage: '', whereYouLive: '', @@ -89,22 +91,36 @@ const UserProfileForm: React.FC = () => { fileInputRef.current?.click(); }; - const onSubmit: SubmitHandler = async (data) => { - if (!imageFile && !profileImage) { - toast.error( - 'Please select a profile image before updating your profile.', - ); - return; + const getExistingImage = async (): Promise => { + if (!user?.User?.profileImage) return null; + + try { + const response = await fetch(user.User.profileImage); + const blob = await response.blob(); + return new File([blob], 'profile_image.jpg', { type: blob.type }); + } catch (error) { + console.error('Error fetching existing image:', error); + return null; } + }; + const onSubmit: SubmitHandler = async (data) => { const formDataToSend = new FormData(); Object.entries(data).forEach(([key, value]) => { formDataToSend.append(key, value as string); }); + let imageToUpload: File | null = null; + if (imageFile) { - formDataToSend.append('profileImage', imageFile); + imageToUpload = imageFile; + } else { + imageToUpload = await getExistingImage(); + } + + if (imageToUpload) { + formDataToSend.append('profileImage', imageToUpload); } try { @@ -112,7 +128,6 @@ const UserProfileForm: React.FC = () => { const response = await dispatch(updateUserProfile(formDataToSend)); setIsLoading(false); if (updateUserProfile.fulfilled.match(response)) { - // Update only the User value in localStorage const currentProfile = JSON.parse( localStorage.getItem('profile') || '{}', ); @@ -153,9 +168,32 @@ const UserProfileForm: React.FC = () => { if (!user) { return
    No user data available. Please try refreshing the page.
    ; } - + const getCurrentDate = () => { + const today = new Date(); + const year = today.getFullYear() - 10; + const month = String(today.getMonth() + 1).padStart(2, '0'); + const day = String(today.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + }; + function convertToNormalDate(isoTimestamp:any) { + const date = new Date(isoTimestamp); + const options:any = { year: 'numeric', month: 'long', day: 'numeric' }; + return date.toLocaleDateString('en-US', options); + } + function formatDate(dateString: string) { + // Parse the date string into a Date object + const date = new Date(dateString); + const year = date.getFullYear(); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const day = date.getDate().toString().padStart(2, '0'); + const formattedDate = `${day}-${month}-${year}`; + + return formattedDate; + } + return (
    +
    @@ -167,6 +205,10 @@ const UserProfileForm: React.FC = () => { src={profileImage} alt="Profile" onClick={handleImageClick} + onError={(e) => { + e.currentTarget.src = '/unknown.jpg'; + }} + /> { d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> - {watchedValues.birthDate || 'YYYY-MM-DD'} + {convertToNormalDate(watchedValues.birthDate) || watchedValues.birthDate || 'YYYY-MM-DD'}
  • {
  • @@ -315,6 +357,8 @@ const UserProfileForm: React.FC = () => { placeholder="Birth date" {...register('birthDate')} error={errors.birthDate?.message} + + max={getCurrentDate()} />
  • @@ -322,8 +366,7 @@ const UserProfileForm: React.FC = () => { nameuse="Address" type="text" placeholder="Address" - {...register('whereYouLive')} - error={errors.whereYouLive?.message} + error ={errors.address?.message} />
    @@ -384,7 +427,11 @@ const UserProfileForm: React.FC = () => {
    - +
    + +
    + +
    ); }; diff --git a/src/components/InputBox.tsx b/src/components/InputBox.tsx index fd98ff7..83ae73c 100644 --- a/src/components/InputBox.tsx +++ b/src/components/InputBox.tsx @@ -6,7 +6,8 @@ interface Properties { value?:string; placeholder?: string; error?: string; - name?: string; // Now optional + name?: string; + max?: any; // Now optional onChange?: (e: ChangeEvent) => void; } diff --git a/src/components/profile/About.tsx b/src/components/profile/About.tsx index 67bf79a..df38529 100644 --- a/src/components/profile/About.tsx +++ b/src/components/profile/About.tsx @@ -23,23 +23,27 @@ function About() { if (error) return
    Error: {error}
    ; if (!user) return
    No user found
    ; - + function convertToNormalDate(isoTimestamp:any) { + const date = new Date(isoTimestamp); + const options:any = { year: 'numeric', month: 'long', day: 'numeric' }; + return date.toLocaleDateString('en-US', options); + } const items: any = [ { icon: , - details: `${user.User?.birthDate}`, + details: `${convertToNormalDate(user.User?.birthDate) || user.User?.birthDate || 'YYYY-MM-DD'} `, }, { icon: , - details: `${user.User?.whereYouLive}`, + details: `${user.User?.whereYouLive || "Where You Live"}`, }, { icon: , - details: `${user.User?.email}`, + details: `${user.User?.email || 'email'} `, }, { icon: , - details: `${user.User?.phone}`, + details: `${user.User?.phone || 'Contact Number'}`, }, ]; diff --git a/src/components/profile/ProfileHeader.tsx b/src/components/profile/ProfileHeader.tsx index eaaed72..b9e06cf 100644 --- a/src/components/profile/ProfileHeader.tsx +++ b/src/components/profile/ProfileHeader.tsx @@ -92,8 +92,11 @@ function ProfileHeader() {
    Profile { + e.currentTarget.src = '/unknown.jpg'; + }} />
    diff --git a/src/validations/userProfileSchema.ts b/src/validations/userProfileSchema.ts index a6da366..8ba7483 100644 --- a/src/validations/userProfileSchema.ts +++ b/src/validations/userProfileSchema.ts @@ -28,8 +28,10 @@ birthDate: z.string().optional(), .max(70, "No more than 70 characters for preferredLanguage"), whereYouLive: z .string({ required_error: "Where you live is required" }) - .min(3, "Use at least 3 characters for whereYouLive") .max(70, "No more than 70 characters for whereYouLive"), + address: z + .string({ required_error: "Address is required" }) + .max(70, "No more than 70 characters for Adress"), preferredCurrency: z .string({ required_error: "Preferred Currency is required" }) .min(2, "Use at least 2 characters for preferredCurrency") @@ -41,3 +43,9 @@ birthDate: z.string().optional(), }); export default updateSchema; + + + + + +