Skip to content
Snippets Groups Projects
Commit 34705aa9 authored by 이명건's avatar 이명건
Browse files

Finally checking practice 2

parent 480d035a
No related branches found
No related tags found
No related merge requests found
Showing
with 366 additions and 2 deletions
general-server @ 58994f93
Subproject commit 58994f93a24220ccffb34c0cec78e8036718587f
next-posts-app @ b2fc16e6
Subproject commit b2fc16e65071b7410d7c09e42e45cd784a33371d
{
"presets": ["next/babel"],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true,
"preprocess": false
}
]
]
}
\ No newline at end of file
node_modules
yarn.lock
.next
\ No newline at end of file
# next-posts-app
nextjs 학습 목적을 위해 만든 코드입니다.
export * from "./post.api";
import fetch from "isomorphic-unfetch";
const API_URL = "http://localhost:4000/api";
export interface PostType {
id: string;
title: string;
content: string;
}
export async function getPosts() {
const request = await fetch(`${API_URL}/posts`);
const response = await request.json();
const { posts } = response;
return {
posts,
};
}
export async function getPost(postId: string) {
const request = await fetch(`${API_URL}/posts/${postId}`);
const response = await request.json();
const { post } = response;
return {
post,
};
}
import Link from "next/link";
import React from "react";
import styled from "styled-components";
export const Header: React.FC = () => {
return (
<Container>
<Link href="/">
<Logo>Post-app</Logo>
</Link>
</Container>
);
};
const Container = styled.div`
backgroudn-color: white;
color: #222222;
`;
const Logo = styled.a`
color: #222222;
font-weight: bold;
font-size: 24px;
cursor: pointer;
`;
import Head from "next/head";
import React from "react";
import styled from "styled-components";
import { Header } from "./Header";
interface Props {
title: string;
}
export const MainLayout: React.FC<Props> = ({ title, children }) => {
return (
<Container>
<Head>
<title>{title}</title>
<meta charSet="utf-8" />
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<HeaderWrapper>
<Header />
</HeaderWrapper>
<Main>{children}</Main>
</Container>
);
};
const Container = styled.div`
width: 100%;
background-color: white;
`;
const HeaderWrapper = styled.header`
width: 100%;
padding: 30px 24px;
border-bottom: 1px solid #eeeeee;
margin-bottom: 12px;
`;
const Main = styled.main`
width: 100%;
padding: 30px 24px;
`;
import React from "react";
import styled from "styled-components";
import { PostType } from "../api";
interface Props {
post: PostType;
}
export const Post: React.FC<Props> = ({ post }) => {
return (
<Container>
<Header>
<Title>{post.title}</Title>
<Content>{post.content}</Content>
</Header>
</Container>
);
};
const Container = styled.div`
width: 100%;
`;
const Header = styled.div`
margin-bottom: 12px;
`;
const Title = styled.h1`
color: #222222;
font-size: 18px;
font-weight: bold;
`;
const Content = styled.p`
font-size: 14px;
color: #222222;
`;
import Link from "next/link";
import React from "react";
import styled from "styled-components";
import { PostType } from "../api";
interface Props {
post: PostType;
}
export const PostItem: React.FC<Props> = ({ post }) => {
return (
<Link href={`/posts/[id]`} as={`/posts/${post.id}`}>
<Container>{post.title}</Container>
</Link>
);
};
const Container = styled.div`
width: 100%;
border: 1px solid #eeeeee;
padding: 32px;
cursor: pointer;
`;
import React from "react";
import styled from "styled-components";
import { PostType } from "../api";
import { PostItem } from "./PostItem";
interface Props {
posts: PostType[];
}
export const PostList: React.FC<Props> = ({ posts }) => {
return (
<div>
{posts.map((post) => {
return (
<PostWrapper key={post.id}>
<PostItem post={post} />
</PostWrapper>
);
})}
</div>
);
};
const PostWrapper = styled.div`
margin-bottom: 12px;
:last-child {
margin-bottom: 0;
}
`;
/// <reference types="next" />
/// <reference types="next/types/global" />
{
"name": "next-posts-app",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/jeffchoi72/next-posts-app.git",
"author": "jeffchoi72 <ihello0720@gmail.com>",
"license": "MIT",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"isomorphic-unfetch": "^4.0.2",
"next": "^9.1.4",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"styled-components": "^6.1.11"
},
"devDependencies": {
"@types/node": "^12.12.14",
"@types/react": "^16.9.13",
"@types/styled-components": "^5.1.34",
"babel-plugin-styled-components": "^2.1.4",
"typescript": "^3.7.2"
}
}
import Document, { DocumentContext } from "next/document";
import { ServerStyleSheet } from "styled-components";
class CustomDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles} {sheet.getStyleElement()}{" "}
</>
),
};
} catch (error) {
throw error;
} finally {
sheet.seal();
}
}
}
export default CustomDocument;
import { NextPage } from "next";
import React from "react";
import { getPosts, PostType } from "../api";
import { MainLayout } from "../components/MainLayout";
import { PostList } from "../components/PostList";
interface Props {
posts: PostType[];
}
const Home: NextPage<Props> = ({ posts }) => (
<MainLayout title="홈">
<PostList posts={posts} />
</MainLayout>
);
Home.getInitialProps = async () => {
const { posts } = await getPosts();
console.log("executed home getInitialProps");
return {
posts,
};
};
export default Home;
import { NextPage, NextPageContext } from "next";
import Link from "next/link";
import React from "react";
import styled from "styled-components";
import { getPost, PostType } from "../../api";
import { MainLayout } from "../../components/MainLayout";
import { Post } from "../../components/Post";
interface Props {
post: PostType;
}
const PostDetailPage: NextPage<Props> = ({ post }) => {
return (
<MainLayout title={`${post.title} 게시글`}>
<Link href="/">
<BackToHome>홈으로 돌아가기</BackToHome>
</Link>
<Divier />
<Post post={post} />
</MainLayout>
);
};
PostDetailPage.getInitialProps = async (ctx: NextPageContext) => {
const { id } = ctx.query;
const { post } = await getPost(id as string);
console.log("executed posts/[id] getInitialProps");
return {
post,
};
};
export default PostDetailPage;
const BackToHome = styled.a`
color: #2f5fd1;
cursor: pointer;
display: block;
`;
const Divier = styled.div`
height: 1px;
border-bottom: 1px solid #eeeeee;
margin: 24px 0;
`;
const Test = () => {
return <div>Test</div>;
};
export default Test;
\ No newline at end of file
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}
\ No newline at end of file
node_modules
yarn.lock
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment