상세 컨텐츠

본문 제목

74일차 TIL( user info 수정 handler (if문))

TILs

by API284 2023. 9. 10. 23:56

본문

### my page의 user 정보 변경 tab에 있는 닉네임, 프로필 이미지 변경 handler이다 ###

 

몇 개의 validation check가 적용된다.

사용중인 닉네임과 중복 체크.

특수문자 포함할 수 없다.

네 글자 이하만 변경 가능하다.

 

이미지 핸들러는 input - file에 추가된 이미지가 미리보기로 화면에 렌더되며 "저장" 클릭시 supabase에 저장되며
user profile image가 변경 - 반영 된다.

 

  const handleSaveChanges = async () => {
    let nameChanged = false;
    let imageChanged = false;
    let alertMessages = [];

    const specialCharacters = /[!@#$%^&*()_+{}\[\]:;<>,.?~\\]/;

    if (newName.trim() !== '' && newName !== currentUser?.name) {
      if (newName.length <= 4) {
        if (!specialCharacters.test(newName)) {
          // 이름 중복 확인
          const { data: existingUsers, error: nameError } = await supabase
            .from('user')
            .select('name')
            .eq('name', newName);

          if (!nameError) {
            if (existingUsers.length === 0) {
              // 중복되는 닉네임이 없는 경우에만 변경 처리
              const { error: updateNameError } = await supabase
                .from('user')
                .update({ name: newName })
                .eq('id', currentUser?.id);

              if (!updateNameError) {
                const userData = await getUser(currentUser?.id ?? '');
                setCurrentUser(userData);
                setEditingName(false);
                nameChanged = true;
              } else {
                console.error(updateNameError);
                alertMessages.push('닉네임 변경 중 오류가 발생했습니다 :(');
              }
            } else {
              alertMessages.push('이미 사용 중인 닉네임입니다 :(');
            }
          } else {
            console.error(nameError);
            alertMessages.push('닉네임 변경 중 오류가 발생했습니다 :(');
          }
        } else {
          alertMessages.push('닉네임에는 특수문자를 포함할 수 없어요 :(');
        }
      } else {
        alertMessages.push('닉네임은 네 글자 이하로 입력해주세요 :(');
      }
    }
    // 나머지 조건에 대한 else 추가
    if (selectedImage) {
      try {
        const newFileName = randomFileName(selectedImage.name);
        const renamedFile = new File([selectedImage], newFileName);
        const { data } = await supabase.storage.from('images').upload(`profile/${renamedFile.name}`, renamedFile);
        if (data) {
          const imgUrl = data.path;
          await supabase.from('user').update({ avatar_url: imgUrl }).eq('id', currentUser?.id);
          // Fetch updated user data using getUser
          if (currentUser) {
            const userData = await getUser(currentUser?.id ?? '');
            setCurrentUser(userData);
            imageChanged = true;
          }
        }
      } catch (error) {
        console.error(error);
        alertMessages.push('프로필 사진 변경 중 오류가 발생했습니다! :)');
      }
    }

    if ((nameChanged || imageChanged) && alertMessages.length === 0) {
      // 변경된 내용이 있는 경우
      alertMessages.push('프로필 변경이 완료됐습니다! :)');
      setEditingName(false);
      setImageUploadVisible(false);
    } else if (!nameChanged && !imageChanged && alertMessages.length === 0) {
      // 변경된 내용이 없는 경우
      alertMessages.push('변경된 부분이 없어요! "취소" 버튼을 눌러주세요 :)');
    }

    alertMessages.forEach((message) => {
      toast.info(message, {
        className: 'custom-toast',
        theme: 'light'
      });
    });
  };

  // 닉네임 수정 handler
  const handleNameEdit = () => {
    setEditingName(true);
    setNewName(currentUser?.name || '');
    setSelectedImage(null);
    setImageUploadVisible(!imageUploadVisible);
  };
  // 수정 모드 해제
  const handleNameCancel = () => {
    setEditingName(false);
    setSelectedImage(null);
    setImageUploadVisible(!imageUploadVisible);
  };
  // 프로필 이미지 변경
  const handleImageInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      setSelectedImage(files[0]);
      setImageUploadVisible(true);
    } else {
      setSelectedImage(null); // 이미지를 선택하지 않은 경우에 null로 설정
      setImageUploadVisible(false);
    }
  };
  // 프로필 이미지 선택-미리보여주기
  const handleSectionChange = (e: React.MouseEvent<HTMLButtonElement>) => {
    const button = e.target as HTMLButtonElement;
    const section = button.getAttribute('data-section');
    if (section !== null) {
      setActiveSection(section);
    }
  };

 


사용자가 입력한 닉네임 변경 사항을 검증하고, 특수 문자, 닉네임 길이 등을 확인.
닉네임 중복 확인: 데이터베이스에서 이미 사용 중인 닉네임인지 확인하고, 중복이 없으면 변경된 닉네임을 업데이트.
프로필 사진 변경: 선택한 이미지를 업로드하고 사용자의 프로필 사진 URL을 업데이트.
변경 사항이 있고 오류가 없으면 성공 알림을 표시해 준다.
handleNameEdit 함수: 이 함수는 사용자의 닉네임을 수정하기 위해 호출됩니다. 수정 모드를 활성화하고 새 닉네임을 입력할 수 있는 상태를 설정.
handleNameCancel 함수: 이 함수는 수정 모드를 해제하고 변경된 내용을 취소하는 데 사용.
handleImageInputChange 함수: 이 함수는 사용자가 프로필 사진을 선택하면 호출되며. 선택한 이미지를 선택한 상태로 설정하고 이미지 업로드 모달을 표시.
handleSectionChange 함수: 이 함수는 사용자가 프로필 수정 섹션 중 하나를 선택할 때 호출하며 이벤트를 통해 선택한 섹션을 액티브 섹션으로 설정하여 해당 섹션을 표시.
유저 정보는 변경하고 상태를 취소할 수도 있다 !

 

 

관련글 더보기