-
Notifications
You must be signed in to change notification settings - Fork 8
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
문의하기 모달 생성 #777
문의하기 모달 생성 #777
Changes from 7 commits
58faa60
1adf9ac
e82ea1f
ce6d6eb
ed8726a
ab27700
b7ff8b9
58d50ee
51d15d8
bb228c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
export const ContactUSButton = styled.button` | ||
cursor: pointer; | ||
`; | ||
|
||
export const Form = styled.form` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 1.25rem; | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { useInput, useInputWithValidate, useToggle } from '@/hooks'; | ||
import { useToast } from '@/hooks/useToast'; | ||
import { validateEmail } from '@/service/validates'; | ||
import { theme } from '@/style/theme'; | ||
|
||
import { Button, Input, Modal, Text, Textarea } from '..'; | ||
import * as S from './ContactUs.style'; | ||
|
||
const ContactUs = () => { | ||
const [isModalOpen, toggleModal] = useToggle(); | ||
const [message, handleMessage, resetMessage] = useInput(''); | ||
const { | ||
value: email, | ||
handleChange: handleEmail, | ||
resetValue: resetEmail, | ||
errorMessage: emailErrorMessage, | ||
} = useInputWithValidate('', validateEmail); | ||
|
||
const { failAlert, successAlert } = useToast(); | ||
|
||
const isValidContents = message.trim().length; | ||
|
||
const handleSubmit = (e: React.FormEvent<HTMLFormElement> | React.MouseEvent<HTMLButtonElement>) => { | ||
e.preventDefault(); | ||
|
||
if (!isValidContents || emailErrorMessage) { | ||
return; | ||
} | ||
|
||
submitForm(); | ||
}; | ||
|
||
const submitForm = async () => { | ||
const res = await sendData(); | ||
|
||
if (!res.ok) { | ||
failAlert('보내기에 실패했습니다. 계속 실패한다면 이메일로 제보 부탁드립니다.'); | ||
|
||
return; | ||
} | ||
|
||
successSubmit(); | ||
successAlert('보내기 완료! 소중한 의견 감사합니다:)'); | ||
}; | ||
|
||
const sendData = () => { | ||
const URL = process.env.GOOGLE_URL || ''; | ||
|
||
return fetch(URL, { | ||
method: 'POST', | ||
mode: 'no-cors', | ||
body: JSON.stringify({ message, email }), | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
}; | ||
Comment on lines
+46
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다음 부분에서 env 변수가 없을 때, 빈 문자열을 넣는게 아니라, 그냥 google URL을 넣어줘도 되지 않을까 했는데 해당 URL은 key인 건가요?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네네 특정 web app(구글 시트에 값을 넣어줄 수 있도록 구글에서 제공해주는 웹앱)의 url입니다! URL이 무조건 |
||
|
||
const successSubmit = () => { | ||
resetForm(); | ||
toggleModal(); | ||
}; | ||
|
||
const resetForm = () => { | ||
resetEmail(); | ||
resetMessage(); | ||
}; | ||
|
||
return ( | ||
<> | ||
<S.ContactUSButton onClick={toggleModal}> | ||
<Text.Medium weight='bold' color={theme.color.light.secondary_800}> | ||
문의하기 | ||
</Text.Medium> | ||
</S.ContactUSButton> | ||
<Modal isOpen={isModalOpen} toggleModal={toggleModal} size='large'> | ||
<Modal.Header>문의하기</Modal.Header> | ||
<Modal.Body> | ||
<S.Form onSubmit={handleSubmit}> | ||
<Text.Medium as='p' color={theme.color.light.secondary_500}> | ||
질문/피드백을 편하게 남겨주세요! 여러분의 의견은 더 나은 서비스를 만드는 데 큰 도움이 됩니다. <br /> | ||
이미지 등을 함께 보내실 경우 [email protected]으로 직접 이메일을 보내실 수 있습니다. | ||
</Text.Medium> | ||
<Textarea id='voc' variant='outlined'> | ||
<Textarea.Label htmlFor={'voc'}>무엇을 도와드릴까요?</Textarea.Label> | ||
<Textarea.TextField minRows={5} maxRows={10} value={message} onChange={handleMessage} /> | ||
</Textarea> | ||
<Text.Medium as='p' color={theme.color.light.secondary_500}> | ||
답변이 필요하시면 아래 이메일 주소를 남겨주세요. 이메일은 오직 답변을 위해서만 사용됩니다 :) | ||
</Text.Medium> | ||
<Input variant='outlined' isValid={!emailErrorMessage}> | ||
<Input.Label>이메일 (선택)</Input.Label> | ||
<Input.TextField value={email} onChange={handleEmail} /> | ||
<Input.HelperText>{emailErrorMessage}</Input.HelperText> | ||
</Input> | ||
</S.Form> | ||
</Modal.Body> | ||
<Modal.Footer> | ||
<Button onClick={toggleModal} variant='outlined'> | ||
닫기 | ||
</Button> | ||
<Button disabled={isValidContents && !emailErrorMessage ? false : true} onClick={handleSubmit}> | ||
보내기 | ||
</Button> | ||
</Modal.Footer> | ||
</Modal> | ||
</> | ||
); | ||
}; | ||
|
||
export default ContactUs; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import { Text } from '@/components'; | ||
import { ContactUs, Text } from '@/components'; | ||
import { useAuth } from '@/hooks/authentication'; | ||
|
||
import * as S from './Footer.style'; | ||
|
@@ -19,11 +19,8 @@ const Footer = () => { | |
</Text.Small>{' '} | ||
© All rights reserved. | ||
</Text.Small> | ||
<S.ContactEmail href='mailto:[email protected]'> | ||
<Text.Small color='inherit' weight='bold'> | ||
문의 : | ||
</Text.Small>{' '} | ||
<Text.Small color='inherit'>[email protected]</Text.Small>{' '} | ||
<S.ContactEmail> | ||
<ContactUs /> | ||
Comment on lines
-22
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
</S.ContactEmail> | ||
</S.FooterContainer> | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ import { useEffect } from 'react'; | |
import { Link, useLocation } from 'react-router-dom'; | ||
|
||
import { CodeZapLogo, HamburgerIcon, PlusIcon } from '@/assets/images'; | ||
import { Button, Flex, Heading, Text } from '@/components'; | ||
import { Button, ContactUs, Flex, Heading, Text } from '@/components'; | ||
import { ToastContext } from '@/contexts'; | ||
import { useCustomContext, useCustomNavigate, useToggle } from '@/hooks'; | ||
import { useAuth } from '@/hooks/authentication/useAuth'; | ||
|
@@ -56,6 +56,7 @@ const Header = ({ headerRef }: { headerRef: React.RefObject<HTMLDivElement> }) = | |
<S.NavContainer> | ||
{!isChecking && isLogin && <NavOption route={END_POINTS.MY_TEMPLATES} name='내 템플릿' />} | ||
<NavOption route={END_POINTS.TEMPLATES_EXPLORE} name='구경가기' /> | ||
<ContactUs /> | ||
</S.NavContainer> | ||
<S.NavContainer> | ||
<S.MobileHiddenButton | ||
|
@@ -100,15 +101,23 @@ const Logo = () => ( | |
</Link> | ||
); | ||
|
||
const NavOption = ({ route, name }: { route: string; name: string }) => ( | ||
<Link to={route}> | ||
<S.NavOptionButton> | ||
<Text.Medium weight='bold' color={theme.color.light.secondary_800}> | ||
{name} | ||
</Text.Medium> | ||
</S.NavOptionButton> | ||
</Link> | ||
); | ||
const NavOption = ({ route, name }: { route: string; name: string }) => { | ||
const location = useLocation(); | ||
const isCurrentPage = location.pathname === route; | ||
|
||
return ( | ||
<Link to={route}> | ||
<S.NavOptionButton> | ||
<Text.Medium | ||
weight='bold' | ||
color={isCurrentPage ? theme.color.light.primary_500 : theme.color.light.secondary_800} | ||
> | ||
Comment on lines
+118
to
+121
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 색으로만 구분하니 직관적이지 않을 것 같아서, 색 말고 밑줄 혹은 색과 함께 밑줄까지 하면 어떨까요? |
||
{name} | ||
</Text.Medium> | ||
</S.NavOptionButton> | ||
</Link> | ||
); | ||
}; | ||
|
||
const LogoutButton = () => { | ||
const { mutateAsync } = useLogoutMutation(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사소하지만
isValidContents
변수명을 length가 들어가도록 바꾸거나, 아예 조건문을 넣어도 괜찮지 않을까 했습니다!is-로 시작하니
boolean
이면 좋지않을까 하는 생각이었어요.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아주 좋은 의견입니다.👍👍
isValidContents
을boolean
으로 사용하도록 조건문으로 변경하겠습니다~!