사용자 수정 상단 api,css :push
This commit is contained in:
@ -2,16 +2,26 @@ package com.eogns.board_back.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.eogns.board_back.dto.request.user.PatchNicknameRequestDto;
|
||||
import com.eogns.board_back.dto.request.user.PatchProfileImageRequestDto;
|
||||
import com.eogns.board_back.dto.response.user.GetSignInUserResponseDto;
|
||||
import com.eogns.board_back.dto.response.user.GetUserResponseDto;
|
||||
import com.eogns.board_back.dto.response.user.PatchNicknameResponseDto;
|
||||
import com.eogns.board_back.dto.response.user.PatchProfileImageResponseDto;
|
||||
import com.eogns.board_back.service.UserService;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.sound.midi.Patch;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
|
||||
|
||||
@ -39,5 +49,21 @@ public class UserController {
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@PatchMapping("/nickname")
|
||||
public ResponseEntity<? super PatchNicknameResponseDto> patchNickname(
|
||||
@RequestBody @Valid PatchNicknameRequestDto requestBody,
|
||||
@AuthenticationPrincipal String email
|
||||
) {
|
||||
ResponseEntity<? super PatchNicknameResponseDto> response = userService.patchNickname(requestBody, email);
|
||||
return response;
|
||||
}
|
||||
|
||||
@PatchMapping("/profile-image")
|
||||
public ResponseEntity<? super PatchProfileImageResponseDto> patchProfileImage(
|
||||
@RequestBody @Valid PatchProfileImageRequestDto requestBody,
|
||||
@AuthenticationPrincipal String email
|
||||
) {
|
||||
ResponseEntity<? super PatchProfileImageResponseDto> response = userService.patchProfileImage(requestBody, email);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,15 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon-box-large {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon-box-small {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
@ -241,3 +250,11 @@
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.edit-icon {
|
||||
background-image: url(assets/image/edit-light.png);
|
||||
}
|
||||
|
||||
.image-box-white-icon {
|
||||
background-image: url(assets/image/image-box-white-light.png);
|
||||
}
|
||||
|
BIN
board-front/src/assets/image/edit-light.png
Normal file
BIN
board-front/src/assets/image/edit-light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 377 B |
BIN
board-front/src/assets/image/image-box-white-light.png
Normal file
BIN
board-front/src/assets/image/image-box-white-light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
@ -1,9 +1,154 @@
|
||||
import React from "react";
|
||||
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
|
||||
import "./style.css";
|
||||
import DefaultProfileImage from "assets/image/default-profile-image.png";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
// component 유저 화면 //
|
||||
|
||||
export default function User() {
|
||||
// render 유저 화면 렌더링 //
|
||||
// component: 마이페이지 여부 상태 //
|
||||
const { userEmail } = useParams();
|
||||
|
||||
return <div>유저화면</div>;
|
||||
// component 유저 화면 상단 컴포넌트 //
|
||||
const UserTop = () => {
|
||||
// state: 이미지 파일 인풋 참조 상태 //
|
||||
const imageInputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
// state: 마이페이지 여부 상태 //
|
||||
const [isMyPage, setMyPage] = useState<boolean>(true);
|
||||
|
||||
// state: 닉네임 변경 여부 상태 //
|
||||
const [isNicknameChange, setNicknameChange] = useState<boolean>(false);
|
||||
|
||||
// state: 닉네임 상태 //
|
||||
const [nickname, setNickname] = useState<string>("");
|
||||
|
||||
// state: 닉네임 변경 상태 //
|
||||
const [changeNickname, setChangenickname] = useState<string>("");
|
||||
|
||||
// state: 프로필 이미지 상태 //
|
||||
const [profileImage, setProfileImage] = useState<string | null>(null);
|
||||
|
||||
// event handler: 프로필 박스 클릭 이벤트 처리 //
|
||||
const onProfileBoxClickHandler = () => {
|
||||
if (!isMyPage) return;
|
||||
if (!imageInputRef.current) return;
|
||||
imageInputRef.current.click();
|
||||
};
|
||||
|
||||
// event handler: 닉네임 수정 버튼 클릭 이벤트 처리 //
|
||||
const onNicknameEditButtonClickHandler = () => {
|
||||
setChangenickname(nickname);
|
||||
setNicknameChange(!isNicknameChange);
|
||||
};
|
||||
|
||||
// event handler: 프로필 이미지 변경 이벤트 처리 //
|
||||
const onProfileImageChangeHandler = (
|
||||
event: ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
if (!event.target.files || !event.target.files.length) return;
|
||||
|
||||
const file = event.target.files[0];
|
||||
const data = new FormData();
|
||||
data.append("file", file);
|
||||
};
|
||||
|
||||
// event handler: 닉네임 변경 이벤트 처리 //
|
||||
const onNicknameChangeHandler = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const { value } = event.target;
|
||||
setChangenickname(value);
|
||||
};
|
||||
|
||||
// effect: user email path variable 변경시 실행 할 함수 //
|
||||
useEffect(() => {
|
||||
if (!userEmail) return;
|
||||
setNickname("닉네임");
|
||||
/* setProfileImage(
|
||||
"https://d2u3dcdbebyaiu.cloudfront.net/uploads/atch_img/724/2329af2ecf5f9b4dc8846a398dbd8635_res.jpeg"
|
||||
); */
|
||||
}, [userEmail]);
|
||||
|
||||
// render 유저 화면 상단 렌더링 //
|
||||
return (
|
||||
<div id="user-top-wrapper">
|
||||
<div className="user-top-container">
|
||||
{isMyPage ? (
|
||||
<div
|
||||
className="user-top-my-profile-image-box"
|
||||
onClick={onProfileBoxClickHandler}
|
||||
>
|
||||
{profileImage !== null ? (
|
||||
<div
|
||||
className="user-top-profile-image"
|
||||
style={{ backgroundImage: `url(${profileImage})` }}
|
||||
></div>
|
||||
) : (
|
||||
<div className="icon-box-large">
|
||||
<div className="icon image-box-white-icon"></div>
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
ref={imageInputRef}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
style={{ display: "none" }}
|
||||
onChange={onProfileImageChangeHandler}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className="user-top-profile-image-box"
|
||||
style={{
|
||||
backgroundImage: `url(${
|
||||
profileImage ? profileImage : DefaultProfileImage
|
||||
})`,
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
<div className="user-top-info-box">
|
||||
<div className="user-top-info-nickname-box">
|
||||
{isMyPage ? (
|
||||
<>
|
||||
{isNicknameChange ? (
|
||||
<input
|
||||
className="user-top-info-nickname-input"
|
||||
type="text"
|
||||
size={nickname.length}
|
||||
value={changeNickname}
|
||||
onChange={onNicknameChangeHandler}
|
||||
/>
|
||||
) : (
|
||||
<div className="user-top-info-nickname">{nickname}</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className="icon-button"
|
||||
onClick={onNicknameEditButtonClickHandler}
|
||||
>
|
||||
<div className="icon edit-icon"></div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="user-top-info-nickname">{nickname}</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="user-top-info-email">{"eogns1@naver.com"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// component 유저 화면 하단 컴포넌트 //
|
||||
const UserBottom = () => {
|
||||
// render 유저 화면 하단 렌더링 //
|
||||
return <div></div>;
|
||||
};
|
||||
|
||||
// render 유저 화면 렌더링 //
|
||||
return (
|
||||
<>
|
||||
<UserTop />
|
||||
<UserBottom />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,99 @@
|
||||
#user-top-wrapper {
|
||||
padding: 40px 0 45px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.user-top-container {
|
||||
width: 1200px;
|
||||
min-width: 1200px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
.user-top-my-profile-image-box {
|
||||
border-radius: 50%;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
background-color: rgba(217, 217, 217, 1);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-top-profile-image {
|
||||
border-radius: 50%;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
background-position: 50% 50%;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.user-top-profile-image-box {
|
||||
border-radius: 50%;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
background-color: rgba(217, 217, 217, 1);
|
||||
background-position: 50% 50%;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.user-top-info-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.user-top-info-nickname-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.user-top-info-nickname {
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.user-top-info-email {
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.user-top-info-nickname-input {
|
||||
border: none;
|
||||
outline: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
|
||||
display: inline-block;
|
||||
padding-block: 0px;
|
||||
padding-inline: 0px;
|
||||
color: rgba(0, 0, 0, 1);
|
||||
|
||||
font-size: 22px;
|
||||
font-weight: 500;
|
||||
line-height: 140%;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
Reference in New Issue
Block a user