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
41 changes: 41 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Created by https://www.toptal.com/developers/gitignore/api/nextjs
# Edit at https://www.toptal.com/developers/gitignore?templates=nextjs

### NextJS ###
# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# End of https://www.toptal.com/developers/gitignore/api/nextjs
node_modules
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
# 2hour-blog
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
22 changes: 22 additions & 0 deletions app/_components/Layout/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Image from "next/image";
import logo from "@/public/images/logo-white.svg";

const Footer = () => {
return (
<footer>
<div className="layout-items">
<div className="layout-item">
<Image src={logo} alt="logo" width={122} height={32} />
</div>
<div className="footer-menu layout-item">
<div>Additional Link</div>
<div>Additional Link</div>
<div>Additional Link</div>
</div>
<div className="copyright">© Your Company 2022. We love you!</div>
</div>
</footer>
);
};

export default Footer;
29 changes: 29 additions & 0 deletions app/_components/Layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Image from "next/image";
import logo from "@/public/images/logo.svg";

const Header = () => {
return (
<header>
<div className="layout-items">
<div className="layout-item">
<Image src={logo} alt="logo" width={122} height={32} />
</div>
<div className="header-menu layout-item">
<div>Menu</div>
<div>Menu</div>
<div>Menu</div>
<div>Menu</div>
</div>
<div className="search">
<div className="search-input">
<div>Search</div>
<input />
</div>
</div>
</div>
<div className="line" />
</header>
);
};

export default Header;
Empty file.
25 changes: 25 additions & 0 deletions app/_components/common/PostCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const mockPost = {
title: "Post Title",
category: "Category",
author: "Author",
content:
" Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur.",
};

const PostCard = () => {
return (
<div className="postcard">
<div className="card-thumbnail" />
<div className="card-content">
<div className="title">{mockPost.title}</div>
<p>
<span className="author">{mockPost.author}</span>
<span className="created-at">a min ago</span>
</p>
<div className="content">{mockPost.content}</div>
</div>
</div>
);
};

export default PostCard;
5 changes: 5 additions & 0 deletions app/_components/common/Tag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Tag = ({ text }: { text: string }) => {
return <div className="tag">{text}</div>;
};

export default Tag;
35 changes: 35 additions & 0 deletions app/_components/post/Comment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import CommentForm from "./CommentForm";
import CommentItem from "./CommentItem";

const mockComment = [
{
name: "user1",
content:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ligula nibh, interdum non enim sit amet, iaculis aliquet nunc.",
},
{
name: "user2",
content:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ligula nibh, interdum non enim sit amet, iaculis aliquet nunc.",
},
{
name: "user3",
content:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ligula nibh, interdum non enim sit amet, iaculis aliquet nunc.",
},
];

const Comment = () => {
return (
<div className="comment-container">
<h1>Comments</h1>
<CommentForm />
<div className="comment-list">
{mockComment.map((comment, index) => {
return <CommentItem key={index} comment={comment} />;
})}
</div>
</div>
);
};
export default Comment;
11 changes: 11 additions & 0 deletions app/_components/post/CommentForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const CommentForm = () => {
return (
<div className="comment-area">
<input className="input-username" placeholder="Username..." />
<input className="input-comment" placeholder="Your Comment..." />
<button className="button-submit">Comment</button>
</div>
);
};

export default CommentForm;
23 changes: 23 additions & 0 deletions app/_components/post/CommentItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import profile from "@/public/images/profile.svg";
import Image from "next/image";

const CommentItem = ({ comment }: { comment: { name: string; content: string } }) => {
return (
<div className="comment-block">
<div className="profile-area">
<Image src={profile} alt="profile" width={74} height={74} />
<div>{comment.name}</div>
</div>

<div className="comment-content-area">
<div className="comment-content">{comment.content}</div>
<div className="comment-under">
<div className="comment-reply">Reply</div>
<div className="comment-time">a min ago</div>
</div>
</div>
</div>
);
};

export default CommentItem;
18 changes: 18 additions & 0 deletions app/_components/post/MorePosts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import PostPreview from "./PostPreview";

const mockPost = ["Post Title 01", "Post Title 02", "Post Title 03"];

const MorePosts = () => {
return (
<>
<div className="more-title">More Posts</div>
<div className="more-post">
{mockPost.map((post, index) => {
return <PostPreview key={index} title={post} />;
})}
</div>
</>
);
};

export default MorePosts;
43 changes: 43 additions & 0 deletions app/_components/post/PostContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const mockPost = {
title: "Post Title",
author: "Author",
content: [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ligula nibh, interdum non enim sit amet, iaculis aliquet nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam sit amet ipsum ac velit egestas ultrices. Vestibulum et neque id ex semper varius a sit amet metus. Vivamus congue dolor eget aliquam hendrerit. Etiam iaculis finibus egestas. Nam viverra urna quis odio efficitur malesuada. Maecenas rhoncus enim eu scelerisque rutrum. Pellentesque et mollis enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sed commodo leo. Suspendisse potenti. Maecenas gravida ipsum placerat ligula posuere, ut rhoncus velit eleifend.",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ligula nibh, interdum non enim sit amet, iaculis aliquet nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam sit amet ipsum ac velit egestas ultrices. Vestibulum et neque id ex semper varius a sit amet metus. Vivamus congue dolor eget aliquam hendrerit. Etiam iaculis finibus egestas. Nam viverra urna quis odio efficitur malesuada. Maecenas rhoncus enim eu scelerisque rutrum. Pellentesque et mollis enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sed commodo leo. Suspendisse potenti. Maecenas gravida ipsum placerat ligula posuere, ut rhoncus velit eleifend.",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ligula nibh, interdum non enim sit amet, iaculis aliquet nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam sit amet ipsum ac velit egestas ultrices. Vestibulum et neque id ex semper varius a sit amet metus. Vivamus congue dolor eget aliquam hendrerit. Etiam iaculis finibus egestas. Nam viverra urna quis odio efficitur malesuada. Maecenas rhoncus enim eu scelerisque rutrum. Pellentesque et mollis enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sed commodo leo. Suspendisse potenti. Maecenas gravida ipsum placerat ligula posuere, ut rhoncus velit eleifend.",
],
};

const PostContent = () => {
return (
<div className="post-detail">
<div className="detail-info">
<div className="link">
<div className="home">Home</div>
<div> / </div>
<div>{mockPost.title}</div>
</div>
<h1>{mockPost.title}</h1>
<div className="author-time">
<div className="author">{mockPost.author} </div>
<div>|</div>
<div>a min ago</div>
</div>
</div>
<div className="detail-content">
<div className="thumbnail" />
<div className="detail-text">
{mockPost.content.map((content, index) => {
return (
<div className="text-block" key={index}>
{content}
</div>
);
})}
</div>
</div>
</div>
);
};

export default PostContent;
10 changes: 10 additions & 0 deletions app/_components/post/PostPreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const PostPreview = ({ title }: { title: string }) => {
return (
<div>
<div className="preview-thumbnail" />
<h3>{title}</h3>
</div>
);
};

export default PostPreview;
27 changes: 27 additions & 0 deletions app/_components/post/Share.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Tag from "../common/Tag";
import Image from "next/image";
import facebook from "@/public/images/facebook.svg";
import twitter from "@/public/images/twitter.svg";
import instagram from "@/public/images/instagram.svg";

const Share = () => {
return (
<div className="share-container">
<div className="sns-container">
<div>Share this</div>

<div className="sns">
<Image src={facebook} alt="facebook" width={40} height={40} />
<Image src={twitter} alt="twitter" width={40} height={40} />
<Image src={instagram} alt="instagram" width={40} height={40} />
</div>
</div>
<div className="tag-container">
<Tag text="design" />
<Tag text="web" />
</div>
</div>
);
};

export default Share;
Binary file added app/favicon.ico
Binary file not shown.
23 changes: 23 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Header from "./_components/layout/Header";
import Footer from "./_components/layout/Footer";
import "./styles/main.scss";
import localFont from "next/font/local";

export const montserrat = localFont({
src: "../public/fonts/Montserrat-VariableFont_wght.ttf",
display: "swap",
weight: "100 900",
variable: "--font-montserrat",
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ko" className={montserrat.className}>
<body>
<Header />
<main>{children}</main>
<Footer />
</body>
</html>
);
}
23 changes: 23 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Image from "next/image";
import arrow from "@/public/images/arrow.svg";
import PostCard from "./_components/common/PostCard";

export default function Home() {
return (
<div className="main-content">
<div className="align-title">
<div className="featured-post">Featured Posts</div>
<div className="more">
More
<Image src={arrow} alt="arrow" width={50} height={50} />
</div>
</div>
<div className="align-card">
<PostCard />
<PostCard />
</div>

<div className="short-line" />
</div>
);
}
Loading