Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ApplicantAnagementDetailPage as default } from 'pages/applicant-management'
22 changes: 18 additions & 4 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,33 @@ button {
overflow: auto;
}

.scrollbar::-webkit-scrollbar {
.scrollbar.gutter-stable {
scrollbar-gutter: stable;
}

.scrollbar.light::-webkit-scrollbar {
@apply h-2 w-2 bg-transparent;
}

.scrollbar.light::-webkit-scrollbar-thumb {
background-clip: padding-box;
border: 2px solid transparent;
@apply rounded-full bg-gray-300;
}

.scrollbar.dark::-webkit-scrollbar {
@apply h-3 w-3 bg-white;
}

.scrollbar::-webkit-scrollbar-thumb {
.scrollbar.dark::-webkit-scrollbar-thumb {
@apply rounded-full border border-solid border-transparent bg-gray-700 bg-clip-content;
}

.scrollbar::-webkit-scrollbar:vertical {
.scrollbar.dark::-webkit-scrollbar:vertical {
@apply border-0 border-l border-solid border-l-gray-300;
}

.scrollbar::-webkit-scrollbar:horizontal {
.scrollbar.dark::-webkit-scrollbar:horizontal {
@apply border-0 border-t border-solid border-t-gray-300;
}
}
Expand Down
40 changes: 11 additions & 29 deletions src/entities/job-post-resume-relation/api/get-job-post-resume.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,23 @@
'use server'

import { getBusinessSession, getTeacherSession } from 'entities/auth'
import { apiClient, Pagination, PaginationParams } from 'shared/api'
import { getBusinessSession } from 'entities/auth'
import { apiClient } from 'shared/api'

import { JobPostRelation } from '../model/application'
import { ApplicationStatus } from '../model/status'
import { JobPostRelationDetail } from '../model/application'

export type GetJobPostResumeRequest = PaginationParams<{
status?: ApplicationStatus
}>

type GetJobPostResumeResponse = Pagination<JobPostRelation>

export const getTeacherJobPostResumeRelations = async (
queryParams: GetJobPostResumeRequest,
) => {
const { accessToken } = await getTeacherSession()

const response = await apiClient.get<GetJobPostResumeResponse>({
endpoint: '/job-post-resume-relations',
queryParams,
option: {
authorization: `Bearer ${accessToken}`,
},
})

return response
export type GetJobPostResumeRequest = {
jobPostResumeRelationId: number
}

export const getBusinessJobPostResumeRelations = async (
queryParams: GetJobPostResumeRequest,
) => {
type GetJobPostResumeResponse = JobPostRelationDetail

export const getBusinessJobPostResumeRelation = async ({
jobPostResumeRelationId,
}: GetJobPostResumeRequest) => {
const { accessToken } = await getBusinessSession()

const response = await apiClient.get<GetJobPostResumeResponse>({
endpoint: '/job-post-resume-relations',
queryParams,
endpoint: `/job-post-resume-relations/${jobPostResumeRelationId}`,
option: {
authorization: `Bearer ${accessToken}`,
},
Expand Down
47 changes: 47 additions & 0 deletions src/entities/job-post-resume-relation/api/get-job-post-resumes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use server'

import { getBusinessSession, getTeacherSession } from 'entities/auth'
import { apiClient, Pagination, PaginationParams } from 'shared/api'

import { JobPostRelation } from '../model/application'
import { ApplicationStatus } from '../model/status'

export type GetJobPostResumeRequest = PaginationParams<{
status?: ApplicationStatus
}>

type GetJobPostResumeResponse = Pagination<JobPostRelation>

export const getTeacherJobPostResumeRelations = async (
queryParams: GetJobPostResumeRequest,
) => {
const { accessToken } = await getTeacherSession()

const response = await apiClient.get<GetJobPostResumeResponse>({
endpoint: '/job-post-resume-relations',
queryParams,
option: {
authorization: `Bearer ${accessToken}`,
},
})

return response
}

export const getBusinessJobPostResumeRelations = async (
queryParams: GetJobPostResumeRequest,
) => {
const { accessToken } = await getBusinessSession()

console.log(accessToken)

const response = await apiClient.get<GetJobPostResumeResponse>({
endpoint: '/job-post-resume-relations',
queryParams,
option: {
authorization: `Bearer ${accessToken}`,
},
})

return response
}
2 changes: 1 addition & 1 deletion src/entities/job-post-resume-relation/api/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
getBusinessJobPostResumeRelations,
getTeacherJobPostResumeRelations,
GetJobPostResumeRequest,
} from './get-job-post-resume'
} from './get-job-post-resumes'

export const jobPostResumeRelationQueries = {
all: () => ['job-post-resume-relation'],
Expand Down
2 changes: 2 additions & 0 deletions src/entities/job-post-resume-relation/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export { getJobPostResumeSummary } from './api/get-job-post-resume-summary'
export { getJobPostResumeByCode } from './api/get-job-post-resume-by-code'
export { getBusinessJobPostResumeRelation } from './api/get-job-post-resume'
export { jobPostResumeRelationQueries } from './api/query'
export { ApplicationStatus, type StatusSummary } from './model/status'
export type { JobPostRelationDetail } from './model/application'
export { HistoryPanel } from './ui/history-panel'
export { StatusPanel } from './ui/status-panel'
export { ApplicationTable } from './ui/application-table'
export { ApplicationStatusSelect } from './ui/application-status-select'
2 changes: 1 addition & 1 deletion src/entities/job-post-resume-relation/model/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export type JobPostRelation = {
coverLetter: string
status: ApplicationStatus
submittedDate: string
resumeId: number
resumeTitle: string
resumeFirstName: string
resumeLastName: string
Expand All @@ -21,6 +20,7 @@ export type JobPostRelationDetail = {
coverLetter: string
status: ApplicationStatus
submittedDate: string
academyMemo: string | null
resumeTitle: string
personalIntroduction: string
firstName: string
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ApplicationStatus } from 'entities/job-post-resume-relation'
import { Form, FormSelectProps } from 'shared/form'

const StatusLabel = {
[ApplicationStatus.SUBMITTED]: '접수',
[ApplicationStatus.REVIEWED]: '검토',
[ApplicationStatus.ACCEPTED]: '합격',
[ApplicationStatus.REJECTED]: '불합격',
}

export const ApplicationStatusSelect = (props: FormSelectProps) => {
return (
<Form.Select
name="status"
size="medium"
className="w-[85px]"
displayValue={value => StatusLabel[value as ApplicationStatus]}
{...props}
>
<Form.SelectItem value={ApplicationStatus.SUBMITTED}>
접수
</Form.SelectItem>
<Form.SelectItem value={ApplicationStatus.REVIEWED}>검토</Form.SelectItem>
<Form.SelectItem value={ApplicationStatus.ACCEPTED}>합격</Form.SelectItem>
<Form.SelectItem value={ApplicationStatus.REJECTED}>
불합격
</Form.SelectItem>
</Form.Select>
)
}
1 change: 1 addition & 0 deletions src/features/application-side-panel/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ApplicationSidePanel } from './ui/side-panel'
56 changes: 56 additions & 0 deletions src/features/application-side-panel/ui/side-panel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use client'

import { useForm } from 'react-hook-form'

import {
ApplicationStatus,
ApplicationStatusSelect,
} from 'entities/job-post-resume-relation'
import { Form } from 'shared/form'
import { Button, Separator } from 'shared/ui'

type Props = {
values: {
status?: ApplicationStatus
memo?: string
}
}

export const ApplicationSidePanel = ({ values }: Props) => {
const form = useForm({
values,
})

return (
<div className="h-fit min-h-[329px] w-[250px] shrink-0 rounded-2xl border border-gray-300 p-6">
<Form {...form}>
<div className="mb-3 flex h-[38px] items-center gap-2">
<Form.Control name="status">
<label className="title-small font-bold text-gray-900">
현재 채용 단계:
</label>
<ApplicationStatusSelect />
</Form.Control>
</div>
<p className="body-large mb-5 font-normal text-gray-900">
채용 단계를 변경하면 지원자에게 알림으로 결과를 알려줘요
</p>
<Separator className="mb-5" />
<div className="mb-6 flex flex-col gap-2">
<Form.Control name="memo">
<label className="title-small font-bold text-gray-900">
한 줄 메모
</label>
<Form.TextArea
className="body-large placeholder:body-large h-12 border-0 px-0 py-1 font-normal placeholder:font-normal placeholder:underline"
placeholder="지원자에 대해 기억하고 싶은 점이 있다면 적어주세요 (최대 100자)"
/>
</Form.Control>
</div>
<Button variant="primary" fullWidth size="large">
저장하기
</Button>
</Form>
</div>
)
}
1 change: 1 addition & 0 deletions src/pages/applicant-management/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { ApplicantManagementListPage } from './ui/applicant-management-list-page'
export { ApplicantAnagementDetailPage } from './ui/applicant-management-detail-page'
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { getBusinessJobPostResumeRelation } from 'entities/job-post-resume-relation'
import { Layout } from 'shared/ui'
import { FileResume, FormResume } from 'widgets/application-resume'

type Params = {
jobPostResumeRelationId: string
}

export const ApplicantAnagementDetailPage = async ({
params,
}: {
params: Promise<Params>
}) => {
const { jobPostResumeRelationId } = await params

const jobPostResumeRelation = await getBusinessJobPostResumeRelation({
jobPostResumeRelationId: Number(jobPostResumeRelationId),
})

const isFileResume = jobPostResumeRelation.filePath !== null

return (
<Layout wide>
{isFileResume ? (
<FileResume jobPostResumeRelation={jobPostResumeRelation} />
) : (
<FormResume jobPostResumeRelation={jobPostResumeRelation} />
)}
</Layout>
)
}
5 changes: 4 additions & 1 deletion src/shared/config/middleware/with-business-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { getBusinessSession } from 'auth'

import { MiddlewareFactory } from './type'

const matchersForAuth = ['/business/setting/*path']
const matchersForAuth = [
'/business/setting/*path',
'/business/applicant-management/*path',
]
const matchersForSignIn = ['/business/sign-up', '/business/sign-in']

export const withBusinessAuth: MiddlewareFactory = next => {
Expand Down
2 changes: 1 addition & 1 deletion src/shared/ui/dropdown/variants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const dropdownWrapper = cva(
export const dropdown = cva('', {
variants: {
scrollable: {
true: 'scrollbar overflow-auto',
true: 'scrollbar dark overflow-auto',
false: 'overflow-visible',
},
},
Expand Down
3 changes: 1 addition & 2 deletions src/shared/ui/select-field/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
DropdownRootProps,
} from '../dropdown/dropdown'
import { Icon } from '../icon'

import SelectProvider, { useSelectContext } from './context'
import { SelectVariants } from './variants'
import * as css from './variants'
Expand Down Expand Up @@ -166,7 +165,7 @@ const SelectRoot = ({
<Icon
name="ChevronDown"
color={colors.gray['700']}
className={cn(css.arrowIcon({ isOpen }))}
className={cn(css.arrowIcon({ isOpen, size }))}
/>
)}
</div>
Expand Down
11 changes: 8 additions & 3 deletions src/shared/ui/select-field/variants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export const selected = cva(
{
variants: {
size: {
small: 'body-small min-h-8 px-3 py-2',
medium: 'body-large min-h-9 px-3 py-2',
large: 'body-large min-h-12 p-3',
small: 'body-small min-h-[30px] px-[11px] py-[6px]',
medium: 'body-large min-h-[36px] px-[11px] py-[7px]',
large: 'body-large min-h-[46px] px-[11px] py-[10px]',
},
error: {
true: '',
Expand Down Expand Up @@ -84,6 +84,11 @@ export const arrowIcon = cva(
true: 'rotate-180 transform',
false: 'rotate-0',
},
size: {
small: 'h-4 w-4',
medium: 'h-5 w-5',
large: 'h-6 w-6',
},
},
},
)
Expand Down
6 changes: 6 additions & 0 deletions src/widgets/application-resume/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { CoverLetter } from './ui/cover-letter'
export { FileResume } from './ui/file-resume'
export { FormResume } from './ui/form-resume'
export { Header } from './ui/header'
export { Introduction } from './ui/introduction'
export { PersonalInformation } from './ui/personal-information'
16 changes: 16 additions & 0 deletions src/widgets/application-resume/ui/cover-letter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
type Props = {
coverLetter: string
}

export const CoverLetter = ({ coverLetter }: Props) => {
return (
<section>
<h3 className="title-medium flex h-[42px] items-center font-bold text-blue-800">
Cover Letter
</h3>
<div className="title-small scrollbar light gutter-stable max-h-[400px] min-h-[200px] w-full whitespace-pre-line rounded-lg border border-gray-300 py-3 pl-3 pr-1 font-normal leading-[28px] text-gray-900">
{coverLetter}
</div>
</section>
)
}
Loading
Loading