Skip to content

Commit 2fb235e

Browse files
authored
feat: News 페이지 구현
* feat: 공지 기본이미지(임시용)추가 * feat: News 페이지 구현 * feat; 배너이미지 고정정 * feat: NewsInfo페이지 구현 * feat: news 상세페이지 이동 추가
1 parent b6b4cba commit 2fb235e

File tree

6 files changed

+160
-0
lines changed

6 files changed

+160
-0
lines changed

src/App.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import Main from './pages/Main'
55
import Login from './pages/Login'
66
import RecruitMeeting from './pages/RecruitMeeting'
77
import RecruitSubmitMeeting from './pages/RecruitSubmitMeeting'
8+
import News from './pages/News'
9+
import NewsInfo from './pages/NewsInfo'
810

911
function App() {
1012
return (
@@ -15,6 +17,8 @@ function App() {
1517
<Route path='/login' element={<Login />} />
1618
<Route path='/recruit-meeting' element={<RecruitMeeting />} />
1719
<Route path='/recruit-meeting/submit' element={<RecruitSubmitMeeting />} />
20+
<Route path='/news' element={<News />} />
21+
<Route path='/news/:no' element={<NewsInfo />} />
1822
</Routes>
1923
</Router>
2024
</div>

src/assets/images/newsBannerExam.svg

Lines changed: 12 additions & 0 deletions
Loading

src/components/UI/NewsContent.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { JSX, useEffect, useState } from 'react'
2+
import defaultBanner from '../../assets/images/newsBannerExam.svg'
3+
4+
interface news {
5+
id: number
6+
title: string
7+
banner: string | null
8+
date: string
9+
onClick: () => void
10+
}
11+
12+
/** 공지사항 컴포넌트 */
13+
const NewsContent = ({ title, banner, date, onClick }: news): JSX.Element => {
14+
const [src, setSrc] = useState<string>(defaultBanner) // 기본 배너 이미지
15+
16+
// 배너 이미지 있을 경우 src 변경
17+
useEffect(() => {
18+
if (banner) {
19+
setSrc(banner)
20+
}
21+
}, [banner])
22+
23+
return (
24+
<div className='mb-5 w-[90%] cursor-pointer' onClick={onClick}>
25+
{/* 배너 이미지 */}
26+
<img className='w-[350px] h-[140px]' src={src} />
27+
{/* 제목 */}
28+
<p className='font-pretendardBold text-white text-[20px]'>{title}</p>
29+
{/* 날짜 */}
30+
<p className='font-pretendardRegular text-[12px] text-subGrey2'>{date}</p>
31+
</div>
32+
)
33+
}
34+
35+
export default NewsContent

src/components/UI/NewsNotice.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { JSX } from 'react'
2+
3+
interface notice {
4+
text: string
5+
date: Date
6+
}
7+
8+
const NewsNotice = ({ text, date }: notice): JSX.Element => {
9+
return (
10+
<div className='w-[90%] mb-5'>
11+
<div className='text-white font-pretendardRegular whitespace-pre-wrap' dangerouslySetInnerHTML={{ __html: text }} />
12+
<p className='text-subGrey2 font-pretendardRegular mt-5'>작성일 : {date.toLocaleDateString('ko-KR', { year: 'numeric', month: '2-digit', day: '2-digit' })}</p>
13+
</div>
14+
)
15+
}
16+
17+
export default NewsNotice

src/pages/News.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from 'react'
2+
import MobileLayout from '../components/layout/MobileLayout'
3+
import { Header } from '../components/UI/Header'
4+
import dasomLogo from '../assets/images/dasomLogo.svg'
5+
import NewsContent from '../components/UI/NewsContent'
6+
import { useNavigate } from 'react-router-dom'
7+
8+
interface news {
9+
id: number // 고유번호
10+
title: string // 제목
11+
banner: string | null // 배너 이미지
12+
date: string // 기간
13+
}
14+
15+
/** 예시 데이터 */
16+
const newsContentExam: news[] = [
17+
{ id: 1, title: '다솜 34기 신규 부원 모집!', banner: null, date: '2월 25일(화) ~ 3월 14일(금)' },
18+
{ id: 2, title: '다솜 34기 신규 부원 모집!', banner: null, date: '2월 25일(화) ~ 3월 14일(금)' },
19+
{ id: 3, title: '다솜 34기 신규 부원 모집!', banner: null, date: '2월 25일(화) ~ 3월 14일(금)' },
20+
{ id: 4, title: '다솜 34기 신규 부원 모집!', banner: null, date: '2월 25일(화) ~ 3월 14일(금)' },
21+
]
22+
23+
/** 소식 페이지 */
24+
const News: React.FC = () => {
25+
const navigate = useNavigate()
26+
27+
// 데이터의 id를 받아와 해당 상세 페이지로 이동
28+
const handleClick = (id: number) => {
29+
navigate(`/news/${id}`)
30+
}
31+
32+
return (
33+
<MobileLayout>
34+
<Header />
35+
<div className='mt-[65px] mb-2 ml-[12px] flex'>
36+
<img className='w-[21px] h-[24px] cursor-pointer' alt='logo' src={dasomLogo} />
37+
<div className='font-pretendardSemiBold text-white text-[16px] ml-[9px]'>다솜 소식</div>
38+
</div>
39+
<div className='flex flex-col items-center w-full mb-40'>
40+
{/* 공지사항 리스트 출력 */}
41+
{newsContentExam.map((news) => (
42+
<NewsContent key={news.id} {...news} onClick={() => handleClick(news.id)} />
43+
))}
44+
</div>
45+
</MobileLayout>
46+
)
47+
}
48+
49+
export default News

src/pages/NewsInfo.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react'
2+
import MobileLayout from '../components/layout/MobileLayout'
3+
import dasomLogo from '../assets/images/dasomLogo.svg'
4+
import NewsContent from '../components/UI/NewsContent'
5+
import NewsNotice from '../components/UI/NewsNotice'
6+
import { Header } from '../components/UI/Header'
7+
8+
interface notice {
9+
id: number
10+
text: string
11+
date: Date
12+
}
13+
14+
/** 소식 상세페이지 */
15+
const NewsInfo: React.FC = () => {
16+
return (
17+
<MobileLayout>
18+
<Header />
19+
<div className='mt-[65px] mb-2 ml-[12px] flex'>
20+
<img className='w-[21px] h-[24px] cursor-pointer' alt='logo' src={dasomLogo} />
21+
<div className='font-pretendardSemiBold text-white text-[16px] ml-[9px]'>다솜 소식</div>
22+
</div>
23+
<div className='flex flex-col items-center w-full mb-40'>
24+
<NewsContent title='다솜 34기 신규 부원 모집!' banner={null} date='2월 25일(화) ~ 3월 14일(금)' onClick={() => {}} id={1} />
25+
<NewsNotice text={examText} date={examDate} />
26+
</div>
27+
</MobileLayout>
28+
)
29+
}
30+
31+
/** DB에서 받아올 예시 데이터 */
32+
const examText: string =
33+
'<p>컴퓨터공학부 전공 동아리 <span style="color:#00B493 ">다솜</span>은 1992년에 설립된, <strong>웹/앱 서비스 개발</strong>을 통해 개인의 개발 실력 향상을 도모하는 동아리입니다.</p>\n' +
34+
'<p>다솜에서는 활발한 커뮤니티 형성을 목적으로 하며, 현직자 강의, 세미나와 스터디 및 팀 프로젝트 활동 등으로 비단 개인만이 아닌 <strong>팀과의 협업을 경험</strong>하고, <strong>실력과 인사이트 모두 한 단계 더 성장</strong>할 수 있게끔 지원해드리고 있습니다. ☺️</p>\n' +
35+
'<p>또한, 다솜의 매력은 <strong>동료 개발자들과의 교류</strong>라고 생각하는데요, 하계, 동계 MT, 비어 네트워킹과 팀 프로젝트 등으로 <strong>친밀감을 쌓으며</strong> ' +
36+
'여러분이 "<strong>함께 성장하는 개발자</strong>"가 될 수 있을 것이라고 생각합니다. 🌟</p>\n' +
37+
'<p><strong>지금, 다솜에서 여러분의 가능성을 펼쳐보세요!\n' +
38+
'더 큰 미래를 그릴 준비가 되셨나요? 다솜은 여러분과 함께합니다.</strong></p>'
39+
40+
/** DB에서 받아올 예시 데이터 */
41+
const examDate: Date = new Date('2025-02-13')
42+
43+
export default NewsInfo

0 commit comments

Comments
 (0)