Skip to content
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
12 changes: 10 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { Route, Switch } from 'react-router-dom';
// import MainPage from './pages/main/MainPage';
import { Route, Switch, Redirect } from 'react-router-dom';
// import PostPage from './pages/PostPage';

import loadable from '@loadable/component';
Expand All @@ -13,6 +12,7 @@ import ErrorBoundary from './components/error/ErrorBoundary';
import NotFoundPage from './pages/NotFoundPage';
import { Helmet } from 'react-helmet-async';
import HomePage from './pages/home/HomePage';
import MainPageTemplate from './components/main/MainPageTemplate';

const loadableConfig = {
fallback: <PageTemplate />,
Expand All @@ -39,6 +39,12 @@ const SettingPage = loadable(
loadableConfig,
);
const SuccessPage = loadable(() => import('./pages/SuccessPage'));
const ReadingListPage = loadable(
() => import('./pages/readingList/ReadingListPage'),
{
fallback: <MainPageTemplate />,
},
);

interface AppProps {}

Expand Down Expand Up @@ -73,6 +79,8 @@ const App: React.FC<AppProps> = props => {
<Route path={['/policy/:type?']} component={PolicyPage} />
<Route path="/setting" component={SettingPage} />
<Route path="/success" component={SuccessPage} />
<Route path="/lists/:type(liked|read)" component={ReadingListPage} />
<Route path="/lists" render={() => <Redirect to="/lists/liked" />} />
<Route component={NotFoundPage} />
</Switch>
</ErrorBoundary>
Expand Down
6 changes: 3 additions & 3 deletions src/components/base/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import HeaderLogo from './HeaderLogo';
import media from '../../lib/styles/media';
import { SearchIcon2 } from '../../static/svg';
import { Link } from 'react-router-dom';
import HomeResponsive from '../home/HomeResponsive';
import MainResponsive from '../main/MainResponsive';

const HeaderBlock = styled.div<{ floating: boolean }>`
width: 100%;
Expand Down Expand Up @@ -123,7 +123,7 @@ const Header: React.FC<HeaderProps> = ({
style={{ marginTop: floating ? floatingMargin : 0 }}
data-testid="Header"
>
<HomeResponsive>
<MainResponsive>
<div className="wrapper">
<div className="brand">
<HeaderLogo
Expand Down Expand Up @@ -181,7 +181,7 @@ const Header: React.FC<HeaderProps> = ({
)}
</div>
</div>
</HomeResponsive>
</MainResponsive>
</HeaderBlock>
{floating && <Placeholder />}
</>
Expand Down
1 change: 1 addition & 0 deletions src/components/base/HeaderUserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const HeaderUserMenu: React.FC<HeaderUserMenuProps> = ({
내 벨로그
</HeaderUserMenuItem>
<HeaderUserMenuItem to="/saves">임시 글</HeaderUserMenuItem>
<HeaderUserMenuItem to="/lists/liked">읽기 목록</HeaderUserMenuItem>
<HeaderUserMenuItem to="/setting">설정</HeaderUserMenuItem>
<HeaderUserMenuItem onClick={onLogout}>로그아웃</HeaderUserMenuItem>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/components/base/HeaderUserMenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const HeaderUserMenuItemBlock = styled.div`
padding: 0.75rem 1rem;
line-height: 1.5;
font-weight: 500;
cursor: pointer;
&:hover {
background: ${palette.gray0};
}
Expand Down
56 changes: 44 additions & 12 deletions src/components/common/HorizontalTab.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import styled from 'styled-components';
import styled, { css } from 'styled-components';
import { Link } from 'react-router-dom';
import palette from '../../lib/styles/palette';
import { useSpring, animated } from 'react-spring';
Expand All @@ -10,13 +10,17 @@ export type HorizontalTabProps = {
children: React.ReactElement<TabItemProps>[];
activeTab: string;
tabWidth: number;
align: 'center' | 'left';
theme: 'teal' | 'gray';
};

function HorizontalTab({
className,
children,
activeTab,
tabWidth,
align,
theme,
}: HorizontalTabProps) {
const activeIndex = React.Children.toArray(children).findIndex(
tab => tab.props.name === activeTab,
Expand All @@ -34,22 +38,25 @@ function HorizontalTab({
});

return (
<Block className={className}>
<Block className={className} align={align}>
<div className="tab-wrapper">
{React.Children.map(children, tab => {
return React.cloneElement(tab, {
active: tab.props.name === activeTab,
width: `${tabWidth}rem`,
theme,
});
})}
<Indicator style={springStyle} />
<Indicator style={springStyle} theme={theme} />
</div>
</Block>
);
}

HorizontalTab.defaultProps = {
tabWidth: 8,
align: 'center',
theme: 'teal',
};

export type TabItemProps = {
Expand All @@ -58,42 +65,62 @@ export type TabItemProps = {
to: string;
active?: boolean;
width?: string;
theme: 'teal' | 'gray';
};

function TabItem({ name, text, to, active, width }: TabItemProps) {
function TabItem({ name, text, to, active, width, theme }: TabItemProps) {
return (
<StyledLink to={to} className={active ? 'active' : ''} style={{ width }}>
<StyledLink
to={to}
className={active ? 'active' : ''}
style={{ width }}
theme={theme}
>
{text}
</StyledLink>
);
}

const Block = styled.div`
TabItem.defaultProps = {
theme: 'teal',
};

const Block = styled.div<{ align: 'center' | 'left' }>`
display: flex;
justify-content: center;
${props =>
props.align === 'center' &&
css`
justify-content: center;
`}
.tab-wrapper {
display: flex;
position: relative;
}
`;

const Indicator = styled(animated.div)`
const Indicator = styled(animated.div)<{ theme: 'teal' | 'gray' }>`
height: 2px;
display: block;
position: absolute;
bottom: 0px;
background: ${palette.teal5};
${props =>
props.theme === 'gray' &&
css`
background: ${palette.gray8};
`}
`;

const StyledLink = styled(Link)`
const StyledLink = styled(Link)<{
theme: 'teal' | 'gray';
}>`
width: 8rem;
height: 3rem;
font-size: 1.3125rem;
font-size: 1.125rem;
${media.small} {
height: 2.5rem;
font-size: 1rem;
}
color: ${palette.gray7};
color: ${palette.gray6};
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -102,6 +129,11 @@ const StyledLink = styled(Link)`
&.active {
font-weight: bold;
color: ${palette.teal5};
${props =>
props.theme === 'gray' &&
css`
color: ${palette.gray8};
`}
}
`;

Expand Down
1 change: 1 addition & 0 deletions src/components/common/MarkdownRender.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ function filter(html: string) {
'iframe',
'span',
'img',
'del',
],
allowedAttributes: {
a: ['href', 'name', 'target'],
Expand Down
27 changes: 22 additions & 5 deletions src/components/common/PostCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ import usePrefetchPost from '../../lib/hooks/usePrefetchPost';

export type PostCardProps = {
post: PartialPost;
forHome?: boolean;
};

function PostCard({ post }: PostCardProps) {
function PostCard({ post, forHome }: PostCardProps) {
const url = `/@${post.user.username}/${post.url_slug}`;

const prefetch = usePrefetchPost(post.user.username, post.url_slug);
Expand All @@ -35,7 +36,11 @@ function PostCard({ post }: PostCardProps) {
};

return (
<Block onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<Block
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
forHome={!!forHome}
>
{post.thumbnail && (
<StyledLink to={url}>
<RatioImage
Expand Down Expand Up @@ -83,9 +88,9 @@ function PostCard({ post }: PostCardProps) {
);
}

export function PostCardSkeleton() {
export function PostCardSkeleton({ forHome }: { forHome?: boolean }) {
return (
<SkeletonBlock>
<SkeletonBlock forHome={!!forHome}>
<div className="skeleton-thumbnail-wrapper">
<Skeleton className="skeleton-thumbnail"></Skeleton>
</div>
Expand Down Expand Up @@ -136,7 +141,7 @@ const StyledLink = styled(Link)`
text-decoration: none;
`;

const Block = styled.div`
const Block = styled.div<{ forHome: boolean }>`
width: 20rem;
background: white;
border-radius: 4px;
Expand All @@ -153,6 +158,18 @@ const Block = styled.div`
overflow: hidden;
display: flex;
flex-direction: column;

${props =>
!props.forHome &&
css`
${mediaQuery(1440)} {
width: calc(25% - 2rem);
}
${mediaQuery(1312)} {
width: calc(33% - 1.8125rem);
}
`}

${mediaQuery(944)} {
width: calc(50% - 2rem);
}
Expand Down
10 changes: 8 additions & 2 deletions src/components/common/PostCardGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@ import { mediaQuery } from '../../lib/styles/media';

export type PostCardGridProps = {
posts: PartialPost[];
loading?: boolean;
forHome?: boolean;
};

function PostCardGrid({ posts }: PostCardGridProps) {
function PostCardGrid({ posts, loading, forHome }: PostCardGridProps) {
return (
<Block>
{posts.map(post => (
<PostCard post={post} key={post.id} />
<PostCard post={post} key={post.id} forHome={forHome} />
))}
{loading &&
Array.from({ length: 8 }).map((_, i) => (
<PostCardSkeleton key={i} forHome={forHome} />
))}
</Block>
);
}
Expand Down
Loading