Skip to content

Commit

Permalink
feat: 0913 QA (#34)
Browse files Browse the repository at this point in the history
* feat: Digest탭 버튼 필터 적용

- selectedTab과 필터 버튼 렌더링 동기화

* style: Digest 호버했을때 여백 있으면 안됨

* feat: GA 삽입

* WIP: 발신인 상세 페이지 API 연동 WIP

* refactor: Headwind 적용

* feat: 랜딩페이지 UI 구현

* feat: 랜딩페이지 유저 반응 추가

* fix: Intersection Observer 로직 수정

* feat: Today탭 UI 수정

* fix: Intersection Observer 로직 수정 반영
  • Loading branch information
moong23 authored Sep 13, 2024
1 parent ccd0aee commit 87d0d8b
Show file tree
Hide file tree
Showing 28 changed files with 137 additions and 67 deletions.
18 changes: 18 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@mdx-js/loader": "^3.0.1",
"@mdx-js/react": "^3.0.1",
"@next/mdx": "^14.2.7",
"@next/third-parties": "^14.2.11",
"@tanstack/react-query": "^5.51.23",
"@types/mdx": "^2.0.13",
"axios": "^1.7.2",
Expand Down
1 change: 0 additions & 1 deletion src/app/article/[id]/ArticleContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ interface ArticleContentProps {

const ArticleContent = ({ mailData }: ArticleContentProps) => {
const [headerType, setHeaderType] = useState<'default' | 'simplified'>('default');

return (
<div id={mailData.mailId} className='flex flex-col items-center w-full gap-2'>
<ArticleHeader {...mailData} headerType={headerType} />
Expand Down
4 changes: 2 additions & 2 deletions src/app/article/[id]/ArticleFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const ArticleFooter = ({ mailId }: ArticleFooterProps) => {
{ mailId },
{
onSuccess: () => {
router.push('/main?tab=Digest'); // 클라이언트 사이드에서 리디렉션
handleRedirectMain();
},
},
);
Expand All @@ -29,7 +29,7 @@ const ArticleFooter = ({ mailId }: ArticleFooterProps) => {

return (
<div className='fixed bottom-0 flex flex-row items-center justify-center w-full h-12 bg-white border-t border-lightgrey'>
<div className='flex flex-row justify-end gap-6 px-6 w-content'>
<div className='flex flex-row justify-end px-6 gap-6 w-content'>
<span className='flex items-center justify-center w-6 h-6 cursor-pointer'>
<Image src={DeleteIcon} alt='delete' width={16} height={24} onClick={() => handleDeleteMail(mailId)} />
</span>
Expand Down
34 changes: 23 additions & 11 deletions src/app/landingpage/Landing1.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
import Image from 'next/image';
import Link from 'next/link';
import LandingImage1 from '@/assets/images/Landing1_1.svg';
import LandingImage3 from '@/assets/images/Landing1_3.png';
import LandingFoldIcon from '@/assets/icons/OnboardFoldIcon.svg';

const Landing1 = () => {
return (
<div className='relative flex flex-col gap-[6.75rem] items-center justify-center text-white'>
<span className='flex flex-col items-center gap-3'>
<h3 className='text-h3-onboard'>Your Daily Insight Source</h3>
<h1 className='text-h1-onboard'>매일 인사이트 얻고 싶은 사람들의 모임</h1>
<p className='flex text-center text-body2-onboard'>
<div className='mt-[calc(20vh-64px)] flex flex-col gap-10 items-center justify-start text-white'>
<div className='flex flex-col'>
<div className='w-[50vw] aspect-[942/100] relative'>
<Image src={LandingImage1} fill alt='Landing1' className='object-contain' />
</div>
<span className='text-center text-body1'>
새로운 인사이트와 정보를 얻기 위해 구독한 뉴스레터, 다 읽지 못하고 쌓여만 있진 않나요?
<br />
받은편지함 속에서 유익한 뉴스레터만 따로 모아 보세요. 매일 인사이트를 얻으세요
</p>
</span>

</span>
</div>
<Link
style={{ width: '11.375rem', height: '3.75rem' }}
style={{ width: '20rem', height: '3.5rem' }}
className={`border-gradient_horizontal text-black flex items-center justify-center rounded`}
href='/onboard'
>
시작하기
인사이트 받으러 가기
</Link>
{/* <Image src={LandingImage3} className='absolute bottom-0 -translate-x-1/2 left-1/2' alt='Landing3' /> */}
<div className='absolute bottom-0 -translate-x-1/2 left-1/2 h-[50vh] w-full'>
<Image src={LandingImage3} fill alt='Landing3' className='object-contain' />
</div>
<div className='absolute bottom-0 left-0 w-full h-[30vh] bg-gradient-to-t from-black to-transparent flex items-center flex-col justify-center gap-4'>
<div className='text-body2'>
인스포메일클럽의 이야기가 궁금하다면 <b>스크롤</b>해 보세요
</div>
<Link href='#1' scroll={true}>
<Image src={LandingFoldIcon} width={72} height={32} alt='scroll down' className='animate-bounce' />
</Link>
</div>
</div>
);
};
Expand Down
11 changes: 3 additions & 8 deletions src/app/landingpage/Landing8/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const cardFirstRow: CardData[] = [
{
id: 2,
author: '김인스포',
text: '제가 여러 시간에 자주 사용하는 서비스입니다. 바쁜 일정에도 쉽게 빠르게 인사이트를 접할 수 있어서 좋아요.',
text: '뉴스레터를 한눈에 분류할수 있다는 아이디어가 좋다고 생각해요',
bgColor: '#FCE4E5',
},
{
Expand All @@ -48,7 +48,7 @@ const cardSecondRow: CardData[] = [
{
id: 6,
author: '김인스포',
text: '이런 뉴스레터 아침 씻다가 InspoMailClub 덕분에 그 유용한 기능이 좋아서 결정했어요!',
text: '평소 메일 뉴스레터 관리가 어려웠는데 이런 서비스를 쓰면 관리가 수월할 것 같아요',
bgColor: '#FCEBFB',
},
{
Expand Down Expand Up @@ -89,12 +89,7 @@ const Landing8: React.FC = () => {
className={`${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'} delay-100 transition flex flex-col items-center gap-3`}
>
<span className='text-h2-onboard'>InspoMailClub로 확 바뀐 뉴스레터 읽기</span>
<Link
className='text-body2-onboard'
//TODO: Add the correct link
href={'https://tally.so/r/mZlV1e'}
target='_blank'
>{`나도 후기 작성하러 가기 →`}</Link>
<Link className='text-body2-onboard' href='#8'>{`나도 후기 작성하러 가기 →`}</Link>
</div>
<div
className={`${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'} delay-500 transition relative flex flex-col w-full gap-6`}
Expand Down
2 changes: 2 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { PropsWithChildren } from 'react';
import ReactQueryProviders from '@/api/queryClient';
import { GoogleAnalytics } from '@next/third-parties/google';
import '@/styles/tailwind.css';

export const metadata = {
Expand Down Expand Up @@ -30,6 +31,7 @@ export default function RootLayout({ children }: Readonly<PropsWithChildren>) {
<body className='flex flex-col items-center w-full h-full'>
<ReactQueryProviders>{children}</ReactQueryProviders>
<div id='portal' />
{process.env.NEXT_PUBLIC_GA_ID && <GoogleAnalytics gaId={process.env.NEXT_PUBLIC_GA_ID} />}
</body>
</html>
);
Expand Down
26 changes: 14 additions & 12 deletions src/app/main/DigestTab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import LoadingComponent from '@/components/Loading';
const DigestTab = () => {
const [selectedTab, setSelectedTab] = useState<'all' | 'unread'>('unread');

const { data, isFetched, refetch } = useUnreadQuery({ type: selectedTab });
const { data, isFetched, refetch } = useUnreadQuery({});
const readMutation = useMailReadMutation();

const handleReadMail = (mailId: string) => {
Expand All @@ -22,22 +22,24 @@ const DigestTab = () => {

return isFetched ? (
<div className='flex flex-row justify-center w-full h-full gap-16'>
<div className='flex flex-col h-full gap-3 pt-3'>
<div className='flex flex-col h-full pt-3 gap-3'>
<TopSection selectedTab={selectedTab} setSelectedTab={setSelectedTab} handleRefresh={() => refetch()} />
{data?.length === 0 ? (
{data?.filter(d => (selectedTab === 'all' ? true : d.isRead === false)).length === 0 ? (
<div className='h-[calc(100vh-8rem-60px)] overflow-visible w-articleCard'>
<EmptyMailView />
</div>
) : (
data?.map((article, index) => (
<div
key={article.mailId}
onClick={() => handleReadMail(article.mailId)}
className={`${index === data.length - 1 && 'mb-10'}`}
>
<ArticleCard {...article} />
</div>
))
data
?.filter(d => (selectedTab === 'all' ? true : d.isRead === false))
.map((article, index) => (
<div
key={article.mailId}
onClick={() => handleReadMail(article.mailId)}
className={`${index === data.length - 1 && 'mb-10'}`}
>
<ArticleCard {...article} />
</div>
))
)}
</div>
<div className='sticky top-0 pt-9 h-fit'>
Expand Down
4 changes: 2 additions & 2 deletions src/app/main/SearchTab/SectionContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ interface SectionContentProps {
const SectionContent = ({ tab, newsLetters }: SectionContentProps) => {
const { scrollRef, onDragStart, onThrottleDragMove, onDragEnd, isDrag } = useDragScroll();
return (
<div className='flex flex-col gap-5 overflow-x-scroll noScrollbar'>
<div className='flex flex-col overflow-x-scroll gap-5 noScrollbar'>
<span className='text-xl font-bold'>{tab}</span>
<div
onMouseDown={onDragStart}
onMouseMove={isDrag ? onThrottleDragMove : () => {}}
onMouseUp={onDragEnd}
onMouseLeave={onDragEnd}
ref={scrollRef}
className='flex flex-row gap-4 overflow-x-scroll noScrollbar scroll-auto'
className='flex flex-row overflow-x-scroll gap-4 noScrollbar scroll-auto'
>
{newsLetters?.map((newsLetter, index) => <ArticleCard key={index} newsLetter={newsLetter} />)}
<div className='h-20 w-[calc(50vw-37.5rem)] bg-white shrink-0' />
Expand Down
4 changes: 2 additions & 2 deletions src/app/main/SearchTab/TopSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const TopSection = ({ selectedTab, setSelectedTab }: TopSectionProps) => {
};

return (
<div className='flex flex-col w-full gap-8 py-10'>
<div className='flex flex-col gap-2 text-black text-h1'>
<div className='flex flex-col w-full py-10 gap-8'>
<div className='flex flex-col text-black gap-2 text-h1'>
오늘 많이 주목된 뉴스레터
<span className='text-body2'>취향에 맞는 새로운 뉴스레터를 발견해보세요</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/main/TodayTab/RecommendArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const RecommendArea = () => {
return isFetched ? (
<div className='flex flex-col gap-3 min-w-domainCard'>
<div className='flex flex-row items-center justify-between'>
<div className='flex flex-col gap-1 text-black'>
<div className='flex flex-col text-black gap-1'>
<span className='text-body3'>{userData?.username}님이 놓치고 있는 뉴스레터</span>
<span className='text-caption text-darkgrey'>더 많은 인사이트를 얻으세요</span>
</div>
Expand Down
13 changes: 9 additions & 4 deletions src/app/main/TodayTab/ScrollNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const ScrollNavigation = ({ articleData }: ScrollNavigationProps) => {
onMouseLeave={() => setIsHovered(false)}
>
{isHovered && (
<div className='flex flex-col gap-2 w-[13.5rem] rounded-xl shadow-[0_0_12px_0_rgba(0,0,0,0.25)] p-4 bg-white'>
<div className='flex flex-col gap-1 w-[13.5rem] rounded-xl shadow-[0_0_12px_0_rgba(0,0,0,0.25)] p-4 bg-white'>
{articleData.map((article, index) => (
<Link
style={{
Expand All @@ -42,10 +42,15 @@ const ScrollNavigation = ({ articleData }: ScrollNavigationProps) => {
))}
</div>
)}
<div className='flex flex-col w-4 cursor-pointer gap-3' onMouseEnter={() => setIsHovered(true)}>
<div className='flex flex-col w-4 gap-1.5 cursor-pointer' onMouseEnter={() => setIsHovered(true)}>
{articleData.map((article, index) => (
<span
className={`w-full rounded-full h-0.5 ${focusId === index ? 'bg-darkgrey' : 'bg-lightgrey'}`}
<Link
href={{
pathname: `/main`,
query: { tab: 'today' },
hash: article.mailId,
}}
className={`w-full rounded-full my-1 h-0.5 ${focusId === index ? 'bg-darkgrey' : 'bg-lightgrey'}`}
key={article.mailId}
/>
))}
Expand Down
16 changes: 12 additions & 4 deletions src/app/main/TodayTab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useRouter } from 'next/navigation';
import { shallow } from 'zustand/shallow';
import EmptyTodayView from '@/components/EmptyTodayView';
import LoadingComponent from '@/components/Loading';
import FoldIconWithDirection from '@/assets/icons/FoldIconWithDirection';

const TodayTab = () => {
const { data: userData } = useProfileQuery();
Expand All @@ -23,7 +24,7 @@ const TodayTab = () => {
const [focusId, setFocusId] = useFocusIdStore(state => [state.focusId, state.setFocusId], shallow);
const [todayArticleData, setTodayArticleData] = useState<MailDataType[]>([]);
const router = useRouter();
const isArticleArea = focusId > 0;
const isArticleArea = focusId >= 0;

useEffect(() => {
if (containerRef.current && todayArticleData.length) {
Expand Down Expand Up @@ -60,7 +61,8 @@ const TodayTab = () => {
);
}) ?? [];

setTodayArticleData(filteredData);
// setTodayArticleData(filteredData);
data && setTodayArticleData(data);
}, [data]);
useEffect(() => {
if (isError && error.response?.status === 403) {
Expand All @@ -73,7 +75,7 @@ const TodayTab = () => {

return isFetched && todayArticleData.length > 0 ? (
<>
<div className='flex flex-col items-center gap-3 mt-10'>
<div className='flex flex-col items-center mt-10 gap-3'>
<span className='text-blue text-body1'>{formatToYMD(new Date())}</span>
<span className='text-center text-h1'>
{userData?.username}님에게
Expand All @@ -92,7 +94,13 @@ const TodayTab = () => {
))}
</div>
{isArticleArea ? (
<Link href='/main' scroll={true} className={`fixed w-10 h-10 bottom-4 left-4 rounded-full bg-green z-[9999]`} />
<Link
href='/main#top'
scroll={true}
className={`fixed w-10 h-10 bottom-8 right-10 rounded-full bg-lightgrey z-[9999] flex items-center justify-center`}
>
<FoldIconWithDirection width={24} fill='#797979' rotate='up' />
</Link>
) : (
<Link
href={`/main#${todayArticleData[0].mailId}`}
Expand Down
2 changes: 1 addition & 1 deletion src/app/main/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function MainPageLayout({
children: React.ReactNode;
}>) {
return (
<main className='flex flex-col items-center gap-4 bg-white'>
<main className='flex flex-col items-center bg-white gap-4'>
<MainPageHeader />
<div className='flex flex-col items-center w-full'>
<Suspense fallback={<div></div>}>
Expand Down
2 changes: 1 addition & 1 deletion src/app/mypage/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default async function MypageLayout({ children }: Readonly<PropsWithChild
<UserDataCard />
</span>
</div>
<div className='flex flex-col gap-3 pb-6 text-caption'>
<div className='flex flex-col pb-6 gap-3 text-caption'>
<Link href='/mypage'>설정</Link>
<Link href='http://pf.kakao.com/_xdxfaxoG' target='_blank'>
문의하기
Expand Down
6 changes: 3 additions & 3 deletions src/app/mypage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ const MyPage = () => {
</div>
<div className='text-xl font-bold -bottom-6'>{userData?.username}</div>
</div>
<div className='flex flex-col w-full gap-8 pl-4 text-btn1'>
<div className='flex flex-col w-full pl-4 gap-8 text-btn1'>
<Link
className='py-4 font-bold w-fit'
href='/mypage/subscribe' // Link to Subscribe Management Page
>
뉴스레터 구독 관리
</Link>
<div role='button' onClick={handleLogout} className='flex flex-col gap-2 py-4 font-bold w-fit'>
<div role='button' onClick={handleLogout} className='flex flex-col py-4 font-bold gap-2 w-fit'>
로그아웃
<span className='font-normal text-body2 text-darkgrey'>다시 로그인 할 때까지 계정이 비활성화됩니다.</span>
</div>
<div
role='button'
onClick={handleWithdrawal}
className='flex flex-col gap-2 py-4 font-bold w-fit text-darkgrey'
className='flex flex-col py-4 font-bold gap-2 w-fit text-darkgrey'
>
회원 탈퇴
<span className='font-normal text-body2'>개인 정보 및 설정이 모두 영구적으로 삭제됩니다</span>
Expand Down
2 changes: 1 addition & 1 deletion src/app/mypage/subscribe/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const SubscribePage = async () => {
return (
<div className='flex flex-col gap-11 w-articleCard pt-[7.625rem]'>
<div className='flex flex-col gap-2'>
<span className='flex flex-row gap-1 text-sm font-medium text-darkgrey'>
<span className='flex flex-row text-sm font-medium gap-1 text-darkgrey'>
마이페이지
<Image src={RightFoldIcon} alt='RightFoldIcon' width={18} height={18} />
</span>
Expand Down
2 changes: 1 addition & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function Home() {
<div
id='0'
ref={landing1Ref}
className='flex items-center justify-center w-full bg-black snap-start h-landingPageHeight shrink-0'
className='relative flex items-start justify-center w-full bg-black snap-start h-landingPageHeight shrink-0'
>
<Landing1 />
</div>
Expand Down
Loading

0 comments on commit 87d0d8b

Please sign in to comment.