Skip to content

Commit

Permalink
Merge pull request #32 from prgrms-fe-devcourse/feat/#2
Browse files Browse the repository at this point in the history
Feat/#2
  • Loading branch information
youngjulee23 authored Oct 29, 2024
2 parents 20d8177 + 93a3c79 commit a1f4678
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 28 deletions.
5 changes: 5 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import WritingPage from './pages/WritingPage'
import PageLayout from './layouts/pageLayout'
import MyPage from './pages/MyPage'
import PostPage from './pages/PostPage'
import MainPage from './pages/MainPage'
import SearchPage from './pages/SearchPage'
import UserEditModal from './components/UserEditModal'
function App() {
Expand Down Expand Up @@ -50,6 +51,10 @@ function App() {
path='/search/category'
element={<SearchPage />}
/>
<Route
path='/'
element={<MainPage />}
/>
</Route>
</Routes>
</BrowserRouter>
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/apis/postService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import axios from 'axios'

const API_URL = 'http://localhost:3000/post'

export const fetchPosts = async () => {
try {
const response = await axios.get(API_URL)
return response.data
} catch (error) {
console.error('Error fetching posts:', error)
throw error
}
}
122 changes: 122 additions & 0 deletions frontend/src/components/CategoryButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React, { useState } from 'react'
import styled from 'styled-components'
import { useQuery } from '@tanstack/react-query'
import PostCard from '@/components/PostCard'
import axios from 'axios'

interface CategoryButtonProps {
label: string
onClick: () => void
}

const Button = styled.button`
height: 125px;
width: 125px;
border: 1px solid #7d7d7d;
background-color: #ffffff;
color: #1c1c1c;
cursor: pointer;
font-size: 16px;
&:hover {
background-color: #1c1c1c;
color: #ffffff;
}
padding: 0;
`

const ButtonGrid = styled.div`
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 0;
`

const CenteredContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
width: 100%;
`

const PostsContainer = styled.div`
margin-top: 20px;
width: 80%;
display: flex;
flex-direction: column;
align-items: center;
`

const CategoryButton: React.FC<CategoryButtonProps> = ({ label, onClick }) => {
return <Button onClick={onClick}>{label}</Button>
}

const categories = [
'한식',
'중식',
'일식',
'양식',
'동남아 요리',
'남미 요리',
'중동 요리',
'퓨전 요리',
'채식 요리',
'해산물 요리',
'바베큐 요리',
'디저트',
]

const CategoryButtons: React.FC = () => {
const [selectedCategory, setSelectedCategory] = useState<string | null>(null)

const { data: posts = [], isLoading, error } = useQuery({
queryKey: ['posts'],
queryFn: async () => {
const response = await axios.get('/api/post')
console.log('ADD ', response.data)
return response.data
},
})

const handleClick = (category: string) => {
setSelectedCategory(category)
}

// 선택된 카테고리에 따라 포스트 필터링
const filteredPosts = selectedCategory
? posts.filter((post: any) => post.category === selectedCategory)
: [...posts].sort(
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
) // 최신순 정렬

if (isLoading) return <div>Loading...</div>
if (error) return <div>Something went wrong!</div>

return (
<CenteredContainer>
<ButtonGrid>
{categories.map((category) => (
<CategoryButton
key={category}
label={category}
onClick={() => handleClick(category)}
/>
))}
</ButtonGrid>
<PostsContainer>
{filteredPosts.map((post:any) => (
<PostCard
key={post.id}
category={post.category}
title={post.title}
author={post.author}
date={post.date}
text={post.text}
image_url={post.imgUrl}
/>
))}
</PostsContainer>
</CenteredContainer>
)
}

export default CategoryButtons
13 changes: 10 additions & 3 deletions frontend/src/components/PostCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface CardProps {
author: string
date: string
text: string
imgUrl: string
image_url: string
}

const Card = styled.div`
Expand Down Expand Up @@ -59,11 +59,18 @@ const PostText = styled.p`
margin-top: 8px;
`

function PostCard({ title, author, date, text, category, imgUrl }: CardProps) {
function PostCard({
title,
author,
date,
text,
category,
image_url,
}: CardProps) {
return (
<Card>
<PostImage
src={imgUrl}
src={image_url}
alt='Post Thumbnail'
/>
<PostContent>
Expand Down
73 changes: 73 additions & 0 deletions frontend/src/components/TopPost.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react'
import styled from 'styled-components'

interface TopPostProps {
post: {
category: string
title: string
author: string
date: string
text: string
image_url: string
heartCount: number
}
}

const TopPostContainer = styled.div<{ $imgUrl: string }>`
position: relative;
background-image: url(${(props) => props.$imgUrl});
background-size: cover;
background-position: center;
height: 300px;
display: flex;
align-items: flex-start;
`

const ContentContainer = styled.div`
background-color: rgba(255, 255, 255, 1);
padding: 16px;
margin: 16px;
max-width: 400px;
`

const PostCategory = styled.p`
font-size: 20px;
color: #7d7d7d;
margin: 0;
font-weight: bold;
`

const PostTitle = styled.h2`
font-size: 33px;
margin: 8px 0;
`

const PostAuthor = styled.p`
font-size: 16px;
color: #7d7d7d;
margin: 0;
`
const PostText = styled.p`
font-size: 16px;
color: #1c1c1c;
margin-top: 8px;
`

const TopPost: React.FC<TopPostProps> = ({ post }) => {
const { image_url, category, title, author, date, text } = post

return (
<TopPostContainer $imgUrl={image_url}>
<ContentContainer>
<PostCategory>{category}</PostCategory>
<PostTitle>{title}</PostTitle>
<PostAuthor>
{author} | {date}
</PostAuthor>
<PostText>{text}</PostText>
</ContentContainer>
</TopPostContainer>
)
}

export default TopPost
57 changes: 57 additions & 0 deletions frontend/src/pages/MainPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import CategoryButtons from '@/components/CategoryButton'
import PostCard from '@/components/PostCard'
import TopPost from '@/components/TopPost'
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
import styled from 'styled-components'

const Header = styled.h1`
text-align: center;
margin: 20px 0;
`

const MainPage = () => {
const {
data: posts,
isLoading,
error,
} = useQuery({
queryKey: ['posts'],
queryFn: async () => {
const response = await axios.get('/api/post')
console.log('ADD ', response.data)
return response.data
},
})

if (isLoading) return <p>Loading...</p>
if (error) return <p>오류 발생: {error.message}</p>
if (!Array.isArray(posts)) {
return <p>포스트 데이터가 올바르지 않습니다.</p>
}

const sortedPosts = posts.sort((a, b) => b.heartCount - a.heartCount)
const topPost = sortedPosts[0]

return (
<div>
<TopPost post={topPost} />
<Header>Trending Now</Header>
{sortedPosts.map((post) => (
<PostCard
key={post.id}
category={post.category}
title={post.title}
author={post.author}
date={post.date}
text={post.text}
image_url={post.image_url}
/>
))}
<Header>Category</Header>
<CategoryButtons />
</div>
)
}

export default MainPage
53 changes: 28 additions & 25 deletions frontend/src/utils/mockPosts.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
export const mockPosts = [
{
category: '중식',
title: '가족과 함께 짜장면 집에서 만들기',
author: 'John Doe',
date: '2024-10-22',
text: '짜장면은 언제 먹어도 질리지 않는 대표적인 중식 요리입니다. 특별한 날이 아니더라도, 집에서 간단하게 짜장면을 만들어 먹으면 가족 모두가 즐거운 시간을 보낼 수 있죠. 오늘은 집에서도 쉽게 만들 수 있는 짜장면 레시피를 준비해 보았어요.',
imgUrl: 'https://via.placeholder.com/150',
},
{
category: '동남아 요리',
title: '집에서 즐기는 동남아 요리: 팟타이 만들기',
author: 'Jane Smith',
date: '2024-10-21',
text: '태국 여행을 떠올리게 하는 그 맛, 바로 팟타이! 새콤달콤한 소스에 쫄깃한 쌀국수와 각종 채소가 어우러져 한국에서도 많은 사랑을 받고 있는 태국 대표 요리죠. 오늘은 집에서도 간단하게 만들 수 있는 팟타이 레시피를 준비했어요.',
imgUrl: 'https://via.placeholder.com/150',
},
{
category: '일식',
title: '집에서 간단하게 만드는 사케동, 연어 덮밥 레시피',
author: 'Mark Wilson',
date: '2024-10-19',
text: '두툼한 연어가 가득 올라간 사케동, 이제 집에서도 손쉽게 즐길 수 있어요! 신선한 연어와 새콤달콤한 양념, 따뜻한 밥만 있으면 레스토랑에서 먹는 것처럼 고급스러운 한 끼를 완성할 수 있답니다.',
imgUrl: 'https://via.placeholder.com/150',
},
]
{
category: '중식',
title: '가족과 함께 짜장면 집에서 만들기',
author: 'John Doe',
date: '2024-10-22',
text: '짜장면은 언제 먹어도 질리지 않는 대표적인 중식 요리입니다. 특별한 날이 아니더라도, 집에서 간단하게 짜장면을 만들어 먹으면 가족 모두가 즐거운 시간을 보낼 수 있죠. 오늘은 집에서도 쉽게 만들 수 있는 짜장면 레시피를 준비해 보았어요.',
imgUrl: 'https://via.placeholder.com/150',
heartCount: 13,
},
{
category: '동남아 요리',
title: '집에서 즐기는 동남아 요리: 팟타이 만들기',
author: 'Jane Smith',
date: '2024-10-21',
text: '태국 여행을 떠올리게 하는 그 맛, 바로 팟타이! 새콤달콤한 소스에 쫄깃한 쌀국수와 각종 채소가 어우러져 한국에서도 많은 사랑을 받고 있는 태국 대표 요리죠. 오늘은 집에서도 간단하게 만들 수 있는 팟타이 레시피를 준비했어요.',
imgUrl: 'https://via.placeholder.com/150',
heartCount: 5,
},
{
category: '일식',
title: '집에서 간단하게 만드는 사케동, 연어 덮밥 레시피',
author: 'Mark Wilson',
date: '2024-10-19',
text: '두툼한 연어가 가득 올라간 사케동, 이제 집에서도 손쉽게 즐길 수 있어요! 신선한 연어와 새콤달콤한 양념, 따뜻한 밥만 있으면 레스토랑에서 먹는 것처럼 고급스러운 한 끼를 완성할 수 있답니다.',
imgUrl: 'https://via.placeholder.com/150',
heartCount: 22,
},
];

0 comments on commit a1f4678

Please sign in to comment.