diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml
index a0a5cf94..68cfb9bf 100644
--- a/.github/workflows/deployment.yml
+++ b/.github/workflows/deployment.yml
@@ -37,7 +37,4 @@ jobs:
aws-region: ${{ secrets.AWS_REGION }}
- name: Deploy to S3
- run: aws s3 sync ./client/build s3://${{ secrets.DEV_AWS_S3_BUCKET }} --delete
-
- - name: Invalidate CloudFront Cache
- run: aws cloudfront create-invalidation --distribution-id ${{secrets.DEV_AWS_DISTRIBUTION_ID}} --paths "/*"
+ run: aws s3 sync ./client/build s3://${{ secrets.DEV_AWS_S3_BUCKETNAME }} --delete
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index 05d9c43e..3b8ef2dd 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -17,7 +17,7 @@ permissions:
contents: read
env:
- S3_BUCKET_NAME: 004-s3-bucket
+ S3_BUCKET_NAME: fe-004-s3-bucket
jobs:
build:
diff --git a/client/public/index.html b/client/public/index.html
index f08253ed..2822e8a5 100644
--- a/client/public/index.html
+++ b/client/public/index.html
@@ -12,7 +12,7 @@
/>
{
)
}
-
const InputWrapper = styled.div`
- height: 6rem;
flex: 1;
`
diff --git a/client/src/components/Common/Radio.tsx b/client/src/components/Common/Radio.tsx
index 1643f4f9..903e8166 100644
--- a/client/src/components/Common/Radio.tsx
+++ b/client/src/components/Common/Radio.tsx
@@ -10,7 +10,7 @@ const Radio = (props: radioProps) => {
{radioArray.map((i) => (
-
+
{
onChange={onChange}
/>
{i.label}
-
+
))}
@@ -30,22 +30,26 @@ const Radio = (props: radioProps) => {
const RadioWrapper = styled.div`
display: flex;
flex-wrap: wrap;
- gap: 2rem;
+ gap: 1rem;
+ row-gap: 2rem;
+
+ input[type='radio'] {
+ display: none;
+ }
- input[type='radio'],
input[type='radio']:checked + label {
- color: var(--color-point);
- accent-color: var(--color-point);
+ color: var(--color-white);
+ background-color: var(--color-primary);
font-weight: 600;
+ transition: all 0.1s;
}
+`
- .radio-div {
- margin-top: 0.8rem;
- }
+const RadioInputWrapper = styled.div`
+ margin-top: 1rem;
`
const Legend = styled.legend`
- display: inline-block;
margin: 0 0 0.4rem 0.4rem;
font-size: 1.4rem;
font-weight: 700;
@@ -53,6 +57,11 @@ const Legend = styled.legend`
const StyledLabel = styled.label`
font-size: 1.4rem;
+ color: var(--color-secondary);
+ border: 1px solid var(--color-secondary);
+ border-radius: 1rem;
+ padding: 0.8rem 1rem;
+ cursor: pointer;
`
export default Radio
diff --git a/client/src/components/Common/Tab.tsx b/client/src/components/Common/Tab.tsx
index 1774ab72..3157785a 100644
--- a/client/src/components/Common/Tab.tsx
+++ b/client/src/components/Common/Tab.tsx
@@ -15,7 +15,7 @@ const Tab = ({ tabItem }: TabMenus) => {
}, [])
return (
-
+ <>
{tabItem.map((i, idx) => (
{
-
+ >
)
}
@@ -52,6 +52,7 @@ const TabLink = styled(Link)`
}
`
const SubpageContainer = styled.div`
+ width: 100%;
min-height: 30rem;
padding: 2.6rem;
border: 1px solid var(--color-light-gray);
diff --git a/client/src/components/User/ChangePwd.tsx b/client/src/components/User/ChangePwd.tsx
index 61b9ce6e..36e9a386 100644
--- a/client/src/components/User/ChangePwd.tsx
+++ b/client/src/components/User/ChangePwd.tsx
@@ -106,38 +106,36 @@ const ChangePwd = () => {
return (
<>
-
-
-
+
{
)
}
-const Wrapper = styled.div`
- width: 63.7rem;
- min-height: 40rem;
-
- @media ${({ theme }) => theme.device.tablet} {
- width: 88vw;
- }
-`
-
const Form = styled.form`
- width: 35rem;
+ width: 40rem;
display: flex;
flex-direction: column;
gap: 1rem;
@@ -168,6 +157,15 @@ const Form = styled.form`
> button {
margin-top: 0.8rem;
}
+
+ @media ${({ theme }) => theme.device.tablet} {
+ width: 80%;
+ min-width: 20rem;
+ }
+
+ @media ${({ theme }) => theme.device.mobile} {
+ width: 100%;
+ }
`
export default ChangePwd
diff --git a/client/src/components/User/EditProfile.tsx b/client/src/components/User/EditProfile.tsx
index 0b3c2e0a..e1cf092e 100644
--- a/client/src/components/User/EditProfile.tsx
+++ b/client/src/components/User/EditProfile.tsx
@@ -14,7 +14,7 @@ import { useSelector, useDispatch } from 'react-redux'
import { RootState } from '../../store'
import { getCookie } from '../../utils/Cookie'
import { __editUser } from '../../store/slices/profileSlice'
-import { userLogout } from '../../utils/userfunc'
+import { userLogout, checkDate, checkNumber } from '../../utils/userfunc'
interface noticeType {
nickName: string
@@ -73,6 +73,24 @@ const EditProfile = () => {
const { name, value } = e.target
setProfile({ ...profile, [name]: value })
+
+ if (name === 'birth') {
+ if (!checkDate(value)) {
+ setNotice({ ...notice, birth: '유효하지 않은 생년월일입니다.' })
+ } else {
+ setProfile({ ...profile, birth: value })
+ setNotice({ ...notice, birth: '' })
+ }
+ }
+
+ if (name === 'height' || name === 'weight') {
+ if (!checkNumber(value)) {
+ setNotice({ ...notice, [name]: '유효하지 않은 값입니다.' })
+ } else {
+ setProfile({ ...profile, [name]: Number(value) })
+ setNotice({ ...notice, [name]: '' })
+ }
+ }
}
// 닉네임 중복 확인
@@ -118,13 +136,18 @@ const EditProfile = () => {
// 프로필 수정
const updateProfile = () => {
+ console.log(profile)
const msg = { nickName: '', weight: '', height: '', birth: '' }
let isBlank = false
- for (const key in profile) {
- if (profile[key] === '') {
- isBlank = true
- }
+ // for (const key in profile) {
+ // if (profile[key] === '') {
+ // isBlank = true
+ // }
+ // }
+
+ if (notice.birth !== '' || notice.weight !== '' || notice.height !== '') {
+ isBlank = true
}
if ((isActive && nameCheck === cantUse) || nameCheck !== nickName) {
@@ -132,18 +155,8 @@ const EditProfile = () => {
return
}
- if (weight <= 0 && weight >= 500) {
- msg.weight = '유효하지 않은 값입니다.'
- }
- if (height <= 0 && height >= 300) {
- msg.height = '유효하지 않은 값입니다.'
- }
- if (birth === '') {
- msg.birth = '생년월일을 입력해주세요.'
- }
-
if (isBlank) {
- setNotice({ ...notice, ...msg })
+ openModal('입력값을 확인해주세요.')
} else {
axios
.patch(
@@ -175,7 +188,7 @@ const EditProfile = () => {
}
// 회원탈퇴
- const deleteUser = () => {
+ const deleteUser = async () => {
setDel(false)
openModal(
'회원 탈퇴가 완료되었습니다. \n그동안 라이팅을 이용해주셔서 감사합니다.'
@@ -202,102 +215,95 @@ const EditProfile = () => {
return (
<>
-
-
-
-
-
-
-
-
- {!isActive ? (
-
-
-
- ) : (
-
-
-
- )}
-
-
-
-
+
+
+
+
+
+
-
+ {!isActive ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
theme.device.tablet} {
- width: 88vw;
- }
-`
const GridContainer = styled.div`
display: grid;
@@ -345,6 +346,14 @@ const GridContainer = styled.div`
@media ${({ theme }) => theme.device.tablet} {
grid-template-columns: none;
+
+ .flex-div {
+ flex-direction: column;
+
+ button {
+ top: 0;
+ }
+ }
}
`
diff --git a/client/src/components/User/TabFrame.tsx b/client/src/components/User/TabFrame.tsx
index c5d1e6f2..2f98dc3d 100644
--- a/client/src/components/User/TabFrame.tsx
+++ b/client/src/components/User/TabFrame.tsx
@@ -11,7 +11,7 @@ const TabFrame = ({ title, children }: propType) => {
{title}
- {children}
+ {children}
)
}
@@ -28,4 +28,8 @@ const Container = styled.div`
}
`
+const Wrapper = styled.div`
+ min-height: 40rem;
+`
+
export default TabFrame
diff --git a/client/src/pages/NotFound.tsx b/client/src/pages/NotFound.tsx
index 367cd555..4e4d9894 100644
--- a/client/src/pages/NotFound.tsx
+++ b/client/src/pages/NotFound.tsx
@@ -62,7 +62,7 @@ const Icon = styled.span`
`
const ErrorWrapper = styled.div`
- width: 55srem;
+ width: 55rem;
text-align: center;
h1 {
diff --git a/client/src/pages/UserFindPwd.tsx b/client/src/pages/UserFindPwd.tsx
index f29668ac..9c15fdd2 100644
--- a/client/src/pages/UserFindPwd.tsx
+++ b/client/src/pages/UserFindPwd.tsx
@@ -269,13 +269,28 @@ const Container = styled.div`
.flex-div {
width: 100%;
- display: flex;
- align-items: flex-center;
+ display: grid;
+ grid-template-columns: 2fr 1.2fr;
gap: 0.6rem;
button {
+ width: 100%;
position: relative;
- top: 2rem;
+ top: 1.8rem;
+ }
+ }
+
+ @media ${({ theme }) => theme.device.mobile} {
+ width: 100%;
+ padding: 2rem 1.8rem;
+
+ .flex-div {
+ grid-template-columns: 1fr;
+
+ button {
+ width: 100%;
+ position: relative;
+ top: 0;
}
}
`
diff --git a/client/src/pages/UserPage.tsx b/client/src/pages/UserPage.tsx
index 46b28b53..f96d581a 100644
--- a/client/src/pages/UserPage.tsx
+++ b/client/src/pages/UserPage.tsx
@@ -53,16 +53,19 @@ const UserPage = () => {
-
+
+
+
)
}
const Container = styled.div`
+ width: 100%;
max-width: 88rem;
`
@@ -108,7 +111,14 @@ const UserProfile = styled.div`
margin-bottom: 2rem;
}
- @media screen and (max-width: 500px) {
+ @media ${({ theme }) => theme.device.mobile} {
+ flex-direction: column;
+ gap: 2rem;
+
+ img {
+ width: 9rem;
+ height: 9rem;
+ }
}
`
diff --git a/client/src/pages/UserSignIn.tsx b/client/src/pages/UserSignIn.tsx
index 547b5b4a..52391794 100644
--- a/client/src/pages/UserSignIn.tsx
+++ b/client/src/pages/UserSignIn.tsx
@@ -55,17 +55,13 @@ const UserSignIn = () => {
setCookie('access', tokenWithNoBearer, {
path: '/',
- secure: true,
expires: current,
- sameSite: 'none',
})
current.setMinutes(current.getMinutes() + 1440)
setCookie('refresh', tokenForReissue, {
path: '/',
- secure: true,
expires: current,
- sameSite: 'none',
})
})
.catch((error) => {
@@ -151,6 +147,11 @@ const Container = styled.div`
span {
font-size: 1.2rem;
}
+
+ @media ${({ theme }) => theme.device.mobile} {
+ width: 100%;
+ padding: 2rem 1.8rem;
+ }
`
const Logo = styled.div`
diff --git a/client/src/pages/UserSignUp.tsx b/client/src/pages/UserSignUp.tsx
index eb07f3a9..856b6d3b 100644
--- a/client/src/pages/UserSignUp.tsx
+++ b/client/src/pages/UserSignUp.tsx
@@ -4,13 +4,12 @@ import Input from '../components/Common/Input'
import Button from '../components/Common/Button'
import Radio from '../components/Common/Radio'
import { genderList, activityScore } from '../utils/options'
-import { checkEmail, checkPassword } from '../utils/userfunc'
-import { ApiCaller } from '../utils/apiCaller'
import {
- dtoReqEmailCheck,
- dtoReqVerifyEmail,
-} from '../dto/membership/members/dtoSignup'
-import { dtoResponse } from '../dto'
+ checkEmail,
+ checkPassword,
+ checkDate,
+ checkNumber,
+} from '../utils/userfunc'
import { debounce } from '../utils/timefunc'
import axios from 'axios'
import Modal from '../components/Common/Modal'
@@ -28,8 +27,8 @@ interface userInfo {
password: string
gender: string
activity: string
- height: number
- weight: number
+ height: string
+ weight: string
birth: string
}
@@ -39,11 +38,15 @@ interface authentication {
}
interface errorType {
+ [key: string]: any
email: string
auth: string
nickName: string
password: string
- ckPassword: string
+ passwordcheck: string
+ birth: string
+ weight: string
+ height: string
}
interface successType {
@@ -59,8 +62,8 @@ const UserSignUp = ({ social }: Props) => {
password: '',
gender: 'male',
activity: 'NONE_ACTIVE',
- height: 0,
- weight: 0,
+ height: '',
+ weight: '',
birth: '',
})
@@ -78,7 +81,10 @@ const UserSignUp = ({ social }: Props) => {
auth: '',
nickName: '',
password: '',
- ckPassword: '',
+ passwordcheck: '',
+ birth: '',
+ weight: '',
+ height: '',
})
const [success, setSuccess] = useState({
@@ -103,17 +109,59 @@ const UserSignUp = ({ social }: Props) => {
}
// 사용자 입력값 핸들링
- const handleInput = (e: React.ChangeEvent) => {
+ const handleInput = debounce((e: React.ChangeEvent) => {
const { name, value } = e.target
- setValues({ ...values, [name]: value })
- }
+ // 인증번호
+ if (name === 'ckAuth') {
+ setAuthNums({ ...authNums, ckAuth: value })
+ }
- const handleAuthNum = (e: React.ChangeEvent) => {
- const { name, value } = e.target
+ // 신장, 체중
+ if (name === 'height' || name === 'weight') {
+ if (!checkNumber(value)) {
+ setError({ ...error, [name]: '유효하지 않은 값입니다.' })
+ } else {
+ setValues({ ...values, [name]: Number(value) })
+ setError({ ...error, [name]: '' })
+ }
+ }
- setAuthNums({ ...authNums, [name]: value })
- }
+ // 비밀번호
+ if (name === 'password') {
+ if (!checkPassword(value)) {
+ setError({
+ ...error,
+ [name]:
+ '최소 8자, 영문+숫자+특수문자(!@#$%&*?) 조합으로 구성되어야 합니다.',
+ })
+ } else {
+ setValues({ ...values, [name]: value })
+ setError({ ...error, [name]: '' })
+ }
+ }
+
+ if (name === 'passwordcheck') {
+ setCkPassword(value)
+ }
+
+ // 생년월일
+ if (name === 'birth') {
+ if (!checkDate(value)) {
+ setError({
+ ...error,
+ [name]: '유효하지 않은 생년월일입니다.',
+ })
+ } else {
+ setValues({ ...values, [name]: value })
+ setError({ ...error, [name]: '' })
+ }
+ }
+
+ if (name) {
+ setValues({ ...values, [name]: value })
+ }
+ }, 300)
// 인증번호 전송
const sendNumbers = async (email: string) => {
@@ -247,47 +295,40 @@ const UserSignUp = ({ social }: Props) => {
})
}
- // 비밀번호 유효성 검사
- const isValidPassword = () => {
- const msg = { password: '', ckPassword: '' }
-
- if (!checkPassword(password)) {
- msg.password =
- '최소 8자, 영문+숫자+특수문자(!@#$%&*?) 조합으로 구성되어야 합니다.'
- setError({ ...error, ...msg })
- } else if (password !== ckPassword) {
- msg.ckPassword = '비밀번호가 일치하지 않습니다.'
- setError({ ...error, ...msg })
- } else {
- setError({ ...error, ...msg })
- }
- }
-
// 버튼 활성화를 위한 입력값 검증
const checkValues = useCallback(
- debounce((values: userInfo, isConfirm: boolean, ckpwd: string) => {
+ debounce((values: userInfo, isConfirm: boolean) => {
let isBlank = false
+ let isNotError = true
let isNotValid = true
+ for (const key in error) {
+ if (error[key] !== '') {
+ isNotError = false
+ break
+ }
+ }
+
for (const key in values) {
if (values[key] === '') {
isBlank = true
+ break
}
}
if (
!isBlank &&
+ isNotError &&
isConfirm &&
- ckpwd === values.password &&
- values.height > 0 &&
- values.weight > 0
+ values.passwordcheck === values.password
) {
isNotValid = false
}
+ console.log(values)
setIsEmpty(isNotValid)
- }, 700),
- []
+ }, 300),
+ [error]
)
// 가입하기 - 모든 값이 유효한 경우 버튼 활성화
@@ -298,9 +339,18 @@ const UserSignUp = ({ social }: Props) => {
return
}
+ const convertedUserinfo = {
+ ...values,
+ weight: Number(values.weight),
+ height: Number(values.height),
+ }
+
axios
- .post(`${process.env.REACT_APP_SERVER_URL}/members/signup`, values)
- .then((response) => {
+ .post(
+ `${process.env.REACT_APP_SERVER_URL}/members/signup`,
+ convertedUserinfo
+ )
+ .then(() => {
openModal('회원가입이 완료되었습니다. \n로그인 페이지로 이동합니다.')
})
.catch((error) => {
@@ -311,8 +361,8 @@ const UserSignUp = ({ social }: Props) => {
}
useEffect(() => {
- checkValues(values, isConfirm, ckPassword)
- }, [values, isConfirm, ckPassword])
+ checkValues(values, isConfirm)
+ }, [values, ckPassword, isConfirm])
return (
<>
@@ -331,7 +381,7 @@ const UserSignUp = ({ social }: Props) => {
disabled={isConfirm}
onChange={handleInput}
/>
-
+