Skip to content
Open
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
26 changes: 26 additions & 0 deletions App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import styled from "styled-components";
import MainPage from "./Component/page/MainPage";
import PostWritePage from "./Component/page/PostWritePage";
import PostViewPage from "./Component/page/PostViewPage";

const MainTitleText = styled.p`
font-size: 24px;
font-weight: bold;
text-align: center;
`;
function App() {
return (
<BrowserRouter>
<MainTitleText>소플의 미니 블로그</MainTitleText>
<Routes>
<Route index element={<MainPage />} />
<Route path="post-write" element={<PostWritePage />} />
<Route path="post/:postId" element={<PostViewPage />} />
</Routes>
</BrowserRouter>
);
}

export default App;
15 changes: 15 additions & 0 deletions Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 8px 16px;
font-size: 16px;
border-width: 1px;
border-radius: 8px;
cursor: pointer;
`;

function Button(props) {
const { title, onClick } = props;
return <StyledButton onClick={onClick}>{title || "button"}</StyledButton>;
}
export default Button;
33 changes: 33 additions & 0 deletions CommentLIstItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import styled from "styled-components";

const Wrapper = styled.div`
width: calc(100%-32px);
padding: 16px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
border: 1px solid grey;
border-radius: 8px;
cursor: pointer;
background: white;
:hover {
background: lightgrey;
}
`;

const ContentText = styled.p`
font-size: 14px;
`;

function CommentListItem(props) {
const { comment } = props;

return (
<Wrapper>
<ContentText>{comment.content}</ContentText>
</Wrapper>
);
}
export default CommentListItem;
28 changes: 28 additions & 0 deletions CommentList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import styled from "styled-components";
import CommentListItem from "./CommentLIstItem";

const Wrapper = styled.div`
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
& > * {
:not(:last-child) {
margin-bottom: 16px;
}
}
`;
function CommentList(props) {
const { comments } = props;
return (
<Wrapper>
{comments.map((comment, index) => {
return (
<CommentListItem key={comment.id} comment={comment}></CommentListItem>
);
})}
</Wrapper>
);
}
export default CommentList;
51 changes: 51 additions & 0 deletions MainPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from "react";
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
import PostList from "../list/PostList";
import Button from "../UI/Button";
import data from "../../data.json";

const Wrapper = styled.div`
width: calc(100%-32px);
padding: 16px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
`;

const Container = styled.div`
width: 100$;
max-width: 720px;

& > * {
:not(:last-child) {
margin-bottom: 16px;
}
}
`;

function MainPage(props) {
const {} = props;
const navigate = useNavigate();
return (
<Wrapper>
<Container>
<Button
title="글 작성하기"
onClick={() => {
navigate("/post-write");
}}
>
<PostList
posts={data}
onClickItem={(item) => {
navigate(`/post/${item.id}`);
}}
></PostList>
</Button>
</Container>
</Wrapper>
);
}
export default MainPage;
34 changes: 34 additions & 0 deletions PostList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import styled from "styled-components";
import PostListItem from "./PostListItem";

const Wrapper = styled.div`
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
& > * {
:not(:last-child) {
margin-bottom: 16px;
}
}
`;
function PostList(props) {
const { posts, onClickItem } = props;
return (
<Wrapper>
{posts.map((post, index) => {
return (
<PostListItem
key={post.id}
post={post}
onClick={() => {
onClickItem(post);
}}
></PostListItem>
);
})}
</Wrapper>
);
}
export default PostList;
32 changes: 32 additions & 0 deletions PostListItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from "react";
import styled from "styled-components";

const Wrapper = styled.div`
width: calc(100%-32px);
padding: 16px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
border: 1px solid grey;
border-radius: 8px;
cursor: pointer;
background: white;
:hover {
background: lightgrey;
}
`;
const TitleText = styled.p`
font-size: 20px;
font-weight: 500;
`;
function PostListItem(props) {
const { post, onClick } = props;
return (
<Wrapper onClick={onClick}>
<TitleText>{post.title}</TitleText>
</Wrapper>
);
}

export default PostListItem;
88 changes: 88 additions & 0 deletions PostViewPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import styled from "styled-components";
import CommentList from "../list/CommentList";
import TextInput from "../UI/TextInput";
import Button from "../UI/Button";
import data from "../../data.json";

const Wrapper = styled.div`
width: calc(100%-32px);
padding: 16px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
`;

const Container = styled.div`
width: 100$;
max-width: 720px;

& > * {
:not(:last-child) {
margin-bottom: 16px;
}
}
`;

const PostContainer = styled.div`
padding: 8px 16px;
border: 1px solid grey;
border-radius: 8px;
`;
const TitleText = styled.p`
font-size:28px;
font-weight;500;
`;
const ContentText = styled.p`
font-size: 20px;
line-height: 32px;
white-space: pre-wrap;
`;
const CommentLabel = styled.p`
font-size: 16px;
font-weight: 500;
`;
function PostViewPage(props) {
const navigate = useNavigate();
const { postId } = useParams();
const post = data.find((item) => {
return item.id == postId;
});
const [comment, setComment] = useState("");

return (
<Wrapper>
<Container>
<Button
title="뒤로가기"
onClick={() => {
navigate("/");
}}
></Button>
<PostContainer>
<TitleText>{post.title}</TitleText>
<ContentText>{post.content}</ContentText>
</PostContainer>
<CommentLabel>댓글</CommentLabel>
<CommentList comments={post.comments}></CommentList>
<TextInput
height={40}
value={comment}
onChange={(event) => {
setComment(event.target.value);
}}
></TextInput>
<Button
title="댓글 작성하기"
onClick={() => {
navigate("/");
}}
></Button>
</Container>
</Wrapper>
);
}

export default PostViewPage;
58 changes: 58 additions & 0 deletions PostWritePage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
import TextInput from "../UI/TextInput";
import Button from "../UI/Button";

const Wrapper = styled.div`
width: calc(100%-32px);
padding: 16px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
`;

const Container = styled.div`
width: 100%;
max-width: 720px;

& > * {
:not(:last-child) {
margin-bottom: 16px;
}
}
`;

function PostWritePage(props) {
const navigate = useNavigate();
const [title, setTItle] = useState("");
const [content, setContent] = useState("");
return (
<Wrapper>
<Container>
<TextInput
height={20}
value={title}
onChange={(event) => {
setTItle(event.target.value);
}}
></TextInput>
<TextInput
height={480}
value={content}
onChange={(event) => {
setContent(event.target.value);
}}
></TextInput>
<Button
title="글 작성하기"
onClick={() => {
navigate("/");
}}
></Button>
</Container>
</Wrapper>
);
}
export default PostWritePage;
25 changes: 25 additions & 0 deletions TextInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import styled from "styled-components";

const StyledTextarea = styled.textarea`
width: calc(100%-32px);
${(props) =>
props.height &&
`height:${props.height}px;
`}
padding:16px;
font-size: 16px;
line=height: 20px;
`;

function TextInput(props) {
const { height, value, onChange } = props;
return (
<StyledTextarea
height={height}
value={value}
onChange={onChange}
></StyledTextarea>
);
}
export default TextInput;
Loading