Skip to content
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

Feat: 마이페이지 마크업 #14

Merged
merged 7 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/domain/[id]/DomainCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Chip } from '@/components/Chip';
import SubscribeButton from '@/components/SubscribeButton';
import type { DomainType } from '@/types/article';
import type { DomainType } from '@/types/';
import Image from 'next/image';
import Link from 'next/link';
import WebsiteIcon from '@/assets/icons/WebsiteIcon.svg';
Expand Down
63 changes: 15 additions & 48 deletions src/app/domain/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import MainPageHeader from '@/components/Header/MainPageHeader';
import DomainListTap from '@/components/ListTap/DomainListTap';
import AlternateListTap from '@/components/ListTap/AlternateListTap';
import Image from 'next/image';
import ArticleCard from '@/components/Article/ArticleCard';
import DomainCard from '@/app/domain/[id]/DomainCard';
import { GET } from '@/network';
import { ArticleType, DomainType } from '@/types';

interface DomainPageProps {
params: {
Expand All @@ -11,7 +13,15 @@ interface DomainPageProps {
}

const DomainPage = async ({ params }: DomainPageProps) => {
const { domainData, isSubscribed, domainArticleData } = await getDomainPageData(params.id);
const {
domainData,
isSubscribed,
domainArticleData,
}: {
domainData: DomainType;
isSubscribed: boolean;
domainArticleData: ArticleType[];
} = await getDomainPageData(params.id);

return (
<div className='flex flex-col items-center w-full'>
Expand All @@ -23,7 +33,7 @@ const DomainPage = async ({ params }: DomainPageProps) => {
<div className='absolute bottom-0 w-full h-2/5 bg-gradient-to-t from-white' />
</div>
<div className='relative -top-10 text-h1'>{domainData.name}</div>
<DomainListTap />
<AlternateListTap tapName='지난 아티클' tapCount={domainArticleData.length} />
<div className='flex flex-col w-full gap-4'>
{domainArticleData.map(article => (
<ArticleCard key={article.id} {...article} currentTab={'currentTab'} />
Expand All @@ -42,49 +52,6 @@ const DomainPage = async ({ params }: DomainPageProps) => {
export default DomainPage;

export const getDomainPageData = async (id: string) => {
return {
domainData: {
id: id,
name: '뉴닉',
type: '시사',
domain: '[email protected]',
profile: 'https://picsum.photos/800',
description:
'우리가 시간이 없지, 세상이 안 궁금하냐!\n시사, 경제, 커리어 등 지식 정보부터 일상 속 사소한\n영감까지 자유롭게 이야기할 수 있는 플랫폼이에요.',
website: 'https://newneek.co/',
},
isSubscribed: true,
domainArticleData: [
{
id: 'randomString111',
title: '국가안전보장회의',
url: '/article/1',
type: 'IT/테크',
content:
'국가는 평생교육을 진흥하여야 한다. 국가안전보장에 관련되는 대외정책·군사정책과 국내정책의 수립에 관하여 국무회의의 심의에 앞서 대통령의 자문에 응하기 위하여 국가안전보장회의를 둔다. 모든 국민은 법률이 정하는 바에 의하여 공무담임권을 가진다. 광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.',
date: '2024-07-13',
thumbnail: 'https://picsum.photos/156',
isRead: true,
from: {
domain: 'official@git',
profile: 'https://picsum.photos/36',
},
},
{
id: 'randomString112',
title: '국가안전보장회의',
url: '/article/2',
type: 'IT/테크',
content:
'국가는 평생교육을 진흥하여야 한다. 국가안전보장에 관련되는 대외정책·군사정책과 국내정책의 수립에 관하여 국무회의의 심의에 앞서 대통령의 자문에 응하기 위하여 국가안전보장회의를 둔다. 모든 국민은 법률이 정하는 바에 의하여 공무담임권을 가진다. 광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.',
date: '2024-07-13',
thumbnail: 'https://picsum.photos/156',
isRead: true,
from: {
domain: 'official@git',
profile: 'https://picsum.photos/36',
},
},
],
};
const response = await GET(`/domainData/${id}`);
return response;
};
54 changes: 5 additions & 49 deletions src/app/main/CategoryTab.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import ArticleCard from '@/components/Article/ArticleCard';
import { Chip } from '@/components/Chip';
import type { ArticleType } from '@/types/article';
import type { ArticleType } from '@/types';
import RecommendArea from '@/app/main/TodayTab/RecommendArea';
import { GET } from '@/network';

interface CategoryTabProps {
currentTab: string;
Expand All @@ -28,52 +29,7 @@ const CategoryTab = async ({ currentTab }: CategoryTabProps) => {
export default CategoryTab;

// currentTab을 props로 넘겨서 해당 탭에 맞는 데이터를 fetch
const getCategoryArticleData = async (currentTab: string): Promise<Article[]> => {
return [
{
id: 'randomString111',
title: '국가안전보장회의',
url: '/article/1',
type: 'IT/테크',
content:
'국가는 평생교육을 진흥하여야 한다. 국가안전보장에 관련되는 대외정책·군사정책과 국내정책의 수립에 관하여 국무회의의 심의에 앞서 대통령의 자문에 응하기 위하여 국가안전보장회의를 둔다. 모든 국민은 법률이 정하는 바에 의하여 공무담임권을 가진다. 광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.',
date: '2024-07-13',
thumbnail: 'https://picsum.photos/156',
isRead: true,
from: {
domain: 'official@git',
profile: 'https://picsum.photos/36',
},
},
{
id: 'randomString112',
title: '국가안전보장회의',
url: '/article/1',
type: 'IT/테크',
content:
'국가는 평생교육을 진흥하여야 한다. 국가안전보장에 관련되는 대외정책·군사정책과 국내정책의 수립에 관하여 국무회의의 심의에 앞서 대통령의 자문에 응하기 위하여 국가안전보장회의를 둔다. 모든 국민은 법률이 정하는 바에 의하여 공무담임권을 가진다. 광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.',
date: '2024-07-13',
thumbnail: 'https://picsum.photos/156',
isRead: false,
from: {
domain: 'official@git',
profile: 'https://picsum.photos/36',
},
},
{
id: 'randomString113',
title: '국가안전보장회의',
url: '/article/1',
type: '시사',
content:
'국가는 평생교육을 진흥하여야 한다. 국가안전보장에 관련되는 대외정책·군사정책과 국내정책의 수립에 관하여 국무회의의 심의에 앞서 대통령의 자문에 응하기 위하여 국가안전보장회의를 둔다. 모든 국민은 법률이 정하는 바에 의하여 공무담임권을 가진다. 광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.',
date: '2024-07-13',
thumbnail: 'https://picsum.photos/156',
isRead: false,
from: {
domain: 'official@git',
profile: 'https://picsum.photos/36',
},
},
];
const getCategoryArticleData = async (currentTab: string): Promise<ArticleType[]> => {
const response = await GET('/articleList', { currentTab });
return response.data;
};
57 changes: 12 additions & 45 deletions src/app/main/TodayTab/RecommendArea.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,26 @@
import { Chip } from '@/components/Chip';
import DomainListItem from '@/components/Domain/DomainListItem';
import SubscribeButton from '@/components/SubscribeButton';
import { GET } from '@/network';
import { DomainType } from '@/types';
import Image from 'next/image';

const RecommendArea = async () => {
const recommendBrandData = await getRecommendBrandData();
const recommendDomainData: DomainType[] = await getRecommendDomainData();

return (
<div className='flex flex-col gap-3 w-brandCard'>
<div className='flex flex-col gap-3 min-w-domainCard'>
<div className='flex flex-col'>
<span className='text-body3'>채현님이 놓치고 있는 뉴스레터</span>
<span className='text-caption text-darkgrey'>더 많은 인사이트를 얻으세요</span>
</div>
<div className='flex flex-col'>
{recommendBrandData.map((brand, index) => (
{recommendDomainData.map((domain, index: number) => (
<div
key={brand.id}
className={`${index !== recommendBrandData.length - 1 && 'border-b border-lightgrey'} flex flex-row justify-between w-full py-3`}
key={index}
className={`${index === recommendDomainData.length - 1 ? 'border-b-white' : 'border-b-lightgrey'} border-b`}
>
<span className='flex flex-row items-center gap-3'>
<Image
src={brand.thumbnail}
alt={`thumbnail-${brand.brandName}`}
width={48}
height={48}
className='rounded-full'
/>
<span className='flex flex-row gap-1 h-fit'>
<span className='text-body3'>{brand.brandName}</span>
<Chip text={brand.type} />
</span>
</span>
<span className='py-2'>
<SubscribeButton isSubscribed={brand.subscribed} />
</span>
<DomainListItem domainData={domain} isSubscribed={false} />
</div>
))}
</div>
Expand All @@ -42,28 +30,7 @@ const RecommendArea = async () => {

export default RecommendArea;

moong23 marked this conversation as resolved.
Show resolved Hide resolved
const getRecommendBrandData = async () => {
return [
{
id: 'randomString111',
brandName: '요즘IT',
thumbnail: 'https://picsum.photos/48',
type: 'IT/테크',
subscribed: false,
},
{
id: 'randomString112',
brandName: '요즘IT',
thumbnail: 'https://picsum.photos/48',
type: 'IT/테크',
subscribed: false,
},
{
id: 'randomString113',
brandName: '요즘IT',
thumbnail: 'https://picsum.photos/48',
type: 'IT/테크',
subscribed: false,
},
];
const getRecommendDomainData = async () => {
const response = await GET('/domainRecommendList');
return response.data;
};
54 changes: 5 additions & 49 deletions src/app/main/TodayTab/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import ArticleCard from '@/components/Article/ArticleCard';
import { Chip } from '@/components/Chip';
import type { ArticleType } from '@/types/article';
import type { ArticleType } from '@/types';
import { formatToYMD } from '@/utils/formatDate/formatToYMD';
import Image from 'next/image';
import DoubleArrow from '@/assets/icons/DoubleArrow.svg';
import Link from 'next/link';
import { GET } from '@/network';

const TodayTab = async () => {
const articleApiData = await getMainPageArticleData();
Expand Down Expand Up @@ -37,52 +38,7 @@ const TodayTab = async () => {
};
export default TodayTab;

const getMainPageArticleData = async (): Promise<Article[]> => {
return [
{
id: 'randomString111',
title: '국가안전보장회의',
url: '/article/1',
type: 'IT/테크',
content:
'국가는 평생교육을 진흥하여야 한다. 국가안전보장에 관련되는 대외정책·군사정책과 국내정책의 수립에 관하여 국무회의의 심의에 앞서 대통령의 자문에 응하기 위하여 국가안전보장회의를 둔다. 모든 국민은 법률이 정하는 바에 의하여 공무담임권을 가진다. 광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.',
date: '2024-07-13',
thumbnail: 'https://picsum.photos/156',
isRead: true,
from: {
domain: 'official@git',
profile: 'https://picsum.photos/36',
},
},
{
id: 'randomString112',
title: '국가안전보장회의',
url: '/article/2',
type: 'IT/테크',
content:
'국가는 평생교육을 진흥하여야 한다. 국가안전보장에 관련되는 대외정책·군사정책과 국내정책의 수립에 관하여 국무회의의 심의에 앞서 대통령의 자문에 응하기 위하여 국가안전보장회의를 둔다. 모든 국민은 법률이 정하는 바에 의하여 공무담임권을 가진다. 광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.',
date: '2024-07-13',
thumbnail: 'https://picsum.photos/156',
isRead: false,
from: {
domain: 'official@git',
profile: 'https://picsum.photos/36',
},
},
{
id: 'randomString113',
title: '국가안전보장회의',
url: '/article/3',
type: '시사',
content:
'국가는 평생교육을 진흥하여야 한다. 국가안전보장에 관련되는 대외정책·군사정책과 국내정책의 수립에 관하여 국무회의의 심의에 앞서 대통령의 자문에 응하기 위하여 국가안전보장회의를 둔다. 모든 국민은 법률이 정하는 바에 의하여 공무담임권을 가진다. 광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.',
date: '2024-07-13',
thumbnail: 'https://picsum.photos/156',
isRead: false,
from: {
domain: 'official@git',
profile: 'https://picsum.photos/36',
},
},
];
const getMainPageArticleData = async (): Promise<ArticleType[]> => {
const response = await GET('/articleList');
return response.data;
};
7 changes: 0 additions & 7 deletions src/app/mypage/ProfileCard.tsx

This file was deleted.

33 changes: 33 additions & 0 deletions src/app/mypage/UserDataCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Chip } from '@/components/Chip';
import { UserDataType } from '@/types';
import Image from 'next/image';
import { GET } from '@/network';

const UserDataCard = async () => {
//TODO: 추후 로그인 로직 완성 후 주석 교체
const userData: UserDataType = await getUserData();
// const userData = cookies().get('userData');

Comment on lines +7 to +10
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserDataCard에서 유저의 정보(이름, 이메일, 태그 유형, 프로필사진)를 받아오기 위해

  1. API 호출을 해야하는가
  2. 저장소에서 가져와야하는가

에서 2번을 선택했는데, next의 SSR특성상 localStorage에는 접근할 수 없어서
유저 정보를 로그인하면 쿠키에 저장하고, 필요한 곳에서 쿠키를 꺼내어 쓰는거로 설계를 했는데요,
혹시 이해가 안가는 부분이나, 더 나은 방법이 있다면 말씀주세요!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

한번에 코멘트 남길게요!

return (
<div className='flex flex-col w-full h-full gap-3'>
<Image src={userData.profile} alt='profile' width={80} height={80} className='rounded-full' />
<div className='flex flex-col'>
<span className='text-h2'>{userData.name}</span>
<span className='text-body3'>{userData.email}</span>
</div>
<div className='flex flex-row gap-2'>
{userData.typeList.map(type => (
<Chip key={type} text={type} />
))}
</div>
</div>
);
};

export default UserDataCard;

// TODO: 추후 로그인 로직 완성 후 아래 제거
const getUserData = async () => {
const response = await GET('/userData');
return response.data;
};
Loading
Loading