Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FE/#287 신규 공고 페이지 퍼블리싱 #309

Merged
merged 2 commits into from
Nov 30, 2023
Merged
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
87 changes: 87 additions & 0 deletions frontend/src/app/recruitment/announcement/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
'use client'

import AnnouncementCard from '@/components/recruitment/announcement/AnnouncementCard'
import { AnnouncementDataType } from '@/utils/types'
import { useInfiniteQuery } from '@tanstack/react-query'
import { useEffect } from 'react'

export default function Announcement() {
const accessToken =
typeof window !== 'undefined' ? sessionStorage.getItem('accessToken') : null
const persistToken =
typeof window !== 'undefined' ? localStorage.getItem('persistToken') : null

const getData = async ({ pageParam = 1 }) => {
const params = new URLSearchParams()
params.set('page', String(pageParam))
params.set('size', '12')
params.set('direction', 'ASC')

const res = await fetch(
`${process.env.NEXT_PUBLIC_BASE_URL}/jobs?${params.toString()}`,
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken || persistToken}`,
},
},
)

if (!res.ok) {
const data = await res.json()
throw new Error(data.message)
}

const data = await res.json()
return data.data
}

const { data, fetchNextPage, hasNextPage, isFetchingNextPage, status } =
useInfiniteQuery(['announcement'], getData, {
getNextPageParam: (lastPage, pages) =>
lastPage.length < 12 ? undefined : pages.length + 1,
})

useEffect(() => {
if (!isFetchingNextPage) {
const handleScroll = () => {
if (
window.innerHeight + document.documentElement.scrollTop !==
document.documentElement.offsetHeight
)
return
fetchNextPage()
}
window.addEventListener('scroll', handleScroll)
}
}, [fetchNextPage, isFetchingNextPage])

if (status === 'loading') {
return <span>Loading...</span>
}

if (status === 'error') {
return <span>Error fetching data</span>
}

return (
<div className="relative flex flex-col items-center w-screen h-auto min-h-screen pb-12 pt-24">
<div className="w-[900px] mb-6 ml-2 border-b-[1px] pb-2">
<span className="text-[14px]">신입 채용 공고</span>
</div>
{data.pages.map((group, i) => (
<div
className="relative flex flex-col justify-center"
key={group[i]?.id}
>
{group.map((item: AnnouncementDataType) => (
<div className="" key={item.id}>
<AnnouncementCard item={item} />
</div>
))}
</div>
))}
{hasNextPage && isFetchingNextPage && <span>Loading more...</span>}
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { AnnouncementDataType } from '@/utils/types'

type PropsType = {
item: AnnouncementDataType
}

export default function AnnouncementCard({ item }: PropsType) {
const extractMonthAndDay = (dateString: string): string => {
if (dateString === '9999-12-31T00:00:00') {
return '상시채용'
}

const date = new Date(dateString)

const month = date.getMonth() + 1
const day = date.getDate()

return `~ ${month.toString().padStart(2, '0')}/${day
.toString()
.padStart(2, '0')} 까지`
}

return (
<div className="w-[900px] flex h-28 items-center mb-2 rounded-2xl shadow-gray-300 shadow-sm">
<div className="w-[180px] h-16 flex items-center border-r-2 border-gray-100 p-6">
<span className="truncate text-[14px]">{item.companyName}</span>
</div>
<div className="flex flex-col w-[570px] p-6">
<h1 className="truncate text-[15px] font-semibold mb-1">
{item.title}
</h1>
<a
target="_blank"
href={item.url}
rel="noreferrer"
className="text-[13px] text-graphyblue underline "
>
채용공고 바로가기
</a>
</div>
<div className="w-[150px] h-full flex justify-end items-end p-4">
<span className="text-gray-400 text-[13px]">
{extractMonthAndDay(item.expirationDate)}
</span>
</div>
</div>
)
}
2 changes: 1 addition & 1 deletion frontend/src/utils/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const recruitfilterState = atom<boolean>({

const directionState = atom<DirectionType>({
key: 'directionState',
default: 'ASC',
default: 'DESC',
})

export {
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@ export type MultipleFilterType = {
}

export type DirectionType = 'ASC' | 'DESC'

export type AnnouncementDataType = {
id: number
companyName: string
title: string
url: string
expirationDate: string
}
Loading