From 02bfd768d4a1c5770b5985241e16691daf72e879 Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Mon, 28 Apr 2025 00:21:31 +0900 Subject: [PATCH 01/14] =?UTF-8?q?Feat:=20PD-265=20=EA=B3=B5=EA=B3=A0=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D,=20=EC=9E=84=EC=8B=9C=EC=A0=80=EC=9E=A5=20AP?= =?UTF-8?q?I=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job-post/api/create-job-post-draft.ts | 39 +++++++++++++++++++ src/entities/job-post/api/create-job-post.ts | 39 +++++++++++++++++++ src/entities/job-post/index.ts | 2 + 3 files changed, 80 insertions(+) create mode 100644 src/entities/job-post/api/create-job-post-draft.ts create mode 100644 src/entities/job-post/api/create-job-post.ts diff --git a/src/entities/job-post/api/create-job-post-draft.ts b/src/entities/job-post/api/create-job-post-draft.ts new file mode 100644 index 0000000..bd50242 --- /dev/null +++ b/src/entities/job-post/api/create-job-post-draft.ts @@ -0,0 +1,39 @@ +'use server' + +import { revalidateTag } from 'next/cache' + +import { getBusinessSession } from 'entities/auth' +import { apiClient, errorHandler, HttpError } from 'shared/api' + +import { CreateJobPost } from '../model/create-job-post' + +const handleSuccess = () => { + revalidateTag('business-job-posts') +} + +const handleError = (error: Error) => { + const isHttpError = error instanceof HttpError + if (!isHttpError) throw error + + return errorHandler.toast('An error occurred while creating job post draft', { + error, + }) +} + +export const createJobPostDraft = async (jobPost: CreateJobPost) => { + const { accessToken } = await getBusinessSession() + + try { + await apiClient.post({ + endpoint: '/job-posts/draft', + option: { + authorization: `Bearer ${accessToken}`, + }, + body: jobPost, + }) + + handleSuccess() + } catch (error) { + return handleError(error as Error) + } +} diff --git a/src/entities/job-post/api/create-job-post.ts b/src/entities/job-post/api/create-job-post.ts new file mode 100644 index 0000000..82756ff --- /dev/null +++ b/src/entities/job-post/api/create-job-post.ts @@ -0,0 +1,39 @@ +'use server' + +import { revalidateTag } from 'next/cache' + +import { getBusinessSession } from 'entities/auth' +import { apiClient, errorHandler, HttpError } from 'shared/api' + +import { CreateJobPost } from '../model/create-job-post' + +const handleSuccess = () => { + revalidateTag('business-job-posts') +} + +const handleError = (error: Error) => { + const isHttpError = error instanceof HttpError + if (!isHttpError) throw error + + return errorHandler.toast('An error occurred while creating job post', { + error, + }) +} + +export const createJobPost = async (jobPost: CreateJobPost) => { + const { accessToken } = await getBusinessSession() + + try { + await apiClient.post({ + endpoint: '/job-posts', + option: { + authorization: `Bearer ${accessToken}`, + }, + body: jobPost, + }) + + handleSuccess() + } catch (error) { + return handleError(error as Error) + } +} diff --git a/src/entities/job-post/index.ts b/src/entities/job-post/index.ts index 1c0427f..f2b199e 100644 --- a/src/entities/job-post/index.ts +++ b/src/entities/job-post/index.ts @@ -20,3 +20,5 @@ export { PostingImageSwiper } from './ui/posting-image-swiper' export { PostingTitle } from './ui/posting-title' export { copyJobPost } from './api/copy-job-post' export type { CreateJobPost } from './model/create-job-post' +export { createJobPost } from './api/create-job-post' +export { createJobPostDraft } from './api/create-job-post-draft' From fcea9f8c462e4a99bb78b95c297d84ab789c1708 Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Mon, 28 Apr 2025 00:24:31 +0900 Subject: [PATCH 02/14] =?UTF-8?q?Feat:=20PD-265=20=EA=B3=B5=EA=B3=A0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95,=20=EC=9E=84=EC=8B=9C=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EA=B3=B5=EA=B3=A0=20=EC=88=98=EC=A0=95=20API=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job-post/api/update-job-post-draft.ts | 47 +++++++++++++++++++ src/entities/job-post/api/update-job-post.ts | 47 +++++++++++++++++++ src/entities/job-post/index.ts | 2 + 3 files changed, 96 insertions(+) create mode 100644 src/entities/job-post/api/update-job-post-draft.ts create mode 100644 src/entities/job-post/api/update-job-post.ts diff --git a/src/entities/job-post/api/update-job-post-draft.ts b/src/entities/job-post/api/update-job-post-draft.ts new file mode 100644 index 0000000..2f283ee --- /dev/null +++ b/src/entities/job-post/api/update-job-post-draft.ts @@ -0,0 +1,47 @@ +'use server' + +import { revalidateTag } from 'next/cache' + +import { getBusinessSession } from 'entities/auth' +import { apiClient, errorHandler, HttpError } from 'shared/api' + +import { CreateJobPost } from '../model/create-job-post' + +type UpdateJobPostDraftRequest = { + jobPostId: number + jobPost: CreateJobPost +} + +const handleSuccess = () => { + revalidateTag('business-job-posts') +} + +const handleError = (error: Error) => { + const isHttpError = error instanceof HttpError + if (!isHttpError) throw error + + return errorHandler.toast('An error occurred while updating job post draft', { + error, + }) +} + +export const updateJobPostDraft = async ({ + jobPostId, + jobPost, +}: UpdateJobPostDraftRequest) => { + const { accessToken } = await getBusinessSession() + + try { + await apiClient.post({ + endpoint: `/job-posts/${jobPostId}/draft`, + option: { + authorization: `Bearer ${accessToken}`, + }, + body: jobPost, + }) + + handleSuccess() + } catch (error) { + return handleError(error as Error) + } +} diff --git a/src/entities/job-post/api/update-job-post.ts b/src/entities/job-post/api/update-job-post.ts new file mode 100644 index 0000000..5774121 --- /dev/null +++ b/src/entities/job-post/api/update-job-post.ts @@ -0,0 +1,47 @@ +'use server' + +import { revalidateTag } from 'next/cache' + +import { getBusinessSession } from 'entities/auth' +import { apiClient, errorHandler, HttpError } from 'shared/api' + +import { CreateJobPost } from '../model/create-job-post' + +type UpdateJobPostRequest = { + jobPostId: number + jobPost: CreateJobPost +} + +const handleSuccess = () => { + revalidateTag('business-job-posts') +} + +const handleError = (error: Error) => { + const isHttpError = error instanceof HttpError + if (!isHttpError) throw error + + return errorHandler.toast('An error occurred while updating job post', { + error, + }) +} + +export const updateJobPost = async ({ + jobPostId, + jobPost, +}: UpdateJobPostRequest) => { + const { accessToken } = await getBusinessSession() + + try { + await apiClient.post({ + endpoint: `/job-posts/${jobPostId}`, + option: { + authorization: `Bearer ${accessToken}`, + }, + body: jobPost, + }) + + handleSuccess() + } catch (error) { + return handleError(error as Error) + } +} diff --git a/src/entities/job-post/index.ts b/src/entities/job-post/index.ts index f2b199e..fbedb5b 100644 --- a/src/entities/job-post/index.ts +++ b/src/entities/job-post/index.ts @@ -22,3 +22,5 @@ export { copyJobPost } from './api/copy-job-post' export type { CreateJobPost } from './model/create-job-post' export { createJobPost } from './api/create-job-post' export { createJobPostDraft } from './api/create-job-post-draft' +export { updateJobPost } from './api/update-job-post' +export { updateJobPostDraft } from './api/update-job-post-draft' From 265d0b340b95dc899f922493f63d638d98b94017 Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Wed, 14 May 2025 23:43:36 +0900 Subject: [PATCH 03/14] =?UTF-8?q?Feat:=20PD-265=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(user)/job-board/[jobPostId]/page.tsx | 4 +- .../job-posting-form/model/form-values.ts | 65 ++++++++++++++ src/features/job-posting-form/model/rules.ts | 66 ++++++++++++++ .../job-posting-form/ui/job-posting-form.tsx | 90 ++++++++++++++++--- .../locales/en/validation.json | 24 +++++ .../locales/ko/validation.json | 24 +++++ src/shared/form/ui/message/message.tsx | 17 +++- src/shared/ui/text-field/text-field.tsx | 8 +- 8 files changed, 279 insertions(+), 19 deletions(-) create mode 100644 src/features/job-posting-form/model/form-values.ts create mode 100644 src/features/job-posting-form/model/rules.ts diff --git a/app/(user)/job-board/[jobPostId]/page.tsx b/app/(user)/job-board/[jobPostId]/page.tsx index bce1eb6..207922e 100644 --- a/app/(user)/job-board/[jobPostId]/page.tsx +++ b/app/(user)/job-board/[jobPostId]/page.tsx @@ -7,7 +7,7 @@ type Params = { jobPostId: string } -export const JobPostingDetailPage = async ({ +const JobPostingDetailPage = async ({ params, }: { params: Promise @@ -37,3 +37,5 @@ export const JobPostingDetailPage = async ({ /> ) } + +export default JobPostingDetailPage diff --git a/src/features/job-posting-form/model/form-values.ts b/src/features/job-posting-form/model/form-values.ts new file mode 100644 index 0000000..c83cc86 --- /dev/null +++ b/src/features/job-posting-form/model/form-values.ts @@ -0,0 +1,65 @@ +import { isArray, isNil } from 'lodash-es' + +import { convertStudentTypeToArray, CreateJobPost } from 'entities/job-post' + +export type FormValues = { + title: string + jobDescription: string + requiredQualification: string + preferredQualification: string + benefits: string + salary: number | null + salaryNegotiable: string[] + jobStartDate: string + dueDate?: string | null + studentType: string[] | null +} + +export const defaultValues: FormValues = { + title: '', + jobDescription: '', + requiredQualification: '', + preferredQualification: '', + benefits: '', + salary: null, + salaryNegotiable: [], + jobStartDate: '', + dueDate: '', + studentType: null, +} + +export const convertToFormValues = (jobPost?: CreateJobPost): FormValues => { + if (isNil(jobPost)) return defaultValues + + return { + ...jobPost, + studentType: convertStudentTypeToArray({ + forKindergarten: jobPost.forKindergarten, + forElementary: jobPost.forElementary, + forMiddleSchool: jobPost.forMiddleSchool, + forHighSchool: jobPost.forHighSchool, + forAdult: jobPost.forAdult, + }), + salaryNegotiable: jobPost.salaryNegotiable ? ['true'] : [], + } +} + +export const convertToCreateJobPostDTO = ({ + studentType, + ...formValues +}: FormValues): CreateJobPost => { + return { + ...formValues, + salary: Number(formValues.salary), + forKindergarten: studentType?.includes('Kindergarten') ?? false, + forElementary: studentType?.includes('Elementary') ?? false, + forMiddleSchool: studentType?.includes('MiddleSchool') ?? false, + forHighSchool: studentType?.includes('HighSchool') ?? false, + forAdult: studentType?.includes('Adult') ?? false, + dueDate: formValues.dueDate || null, + jobStartDate: formValues.jobStartDate || '', + salaryNegotiable: + isArray(formValues.salaryNegotiable) && + formValues.salaryNegotiable.includes('true'), + } +} diff --git a/src/features/job-posting-form/model/rules.ts b/src/features/job-posting-form/model/rules.ts new file mode 100644 index 0000000..7cbb965 --- /dev/null +++ b/src/features/job-posting-form/model/rules.ts @@ -0,0 +1,66 @@ +import { isNull } from 'lodash-es' + +export const title = { + required: 'validation.jobPostingTitle.required', + maxLength: { + value: 100, + message: 'validation.jobPostingTitle.maxLength', + }, +} + +export const jobDescription = { + required: 'validation.jobPostingDescription.required', + maxLength: { + value: 1000, + message: 'validation.jobPostingDescription.maxLength', + }, +} + +export const requiredQualification = { + maxLength: { + value: 1000, + message: 'validation.jobPostingRequiredQualification.maxLength', + }, +} + +export const preferredQualification = { + maxLength: { + value: 1000, + message: 'validation.jobPostingPreferredQualification.maxLength', + }, +} + +export const benefits = { + maxLength: { + value: 1000, + message: 'validation.jobPostingBenefits.maxLength', + }, +} + +export const salary = { + required: 'validation.jobPostingSalary.required', + validate: (value: number) => { + const salary = value.toString().replace(/,/g, '') + + if (salary.length > 10) { + return 'validation.jobPostingSalary.maxLength' + } + + return true + }, +} + +export const studentType = { + required: true, +} + +export const dueDate = { + validate: (value: string) => { + if (isNull(value)) return true + + if (value === '' || value === undefined) + return 'validation.jobPostingDueDate.required' + + return true + }, +} diff --git a/src/features/job-posting-form/ui/job-posting-form.tsx b/src/features/job-posting-form/ui/job-posting-form.tsx index 75836e7..048dc23 100644 --- a/src/features/job-posting-form/ui/job-posting-form.tsx +++ b/src/features/job-posting-form/ui/job-posting-form.tsx @@ -1,14 +1,31 @@ +import { isEqual, isNull } from 'lodash-es' +import { useFormContext, useWatch } from 'react-hook-form' + import { fieldCss, Form } from 'shared/form' import { cn, Slot } from 'shared/lib' import { Checkbox, Label } from 'shared/ui' +import { FormValues } from '../model/form-values' +import * as rules from '../model/rules' + type Props = { className?: string } export const JobPostingForm = ({ className }: Props) => { + const { + control, + setValue, + formState: { errors }, + clearErrors, + } = useFormContext() + + const [studentType, dueDate] = useWatch({ + control, + name: ['studentType', 'dueDate'], + }) + const studentTypeOptions = [ - 'All', 'Kindergarten', 'Elementary', 'MiddleSchool', @@ -16,11 +33,35 @@ export const JobPostingForm = ({ className }: Props) => { 'Adult', ] + const isAllChecked = isEqual(studentType, studentTypeOptions) + + const handleAllCheckboxClick = () => { + if (isAllChecked) { + setValue('studentType', null) + } else { + setValue('studentType', studentTypeOptions) + } + + clearErrors('studentType') + } + + const noExpirationDate = isNull(dueDate) + + const handleExpirationDateChange = () => { + if (noExpirationDate) { + setValue('dueDate', undefined) + } else { + setValue('dueDate', null) + } + + clearErrors('dueDate') + } + return (
- + {
- + {
- + {
- + {
- + {
- + - KRW + 만원 @@ -93,8 +140,18 @@ export const JobPostingForm = ({ className }: Props) => {
- - + + @@ -117,14 +174,21 @@ export const JobPostingForm = ({ className }: Props) => {
- + - + - +
) diff --git a/src/shared/config/internationalization/locales/en/validation.json b/src/shared/config/internationalization/locales/en/validation.json index bdf9002..9f133ec 100644 --- a/src/shared/config/internationalization/locales/en/validation.json +++ b/src/shared/config/internationalization/locales/en/validation.json @@ -58,6 +58,30 @@ "required": "Please enter the business registration number", "length": "Please enter 10 digits", "pattern": "Please enter numbers only" + }, + "jobPostingTitle": { + "required": "Please enter the job posting title", + "maxLength": "Please enter less than 100 characters" + }, + "jobPostingDescription": { + "required": "Please enter the job posting description", + "maxLength": "Please enter less than 1000 characters" + }, + "jobPostingRequiredQualification": { + "maxLength": "Please enter less than 1000 characters" + }, + "jobPostingPreferredQualification": { + "maxLength": "Please enter less than 1000 characters" + }, + "jobPostingBenefits": { + "maxLength": "Please enter less than 1000 characters" + }, + "jobPostingSalary": { + "required": "Please enter the salary", + "maxLength": "Please enter less than 10 characters" + }, + "jobPostingDueDate": { + "required": "Please enter the due date" } } } diff --git a/src/shared/config/internationalization/locales/ko/validation.json b/src/shared/config/internationalization/locales/ko/validation.json index 2bec0b5..d0e04fc 100644 --- a/src/shared/config/internationalization/locales/ko/validation.json +++ b/src/shared/config/internationalization/locales/ko/validation.json @@ -58,6 +58,30 @@ "required": "사업자 등록번호를 입력해 주세요", "length": "10자를 입력해주세요", "pattern": "숫자만 입력해주세요" + }, + "jobPostingTitle": { + "required": "공고 제목을 입력해 주세요", + "maxLength": "공고 제목은 최대 100자를 초과할 수 없습니다" + }, + "jobPostingDescription": { + "required": "주요 업무를 입력해 주세요", + "maxLength": "주요 업무는 최대 1000자를 초과할 수 없습니다" + }, + "jobPostingRequiredQualification": { + "maxLength": "자격 요건은 최대 1000자를 초과할 수 없습니다" + }, + "jobPostingPreferredQualification": { + "maxLength": "우대 사항은 최대 1000자를 초과할 수 없습니다" + }, + "jobPostingBenefits": { + "maxLength": "혜택/복지는 최대 1000자를 초과할 수 없습니다" + }, + "jobPostingSalary": { + "required": "월급을 입력해 주세요", + "maxLength": "월급은 최대 10자를 초과할 수 없습니다" + }, + "jobPostingDueDate": { + "required": "공고 마감일을 입력해 주세요" } } } diff --git a/src/shared/form/ui/message/message.tsx b/src/shared/form/ui/message/message.tsx index 2ad9819..2e1e2bd 100644 --- a/src/shared/form/ui/message/message.tsx +++ b/src/shared/form/ui/message/message.tsx @@ -9,7 +9,10 @@ type FormErrorMessageProps = HelperTextProps & { name?: string } -export const FormErrorMessage = ({ name = '' }: FormErrorMessageProps) => { +export const FormErrorMessage = ({ + name = '', + className, +}: FormErrorMessageProps) => { const { formState: { errors }, } = useFormContext() @@ -21,8 +24,16 @@ export const FormErrorMessage = ({ name = '' }: FormErrorMessageProps) => { if (!error) return null if (error.message.includes('validation')) { - return {t(error.message)} + return ( + + {t(error.message)} + + ) } - return {error.message} + return ( + + {error.message} + + ) } diff --git a/src/shared/ui/text-field/text-field.tsx b/src/shared/ui/text-field/text-field.tsx index 0bd8178..5975c34 100644 --- a/src/shared/ui/text-field/text-field.tsx +++ b/src/shared/ui/text-field/text-field.tsx @@ -96,7 +96,9 @@ export const TextField = forwardRef( )} onClick={handleClick} > - {slots?.left &&
{slots.left}
} + {slots?.left && ( +
{slots.left}
+ )} ( onFocus={handleFocus} onBlur={handleBlur} /> - {slots?.right &&
{slots.right}
} + {slots?.right && ( +
{slots.right}
+ )}
) }, From 5b0256ef6294bb8de33ebb2e5e59a66aca51db12 Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Thu, 15 May 2025 00:05:18 +0900 Subject: [PATCH 04/14] =?UTF-8?q?Feat:=20PD-265=20=EC=A7=80=EC=9B=90=20?= =?UTF-8?q?=EA=B3=B5=EA=B3=A0=20=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/academy/api/get-academy-me.ts | 22 +++++++++++++++ src/entities/academy/api/query.ts | 12 +++++++++ src/entities/academy/index.ts | 1 + src/features/job-posting-form/index.ts | 5 ++++ .../job-posting-form/model/form-values.ts | 27 ++++++++++++++++++- .../ui/create-job-posting-page.tsx | 19 ++++++++++++- 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 src/entities/academy/api/get-academy-me.ts create mode 100644 src/entities/academy/api/query.ts diff --git a/src/entities/academy/api/get-academy-me.ts b/src/entities/academy/api/get-academy-me.ts new file mode 100644 index 0000000..ac60e30 --- /dev/null +++ b/src/entities/academy/api/get-academy-me.ts @@ -0,0 +1,22 @@ +'use server' + +import { getBusinessSession } from 'entities/auth' +import { apiClient } from 'shared/api' + +import { AcademyDetail } from '../model/academy-detail' + +type GetAcademyMeResponse = AcademyDetail + +export const getAcademyMe = async () => { + const { accessToken } = await getBusinessSession() + + const response = await apiClient.get({ + endpoint: `/academies/me`, + option: { + authorization: `Bearer ${accessToken}`, + tags: ['academy', 'me'], + }, + }) + + return response +} diff --git a/src/entities/academy/api/query.ts b/src/entities/academy/api/query.ts new file mode 100644 index 0000000..8bb49b9 --- /dev/null +++ b/src/entities/academy/api/query.ts @@ -0,0 +1,12 @@ +import { queryOptions } from '@tanstack/react-query' + +import { getAcademyMe } from './get-academy-me' + +export const academyQueries = { + all: () => ['academy'], + me: () => + queryOptions({ + queryKey: [...academyQueries.all(), 'me'], + queryFn: () => getAcademyMe(), + }), +} diff --git a/src/entities/academy/index.ts b/src/entities/academy/index.ts index 85edae0..70eae67 100644 --- a/src/entities/academy/index.ts +++ b/src/entities/academy/index.ts @@ -1 +1,2 @@ export { type AcademyDetail } from './model/academy-detail' +export { academyQueries } from './api/query' diff --git a/src/features/job-posting-form/index.ts b/src/features/job-posting-form/index.ts index de87618..a0fef5f 100644 --- a/src/features/job-posting-form/index.ts +++ b/src/features/job-posting-form/index.ts @@ -1,2 +1,7 @@ export { JobPostingForm } from './ui/job-posting-form' export { SidePanel } from './ui/side-panel' +export { + convertToJobDetail, + convertToCreateJobPostDTO, + type FormValues, +} from './model/form-values' diff --git a/src/features/job-posting-form/model/form-values.ts b/src/features/job-posting-form/model/form-values.ts index c83cc86..1159c7d 100644 --- a/src/features/job-posting-form/model/form-values.ts +++ b/src/features/job-posting-form/model/form-values.ts @@ -1,6 +1,11 @@ import { isArray, isNil } from 'lodash-es' -import { convertStudentTypeToArray, CreateJobPost } from 'entities/job-post' +import { AcademyDetail } from 'entities/academy' +import { + convertStudentTypeToArray, + CreateJobPost, + JobPostDetail, +} from 'entities/job-post' export type FormValues = { title: string @@ -63,3 +68,23 @@ export const convertToCreateJobPostDTO = ({ formValues.salaryNegotiable.includes('true'), } } + +export const convertToJobDetail = ( + jobPost: CreateJobPost, + academy: AcademyDetail, +): JobPostDetail => { + return { + ...jobPost, + academyId: academy.id, + academyName: academy.name, + academyNameEn: academy.nameEn, + academyRepresentativeName: academy.representativeName, + academyDescription: academy.description, + academyLocationType: academy.locationType, + academyDetailedAddress: academy.detailedAddress, + lat: academy.lat, + lng: academy.lng, + academyImageUrls: academy.imageUrls, + id: academy.id, + } +} diff --git a/src/pages/business-job-posting/ui/create-job-posting-page.tsx b/src/pages/business-job-posting/ui/create-job-posting-page.tsx index 42b6901..2c111f8 100644 --- a/src/pages/business-job-posting/ui/create-job-posting-page.tsx +++ b/src/pages/business-job-posting/ui/create-job-posting-page.tsx @@ -1,14 +1,30 @@ 'use client' +import { useQuery } from '@tanstack/react-query' import { useForm } from 'react-hook-form' +import { academyQueries } from 'entities/academy' import { JobPostingForm, SidePanel } from 'features/job-posting-form' +import { + convertToCreateJobPostDTO, + convertToJobDetail, + FormValues, +} from 'features/job-posting-form' import { PreviewJobPostingButton } from 'features/preview-job-posting' import { Form } from 'shared/form' import { Layout } from 'shared/ui' export const CreateJobPostingPage = () => { - const form = useForm() + const { data: academyMe } = useQuery(academyQueries.me()) + + const form = useForm() + + const getJobPosting = async () => { + const values = form.getValues() + const createJobPost = convertToCreateJobPostDTO(values) + + return convertToJobDetail(createJobPost, academyMe!) + } return ( @@ -22,6 +38,7 @@ export const CreateJobPostingPage = () => {
From ae36be334bf26bbd6f65f12e6c7fd831b7940b54 Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Thu, 15 May 2025 00:23:28 +0900 Subject: [PATCH 05/14] =?UTF-8?q?Feat:=20PD-265=20=EB=93=B1=EB=A1=9D=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20disabled=20=EC=A1=B0=EA=B1=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/job-posting-form/index.ts | 1 + .../job-posting-form/model/form-values.ts | 38 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/features/job-posting-form/index.ts b/src/features/job-posting-form/index.ts index a0fef5f..88d1c07 100644 --- a/src/features/job-posting-form/index.ts +++ b/src/features/job-posting-form/index.ts @@ -4,4 +4,5 @@ export { convertToJobDetail, convertToCreateJobPostDTO, type FormValues, + defaultValues, } from './model/form-values' diff --git a/src/features/job-posting-form/model/form-values.ts b/src/features/job-posting-form/model/form-values.ts index 1159c7d..69130f6 100644 --- a/src/features/job-posting-form/model/form-values.ts +++ b/src/features/job-posting-form/model/form-values.ts @@ -1,4 +1,5 @@ -import { isArray, isNil } from 'lodash-es' +import { isValid, parse } from 'date-fns' +import { isArray, isNil, isNull, isUndefined } from 'lodash-es' import { AcademyDetail } from 'entities/academy' import { @@ -6,6 +7,7 @@ import { CreateJobPost, JobPostDetail, } from 'entities/job-post' +import { isNilOrEmptyString } from 'shared/lib' export type FormValues = { title: string @@ -15,7 +17,7 @@ export type FormValues = { benefits: string salary: number | null salaryNegotiable: string[] - jobStartDate: string + jobStartDate?: string dueDate?: string | null studentType: string[] | null } @@ -28,8 +30,8 @@ export const defaultValues: FormValues = { benefits: '', salary: null, salaryNegotiable: [], - jobStartDate: '', - dueDate: '', + jobStartDate: undefined, + dueDate: undefined, studentType: null, } @@ -38,6 +40,10 @@ export const convertToFormValues = (jobPost?: CreateJobPost): FormValues => { return { ...jobPost, + jobStartDate: isNilOrEmptyString(jobPost.jobStartDate) + ? undefined + : jobPost.jobStartDate, + dueDate: isNilOrEmptyString(jobPost.dueDate) ? undefined : jobPost.dueDate, studentType: convertStudentTypeToArray({ forKindergarten: jobPost.forKindergarten, forElementary: jobPost.forElementary, @@ -88,3 +94,27 @@ export const convertToJobDetail = ( id: academy.id, } } + +export const canRegisterForm = ( + formValues: Pick< + FormValues, + 'title' | 'jobDescription' | 'salary' | 'studentType' | 'dueDate' + >, +) => { + const isDateString = (str?: string) => { + if (isUndefined(str)) return false + + const parsedDate = parse(str, 'yyyy-MM-dd', new Date()) + + return isValid(parsedDate) + } + + return ( + formValues.title && + formValues.jobDescription && + formValues.salary && + !isNil(formValues.studentType) && + formValues.studentType.length > 0 && + (isNull(formValues.dueDate) || isDateString(formValues.dueDate)) + ) +} From a8ce01454fea2f109114f1943ed13a30bd6c79ef Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Thu, 15 May 2025 01:13:59 +0900 Subject: [PATCH 06/14] =?UTF-8?q?Feat:=20PD-265=20=EA=B3=B5=EA=B3=A0=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5,=20=EC=9E=84=EC=8B=9C=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job-post/ui/posting-detail/index.tsx | 10 ++- .../job-posting-form/model/form-values.ts | 23 +++++-- src/features/job-posting-form/model/rules.ts | 8 ++- .../job-posting-form/ui/job-posting-form.tsx | 38 ++++++----- .../job-posting-form/ui/side-panel.tsx | 63 ++++++++++++++++++- .../ui/create-job-posting-page.tsx | 59 ++++++++++++++++- .../locales/en/validation.json | 3 +- .../locales/ko/validation.json | 3 +- src/shared/form/ui/checkbox/checkbox.tsx | 7 ++- src/shared/form/ui/checkbox/context.tsx | 1 + 10 files changed, 180 insertions(+), 35 deletions(-) diff --git a/src/entities/job-post/ui/posting-detail/index.tsx b/src/entities/job-post/ui/posting-detail/index.tsx index dbcd142..38a3cfc 100644 --- a/src/entities/job-post/ui/posting-detail/index.tsx +++ b/src/entities/job-post/ui/posting-detail/index.tsx @@ -1,3 +1,5 @@ +import { useLocale } from 'next-intl' + import { formatDate, formatCurrency, toDisplayValue } from 'shared/lib' import type { JobPostDetail } from '../../model/job-post-detail' @@ -8,6 +10,10 @@ type Props = { } export const PostingDetail = ({ jobPost }: Props) => { + const local = useLocale() + + const code = local === 'ko' ? '만원' : 'in 10,000 KRW' + return (
  • @@ -51,9 +57,7 @@ export const PostingDetail = ({ jobPost }: Props) => {
  • Salary

    - {toDisplayValue( - formatCurrency({ number: jobPost.salary, code: 'KRW' }), - )} + {toDisplayValue(formatCurrency({ number: jobPost.salary, code }))}

  • diff --git a/src/features/job-posting-form/model/form-values.ts b/src/features/job-posting-form/model/form-values.ts index 69130f6..f9acdba 100644 --- a/src/features/job-posting-form/model/form-values.ts +++ b/src/features/job-posting-form/model/form-values.ts @@ -19,6 +19,7 @@ export type FormValues = { salaryNegotiable: string[] jobStartDate?: string dueDate?: string | null + noExpirationDate: string[] studentType: string[] | null } @@ -33,6 +34,7 @@ export const defaultValues: FormValues = { jobStartDate: undefined, dueDate: undefined, studentType: null, + noExpirationDate: [], } export const convertToFormValues = (jobPost?: CreateJobPost): FormValues => { @@ -44,6 +46,7 @@ export const convertToFormValues = (jobPost?: CreateJobPost): FormValues => { ? undefined : jobPost.jobStartDate, dueDate: isNilOrEmptyString(jobPost.dueDate) ? undefined : jobPost.dueDate, + noExpirationDate: isNil(jobPost.dueDate) ? ['true'] : [], studentType: convertStudentTypeToArray({ forKindergarten: jobPost.forKindergarten, forElementary: jobPost.forElementary, @@ -57,6 +60,7 @@ export const convertToFormValues = (jobPost?: CreateJobPost): FormValues => { export const convertToCreateJobPostDTO = ({ studentType, + noExpirationDate, ...formValues }: FormValues): CreateJobPost => { return { @@ -67,7 +71,9 @@ export const convertToCreateJobPostDTO = ({ forMiddleSchool: studentType?.includes('MiddleSchool') ?? false, forHighSchool: studentType?.includes('HighSchool') ?? false, forAdult: studentType?.includes('Adult') ?? false, - dueDate: formValues.dueDate || null, + dueDate: noExpirationDate.includes('true') + ? null + : formValues.dueDate || null, jobStartDate: formValues.jobStartDate || '', salaryNegotiable: isArray(formValues.salaryNegotiable) && @@ -98,11 +104,16 @@ export const convertToJobDetail = ( export const canRegisterForm = ( formValues: Pick< FormValues, - 'title' | 'jobDescription' | 'salary' | 'studentType' | 'dueDate' + | 'title' + | 'jobDescription' + | 'salary' + | 'studentType' + | 'dueDate' + | 'noExpirationDate' >, ) => { - const isDateString = (str?: string) => { - if (isUndefined(str)) return false + const isDateString = (str?: string | null) => { + if (isNil(str)) return false const parsedDate = parse(str, 'yyyy-MM-dd', new Date()) @@ -115,6 +126,8 @@ export const canRegisterForm = ( formValues.salary && !isNil(formValues.studentType) && formValues.studentType.length > 0 && - (isNull(formValues.dueDate) || isDateString(formValues.dueDate)) + ((formValues.noExpirationDate.includes('true') && + isNil(formValues.dueDate)) || + isDateString(formValues.dueDate)) ) } diff --git a/src/features/job-posting-form/model/rules.ts b/src/features/job-posting-form/model/rules.ts index 7cbb965..1784bf5 100644 --- a/src/features/job-posting-form/model/rules.ts +++ b/src/features/job-posting-form/model/rules.ts @@ -39,7 +39,13 @@ export const benefits = { export const salary = { required: 'validation.jobPostingSalary.required', - validate: (value: number) => { + validate: (value: string) => { + const isNumber = /^\d+$/.test(value) + + if (!isNumber) { + return 'validation.jobPostingSalary.invalid' + } + const salary = value.toString().replace(/,/g, '') if (salary.length > 10) { diff --git a/src/features/job-posting-form/ui/job-posting-form.tsx b/src/features/job-posting-form/ui/job-posting-form.tsx index 048dc23..8d4ab23 100644 --- a/src/features/job-posting-form/ui/job-posting-form.tsx +++ b/src/features/job-posting-form/ui/job-posting-form.tsx @@ -1,9 +1,9 @@ -import { isEqual, isNull } from 'lodash-es' +import { isEqual } from 'lodash-es' import { useFormContext, useWatch } from 'react-hook-form' import { fieldCss, Form } from 'shared/form' import { cn, Slot } from 'shared/lib' -import { Checkbox, Label } from 'shared/ui' +import { Checkbox, CheckboxValue, Label } from 'shared/ui' import { FormValues } from '../model/form-values' import * as rules from '../model/rules' @@ -20,9 +20,9 @@ export const JobPostingForm = ({ className }: Props) => { clearErrors, } = useFormContext() - const [studentType, dueDate] = useWatch({ + const [studentType, noExpirationDate] = useWatch({ control, - name: ['studentType', 'dueDate'], + name: ['studentType', 'noExpirationDate'], }) const studentTypeOptions = [ @@ -45,13 +45,11 @@ export const JobPostingForm = ({ className }: Props) => { clearErrors('studentType') } - const noExpirationDate = isNull(dueDate) - - const handleExpirationDateChange = () => { - if (noExpirationDate) { - setValue('dueDate', undefined) - } else { + const handleExpirationDateChange = (value: CheckboxValue[]) => { + if (value.includes('true')) { setValue('dueDate', null) + } else { + setValue('dueDate', undefined) } clearErrors('dueDate') @@ -178,17 +176,23 @@ export const JobPostingForm = ({ className }: Props) => { - + + + + +
) diff --git a/src/features/job-posting-form/ui/side-panel.tsx b/src/features/job-posting-form/ui/side-panel.tsx index f7379e6..94c0137 100644 --- a/src/features/job-posting-form/ui/side-panel.tsx +++ b/src/features/job-posting-form/ui/side-panel.tsx @@ -1,12 +1,48 @@ +import { isEqual } from 'lodash-es' +import { useFormContext, useWatch } from 'react-hook-form' + import { Button } from 'shared/ui' +import { + canRegisterForm, + defaultValues, + FormValues, +} from '../model/form-values' + type Props = { type: 'register' | 'update' onRegister?: () => void onSave?: () => void } -export const SidePanel = ({ type }: Props) => { +export const SidePanel = ({ type, onRegister, onSave }: Props) => { + const { handleSubmit, control, getValues } = useFormContext() + + const [ + title, + jobDescription, + salary, + studentType, + dueDate, + noExpirationDate, + ] = useWatch({ + control, + name: [ + 'title', + 'jobDescription', + 'salary', + 'studentType', + 'dueDate', + 'noExpirationDate', + ], + }) + + const canSave = isEqual(getValues(), defaultValues) + + const submitForm = handleSubmit(() => { + onRegister?.() + }) + return (

@@ -21,11 +57,32 @@ export const SidePanel = ({ type }: Props) => {

- {type === 'register' && ( - )} diff --git a/src/pages/business-job-posting/ui/create-job-posting-page.tsx b/src/pages/business-job-posting/ui/create-job-posting-page.tsx index 2c111f8..227b51c 100644 --- a/src/pages/business-job-posting/ui/create-job-posting-page.tsx +++ b/src/pages/business-job-posting/ui/create-job-posting-page.tsx @@ -1,23 +1,38 @@ 'use client' import { useQuery } from '@tanstack/react-query' +import { useRouter } from 'next/navigation' import { useForm } from 'react-hook-form' +import { toast } from 'react-toastify' import { academyQueries } from 'entities/academy' -import { JobPostingForm, SidePanel } from 'features/job-posting-form' +import { createJobPost, createJobPostDraft } from 'entities/job-post' +import { + defaultValues, + JobPostingForm, + SidePanel, +} from 'features/job-posting-form' import { convertToCreateJobPostDTO, convertToJobDetail, FormValues, } from 'features/job-posting-form' import { PreviewJobPostingButton } from 'features/preview-job-posting' +import { isServerError, useServerErrorHandler } from 'shared/api' import { Form } from 'shared/form' import { Layout } from 'shared/ui' export const CreateJobPostingPage = () => { + const router = useRouter() + const { data: academyMe } = useQuery(academyQueries.me()) - const form = useForm() + const { handleServerError } = useServerErrorHandler() + + const form = useForm({ + defaultValues, + reValidateMode: 'onSubmit', + }) const getJobPosting = async () => { const values = form.getValues() @@ -26,6 +41,40 @@ export const CreateJobPostingPage = () => { return convertToJobDetail(createJobPost, academyMe!) } + const handleRegisterJobPostingSuccess = () => { + router.push('/business/job-posting') + toast.success('공고를 등록했어요') + } + + const registerJobPosting = async () => { + const values = form.getValues() + + const response = await createJobPost(convertToCreateJobPostDTO(values)) + + if (isServerError(response)) { + handleServerError(response) + } else { + handleRegisterJobPostingSuccess() + } + } + + const handleSaveJobPostingDraftSuccess = () => { + router.push('/business/job-posting') + toast.success('공고를 임시 저장했어요') + } + + const saveJobPostingDraft = async () => { + const values = form.getValues() + + const response = await createJobPostDraft(convertToCreateJobPostDTO(values)) + + if (isServerError(response)) { + handleServerError(response) + } else { + handleSaveJobPostingDraftSuccess() + } + } + return (

@@ -34,7 +83,11 @@ export const CreateJobPostingPage = () => {
- + void } const FormCheckboxGroup = ({ @@ -22,6 +23,7 @@ const FormCheckboxGroup = ({ rules, children, required, + onChange, }: PropsWithChildren) => { const checkboxState = useCheckbox({ name, options }) @@ -37,8 +39,9 @@ const FormCheckboxGroup = ({ () => ({ ...checkboxState, controller, + onChange, }), - [checkboxState, controller], + [checkboxState, controller, onChange], ) return ( @@ -67,6 +70,7 @@ const FormCheckboxItem = ({ updateCheckedValue, getCheckboxProps, getIndeterminateCheckboxProps, + onChange, } = useCheckboxContext() const { @@ -88,6 +92,7 @@ const FormCheckboxItem = ({ checkboxProps.onChange(updatedCheckedValues => { field.onChange(updatedCheckedValues) clearErrors(field.name) + onChange?.(updatedCheckedValues) }) } diff --git a/src/shared/form/ui/checkbox/context.tsx b/src/shared/form/ui/checkbox/context.tsx index 27862e3..2a38636 100644 --- a/src/shared/form/ui/checkbox/context.tsx +++ b/src/shared/form/ui/checkbox/context.tsx @@ -5,6 +5,7 @@ import { useCheckbox } from 'shared/lib' type CheckboxState = ReturnType & { controller: UseControllerReturn + onChange?: (value: CheckboxValue[]) => void } export const CheckboxContext = createContext(null) From dbed3e2fbe3fa6b197d00bd20ea98cdfcbe2ce0c Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Thu, 15 May 2025 02:12:05 +0900 Subject: [PATCH 07/14] =?UTF-8?q?Feat:=20PD-265=20=EA=B3=B5=EA=B3=A0?= =?UTF-8?q?=EB=B3=84=20=EC=A7=80=EC=9B=90=EC=9E=90=20=EB=AA=A9=EB=A1=9D,?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../[jobPostResumeRelationId]/page.ts | 1 + .../[jobPostId]/applicant-management/page.tsx | 21 +++ .../api/get-job-post-resumes.ts | 1 + .../api/use-job-post-relations.ts | 31 ++++ src/pages/business-job-posting/index.ts | 2 + ...-post-applicant-management-detail-page.tsx | 31 ++++ ...ob-post-applicant-management-list-page.tsx | 152 ++++++++++++++++++ .../ui/job-posting-list-page.tsx | 9 +- 8 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 app/(business)/business/job-posting/[jobPostId]/applicant-management/[jobPostResumeRelationId]/page.ts create mode 100644 app/(business)/business/job-posting/[jobPostId]/applicant-management/page.tsx create mode 100644 src/pages/business-job-posting/api/use-job-post-relations.ts create mode 100644 src/pages/business-job-posting/ui/job-post-applicant-management-detail-page.tsx create mode 100644 src/pages/business-job-posting/ui/job-post-applicant-management-list-page.tsx diff --git a/app/(business)/business/job-posting/[jobPostId]/applicant-management/[jobPostResumeRelationId]/page.ts b/app/(business)/business/job-posting/[jobPostId]/applicant-management/[jobPostResumeRelationId]/page.ts new file mode 100644 index 0000000..0d5dadc --- /dev/null +++ b/app/(business)/business/job-posting/[jobPostId]/applicant-management/[jobPostResumeRelationId]/page.ts @@ -0,0 +1 @@ +export { JobPostApplicantManagementDetailPage as default } from 'pages/business-job-posting' diff --git a/app/(business)/business/job-posting/[jobPostId]/applicant-management/page.tsx b/app/(business)/business/job-posting/[jobPostId]/applicant-management/page.tsx new file mode 100644 index 0000000..e2cf417 --- /dev/null +++ b/app/(business)/business/job-posting/[jobPostId]/applicant-management/page.tsx @@ -0,0 +1,21 @@ +import { getJobPost } from 'entities/job-post' +import { JobPostApplicantManagementListPage } from 'pages/business-job-posting' + +type Params = { + jobPostId: string +} + +const Page = async ({ params }: { params: Promise }) => { + const { jobPostId } = await params + + const jobPost = await getJobPost({ jobPostId: Number(jobPostId) }) + + return ( + + ) +} + +export default Page diff --git a/src/entities/job-post-resume-relation/api/get-job-post-resumes.ts b/src/entities/job-post-resume-relation/api/get-job-post-resumes.ts index 35dcc17..3c6c296 100644 --- a/src/entities/job-post-resume-relation/api/get-job-post-resumes.ts +++ b/src/entities/job-post-resume-relation/api/get-job-post-resumes.ts @@ -8,6 +8,7 @@ import { ApplicationStatus } from '../model/status' export type GetJobPostResumeRequest = PaginationParams<{ status?: ApplicationStatus + jobPostId?: number }> type GetJobPostResumeResponse = Pagination diff --git a/src/pages/business-job-posting/api/use-job-post-relations.ts b/src/pages/business-job-posting/api/use-job-post-relations.ts new file mode 100644 index 0000000..64a3650 --- /dev/null +++ b/src/pages/business-job-posting/api/use-job-post-relations.ts @@ -0,0 +1,31 @@ +import { keepPreviousData, useQuery } from '@tanstack/react-query' + +import { + ApplicationStatus, + jobPostResumeRelationQueries, +} from 'entities/job-post-resume-relation' + +export const useJobPostRelations = ({ + status, + pageNumber, + jobPostId, +}: { + status: ApplicationStatus + pageNumber: number + jobPostId?: number +}) => { + const { data } = useQuery({ + ...jobPostResumeRelationQueries.businessList({ + pageNumber, + rowCount: 10, + status, + jobPostId, + }), + placeholderData: keepPreviousData, + }) + + return { + applications: data?.content ?? [], + totalPages: data?.totalPages === 0 ? 1 : data?.totalPages, + } +} diff --git a/src/pages/business-job-posting/index.ts b/src/pages/business-job-posting/index.ts index 148caff..63765f7 100644 --- a/src/pages/business-job-posting/index.ts +++ b/src/pages/business-job-posting/index.ts @@ -1,3 +1,5 @@ export { CreateJobPostingPage } from './ui/create-job-posting-page' export { BusinessJobPostingListPage } from './ui/job-posting-list-page' export { UpdateJobPostingPage } from './ui/update-job-posting-page' +export { JobPostApplicantManagementListPage } from './ui/job-post-applicant-management-list-page' +export { JobPostApplicantManagementDetailPage } from './ui/job-post-applicant-management-detail-page' diff --git a/src/pages/business-job-posting/ui/job-post-applicant-management-detail-page.tsx b/src/pages/business-job-posting/ui/job-post-applicant-management-detail-page.tsx new file mode 100644 index 0000000..fdeae25 --- /dev/null +++ b/src/pages/business-job-posting/ui/job-post-applicant-management-detail-page.tsx @@ -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 JobPostApplicantManagementDetailPage = async ({ + params, +}: { + params: Promise +}) => { + const { jobPostResumeRelationId } = await params + + const jobPostResumeRelation = await getBusinessJobPostResumeRelation({ + jobPostResumeRelationId: Number(jobPostResumeRelationId), + }) + + const isFileResume = jobPostResumeRelation.filePath !== null + + return ( + + {isFileResume ? ( + + ) : ( + + )} + + ) +} diff --git a/src/pages/business-job-posting/ui/job-post-applicant-management-list-page.tsx b/src/pages/business-job-posting/ui/job-post-applicant-management-list-page.tsx new file mode 100644 index 0000000..031cbab --- /dev/null +++ b/src/pages/business-job-posting/ui/job-post-applicant-management-list-page.tsx @@ -0,0 +1,152 @@ +'use client' + +import { useRouter } from 'next/navigation' +import { useTranslations } from 'next-intl' +import { useState } from 'react' + +import { ApplicationStatus } from 'entities/job-post-resume-relation' +import { CopyJobPostingButton } from 'features/copy-job-posting' +import { PreviewJobPostingButton } from 'features/preview-job-posting' +import { cn } from 'shared/lib' +import { Layout, Tabs, Table, Pagination, Button } from 'shared/ui' + +import { useJobPostRelations } from '../api/use-job-post-relations' + +type Props = { + title: string + jobPostId: number +} + +export const JobPostApplicantManagementListPage = ({ + title, + jobPostId, +}: Props) => { + const t = useTranslations('applicant-management-list') + + const router = useRouter() + + const [currentPage, setCurrentPage] = useState(0) + const [status, setStatus] = useState( + ApplicationStatus.SUBMITTED, + ) + + const { applications, totalPages } = useJobPostRelations({ + status, + pageNumber: currentPage, + jobPostId: Number(jobPostId), + }) + + const hasNoApplications = applications.length === 0 + + const handlePageChange = ({ selected }: { selected: number }) => { + setCurrentPage(selected) + } + + const handleStatusChange = (value: string) => { + setStatus(value as ApplicationStatus) + } + + const handleItemClick = (id: number) => () => { + router.push(`/business/job-posting/${jobPostId}/applicant-management/${id}`) + } + + const handleCopySuccess = () => { + router.push(`/business/job-posting`) + } + + return ( + +

{title}

+ +
+ + {t('tabs.submitted')} + {t('tabs.reviewed')} + {t('tabs.accepted')} + {t('tabs.rejected')} + +
+ + + +
+
+ +
+ + + + + {t('table.applicant')} + + + {t('table.job-title')} + + + {t('table.memo')} + + + {t('table.application-date')} + + + + {(() => { + if (hasNoApplications) { + return null + } + + return ( + + {applications.map(application => ( + + + {application.resumeFirstName}{' '} + {application.resumeLastName} + + {application.jobPostTitle} + + {application?.academyMemo ?? ''} + + {application.submittedDate} + + ))} + + ) + })()} + + {hasNoApplications && ( +

+ {t('table.no-data')} +

+ )} +
+
+
+ +
+ ) +} diff --git a/src/pages/business-job-posting/ui/job-posting-list-page.tsx b/src/pages/business-job-posting/ui/job-posting-list-page.tsx index f70015c..29dfeaf 100644 --- a/src/pages/business-job-posting/ui/job-posting-list-page.tsx +++ b/src/pages/business-job-posting/ui/job-posting-list-page.tsx @@ -42,7 +42,9 @@ export const BusinessJobPostingListPage = () => { } const handleItemClick = (id: number) => () => { - router.push(`/business/job-posting/${id}`) + if (status === JobFilter.SAVED) return + + router.push(`/business/job-posting/${id}/applicant-management`) } const handleCopySuccess = () => { @@ -122,7 +124,10 @@ export const BusinessJobPostingListPage = () => { {jobPost.title} {jobPost.resumeCount}명 From 8ee5ea6bbdfdc7f07d1696588eb8d5f4930a3ec3 Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Thu, 15 May 2025 02:24:22 +0900 Subject: [PATCH 08/14] =?UTF-8?q?Feat:=20PD-265=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=EC=9D=BC=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/job-post/model/job-post.ts | 1 + .../business-job-posting/ui/job-posting-list-page.tsx | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/entities/job-post/model/job-post.ts b/src/entities/job-post/model/job-post.ts index e050193..b46532a 100644 --- a/src/entities/job-post/model/job-post.ts +++ b/src/entities/job-post/model/job-post.ts @@ -19,6 +19,7 @@ export type BusinessJobPost = { id: number title: string dueDate: string + openDate: string createdAt: string salary: number resumeCount: number diff --git a/src/pages/business-job-posting/ui/job-posting-list-page.tsx b/src/pages/business-job-posting/ui/job-posting-list-page.tsx index 29dfeaf..7052bce 100644 --- a/src/pages/business-job-posting/ui/job-posting-list-page.tsx +++ b/src/pages/business-job-posting/ui/job-posting-list-page.tsx @@ -137,9 +137,11 @@ export const BusinessJobPostingListPage = () => { code: '만원', })} - - {jobPost.createdAt - ? format(jobPost.createdAt, 'yyyy.MM.dd') + + {jobPost.openDate + ? format(jobPost.openDate, 'yyyy.MM.dd') : t('table.draft')} Date: Thu, 15 May 2025 23:59:10 +0900 Subject: [PATCH 09/14] =?UTF-8?q?Feat:=20PD-265=20=EA=B3=B5=EA=B3=A0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../[jobPostId]/applicant-management/page.tsx | 7 ++ .../[jobPostId]/update/draft/page.tsx | 21 ++++ .../job-posting/[jobPostId]/update/page.ts | 1 - .../job-posting/[jobPostId]/update/page.tsx | 21 ++++ .../job-post/api/update-job-post-draft.ts | 2 +- src/entities/job-post/api/update-job-post.ts | 2 +- src/features/job-posting-form/index.ts | 1 + .../job-posting-form/model/form-values.ts | 11 +- .../job-posting-form/ui/job-posting-form.tsx | 1 + src/pages/business-job-posting/index.ts | 1 + ...ob-post-applicant-management-list-page.tsx | 13 +- .../ui/job-posting-list-page.tsx | 13 ++ .../ui/update-job-posting-draft-page.tsx | 112 ++++++++++++++++++ .../ui/update-job-posting-page.tsx | 60 +++++++++- 14 files changed, 256 insertions(+), 10 deletions(-) create mode 100644 app/(business)/business/job-posting/[jobPostId]/update/draft/page.tsx delete mode 100644 app/(business)/business/job-posting/[jobPostId]/update/page.ts create mode 100644 app/(business)/business/job-posting/[jobPostId]/update/page.tsx create mode 100644 src/pages/business-job-posting/ui/update-job-posting-draft-page.tsx diff --git a/app/(business)/business/job-posting/[jobPostId]/applicant-management/page.tsx b/app/(business)/business/job-posting/[jobPostId]/applicant-management/page.tsx index e2cf417..6a78c8c 100644 --- a/app/(business)/business/job-posting/[jobPostId]/applicant-management/page.tsx +++ b/app/(business)/business/job-posting/[jobPostId]/applicant-management/page.tsx @@ -1,3 +1,5 @@ +import { isAfter, parseISO } from 'date-fns' + import { getJobPost } from 'entities/job-post' import { JobPostApplicantManagementListPage } from 'pages/business-job-posting' @@ -10,10 +12,15 @@ const Page = async ({ params }: { params: Promise }) => { const jobPost = await getJobPost({ jobPostId: Number(jobPostId) }) + const isExpired = jobPost.dueDate + ? isAfter(new Date(), parseISO(jobPost.dueDate)) + : false + return ( ) } diff --git a/app/(business)/business/job-posting/[jobPostId]/update/draft/page.tsx b/app/(business)/business/job-posting/[jobPostId]/update/draft/page.tsx new file mode 100644 index 0000000..f281d37 --- /dev/null +++ b/app/(business)/business/job-posting/[jobPostId]/update/draft/page.tsx @@ -0,0 +1,21 @@ +import { getJobPost } from 'entities/job-post' +import { UpdateJobPostingDraftPage } from 'pages/business-job-posting' + +type Params = { + jobPostId: string +} + +const Page = async ({ params }: { params: Promise }) => { + const { jobPostId } = await params + + const jobPost = await getJobPost({ jobPostId: Number(jobPostId) }) + + return ( + + ) +} + +export default Page diff --git a/app/(business)/business/job-posting/[jobPostId]/update/page.ts b/app/(business)/business/job-posting/[jobPostId]/update/page.ts deleted file mode 100644 index c62aed0..0000000 --- a/app/(business)/business/job-posting/[jobPostId]/update/page.ts +++ /dev/null @@ -1 +0,0 @@ -export { UpdateJobPostingPage as default } from 'pages/business-job-posting' diff --git a/app/(business)/business/job-posting/[jobPostId]/update/page.tsx b/app/(business)/business/job-posting/[jobPostId]/update/page.tsx new file mode 100644 index 0000000..8840d84 --- /dev/null +++ b/app/(business)/business/job-posting/[jobPostId]/update/page.tsx @@ -0,0 +1,21 @@ +import { getJobPost } from 'entities/job-post' +import { UpdateJobPostingPage } from 'pages/business-job-posting' + +type Params = { + jobPostId: string +} + +const Page = async ({ params }: { params: Promise }) => { + const { jobPostId } = await params + + const jobPost = await getJobPost({ jobPostId: Number(jobPostId) }) + + return ( + + ) +} + +export default Page diff --git a/src/entities/job-post/api/update-job-post-draft.ts b/src/entities/job-post/api/update-job-post-draft.ts index 2f283ee..4bf635f 100644 --- a/src/entities/job-post/api/update-job-post-draft.ts +++ b/src/entities/job-post/api/update-job-post-draft.ts @@ -32,7 +32,7 @@ export const updateJobPostDraft = async ({ const { accessToken } = await getBusinessSession() try { - await apiClient.post({ + await apiClient.put({ endpoint: `/job-posts/${jobPostId}/draft`, option: { authorization: `Bearer ${accessToken}`, diff --git a/src/entities/job-post/api/update-job-post.ts b/src/entities/job-post/api/update-job-post.ts index 5774121..e166da9 100644 --- a/src/entities/job-post/api/update-job-post.ts +++ b/src/entities/job-post/api/update-job-post.ts @@ -32,7 +32,7 @@ export const updateJobPost = async ({ const { accessToken } = await getBusinessSession() try { - await apiClient.post({ + await apiClient.put({ endpoint: `/job-posts/${jobPostId}`, option: { authorization: `Bearer ${accessToken}`, diff --git a/src/features/job-posting-form/index.ts b/src/features/job-posting-form/index.ts index 88d1c07..5a7d8ae 100644 --- a/src/features/job-posting-form/index.ts +++ b/src/features/job-posting-form/index.ts @@ -5,4 +5,5 @@ export { convertToCreateJobPostDTO, type FormValues, defaultValues, + convertToFormValues, } from './model/form-values' diff --git a/src/features/job-posting-form/model/form-values.ts b/src/features/job-posting-form/model/form-values.ts index f9acdba..667e36d 100644 --- a/src/features/job-posting-form/model/form-values.ts +++ b/src/features/job-posting-form/model/form-values.ts @@ -37,11 +37,17 @@ export const defaultValues: FormValues = { noExpirationDate: [], } -export const convertToFormValues = (jobPost?: CreateJobPost): FormValues => { +export const convertToFormValues = (jobPost?: JobPostDetail): FormValues => { if (isNil(jobPost)) return defaultValues return { - ...jobPost, + title: jobPost.title, + jobDescription: jobPost.jobDescription, + requiredQualification: jobPost.requiredQualification, + preferredQualification: jobPost.preferredQualification, + benefits: jobPost.benefits, + salary: jobPost.salary, + salaryNegotiable: jobPost.salaryNegotiable ? ['true'] : [], jobStartDate: isNilOrEmptyString(jobPost.jobStartDate) ? undefined : jobPost.jobStartDate, @@ -54,7 +60,6 @@ export const convertToFormValues = (jobPost?: CreateJobPost): FormValues => { forHighSchool: jobPost.forHighSchool, forAdult: jobPost.forAdult, }), - salaryNegotiable: jobPost.salaryNegotiable ? ['true'] : [], } } diff --git a/src/features/job-posting-form/ui/job-posting-form.tsx b/src/features/job-posting-form/ui/job-posting-form.tsx index 8d4ab23..5fcd9e8 100644 --- a/src/features/job-posting-form/ui/job-posting-form.tsx +++ b/src/features/job-posting-form/ui/job-posting-form.tsx @@ -165,6 +165,7 @@ export const JobPostingForm = ({ className }: Props) => { diff --git a/src/pages/business-job-posting/index.ts b/src/pages/business-job-posting/index.ts index 63765f7..e541d43 100644 --- a/src/pages/business-job-posting/index.ts +++ b/src/pages/business-job-posting/index.ts @@ -1,4 +1,5 @@ export { CreateJobPostingPage } from './ui/create-job-posting-page' +export { UpdateJobPostingDraftPage } from './ui/update-job-posting-draft-page' export { BusinessJobPostingListPage } from './ui/job-posting-list-page' export { UpdateJobPostingPage } from './ui/update-job-posting-page' export { JobPostApplicantManagementListPage } from './ui/job-post-applicant-management-list-page' diff --git a/src/pages/business-job-posting/ui/job-post-applicant-management-list-page.tsx b/src/pages/business-job-posting/ui/job-post-applicant-management-list-page.tsx index 031cbab..0e15d1a 100644 --- a/src/pages/business-job-posting/ui/job-post-applicant-management-list-page.tsx +++ b/src/pages/business-job-posting/ui/job-post-applicant-management-list-page.tsx @@ -15,11 +15,13 @@ import { useJobPostRelations } from '../api/use-job-post-relations' type Props = { title: string jobPostId: number + isExpired: boolean } export const JobPostApplicantManagementListPage = ({ title, jobPostId, + isExpired, }: Props) => { const t = useTranslations('applicant-management-list') @@ -50,6 +52,10 @@ export const JobPostApplicantManagementListPage = ({ router.push(`/business/job-posting/${jobPostId}/applicant-management/${id}`) } + const handleEditButtonClick = () => { + router.push(`/business/job-posting/${jobPostId}/update`) + } + const handleCopySuccess = () => { router.push(`/business/job-posting`) } @@ -75,7 +81,12 @@ export const JobPostApplicantManagementListPage = ({ {t('tabs.rejected')}
- diff --git a/src/pages/business-job-posting/ui/job-posting-list-page.tsx b/src/pages/business-job-posting/ui/job-posting-list-page.tsx index 7052bce..92e2d2a 100644 --- a/src/pages/business-job-posting/ui/job-posting-list-page.tsx +++ b/src/pages/business-job-posting/ui/job-posting-list-page.tsx @@ -4,6 +4,7 @@ import { useQueryClient } from '@tanstack/react-query' import { format } from 'date-fns' import { useRouter } from 'next/navigation' import { useTranslations } from 'next-intl' +import { type MouseEvent } from 'react' import { useState } from 'react' import { jobPostQueries } from 'entities/job-post' @@ -47,6 +48,17 @@ export const BusinessJobPostingListPage = () => { router.push(`/business/job-posting/${id}/applicant-management`) } + const handleEditButtonClick = (id: number) => (event: MouseEvent) => { + event.stopPropagation() + event.preventDefault() + + if (status === JobFilter.SAVED) { + router.push(`/business/job-posting/${id}/update/draft`) + } else { + router.push(`/business/job-posting/${id}/update`) + } + } + const handleCopySuccess = () => { queryClient.invalidateQueries({ queryKey: jobPostQueries.businessLists(), @@ -155,6 +167,7 @@ export const BusinessJobPostingListPage = () => { + + + + +
+ + + + +
+ ) +} diff --git a/src/features/academy-detail-form/ui/field/business-registration-number.tsx b/src/features/academy-detail-form/ui/field/business-registration-number.tsx new file mode 100644 index 0000000..cee1430 --- /dev/null +++ b/src/features/academy-detail-form/ui/field/business-registration-number.tsx @@ -0,0 +1,23 @@ +import { useTranslations } from 'next-intl' + +import { fieldCss, Form } from 'shared/form' +import { Label } from 'shared/ui' + +export const BusinessRegistrationNumber = () => { + const t = useTranslations() + + return ( +
+ + + + + +
+ ) +} diff --git a/src/features/academy-detail-form/ui/field/description.tsx b/src/features/academy-detail-form/ui/field/description.tsx new file mode 100644 index 0000000..376ed80 --- /dev/null +++ b/src/features/academy-detail-form/ui/field/description.tsx @@ -0,0 +1,18 @@ +import { fieldCss, Form } from 'shared/form' +import { Label } from 'shared/ui' + +export const Description = () => { + return ( +
+ + + + + +
+ ) +} diff --git a/src/features/academy-detail-form/ui/field/images.tsx b/src/features/academy-detail-form/ui/field/images.tsx new file mode 100644 index 0000000..83d9752 --- /dev/null +++ b/src/features/academy-detail-form/ui/field/images.tsx @@ -0,0 +1,60 @@ +import { useFieldArray, useFormContext } from 'react-hook-form' + +import { Label } from 'shared/ui' + +import { FormValues } from '../../model/form-values' +import { ImageUploader } from '../image-uploader' + +export const Images = () => { + const { + control, + formState: { errors }, + } = useFormContext() + + const { fields, append, remove, update } = useFieldArray({ + control, + name: 'images', + }) + + const handleImageChange = (index: number) => (image: File, url: string) => { + update(index, { image, url }) + + const canAddImage = index < 5 + + if (canAddImage) { + append({ image: null, url: null }) + } + } + + const handleImageDelete = (id: number) => () => { + const lastImage = fields.at(-1)?.image + const maxLength = fields.length === 6 + + if (lastImage && maxLength) { + append({ image: null, url: null }) + } + + remove(id) + } + + return ( +
+ +

+ 소개 이미지는 최소 1장 이상 등록해 주세요. +

+
    + {fields.map((field, index) => ( +
  • + +
  • + ))} +
+
+ ) +} diff --git a/src/features/academy-detail-form/ui/field/representative-name.tsx b/src/features/academy-detail-form/ui/field/representative-name.tsx new file mode 100644 index 0000000..d99215e --- /dev/null +++ b/src/features/academy-detail-form/ui/field/representative-name.tsx @@ -0,0 +1,23 @@ +import { useTranslations } from 'next-intl' + +import { fieldCss, Form } from 'shared/form' +import { Label } from 'shared/ui' + +import { representativeName as representativeNameRule } from '../../model/rules' + +export const RepresentativeName = () => { + const t = useTranslations() + + return ( +
+ + + + + +
+ ) +} diff --git a/src/features/academy-detail-form/ui/field/student-type.tsx b/src/features/academy-detail-form/ui/field/student-type.tsx new file mode 100644 index 0000000..bf53b6b --- /dev/null +++ b/src/features/academy-detail-form/ui/field/student-type.tsx @@ -0,0 +1,68 @@ +import { isEqual } from 'lodash-es' +import { useFormContext, useWatch } from 'react-hook-form' + +import { fieldCss, Form } from 'shared/form' +import { Checkbox, Label } from 'shared/ui' + +import { FormValues } from '../../model/form-values' +import * as rules from '../../model/rules' + +export const StudentType = () => { + const { + control, + setValue, + formState: { errors }, + clearErrors, + } = useFormContext() + + const [studentType] = useWatch({ + control, + name: ['studentType'], + }) + + const studentTypeOptions = [ + 'Kindergarten', + 'Elementary', + 'MiddleSchool', + 'HighSchool', + 'Adult', + ] + + const isAllChecked = isEqual(studentType, studentTypeOptions) + + const handleAllCheckboxClick = () => { + if (isAllChecked) { + setValue('studentType', null) + } else { + setValue('studentType', studentTypeOptions) + } + + clearErrors('studentType') + } + + return ( +
+ +
+ + + + + + + + +
+
+ ) +} diff --git a/src/features/academy-detail-form/ui/image-uploader.tsx b/src/features/academy-detail-form/ui/image-uploader.tsx new file mode 100644 index 0000000..01d4a6e --- /dev/null +++ b/src/features/academy-detail-form/ui/image-uploader.tsx @@ -0,0 +1,113 @@ +'use client' + +import { useRef, useState } from 'react' + +import { ImageUploadInput } from 'features/upload-image' +import { colors } from 'shared/config' +import { cn, isNilOrEmptyString } from 'shared/lib' +import { Icon, Image } from 'shared/ui' + +type Props = { + src: string | null + onChange: (file: File, url: string) => void + onDelete?: () => void + className?: string +} + +export const ImageUploader = ({ + src, + onChange, + onDelete, + className, +}: Props) => { + const fileInputRef = useRef(null) + + const [isHovering, setIsHovering] = useState(false) + + const hasImage = !isNilOrEmptyString(src) + + const handleUploadButtonClick = () => { + fileInputRef.current?.click() + } + + const handleFileChange = async (file: File) => { + const reader = new FileReader() + reader.readAsDataURL(file) + + reader.onload = event => { + if (reader.readyState === 2) { + const url = event.target?.result + + if (url) { + onChange(file, url as string) + } + } + } + } + + const handleMouseEnter = () => { + setIsHovering(true) + } + + const handleMouseLeave = () => { + setIsHovering(false) + } + + const handleDeleteButtonClick = async () => { + onDelete?.() + } + + return ( +
+ + + {(() => { + if (hasImage) { + return ( +
+ academy image + {isHovering && ( +
+ +
+ )} +
+ ) + } + + return ( + + ) + })()} +
+ ) +} diff --git a/src/features/academy-detail-form/ui/side-panel.tsx b/src/features/academy-detail-form/ui/side-panel.tsx new file mode 100644 index 0000000..d7aa91d --- /dev/null +++ b/src/features/academy-detail-form/ui/side-panel.tsx @@ -0,0 +1,91 @@ +import { useFormContext, useWatch } from 'react-hook-form' +import { toast } from 'react-toastify' + +import { updateAcademyMe } from 'entities/academy' +import { isServerError, useServerErrorHandler } from 'shared/api' +import { Button } from 'shared/ui' + +import { + canRegisterForm, + convertToUpdateAcademyDetail, + FormValues, +} from '../model/form-values' + +export const SidePanel = () => { + const { handleSubmit, control } = useFormContext() + + const { handleServerError } = useServerErrorHandler() + + const [ + representativeName, + name, + nameEn, + address, + detailedAddress, + description, + studentType, + images, + ] = useWatch({ + control, + name: [ + 'representativeName', + 'name', + 'nameEn', + 'address', + 'detailedAddress', + 'description', + 'studentType', + 'images', + ], + }) + + const handleRegisterSuccess = () => { + toast.success('정보를 저장했어요') + } + + const submitForm = async (data: FormValues) => { + const response = await updateAcademyMe(convertToUpdateAcademyDetail(data)) + + if (isServerError(response)) { + handleServerError(response) + } else { + handleRegisterSuccess() + } + } + + return ( +
+

작성에 유의해 주세요

+
+

+ 입력한 정보는 검색에 반영돼요. +

+

+ 중요한 정보를 빠뜨리지 않았는지 확인해 주세요. +

+
+
+ +
+
+ ) +} diff --git a/src/features/job-posting-form/model/form-values.ts b/src/features/job-posting-form/model/form-values.ts index 667e36d..e01e7ce 100644 --- a/src/features/job-posting-form/model/form-values.ts +++ b/src/features/job-posting-form/model/form-values.ts @@ -1,5 +1,5 @@ import { isValid, parse } from 'date-fns' -import { isArray, isNil, isNull, isUndefined } from 'lodash-es' +import { isArray, isNil } from 'lodash-es' import { AcademyDetail } from 'entities/academy' import { diff --git a/src/pages/academy-detail/index.ts b/src/pages/academy-detail/index.ts new file mode 100644 index 0000000..d2f7cb8 --- /dev/null +++ b/src/pages/academy-detail/index.ts @@ -0,0 +1 @@ +export { AcademyDetailPage } from './ui/academy-detail-page' diff --git a/src/pages/academy-detail/ui/academy-detail-page.tsx b/src/pages/academy-detail/ui/academy-detail-page.tsx new file mode 100644 index 0000000..1488eae --- /dev/null +++ b/src/pages/academy-detail/ui/academy-detail-page.tsx @@ -0,0 +1,36 @@ +'use client' + +import { useForm } from 'react-hook-form' + +import { AcademyDetail } from 'entities/academy' +import { + AcademyDetailForm, + SidePanel, + convertToFormValues, +} from 'features/academy-detail-form' +import { Form } from 'shared/form' +import { Layout } from 'shared/ui' + +type Props = { + academyDetail: AcademyDetail +} + +export const AcademyDetailPage = ({ academyDetail }: Props) => { + const form = useForm({ + defaultValues: convertToFormValues(academyDetail), + }) + + return ( + +

+ 학원 상세 정보 +

+
+ +
+ +
+ +
+ ) +} diff --git a/src/shared/api/api-client.ts b/src/shared/api/api-client.ts index e912472..00d2d47 100644 --- a/src/shared/api/api-client.ts +++ b/src/shared/api/api-client.ts @@ -76,7 +76,13 @@ export class ApiClient { const formData = new FormData() Object.entries(body as Record).forEach(([key, value]) => { - formData.append(key, value) + if (isArray(value) && value.some(item => item instanceof File)) { + value.forEach((file: File) => { + formData.append(key, file) + }) + } else { + formData.append(key, value) + } }) requestBody = formData diff --git a/src/shared/ui/gnb/navigation.tsx b/src/shared/ui/gnb/navigation.tsx index 58ec100..5d3e111 100644 --- a/src/shared/ui/gnb/navigation.tsx +++ b/src/shared/ui/gnb/navigation.tsx @@ -15,7 +15,7 @@ type ItemProps = { export const Item = ({ value, children }: PropsWithChildren) => { const pathname = usePathname() - const isActive = (pathname ?? '/') === value + const isActive = pathname?.includes(value) return (
  • Date: Sat, 17 May 2025 02:10:15 +0900 Subject: [PATCH 11/14] =?UTF-8?q?Feat:=20setting=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(business)/business/setting/layout.tsx | 19 +++++++++++++++++++ app/(business)/business/setting/page.tsx | 5 +++++ app/(user)/setting/(with-layout)/layout.tsx | 4 ++-- src/shared/ui/gnb/business-button.tsx | 2 +- src/widgets/sidebar/index.ts | 1 + src/widgets/sidebar/model/constant.ts | 20 ++++++++++++++++++++ src/widgets/sidebar/ui/sidebar.tsx | 8 ++++++-- 7 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 app/(business)/business/setting/layout.tsx create mode 100644 app/(business)/business/setting/page.tsx diff --git a/app/(business)/business/setting/layout.tsx b/app/(business)/business/setting/layout.tsx new file mode 100644 index 0000000..60bf88f --- /dev/null +++ b/app/(business)/business/setting/layout.tsx @@ -0,0 +1,19 @@ +import { Layout } from 'shared/ui' +import { + SettingSidebar, + SettingSidebarProvider, + businessItems, +} from 'widgets/sidebar' + +const PageLayout = ({ children }: { children: React.ReactNode }) => { + return ( + + + + {children} + + + ) +} + +export default PageLayout diff --git a/app/(business)/business/setting/page.tsx b/app/(business)/business/setting/page.tsx new file mode 100644 index 0000000..0c5a5b1 --- /dev/null +++ b/app/(business)/business/setting/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from 'next/navigation' + +export default function SettingPage() { + redirect('/business/setting/my-academy') +} diff --git a/app/(user)/setting/(with-layout)/layout.tsx b/app/(user)/setting/(with-layout)/layout.tsx index 020129d..a16fbb6 100644 --- a/app/(user)/setting/(with-layout)/layout.tsx +++ b/app/(user)/setting/(with-layout)/layout.tsx @@ -1,11 +1,11 @@ import { Layout } from 'shared/ui' -import { SettingSidebar, SettingSidebarProvider } from 'widgets/sidebar' +import { SettingSidebar, SettingSidebarProvider, items } from 'widgets/sidebar' const PageLayout = ({ children }: { children: React.ReactNode }) => { return ( - + {children} diff --git a/src/shared/ui/gnb/business-button.tsx b/src/shared/ui/gnb/business-button.tsx index 1cd81c4..4564497 100644 --- a/src/shared/ui/gnb/business-button.tsx +++ b/src/shared/ui/gnb/business-button.tsx @@ -31,7 +31,7 @@ export const BusinessButton = () => { } const handleMyPageClick = () => { - router.push('/business/setting/my-page') + router.push('/business/setting/my-academy') close() } diff --git a/src/widgets/sidebar/index.ts b/src/widgets/sidebar/index.ts index 14a7302..700ca7e 100644 --- a/src/widgets/sidebar/index.ts +++ b/src/widgets/sidebar/index.ts @@ -1 +1,2 @@ export * from './ui/sidebar' +export * from './model/constant' diff --git a/src/widgets/sidebar/model/constant.ts b/src/widgets/sidebar/model/constant.ts index c9b0ce7..a822fdf 100644 --- a/src/widgets/sidebar/model/constant.ts +++ b/src/widgets/sidebar/model/constant.ts @@ -27,3 +27,23 @@ export const items: MenuItemData[] = [ ], }, ] + +export const businessItems: MenuItemData[] = [ + { + title: '학원 페이지', + url: '/business/setting/my-academy', + }, + { + title: '내 계정', + subItems: [ + { + title: '개인 정보', + url: '/business/setting/my-account/personal-information', + }, + { + title: '비밀번호 변경', + url: '/business/setting/my-account/change-password', + }, + ], + }, +] diff --git a/src/widgets/sidebar/ui/sidebar.tsx b/src/widgets/sidebar/ui/sidebar.tsx index aa77d93..87f7305 100644 --- a/src/widgets/sidebar/ui/sidebar.tsx +++ b/src/widgets/sidebar/ui/sidebar.tsx @@ -7,9 +7,13 @@ import { Sidebar } from 'shared/ui' import { CollapsibleMenuItem, SingleMenuItem } from './sidebar-item' import { hasSubItems } from '../lib/type-guard' -import { items } from '../model/constant' +import { MenuItemData } from '../model/type' -export const SettingSidebar = () => { +type Props = { + items: MenuItemData[] +} + +export const SettingSidebar = ({ items }: Props) => { const pathname = usePathname() const isActive = useCallback( From 9c121a8e2d15adc1d36bf12ae902c81708477b4a Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Sat, 17 May 2025 02:23:29 +0900 Subject: [PATCH 12/14] =?UTF-8?q?Feat:=20=ED=95=99=EC=9B=90=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/setting/my-academy/page.ts | 1 + src/entities/user/api/get-user-me.ts | 16 +++++++- src/entities/user/index.ts | 2 +- src/pages/my-academy/index.ts | 1 + src/pages/my-academy/ui/my-academy.tsx | 40 +++++++++++++++++++ 5 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 app/(business)/business/setting/my-academy/page.ts create mode 100644 src/pages/my-academy/index.ts create mode 100644 src/pages/my-academy/ui/my-academy.tsx diff --git a/app/(business)/business/setting/my-academy/page.ts b/app/(business)/business/setting/my-academy/page.ts new file mode 100644 index 0000000..9246e3c --- /dev/null +++ b/app/(business)/business/setting/my-academy/page.ts @@ -0,0 +1 @@ +export { MyAcademyPage as default } from 'pages/my-academy' diff --git a/src/entities/user/api/get-user-me.ts b/src/entities/user/api/get-user-me.ts index 1fc414c..95f4ca3 100644 --- a/src/entities/user/api/get-user-me.ts +++ b/src/entities/user/api/get-user-me.ts @@ -1,6 +1,6 @@ 'use server' -import { getTeacherSession } from 'entities/auth' +import { getBusinessSession, getTeacherSession } from 'entities/auth' import { apiClient } from 'shared/api' import { User } from '../model/user' @@ -20,3 +20,17 @@ export const getUserMe = async () => { return response } + +export const getBusinessUserMe = async () => { + const { accessToken } = await getBusinessSession() + + const response = await apiClient.get({ + endpoint: '/users/me', + option: { + authorization: `Bearer ${accessToken}`, + tags: ['user-me'], + }, + }) + + return response +} diff --git a/src/entities/user/index.ts b/src/entities/user/index.ts index 4dc27eb..d5b2709 100644 --- a/src/entities/user/index.ts +++ b/src/entities/user/index.ts @@ -1,7 +1,7 @@ export { changePassword } from './api/change-password' export { deleteProfileImage } from './api/delete-profile-image' export { deleteUserMe } from './api/delete-user-me' -export { getUserMe } from './api/get-user-me' +export { getUserMe, getBusinessUserMe } from './api/get-user-me' export { updateProfileImage } from './api/update-profile-image' export { updateUserMe } from './api/update-user-me' export type { UpdateUserMeRequest } from './api/update-user-me' diff --git a/src/pages/my-academy/index.ts b/src/pages/my-academy/index.ts new file mode 100644 index 0000000..0646796 --- /dev/null +++ b/src/pages/my-academy/index.ts @@ -0,0 +1 @@ +export { MyAcademyPage } from './ui/my-academy' diff --git a/src/pages/my-academy/ui/my-academy.tsx b/src/pages/my-academy/ui/my-academy.tsx new file mode 100644 index 0000000..03d9c41 --- /dev/null +++ b/src/pages/my-academy/ui/my-academy.tsx @@ -0,0 +1,40 @@ +import { getAcademyMe } from 'entities/academy' +import { getBusinessUserMe } from 'entities/user' +import { Button } from 'shared/ui' + +export const MyAcademyPage = async () => { + const academy = await getAcademyMe() + const user = await getBusinessUserMe() + + return ( +
    +
    +

    {academy.name}

    +
    +

    담당자

    +

    {user.firstName}

    +
    +
    +
    + + +
    +
    + ) +} From 41c9df1c57c8ff8b096d07ad7e91afe00f802e2e Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Sat, 17 May 2025 02:50:45 +0900 Subject: [PATCH 13/14] =?UTF-8?q?Feat:=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B3=80=EA=B2=BD,=20=EA=B0=9C=EC=9D=B8=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../my-account/change-password/page.ts | 1 + .../my-account/personal-information/page.tsx | 10 ++ src/entities/user/api/change-password.ts | 20 +++- src/entities/user/index.ts | 5 +- src/features/sign-up/ui/field/birth-date.tsx | 5 +- src/pages/my-academy/index.ts | 2 + src/pages/my-academy/model/form-values.ts | 40 +++++++ .../my-academy/ui/change-password-page.tsx | 103 ++++++++++++++++++ .../ui/personal-information-page.tsx | 69 ++++++++++++ 9 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 app/(business)/business/setting/my-account/change-password/page.ts create mode 100644 app/(business)/business/setting/my-account/personal-information/page.tsx create mode 100644 src/pages/my-academy/model/form-values.ts create mode 100644 src/pages/my-academy/ui/change-password-page.tsx create mode 100644 src/pages/my-academy/ui/personal-information-page.tsx diff --git a/app/(business)/business/setting/my-account/change-password/page.ts b/app/(business)/business/setting/my-account/change-password/page.ts new file mode 100644 index 0000000..fb81fce --- /dev/null +++ b/app/(business)/business/setting/my-account/change-password/page.ts @@ -0,0 +1 @@ +export { ChangePasswordPage as default } from 'pages/my-academy' diff --git a/app/(business)/business/setting/my-account/personal-information/page.tsx b/app/(business)/business/setting/my-account/personal-information/page.tsx new file mode 100644 index 0000000..a32aa85 --- /dev/null +++ b/app/(business)/business/setting/my-account/personal-information/page.tsx @@ -0,0 +1,10 @@ +import { getBusinessUserMe } from 'entities/user' +import { PersonalInformationPage } from 'pages/my-academy' + +const Page = async () => { + const user = await getBusinessUserMe() + + return +} + +export default Page diff --git a/src/entities/user/api/change-password.ts b/src/entities/user/api/change-password.ts index c4707c0..f36067b 100644 --- a/src/entities/user/api/change-password.ts +++ b/src/entities/user/api/change-password.ts @@ -1,6 +1,6 @@ 'use server' -import { getTeacherSession } from 'entities/auth' +import { getBusinessSession, getTeacherSession } from 'entities/auth' import { apiClient, AuthExceptionCode, @@ -50,3 +50,21 @@ export const changePassword = async (data: ChangePasswordRequest) => { return handleError(error as HttpError) } } + +export const changeBusinessUserPassword = async ( + data: ChangePasswordRequest, +) => { + const { accessToken } = await getBusinessSession() + + try { + await apiClient.put({ + endpoint: '/users/me/password', + option: { + authorization: `Bearer ${accessToken}`, + }, + body: data, + }) + } catch (error) { + return handleError(error as HttpError) + } +} diff --git a/src/entities/user/index.ts b/src/entities/user/index.ts index d5b2709..9535df4 100644 --- a/src/entities/user/index.ts +++ b/src/entities/user/index.ts @@ -1,4 +1,7 @@ -export { changePassword } from './api/change-password' +export { + changePassword, + changeBusinessUserPassword, +} from './api/change-password' export { deleteProfileImage } from './api/delete-profile-image' export { deleteUserMe } from './api/delete-user-me' export { getUserMe, getBusinessUserMe } from './api/get-user-me' diff --git a/src/features/sign-up/ui/field/birth-date.tsx b/src/features/sign-up/ui/field/birth-date.tsx index 5dc1d65..26944a5 100644 --- a/src/features/sign-up/ui/field/birth-date.tsx +++ b/src/features/sign-up/ui/field/birth-date.tsx @@ -12,7 +12,10 @@ export const BirthDate = () => {
    - +
    diff --git a/src/pages/my-academy/index.ts b/src/pages/my-academy/index.ts index 0646796..833e50a 100644 --- a/src/pages/my-academy/index.ts +++ b/src/pages/my-academy/index.ts @@ -1 +1,3 @@ export { MyAcademyPage } from './ui/my-academy' +export { PersonalInformationPage } from './ui/personal-information-page' +export { ChangePasswordPage } from './ui/change-password-page' diff --git a/src/pages/my-academy/model/form-values.ts b/src/pages/my-academy/model/form-values.ts new file mode 100644 index 0000000..ccb8963 --- /dev/null +++ b/src/pages/my-academy/model/form-values.ts @@ -0,0 +1,40 @@ +import { UpdateUserMeRequest, User } from 'entities/user' + +export type UpdateUserMeFormValues = { + fullName: string + genderType: 'MALE' | 'FEMALE' + birthDate: string | null +} + +export const convertToUpdateUserMeFormValues = ( + user: User, +): UpdateUserMeFormValues => { + return { + fullName: user.firstName + ' ' + user.lastName, + genderType: user.genderType, + birthDate: user.birthDate, + } +} + +// FIXME: 타입 수정 후 변경 필요 +export const convertToUpdateUserMeDTO = ( + data: UpdateUserMeFormValues, +): UpdateUserMeRequest => { + return { + ...data, + birthDate: data.birthDate!, + countryId: null, + firstName: '', + lastName: '', + } +} + +export type ChangePasswordFormValues = { + currentPassword: string + newPassword: string +} + +export const changePasswordFormDefaultValues: ChangePasswordFormValues = { + currentPassword: '', + newPassword: '', +} diff --git a/src/pages/my-academy/ui/change-password-page.tsx b/src/pages/my-academy/ui/change-password-page.tsx new file mode 100644 index 0000000..2d30331 --- /dev/null +++ b/src/pages/my-academy/ui/change-password-page.tsx @@ -0,0 +1,103 @@ +'use client' + +import { useQueryClient } from '@tanstack/react-query' +import { useRouter } from 'next/navigation' +import { signOut } from 'next-auth/react' +import { useForm, useWatch } from 'react-hook-form' +import { toast } from 'react-toastify' + +import { + currentPasswordRules, + passwordRules, + PasswordValidation, + businessSignOut, +} from 'entities/auth' +import { changeBusinessUserPassword } from 'entities/user' +import { isServerError, useServerErrorHandler } from 'shared/api' +import { fieldCss, Form } from 'shared/form' +import { isEmptyString } from 'shared/lib' +import { Button, Label } from 'shared/ui' + +import { + changePasswordFormDefaultValues, + type ChangePasswordFormValues, +} from '../model/form-values' + +export const ChangePasswordPage = () => { + const queryClient = useQueryClient() + const router = useRouter() + + const form = useForm({ + defaultValues: changePasswordFormDefaultValues, + }) + + const { handleServerError } = useServerErrorHandler(form) + + const [currentPassword, newPassword] = useWatch({ + name: ['currentPassword', 'newPassword'], + control: form.control, + }) + + const canSubmit = + !isEmptyString(currentPassword) && !isEmptyString(newPassword) + + const handleChangePasswordSuccess = async () => { + toast.success('비밀번호가 변경되었어요. 다시 로그인 해주세요.') + + queryClient.removeQueries() + await businessSignOut() + await signOut({ redirect: false }) + + router.push('/business/sign-in') + } + + const submitForm = async (data: ChangePasswordFormValues) => { + const response = await changeBusinessUserPassword(data) + + if (isServerError(response)) { + handleServerError(response) + } else { + handleChangePasswordSuccess() + } + } + + return ( +
    +
    +

    비밀번호 변경

    +
    +
    +
    + + + + + +
    + +
    + +
    + + +
    +
    +
    + +
    +
    +
    + ) +} diff --git a/src/pages/my-academy/ui/personal-information-page.tsx b/src/pages/my-academy/ui/personal-information-page.tsx new file mode 100644 index 0000000..629388c --- /dev/null +++ b/src/pages/my-academy/ui/personal-information-page.tsx @@ -0,0 +1,69 @@ +'use client' + +import { useForm } from 'react-hook-form' +import { toast } from 'react-toastify' + +import { updateUserMe, User } from 'entities/user' +import { DeleteUserButton } from 'features/delete-account' +import { BirthDate, FullName, Gender } from 'features/sign-up' +import { isServerError, useServerErrorHandler } from 'shared/api' +import { Form } from 'shared/form' +import { Button } from 'shared/ui' + +import { + convertToUpdateUserMeDTO, + convertToUpdateUserMeFormValues, + UpdateUserMeFormValues, +} from '../model/form-values' + +type Props = { + user: User +} + +export const PersonalInformationPage = ({ user }: Props) => { + const form = useForm({ + defaultValues: convertToUpdateUserMeFormValues(user), + reValidateMode: 'onSubmit', + }) + + const { handleServerError } = useServerErrorHandler() + + const handleSuccess = () => { + toast.success('Your personal information has been updated') + } + + const submitForm = (data: UpdateUserMeFormValues) => { + const response = updateUserMe(convertToUpdateUserMeDTO(data)) + + if (isServerError(response)) { + handleServerError(response) + } else { + handleSuccess() + } + } + + return ( +
    +
    +

    + 개인 정보 +

    +
    +
    + + + +
    + +
    + +
    +
    + ) +} From b52aa1c37e9b513ef58a6a405df1d83e253a284a Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Sat, 17 May 2025 03:55:25 +0900 Subject: [PATCH 14/14] =?UTF-8?q?Feat:=20=EB=A9=94=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(business)/business/page.tsx | 69 +++++++++++------- public/images/business-banner.png | Bin 0 -> 112588 bytes src/entities/academy/api/get-academy-me.ts | 2 +- src/entities/academy/api/update-academy-me.ts | 2 +- .../config/middleware/with-business-auth.ts | 4 + src/shared/ui/gnb/business-button.tsx | 4 +- src/shared/ui/gnb/user-button.tsx | 4 +- 7 files changed, 52 insertions(+), 33 deletions(-) create mode 100644 public/images/business-banner.png diff --git a/app/(business)/business/page.tsx b/app/(business)/business/page.tsx index 31ecb8b..7ad8008 100644 --- a/app/(business)/business/page.tsx +++ b/app/(business)/business/page.tsx @@ -1,36 +1,51 @@ -import { colors } from 'shared/config' -import { Icon } from 'shared/ui' +import { getNullableBusinessSession } from 'entities/auth' +import { Button, Image } from 'shared/ui' import { Layout } from 'shared/ui' -export default function BusinessPage() { +const BusinessPage = async () => { + const session = await getNullableBusinessSession() + + const link = session ? '/business/job-posting/create' : '/business/sign-up' + return ( -
    - -

    - 현재{' '} - - 페이지 준비중 - - 입니다. -

    -
    -

    - 이용에 불편을 드려 죄송합니다. -

    -

    - 보다 나은 서비스 제공을 위하여 페이지 준비중에 있습니다. -

    -

    - 빠른 시일 내에 준비하여 찾아뵙겠습니다. -

    +
    +
    +

    + 강사를 손쉽게 관리하고, +
    + 빠르게 채용하세요 +

    +
    +

    + 학원에 맞는 원어민 강사를 찾고 계신가요? +

    +

    + 지금, Plus82와 시작하세요. +

    +
    +
    + + business-page-image
    ) } + +export default BusinessPage diff --git a/public/images/business-banner.png b/public/images/business-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..c233c2e86616f316ec2528dcd25882b060346afd GIT binary patch literal 112588 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

    i7_sWOy&Rm<9m||3Eri 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

    r_AMf!bA{qZl z%sQ%&fa`E=gJ~D3&mm`b+q;T%z-p)D^-yH|w>Hu|-et;)=V{&jRlwSO^{lAd%bunq z;o!M}J*zv_QAOZ%RU5Z%*St;SuwHDb`UTZ(kEY^v_aR4?#*ix$;=8Re@JsHBrOkK& zKzW*rK0zCpR&^fMp^%yGZ}oDhtzW;di+Ig38X}q>GIpw~TTb&J_lx5<&-He$F*Q=O z{8;pS_I2LJkL*SzNd)n^I|v{L9E2nHO+I<1iiJwCp6A-ki_}&^95H_xx%hi z-AJI_lgNevkC$hAnb?d9i!b@^Hq*UtXTW{@lGCqMN{J_O#%nR)Jp8LHcm1yfHFbWV z^xe6v{#oXMfA6-`?sRiL@hQV=gwvOK8`TKWX|s?< z!O&iG>u}Bh^VleD{Lny#VHf`lhjP%j;&J!XJZzKonI@O9+uNsl$shDLF$|yaMC8)E z$s46;ro$}E&nNy?P&4r4v-Tq)Di)lu4g5~pG2!8penHiczH_)V#Ra^kGNrV45NSW< z(S{xzk8mw~?OIcuD_~?FE)tDy#g`I1!og~NRKnIZIL>X!x1g_Xe(c!kO8Lt@f6-?J zH(KwV8glj*`qWu`ZW)}?I7ea=2-3{I%sj6|EDK8LN!M*iQl?uR;xJy~?rLqnw+YZD zWbPD)9j%)`)Wr2q`Jw~en#qlzdx0I2j<4R}&3kHSJ zChVy9&HykjNz1Qv*;Ekh5w8)K-vu~TDOz5aO}Z1A$lObL>d@ZUPC){=apbw7%kue~ zb}q2!e19t2asaP*qq0*ya;;dFnsu2o_`vCjiw}({nBA|zTaHxV6V5LQ_%=ysI<5g1 zYNupi7zCOqq!&M#P@>OU~y!;ZZV$jEYNA;HP4cOUM*T1;IkD-dmiTfx{*VoEECs84a{hp%u zRObn+2XWq?93!1rXqj_$mqd(q1F0N*GE{tVCqUA-a?95NH2QT#s8&mHh}dT^R8gKh zJ?wINviO_(M;2)Co^Le%rJtT-hTDW%0AvH|{pvLe+Sf*&p6r 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 literal 0 HcmV?d00001 diff --git a/src/entities/academy/api/get-academy-me.ts b/src/entities/academy/api/get-academy-me.ts index ac60e30..b673874 100644 --- a/src/entities/academy/api/get-academy-me.ts +++ b/src/entities/academy/api/get-academy-me.ts @@ -14,7 +14,7 @@ export const getAcademyMe = async () => { endpoint: `/academies/me`, option: { authorization: `Bearer ${accessToken}`, - tags: ['academy', 'me'], + tags: ['academy-me'], }, }) diff --git a/src/entities/academy/api/update-academy-me.ts b/src/entities/academy/api/update-academy-me.ts index a3aa64f..69904e1 100644 --- a/src/entities/academy/api/update-academy-me.ts +++ b/src/entities/academy/api/update-academy-me.ts @@ -14,7 +14,7 @@ import { import { UpdateAcademyDetail } from '../model/academy-detail' const handleSuccess = () => { - revalidateTag('academy-detail') + revalidateTag('academy-me') } const handleError = (error: Error): ServerError => { diff --git a/src/shared/config/middleware/with-business-auth.ts b/src/shared/config/middleware/with-business-auth.ts index cd0de03..983b46e 100644 --- a/src/shared/config/middleware/with-business-auth.ts +++ b/src/shared/config/middleware/with-business-auth.ts @@ -7,8 +7,12 @@ import { MiddlewareFactory } from './type' const matchersForAuth = [ '/business/setting/*path', + '/business/applicant-management', '/business/applicant-management/*path', + '/business/job-posting', '/business/job-posting/*path', + '/business/academy-detail', + '/business/preview/*path', ] const matchersForSignIn = ['/business/sign-up', '/business/sign-in'] diff --git a/src/shared/ui/gnb/business-button.tsx b/src/shared/ui/gnb/business-button.tsx index 4564497..f7ba62b 100644 --- a/src/shared/ui/gnb/business-button.tsx +++ b/src/shared/ui/gnb/business-button.tsx @@ -36,12 +36,12 @@ export const BusinessButton = () => { } const handleSignOutClick = async () => { - queryClient.removeQueries() - await businessSignOut() await signOut({ redirect: false }) router.push('/business') + + queryClient.removeQueries() close() } diff --git a/src/shared/ui/gnb/user-button.tsx b/src/shared/ui/gnb/user-button.tsx index de36475..3a6ad6b 100644 --- a/src/shared/ui/gnb/user-button.tsx +++ b/src/shared/ui/gnb/user-button.tsx @@ -38,12 +38,12 @@ export const UserButton = () => { } const handleSignOutClick = async () => { - queryClient.removeQueries() - await teacherSignOut() await signOut({ redirect: false }) router.push('/') + + queryClient.removeQueries() close() }