Skip to content

Commit

Permalink
Feat: 비회원이 회원전용 기능에 접근 시 로그인 페이지로 유도하는 Alert 추가 (#95)
Browse files Browse the repository at this point in the history
* fix: 에러 수정

- 포스트 수정 시 원본 이미지가 보이지 않는 문제
- 포스트 작성, 수정 시 채널 포스트 리스트 refetch

* Feat: 포스트 수정, 삭제 중 이탈 시 Alert 표시

* Fix: 게시글 수정 시 포스트가 복제되는 문제

* Feat: 비회원 Alert 메세지 상수 저장

* Refactor: Alert 컴포넌트 onChangeOpen 선택 속성 변경, 메세지 가운데 정렬

* Refactor: 재사용을 위한 알림 타입 분리

* Feat: 비회원이 글 작성, 팔로우, 좋아요, 댓글, 디엠 기능 클릭 시 로그인 페이지로 유도하는 Alert(confirm모드) 추가

* Fix: 비회원으로 글 작성 시도할 때 Tab 이전 위치로 돌아가도록 설정

* Refactor: Alert 기본 메세지 글자 크기 증가, useResize 추가하여 내부에서 자체적으로 디폴트 값 scale하도록 변경

---------

Co-authored-by: Jaewoong Hwang <[email protected]>
  • Loading branch information
kim-hyunjoo and Jaeppetto authored Jan 17, 2024
1 parent d8583fa commit c79eed8
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 36 deletions.
4 changes: 4 additions & 0 deletions src/Components/Base/Input/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export const StyledInput = styled.input<{ $invalid?: boolean }>`
outline: none;
border-bottom: 3px solid ${({ theme }) => theme.colors.backgroundReverse};
}
&:disabled {
cursor: not-allowed;
}
`;

export const StyledErrorMessage = styled.p`
Expand Down
37 changes: 29 additions & 8 deletions src/Components/Common/Alert/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useTheme } from 'styled-components';
import Button from '@/Components/Base/Button';
import Modal from '../Modal';
import {
Expand All @@ -6,6 +7,7 @@ import {
StyledMessage,
} from './style';
import { AlertPropsType } from './type';
import useResize from '@/Hooks/useResize';

/**
* @param message Alert에 띄우고 싶은 메시지를 입력하세요.
Expand All @@ -14,35 +16,42 @@ import { AlertPropsType } from './type';
* @param mode alert, confirm 2가지 모드를 제공합니다.
*/
const Alert = ({
width = 20,
height = 15,
width = 30,
height = 20,
message,
fontSize = 1,
fontSize = 1.3,
confirmContent = 'OK',
cancleContent = 'CANCEL',
mode = 'alert',
onChangeOpen,
onConfirm,
onCancle,
onChangeOpen,
}: AlertPropsType) => {
const { isMobileSize } = useResize();
const { colors } = useTheme();

const handleConfirm = () => {
if (onConfirm) {
onConfirm();
}
onChangeOpen(false);
if (onChangeOpen) {
onChangeOpen(false);
}
};

const handleCancle = () => {
if (onCancle) {
onCancle();
}
onChangeOpen(false);
if (onChangeOpen) {
onChangeOpen(false);
}
};

return (
<Modal
width={width}
height={height}
width={isMobileSize && width <= 40 ? width * 1.5 : width}
height={isMobileSize && height <= 30 ? height * 1.2 : height}
onChangeOpen={onChangeOpen}
>
<StyledAlertWrapper>
Expand All @@ -51,13 +60,25 @@ const Alert = ({
<Button
height="30"
onClick={handleConfirm}
textSize={`${fontSize}rem`}
style={{
marginRight: '1rem',
marginTop: '.5rem',
border: `1px solid ${colors.text}`,
}}
>
{confirmContent}
</Button>
{mode === 'confirm' && (
<Button
height="30"
onClick={handleCancle}
textSize={`${fontSize}rem`}
style={{
marginRight: '1rem',
marginTop: '.5rem',
border: `1px solid ${colors.text}`,
}}
>
{cancleContent}
</Button>
Expand Down
4 changes: 4 additions & 0 deletions src/Components/Common/Alert/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ export const StyledButtonWrapper = styled.div`

export const StyledMessage = styled.div<{ $fontSize: number }>`
font-size: ${(props) => props.$fontSize}rem;
display: flex;
flex-direction: column;
align-items: center;
font-size: 1.5rem;
`;
2 changes: 1 addition & 1 deletion src/Components/Common/Alert/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface AlertPropsType extends HTMLAttributes<HTMLDivElement> {
confirmContent?: string;
cancleContent?: string;
mode?: 'alert' | 'confirm';
onChangeOpen: (openState: boolean) => void;
onChangeOpen?: (openState: boolean) => void;
onConfirm?: () => void;
onCancle?: () => void;
}
21 changes: 19 additions & 2 deletions src/Components/Common/Modal/AddOrEditPostModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {
import { Props } from './type';
import validatePostFieldProps from './validatePostField';
import QUERY_KEYS from '@/Constants/queryKeys';
import NON_AUTH_USER from '@/Constants/nonAuthUser';
import useTabStore from '@/Stores/Tab';

const AddOrEditPostModal = ({ onChangeOpen }: Props) => {
const navigate = useNavigate();
Expand All @@ -40,6 +42,8 @@ const AddOrEditPostModal = ({ onChangeOpen }: Props) => {
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const { postId } = useParams();

const { prev, setTab } = useTabStore();

/**
* 컴포넌트의 역할이 '게시글 수정'일 때의 로직 ▼
* @brief param을 통해 가져온 postId가 존재할 경우, 각 폼에 초기값을 할당합니다.
Expand Down Expand Up @@ -173,8 +177,21 @@ const AddOrEditPostModal = ({ onChangeOpen }: Props) => {
</>
) : (
<Alert
message="로그인 후 이용해주세요"
onChangeOpen={onChangeOpen}
mode="confirm"
message={
<>
<div>{NON_AUTH_USER.ADD_POST}</div>
<div>{NON_AUTH_USER.LOGIN}</div>
</>
}
onConfirm={() => {
navigate('/login');
setTab(prev);
}}
onCancle={() => {
navigate(-1);
setTab(prev);
}}
/>
);
};
Expand Down
71 changes: 52 additions & 19 deletions src/Components/Profile/ProfileInfo/UserProfileInfo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable no-underscore-dangle */
import { Link, useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import { useTheme } from 'styled-components';
import { useState } from 'react';
import Button from '@/Components/Base/Button';
import { StyledButtonContainer, StyledName } from '../style';
import { NameProps } from './type';
Expand All @@ -10,6 +11,10 @@ import { sendNotifications } from '@/Services/Notification';
import useCheckAuth from '@/Hooks/Api/Auth';
import useFetchUser from '@/Hooks/Api/User';
import { useReadMessage } from '@/Hooks/Api/Message';
import useAuthUserStore from '@/Stores/AuthUser';
import { NotificationTypeList } from '@/Types/Request';
import Alert from '@/Components/Common/Alert';
import NON_AUTH_USER from '@/Constants/nonAuthUser';

const UserProfileInfo = ({ name, user, isFollowing }: NameProps) => {
const { setReceiver, setIsClickedUserCard } = useMessageReceiver();
Expand All @@ -19,7 +24,17 @@ const UserProfileInfo = ({ name, user, isFollowing }: NameProps) => {
const { userDataRefetch } = useFetchUser(userId || '');
const { mutateReadMessage } = useReadMessage();

const { user: authUser } = useAuthUserStore();
const [errorMode, setErrorMode] = useState<NotificationTypeList>();
const [isAlertOpen, setIsAlertOpen] = useState(false);
const navigate = useNavigate();

const handleFollow = async () => {
if (Object.keys(authUser).length === 0) {
setErrorMode('FOLLOW');
setIsAlertOpen(true);
return;
}
// 이미 팔로우 중이면 언팔로우
if (isFollowing) {
await unfollowUser(isFollowing._id);
Expand All @@ -39,10 +54,16 @@ const UserProfileInfo = ({ name, user, isFollowing }: NameProps) => {
userDataRefetch();
};

const navigateDirectMessage = () => {
const handleDirectMessage = () => {
if (Object.keys(authUser).length === 0) {
setErrorMode('MESSAGE');
setIsAlertOpen(true);
return;
}
setIsClickedUserCard(true);
setReceiver(user);
mutateReadMessage(user._id);
navigate('/directmessage');
};

return (
Expand Down Expand Up @@ -80,23 +101,35 @@ const UserProfileInfo = ({ name, user, isFollowing }: NameProps) => {
</Button>
)}

<Link to="/directmessage">
<Button
type="button"
height="3rem"
textSize="1.4rem"
width="10rem"
borderRadius="1rem"
style={{
marginRight: '1rem',
marginTop: '.5rem',
border: `1px solid ${colors.text}`,
}}
onClick={navigateDirectMessage}
>
메시지 보내기
</Button>
</Link>
<Button
type="button"
height="3rem"
textSize="1.4rem"
width="10rem"
borderRadius="1rem"
style={{
marginRight: '1rem',
marginTop: '.5rem',
border: `1px solid ${colors.text}`,
}}
onClick={handleDirectMessage}
>
메시지 보내기
</Button>
{isAlertOpen && (
<Alert
mode="confirm"
message={
<>
{errorMode === 'FOLLOW' && <div>{NON_AUTH_USER.FOLLOW}</div>}
{errorMode === 'MESSAGE' && <div>{NON_AUTH_USER.MESSAGE}</div>}
<div>{NON_AUTH_USER.LOGIN}</div>
</>
}
onConfirm={() => navigate('/login')}
onCancle={() => setIsAlertOpen(false)}
/>
)}
</StyledButtonContainer>
);
};
Expand Down
10 changes: 10 additions & 0 deletions src/Constants/nonAuthUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const NON_AUTH_USER = {
ADD_POST: '비회원은 글 작성이 불가능합니다.',
FOLLOW: '비회원은 팔로우가 불가능합니다.',
MESSAGE: '비회원은 메세지 보내기가 불가능합니다.',
LIKE: '비회원은 좋아요가 불가능합니다.',
COMMENT: '비회원은 댓글 달기가 불가능합니다.',
LOGIN: '로그인 페이지로 이동하시겠습니까?',
};

export default NON_AUTH_USER;
3 changes: 0 additions & 3 deletions src/Pages/AddOrEditPostPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ import { useNavigate } from 'react-router-dom';
import AddOrEditPostModal from '@/Components/Common/Modal/AddOrEditPostModal';
import useTabStore from '@/Stores/Tab';
import Alert from '@/Components/Common/Alert';
import useResize from '@/Hooks/useResize';

const AddOrEditPostPage = () => {
const [isModalOpen, setIsModalOpen] = useState(true);
const { isMobileSize } = useResize();
const { prev, setTab } = useTabStore();
const [alertMessage, setAlertMessage] = useState<string>('');
const naviagte = useNavigate();
Expand All @@ -30,7 +28,6 @@ const AddOrEditPostPage = () => {
<>
{alertMessage && (
<Alert
width={isMobileSize ? 40 : undefined}
mode="confirm"
message={alertMessage}
onConfirm={handleCloseModal}
Expand Down
Loading

0 comments on commit c79eed8

Please sign in to comment.