Skip to content

Commit

Permalink
ListyWave ver2.4.2 : 댓글기능추가/리프레시토큰 만료기간 재설정/개인정보처리방침페이지/콜렉션페이지 UI수정 (#…
Browse files Browse the repository at this point in the history
…247)

* Fix: 댓글 기능 추가(댓글 줄바꿈 표시, 비회원 댓글창 클릭시 로그인 모달, 답글 작성자 프로필 클릭 로직 추가), 인트로 페이지 영상 ios 자동재생 문제 테스트 (#242)

* Feat: 답글 프로필 클릭시 해당 유저 마이리스트 페이지도 이동하도록 하는 기능 구현

* Fix: 비회원 댓글창 클릭시 로그인 모달 뜨게 구현

* Feat: textarea 출력시 줄바꿈 인식되게 수정

* Fix: 인트로 페이지 영상 ios에서 자동재생 안되는 문제 (테스트)

* Fix: 답글도 줄바꿈 되도록 수정

* Fix: 댓글 작성 폼 모달 GTM id 수정

* Refactor: refreshToken 만료시간 재설정 (#241)

* Style: 주석 정리

* Feat: useUser store에 사용하지 않는 accessToken 저장 로직 삭제 (사용자 id값만 저장되도록 수정)

* Feat: refreshToken 쿠키 만료시간 재설정

* Feat: 개인정보 처리방침 페이지 연결 추가

* fix: 콜렉션 페이지 bottom nav에 가려지는  하단부 여백 추가

---------

Co-authored-by: 강나현 <[email protected]>
Co-authored-by: Sohyun Park <[email protected]>
Co-authored-by: Seoyoung <[email protected]>
  • Loading branch information
4 people authored Jun 5, 2024
1 parent 2a61b39 commit 3cda9eb
Show file tree
Hide file tree
Showing 15 changed files with 125 additions and 119 deletions.
2 changes: 1 addition & 1 deletion src/app/auth/redirect/kakao/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function KakaoRedirectPage() {
});

const { id, accessToken, refreshToken } = res.data;
updateUser({ id, accessToken: '' }); // TODO id만 저장하기
updateUser({ id });
setCookie('accessToken', accessToken, 'AT');
setCookie('refreshToken', refreshToken, 'RT');

Expand Down
6 changes: 5 additions & 1 deletion src/app/collection/page.css.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { style, keyframes } from '@vanilla-extract/css';
import * as fonts from '@/styles/font.css';

export const wrapper = style({
marginBottom: 70,
});

export const title = style([
fonts.headlineSmall,
{
Expand All @@ -9,7 +13,7 @@ export const title = style([
]);

export const categoryFolders = style({
margin: '18px 16px',
padding: '18px 16px',
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gridTemplateRows: 'repeat(5, 1fr)',
Expand Down
4 changes: 2 additions & 2 deletions src/app/collection/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default function CollectionPage() {
};

return (
<>
<div className={styles.wrapper}>
<div className={styles.title}>{collectionLocale[language].collection}</div>
<div className={styles.categoryFolders}>
{data &&
Expand All @@ -89,6 +89,6 @@ export default function CollectionPage() {
</div>
))}
</div>
</>
</div>
);
}
7 changes: 6 additions & 1 deletion src/app/intro/_components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ function Footer() {
</div>
</div>
<div className={styles.policyWrapper}>
<p>{introLocale[language].privacy}</p>
<Link
className={styles.policyWrapper}
href={'https://cypress-tv-724.notion.site/2118cc63884e4365b753cac553f3f7ed?pvs=4'}
>
{introLocale[language].privacy}
</Link>
<p>에잇(Eight)</p>
<p>Makers : 에잇(Eight, [email protected])</p>
<p>Copyright ©Listywave - All rights reserved</p>
Expand Down
2 changes: 1 addition & 1 deletion src/app/intro/_components/Section3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function Section3() {
<span>{introLocale[language].section.message6}</span>
</div>
<div className={styles.imageWrapper}>
<video src={'/videos/video_section3.mp4'} autoPlay loop muted className={styles.video} />
<video src={'/videos/video_section3.mp4'} autoPlay loop muted playsInline className={styles.video} />
<div className={styles.blurBox}></div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/intro/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export const introLocale = {
en: {
start: 'Getting started',
tour: 'Take a tour',
privacy: 'Privacy Statement',
privacy: 'Privacy',
exampleTitles: {
line1: {
title1: 'My top 10 favorite celebrities',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ export const commentCreatedTime = style({
export const commentContent = style({
fontSize: '1.2rem',
fontWeight: 500,
lineHeight: 'normal',
// lineHeight: 'normal',
letterSpacing: '-0.36px',
wordBreak: 'break-word',
whiteSpace: 'pre-wrap',
});

export const deletedComment = style({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ function Comment({
<span className={styles.commentCreatedTime}>{comment && timeDiff(comment?.updatedDate)}</span>
</div>
{!comment?.isDeleted ? (
<p className={styles.commentContent}>{comment?.content}</p>
<div className={styles.commentContent}>{comment?.content}</div>
) : (
<span className={styles.deletedComment}>{commentLocale[language].deletedMessage}</span>
)}
Expand Down
128 changes: 72 additions & 56 deletions src/app/list/[listId]/_components/ListDetailOuter/CommentForm.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { ChangeEvent, useEffect } from 'react';
import { ChangeEvent, Dispatch, useEffect, SetStateAction } from 'react';

import { useUser } from '@/store/useUser';
import { useIsEditing, useCommentStatus } from '@/store/useComment';
import { useLanguage } from '@/store/useLanguage';
import useResizeTextarea from '@/hooks/useResizeTextarea';
import { commentPlaceholder } from '@/lib/constants/placeholder';
import { commentLocale } from '@/app/list/[listId]/locale';
import Modal from '@/components/Modal/Modal';
import LoginModal from '@/components/login/LoginModal';
import useBooleanOutput from '@/hooks/useBooleanOutput';

import { vars } from '@/styles/theme.css';
import * as styles from './Comments.css';
Expand Down Expand Up @@ -37,6 +40,7 @@ function CommentForm({
const { language } = useLanguage();
const { isEditing } = useIsEditing();
const { textareaRef, handleResizeHeight } = useResizeTextarea();
const { isOn, handleSetOn, handleSetOff } = useBooleanOutput();

const handleResetTextArea = () => {
if (textareaRef.current !== null) {
Expand All @@ -51,13 +55,11 @@ function CommentForm({

const handleSubmitForm = (e: React.FormEvent<HTMLFormElement>) => {
handleSubmit(e);
// handleResizeHeight();
handleResetTextArea();
};

const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Enter' && !e.shiftKey && !isPending) {
// handleResizeHeight();
handleResetTextArea();
e.preventDefault();
handleSubmit(e);
Expand All @@ -69,6 +71,12 @@ function CommentForm({
handleResizeHeight();
};

const handleClickInactiveForm = () => {
if (!userId) {
handleSetOn();
}
};

const textAreaHeight = () => {
if (textareaRef.current === null) {
return false;
Expand Down Expand Up @@ -106,61 +114,69 @@ function CommentForm({
}, [textareaRef, handleResizeHeight]);

return (
<div className={styles.formWrapperOuter}>
<div
className={`${styles.formWrapperInner} ${!!activeNickname || isEditing || textAreaHeight() ? styles.activeFormWrapper : ''}`}
>
{status === 'createReply' && activeNickname && (
<div className={styles.activeReplyWrapper}>
<span className={styles.replyNickname}>
{language === 'ko'
? `@${activeNickname} ${commentLocale.ko.replyNickname}`
: `${commentLocale.en.replyNickname} @${activeNickname}`}
</span>
<CancelButton
className={styles.clearButton}
alt={commentLocale[language].cancelButtonAlt}
onClick={handleUpdate}
width={18}
height={18}
fill={vars.color.gray7}
/>
</div>
)}
{status === 'edit' && isEditing && (
<div className={styles.activeReplyWrapper}>
<span className={styles.replyNickname}>{commentLocale[language].editing}</span>
<CancelButton
className={styles.clearButton}
alt={commentLocale[language].cancelButtonAlt}
onClick={handleCancelForm}
width={18}
height={18}
fill={vars.color.gray7}
/>
</div>
)}
<form className={styles.formContainer} onSubmit={handleSubmitForm}>
<textarea
rows={1}
className={styles.formInput}
value={comment}
onChange={handleTextareaChange}
disabled={!userId}
ref={textareaRef}
placeholder={
userId === null ? commentPlaceholder[language].requiredLogin : commentPlaceholder[language].comment
}
onKeyDown={handleKeyDown}
/>
{comment && (
<button type="submit" disabled={isPending} className={styles.formButton}>
<Airplane width={20} height={20} fill={vars.color.blue} />
</button>
<>
{isOn && (
<Modal handleModalClose={handleSetOff} size="large">
<LoginModal id="commentLoginBtn" />
</Modal>
)}
<div className={styles.formWrapperOuter}>
<div
className={`${styles.formWrapperInner} ${!!activeNickname || isEditing || textAreaHeight() ? styles.activeFormWrapper : ''}`}
>
{status === 'createReply' && activeNickname && (
<div className={styles.activeReplyWrapper}>
<span className={styles.replyNickname}>
{language === 'ko'
? `@${activeNickname} ${commentLocale.ko.replyNickname}`
: `${commentLocale.en.replyNickname} @${activeNickname}`}
</span>
<CancelButton
className={styles.clearButton}
alt={commentLocale[language].cancelButtonAlt}
onClick={handleUpdate}
width={18}
height={18}
fill={vars.color.gray7}
/>
</div>
)}
{status === 'edit' && isEditing && (
<div className={styles.activeReplyWrapper}>
<span className={styles.replyNickname}>{commentLocale[language].editing}</span>
<CancelButton
className={styles.clearButton}
alt={commentLocale[language].cancelButtonAlt}
onClick={handleCancelForm}
width={18}
height={18}
fill={vars.color.gray7}
/>
</div>
)}
</form>
<form className={styles.formContainer} onSubmit={handleSubmitForm}>
<textarea
rows={1}
className={styles.formInput}
value={comment}
onChange={handleTextareaChange}
readOnly={!userId}
ref={textareaRef}
placeholder={
userId === null ? commentPlaceholder[language].requiredLogin : commentPlaceholder[language].comment
}
onKeyDown={handleKeyDown}
onClick={handleClickInactiveForm}
/>
{comment && (
<button type="submit" disabled={isPending} className={styles.formButton}>
<Airplane width={20} height={20} fill={vars.color.blue} />
</button>
)}
</form>
</div>
</div>
</div>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const deleteButton = style({
});

export const profileImage = style({
flex: '0 0 1',
flex: '0 0 0',

borderRadius: '16px',
backgroundColor: vars.color.gray7,
Expand Down Expand Up @@ -85,4 +85,5 @@ export const replyContent = style({
fontWeight: 500,
lineHeight: 'normal',
letterSpacing: '-0.36px',
whiteSpace: 'pre-wrap',
});
51 changes: 28 additions & 23 deletions src/app/list/[listId]/_components/ListDetailOuter/Replies.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';
import Image from 'next/image';
import Link from 'next/link';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import DeleteModalButton from '@/app/list/[listId]/_components/ListDetailOuter/DeleteModalButton';
Expand Down Expand Up @@ -81,6 +82,7 @@ function Reply({ reply, listId, currentUserInfo, handleEdit, commentId }: ReplyP
const { setStatusEdit } = useCommentStatus();
const { setCommentId } = useCommentId();
const { setReplyId } = useReplyId();

const deleteReplyMutation = useMutation({
mutationFn: () => deleteReply({ listId: listId, commentId: reply?.commentId, replyId: reply?.id }),
onSuccess: () => {
Expand All @@ -98,32 +100,35 @@ function Reply({ reply, listId, currentUserInfo, handleEdit, commentId }: ReplyP
const handleDeleteButtonClick = () => {
deleteReplyMutation.mutate();
};

return (
<>
<div className={styles.replyWrapper}>
{reply.userProfileImageUrl ? (
<Image
src={reply.userProfileImageUrl}
className={styles.profileImage}
width={20}
height={20}
alt={replyLocale[language].profileImageAlt}
style={{
objectFit: 'cover',
}}
/>
) : (
<Image
src={fallbackProfile}
className={styles.profileImage}
width={20}
height={20}
alt={replyLocale[language].profileImageAlt}
style={{
objectFit: 'cover',
}}
/>
)}
<Link href={`/user/${reply?.userId}/mylist`}>
{reply.userProfileImageUrl ? (
<Image
src={reply.userProfileImageUrl}
className={styles.profileImage}
width={20}
height={20}
alt={replyLocale[language].profileImageAlt}
style={{
objectFit: 'cover',
}}
/>
) : (
<Image
src={fallbackProfile}
className={styles.profileImage}
width={20}
height={20}
alt={replyLocale[language].profileImageAlt}
style={{
objectFit: 'cover',
}}
/>
)}
</Link>
<div className={styles.replyContainer}>
<div className={styles.replyInformationWrapper}>
<span className={styles.replyWriter}>{reply.userNickname}</span>
Expand Down
13 changes: 0 additions & 13 deletions src/components/login/LoginModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@ import KakaoLoginIcon from '/public/icons/kakao_login_narrow.svg';
import { commonLocale } from '@/components/locale';
import { useLanguage } from '@/store/useLanguage';

// 다른 소셜 로그인 도입을 위해 주석처리 해둠
// import NaverLoginIcon from '/public/icons/naver_login.svg';
// import GoogleLoginIcon from '/public/icons/google_login.svg';
// import KakaoLoginIcon from '/public/icons/kakao_login.svg';

const oauthType = {
naver: 'naver',
google: 'google',
kakao: 'kakao',
};

Expand Down Expand Up @@ -45,12 +38,6 @@ export default function LoginModal({ id }: LoginModalProps) {
</div>
</div>
<div className={styles.buttonContainer}>
{/* <Link href={`${baseUrl}/auth/${oauthType.naver}`}>
<NaverLoginIcon />
</Link>
<Link href={`${baseUrl}/auth/${oauthType.google}`}>
<GoogleLoginIcon />
</Link> */}
<Link id={id} href={`${process.env.NEXT_PUBLIC_SERVER_DOMAIN}/auth/${oauthType.kakao}`}>
<KakaoLoginIcon />
</Link>
Expand Down
Loading

0 comments on commit 3cda9eb

Please sign in to comment.