Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] #152 닉네임 수정 페이지 및 회원탈퇴 추가 #152

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@

<br />

> 서비스 바로가기 <br /> ( 현재 리팩토링중인 서비스입니다 :) 5월 출시를 기다려주세요! )


## [💗💗💗 서비스 바로가기 💗💗💗](https://www.moodmate.site/main)



<br/>

<p align=center>
<a href="https://plum-lightyear-dd5.notion.site/MoodMate-328ba219563f46118193cd5d7a5acf8f?pvs=4">팀 노션</a>
&nbsp; | &nbsp;
<a href="https://github.com/orgs/Leets-Official/projects/2">백로그</a>
&nbsp; | &nbsp;
<a href="https://www.figma.com/file/Pf9BoSgENbbP5DgxTFz7sg/MM-Design?node-id=1%3A2&mode=dev">figma</a>
<br />

<div align=center>
<a href="https://hits.seeyoufarm.com"><img src="https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FLeets-Official%2FMoodMate-FE&count_bg=%23333333&title_bg=%23FC4F59&icon=&icon_color=%23FC4F59&title=hits&edge_flat=false)](https://hits.seeyoufarm.com"/></a>
Expand Down
2 changes: 1 addition & 1 deletion public/sw.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/app/(route)/mypage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default function MyPage() {
userNickname={userNickname}
year={year}
userDepartment={userDepartment}
preferMood={preferMood}
/>
<MypageSecondBoxContainer
userKeywords={userKeywords}
Expand Down
8 changes: 8 additions & 0 deletions src/app/_atom/userinfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,11 @@ export const editUserInfoState = atom<EditUserInfoData>({
preferMood: '',
},
})

export const editUserNickname = atom({
key: 'editUserNickname',
default: {
isNicknameEdit: false,
userNickname: '',
},
})
128 changes: 128 additions & 0 deletions src/app/_components/information/EditNickname.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
'use client'

import { useState } from 'react'
import Input from '../common/Input'
import { INPUT_NICKNAME, NICK_NAME_PAGE } from '@/_constants/info'
import { useRecoilState } from 'recoil'
import { editUserNickname } from '@/_atom/userinfo'
import { useMutation } from '@tanstack/react-query'
import { postCheckNickname } from '@/_service/mypage'
import { putUserNickname } from '@/_service/userinfo'
import Icons from '../common/Icons'
import { exit } from '@/_ui/IconsPath'

interface EditNicknameProps {
userNickname: string
preferMood: string
userGender: string
}

const EditNickname = ({
userNickname,
preferMood,
userGender,
}: EditNicknameProps) => {
const [inputValue, setInputValue] = useState(userNickname)
const [inputCount, setinputCount] = useState(`${userNickname.length}/5`)
const [editUserInfo, setEditUserInfoState] = useRecoilState(editUserNickname)
const [canUseNickname, setCanUseNickname] = useState(false)

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value.slice(0, INPUT_NICKNAME.MAX)
const koeranOnly = /^[ㄱ-ㅎㅏ-ㅣ가-힣]*$/g
if (!koeranOnly.test(newValue)) {
alert('한글만 입력 가능합니다.')
} else {
setInputValue(newValue)
setEditUserInfoState({ ...editUserInfo, userNickname: newValue })
setinputCount(`${newValue.length}/${INPUT_NICKNAME.MAX}`)
}
}

const inputStyles = {
defaultStyles: 'bg-lightgray',
activeStyles: 'bg-primary',
}

const postUserDataMutation = useMutation({
mutationFn: () =>
postCheckNickname(editUserInfo.userNickname, preferMood, userGender),
onSuccess: () => {},
onError: () => alert('다시 시도해 주세요.'),
})

const putUserNicknameMutation = useMutation({
mutationFn: () => putUserNickname(editUserInfo.userNickname),
onSuccess: () => {
//window.location.href = '/mypage'
},
onError: () => alert('다시 시도해 주세요.'),
})

const checkCanUseNickname = () => {
console.log(editUserInfo.userNickname, preferMood, userGender)
const response = postUserDataMutation.mutate()
console.log(response)
setCanUseNickname(true)
}

const changeNickname = () => {
console.log(editUserInfo.userNickname)
const response = putUserNicknameMutation.mutate()
console.log(response)
}

return (
<div className="w-[100%] mt-4 flex-col">
<div className="w-full flex justify-between items-center px-2">
<Input
sort="info"
textValue={inputValue}
placeholder={NICK_NAME_PAGE.INPUTBOX}
onChange={handleInputChange}
className="w-[73%] text-sm placeholder:text-secondary placeholder:text-xs placeholder:leading-[174%] focus:outline-none"
/>
<span className="block text-sm w-7 relative text-secondary">
{inputCount}
</span>
</div>
<div
className={`w-full h-[2px] mt-[3px] rounded-[2.415px] ${
inputValue.length > 0
? inputStyles.activeStyles
: inputStyles.defaultStyles
}`}
/>
<div className="w-full text-xs px-2 text-black flex items-center justify-between mt-4">
<button
type="button"
className="w-[40%] py-1 rounded-md bg-gray-200"
onClick={() => checkCanUseNickname()}
>
중복확인
</button>
<button
type="button"
className={`w-[40%] py-1 rounded-md ${
canUseNickname ? 'text-primary bg-onepink' : 'bg-gray-200'
}`}
onClick={() => changeNickname()}
disabled={!canUseNickname}
>
수정하기
</button>
<div className="cursor-pointer">
<Icons
name={exit}
className="w-3 h-3"
onClick={() =>
setEditUserInfoState({ ...editUserInfo, isNicknameEdit: false })
}
/>
</div>
</div>
</div>
)
}

export default EditNickname
19 changes: 12 additions & 7 deletions src/app/_components/information/Profile.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
import femaleImage from 'public/illustration/female/mypage/myprofile.png'
import maleImage from 'public/illustration/male/mypage/myprofile.png'
import Image from 'next/image'
import UserNickname from './UserNickname'
import YearDept from './YearDept'

interface UserInfoProps {
userGender: string
userNickname: string
year: number
userDepartment: string
preferMood: string
}
const Profile = ({
userGender,
userNickname,
year,
userDepartment,
preferMood,
}: UserInfoProps) => {
const gender = userGender === 'MALE' ? maleImage : femaleImage
const age = year?.toString().slice(-2)

return (
<section className="flex flex-col">
<div className="mx-auto text-center">
<div className="mx-auto text-center flex flex-col items-center justify-center">
<Image src={gender} alt="gender" className="mt-4 w-[70px] h-[72px]" />
<p className="mt-4 text-[18px] font-bold">{userNickname}</p>
</div>
<div className="mt-3 justify-center px-4 pt-[4px] h-[30px] text-[14px] text-[#4D4D4D] flex mx-auto border border-[#4D4D4D] rounded-[25px]">
<p className="mr-3">{age}년생</p>
<p className="mr-3 ">|</p>
<p>{userDepartment}</p>
<UserNickname
userNickname={userNickname}
preferMood={preferMood}
userGender={userGender}
/>
</div>
<YearDept age={age} userDepartment={userDepartment} />
<div className="w-auto h-2 bg-lightgray mt-6" />
</section>
)
Expand Down
51 changes: 51 additions & 0 deletions src/app/_components/information/UserNickname.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use cleint'

import { useRecoilState } from 'recoil'
import EditNickname from './EditNickname'
import { editUserNickname } from '@/_atom/userinfo'
import Icons from '../common/Icons'
import { pencile } from '@/_ui/IconsPath'
import { useEffect } from 'react'

interface UserNicknameProps {
userNickname: string
preferMood: string
userGender: string
}

const UserNickname = ({
userNickname,
preferMood,
userGender,
}: UserNicknameProps) => {
const [editUserInfo, setEditUserInfoState] = useRecoilState(editUserNickname)
useEffect(() => {
setEditUserInfoState({ ...editUserInfo, isNicknameEdit: false })
}, [])
return (
<>
{!editUserInfo.isNicknameEdit ? (
<div className="w-full flex items-center justify-center">
<p className="mt-4 text-[18px] font-bold">{userNickname}</p>
<div className="flex flex-row mt-4 ml-2 items-center justify-center gap-3 cursor-pointer">
<Icons
name={pencile}
className="w-3 h-3"
onClick={() =>
setEditUserInfoState({ ...editUserInfo, isNicknameEdit: true })
}
/>
</div>
</div>
) : (
<EditNickname
userNickname={userNickname}
preferMood={preferMood}
userGender={userGender}
/>
)}
</>
)
}

export default UserNickname
23 changes: 23 additions & 0 deletions src/app/_components/information/YearDept.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client'

import { useRecoilValue } from 'recoil'
import { editUserNickname } from '@/_atom/userinfo'

interface YearDeptProps {
age: string
userDepartment: string
}
const YearDept = ({ age, userDepartment }: YearDeptProps) => {
const userInfo = useRecoilValue(editUserNickname)
return (
!userInfo.isNicknameEdit && (
<div className="mt-3 justify-center px-4 pt-[4px] h-[30px] text-[14px] text-[#4D4D4D] flex mx-auto border border-[#4D4D4D] rounded-[25px]">
<p className="mr-3">{age}년생</p>
<p className="mr-3 ">|</p>
<p>{userDepartment}</p>
</div>
)
)
}

export default YearDept
18 changes: 18 additions & 0 deletions src/app/_service/mypage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,21 @@ export const myPageInfo = async () => {
throw error
}
}

export const postCheckNickname = async (
nickname: string,
preferMood: string,
userGender: string,
) => {
try {
const requestBody = {
userNickname: nickname,
preferMood: preferMood,
userGender: userGender,
}
const response = await api.post('/mypage/nickname/check', requestBody)
return response.data
} catch (error) {
throw error
}
}
9 changes: 9 additions & 0 deletions src/app/_service/userinfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ const putEditUserInfo = async (editUserInfo: EditUserInfoData) => {
}
}

export const putUserNickname = async (userNickname: string) => {
try {
const response = await api.put('/mypage/nickname/change', userNickname)
return response.data
} catch (error) {
throw error
}
}

const postUserInfo = async (userInfo: UserInfoData) => {
try {
const response = await api.post('users/user-info', userInfo)
Expand Down
Loading