Skip to content

Commit

Permalink
Merge pull request #76 from themoment-team/develop
Browse files Browse the repository at this point in the history
Release v1.3.0 (Gwangya)
  • Loading branch information
hyeongrok7874 authored Dec 4, 2023
2 parents 7d8e535 + 4ed6ae2 commit ae85ee1
Show file tree
Hide file tree
Showing 34 changed files with 722 additions and 59 deletions.
53 changes: 53 additions & 0 deletions src/app/auth/refresh/gwangya/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { cookies } from 'next/headers';
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';

import { gwangyaUrl } from '@/libs';
import type { GetGwangyaTokenType } from '@/types';

const cookieDomain =
process.env.NODE_ENV === 'development' ? 'localhost' : '.gsm-networking.com';

const setCookie = (name: string, value: string, expires: Date) => {
cookies().set(name, value, {
expires,
domain: cookieDomain,
});
};

export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams;

const redirectPath = searchParams.get('redirect') || '/community/gwangya';

const cookieStore = cookies();

const accessToken = cookieStore.get('accessToken')?.value;

const res = await fetch(
new URL(`/api/v1${gwangyaUrl.getGwangyaToken()}`, process.env.BASE_URL),
{
method: 'GET',
headers: {
Cookie: `accessToken=${accessToken}`,
},
}
);

if (!res.ok) {
return NextResponse.redirect(
new URL(`/auth/refresh?redirect=/auth/refresh/gwangya`, request.url)
);
}

const body: GetGwangyaTokenType = await res.json();

const gwangyaToken = body.gwangyaToken;
const expires = body.expiredTime;

const expiresDate = new Date(`${expires}Z`);

setCookie('gwangyaToken', gwangyaToken, expiresDate);

return NextResponse.redirect(new URL(redirectPath, request.url));
}
38 changes: 37 additions & 1 deletion src/app/community/gwangya/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';

import { gwangyaUrl } from '@/libs';
import { Gwangya } from '@/pageContainer';
import type { GwangyaPostType } from '@/types';

import type { Metadata } from 'next';

Expand All @@ -7,6 +12,37 @@ export const metadata: Metadata = {
description: '익명으로 자유롭게 소통할 수 있는 광소마의 넓은 들판입니다.',
};

const GwangyaPage = () => <Gwangya />;
const GwangyaPage = async () => {
const postList = await getGwangyaPostList();

return <Gwangya initialData={postList} />;
};

const getGwangyaPostList = async (): Promise<GwangyaPostType[]> => {
const gwangyaToken = cookies().get('gwangyaToken')?.value;

if (!gwangyaToken)
return redirect('/auth/refresh/gwangya?redirect=/community/gwangya');

const response = await fetch(
new URL(
`/api/v1${gwangyaUrl.getGwangyaPostList(0)}`,
process.env.NEXT_PUBLIC_API_BASE_URL
),
{ headers: { GwangyaToken: gwangyaToken } }
);

if (response.status === 401) {
return redirect('/auth/refresh/gwangya?redirect=/community/gwangya');
}

if (!response.ok) {
return redirect('/auth/signin');
}

const postList: GwangyaPostType[] = await response.json();

return postList;
};

export default GwangyaPage;
3 changes: 3 additions & 0 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ export const metadata: Metadata = {

const getMentorList = async (): Promise<WorkerType[]> => {
const accessToken = cookies().get('accessToken')?.value;
const gwangyaToken = cookies().get('gwangyaToken')?.value;

if (!accessToken) return redirect('/auth/refresh');

if (!gwangyaToken) return redirect('/auth/refresh/gwangya?redirect=/');

const response = await fetch(
new URL(`/api/v1${mentorUrl.getMentorList()}`, process.env.BASE_URL),
{
Expand Down
17 changes: 17 additions & 0 deletions src/assets/UploadIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const UploadIcon = () => (
<svg
width='2.25rem'
height='2.25rem'
viewBox='0 0 36 36'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<circle cx='18' cy='18' r='15' fill='#94CCFF' />
<path
d='M17.25 24C17.25 24.4142 17.5858 24.75 18 24.75C18.4142 24.75 18.75 24.4142 18.75 24L17.25 24ZM18.5303 11.4697C18.2374 11.1768 17.7626 11.1768 17.4697 11.4697L12.6967 16.2426C12.4038 16.5355 12.4038 17.0104 12.6967 17.3033C12.9896 17.5962 13.4645 17.5962 13.7574 17.3033L18 13.0607L22.2426 17.3033C22.5355 17.5962 23.0104 17.5962 23.3033 17.3033C23.5962 17.0104 23.5962 16.5355 23.3033 16.2426L18.5303 11.4697ZM18.75 24L18.75 12L17.25 12L17.25 24L18.75 24Z'
fill='#148EFF'
/>
</svg>
);

export default UploadIcon;
1 change: 1 addition & 0 deletions src/assets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export { default as SNSIcon } from './SNSIcon';
export { default as SearchIcon } from './SearchIcon';
export { default as SearchNotFoundIcon } from './SearchNotFoundIcon';
export { default as TriangleIcon } from './TriangleIcon';
export { default as UploadIcon } from './UploadIcon';
35 changes: 34 additions & 1 deletion src/components/CommunityCard/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import type { Meta, StoryObj } from '@storybook/react';
const meta: Meta<typeof CommunityCard> = {
component: CommunityCard,
args: {
index: 1,
id: 1,
createdAt: '2023-11-27T09:10:00.000',
},
};

Expand All @@ -26,3 +27,35 @@ export const LongContent: Story = {
'커뮤니티는사람들이모여서서로의관심사를공유하고소통하는공간으로다양한경험과지식을교환하며서로를돕고이해하는장소입니다온라인이나오프라인에서형성되며멤버들은공동의목표를달성하거나지식을나누며함께성장합니다이는문화적사회적차원에서다양성을존중하고유대감을형성하며새로운아이디어를육성하고진보하는데중요한역할을합니다상호작용과협력을통해커뮤니티는멤버들의참여와기여를촉진하며함께하는경험을즐기고배우는공간으로자리매깁니다',
},
};

export const TenUnderTime: Story = {
args: {
content:
'커뮤니티는 다양한 사람들이 모여 소통하고 공유하는 공간으로, 서로의 경험과 지식을 나누며 유대감을 형성합니다.',
createdAt: '2023-11-27T09:09:00.000',
},
};

export const AfternoonTime: Story = {
args: {
content:
'커뮤니티는 다양한 사람들이 모여 소통하고 공유하는 공간으로, 서로의 경험과 지식을 나누며 유대감을 형성합니다.',
createdAt: '2023-11-27T19:09:00.000',
},
};

export const MidnightTime: Story = {
args: {
content:
'커뮤니티는 다양한 사람들이 모여 소통하고 공유하는 공간으로, 서로의 경험과 지식을 나누며 유대감을 형성합니다.',
createdAt: '2023-11-27T00:00:00.000',
},
};

export const AtNoonTime: Story = {
args: {
content:
'커뮤니티는 다양한 사람들이 모여 소통하고 공유하는 공간으로, 서로의 경험과 지식을 나누며 유대감을 형성합니다.',
createdAt: '2023-11-27T12:09:00.000',
},
};
59 changes: 41 additions & 18 deletions src/components/CommunityCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
import React from 'react';
'use client';

import React, { forwardRef } from 'react';

import * as S from './style';

interface Props {
index: number;
content: string;
}

const CommunityCard: React.FC<Props> = ({ index, content }) => (
<S.CardWrapper>
<S.Header>
<S.Index>#{index}</S.Index>
<S.DateBox>
{/* TODO: 추후에 api 연동 시, Date 핸들링 구체화 하겠습니다. */}
<S.Date>2020.01.01</S.Date>
<S.Time>12:12</S.Time>
</S.DateBox>
</S.Header>
<S.Content>{content}</S.Content>
</S.CardWrapper>
import type { GwangyaPostType } from '@/types';

const addZero = (num: number): string => (num < 10 ? `0${num}` : `${num}`);

const removeDuplicateEnter = (str: string) => str.replaceAll(/\n+/g, '\n');

const CommunityCard = forwardRef<HTMLDivElement, GwangyaPostType>(
({ id, content, createdAt }, ref) => {
const createdDate = new Date(createdAt + 'Z');

const createdMonth = createdDate.getMonth() + 1;
const createdDay = createdDate.getDate();
const createdTime = createdDate.getHours();
const createdMinute = createdDate.getMinutes();
const morningOrAfternoon = createdTime < 12 ? '오전' : '오후';
const convertCreatedTime =
createdTime > 12 ? createdTime - 12 : createdTime;

return (
<S.CardWrapper ref={ref}>
<S.Header>
<S.Index>#{id}</S.Index>
<S.DateBox>
<S.Date>
{createdMonth}{createdDay}
</S.Date>
<S.Time>
{morningOrAfternoon} {addZero(convertCreatedTime)}:
{addZero(createdMinute)}
</S.Time>
</S.DateBox>
</S.Header>
<S.Content>{removeDuplicateEnter(content)}</S.Content>
</S.CardWrapper>
);
}
);

CommunityCard.displayName = 'CommunityCard';

export default CommunityCard;
6 changes: 4 additions & 2 deletions src/components/CommunityCard/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const Index = styled.p`
color: ${({ theme }) => theme.color.black};
`;

export const DateBox = styled.p`
export const DateBox = styled.div`
${({ theme }) => theme.typo.caption}
color: ${({ theme }) => theme.color.grey[500]};
display: flex;
Expand All @@ -30,7 +30,9 @@ export const Date = styled.p``;

export const Time = styled.time``;

export const Content = styled.p`
export const Content = styled.pre`
width: 100%;
white-space: break-spaces;
${({ theme }) => theme.typo.body1}
color: #000000;
`;
20 changes: 15 additions & 5 deletions src/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,42 @@ const Header: React.FC<Props> = ({ clearList }) => {

const { push } = useRouter();

const comingSoonToast = () => toast.info('곧 출시 예정입니다. 감사합니다.');

const handleProfileClick = () => {
if (data) push('/mypage');
else toast.info('멘티인 사용자에게는 지원되지 않는 기능입니다.');
};

return (
<S.Header>
<meta
name='viewport'
content='width=device-width, initial-scale=1, maximum-scale=1'
/>
<S.Inner>
<S.LogoLink href='/' onClick={clearList}>
<I.GsmNetworkingIcon />
GSM Networking
</S.LogoLink>
<S.RightBox>
<S.RedirectBox>
<S.MentorContact type='button' onClick={comingSoonToast}>
<S.CommunityLink href='/community/gwangya'>
커뮤니티
</S.CommunityLink>
{/* <S.MentorContact type='button' onClick={comingSoonToast}>
멘토 컨택
</S.MentorContact>
</S.MentorContact> */}
{!data && (
<S.RedirectLink href='/register/search'>멘토 등록</S.RedirectLink>
)}
</S.RedirectBox>
<S.ProfileBox type='button' onClick={handleProfileClick}>
{data?.profileUrl ? (
<Image src={data.profileUrl} alt='profile img' fill />
<Image
src={data.profileUrl}
alt='profile img'
fill
sizes='36px'
/>
) : (
<I.MyPageIcon />
)}
Expand Down
5 changes: 5 additions & 0 deletions src/components/Header/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export const LogoLink = styled(Link)`
column-gap: 0.38rem;
`;

export const CommunityLink = styled(Link)`
${({ theme }) => theme.typo.body1};
color: ${({ theme }) => theme.color.grey[400]};
`;

export const MentorContact = styled.button`
${({ theme }) => theme.typo.body1};
color: ${({ theme }) => theme.color.grey[400]};
Expand Down
4 changes: 0 additions & 4 deletions src/components/SearchBar/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ export const SearchInput = styled.input`
border-radius: 0.625rem;
border: 0.0625rem solid ${({ theme }) => theme.color.grey[100]};
@media (max-width: 600px) {
font-size: 16px;
}
&::placeholder {
${({ theme }) => theme.typo.body1};
color: ${({ theme }) => theme.color.grey[400]};
Expand Down
13 changes: 13 additions & 0 deletions src/components/TextArea/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import TextArea from '.';

import type { Meta, StoryObj } from '@storybook/react';

const meta: Meta<typeof TextArea> = {
component: TextArea,
};

export default meta;

type Story = StoryObj<typeof TextArea>;

export const Primary: Story = {};
Loading

0 comments on commit ae85ee1

Please sign in to comment.