Skip to content

Commit

Permalink
Merge pull request #156 from YIMSEBIN/Weekly
Browse files Browse the repository at this point in the history
Feat: ํ…Œ์ŠคํŠธ์ฝ”๋“œ ๊ตฌํ˜„ ๋ฐ POST ํ™•์ธ ๋ชจ๋‹ฌ์ฐฝ ๊ตฌํ˜„
  • Loading branch information
YIMSEBIN authored Nov 14, 2024
2 parents 98e7829 + 7b947d0 commit 6e19f8b
Show file tree
Hide file tree
Showing 18 changed files with 1,526 additions and 795 deletions.
25 changes: 23 additions & 2 deletions src/assets/translator/Contract/contractData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,19 @@ export const contractData = {
SENTENCE1: '์‚ฌ์šฉ์ž์™€ ๊ทผ๋กœ์ž๋Š” ๊ฐ์ž๊ฐ€ ๊ทผ๋กœ๊ณ„์•ฝ, ์ทจ์—…๊ทœ์น™, ๋‹จ์ฒดํ˜‘์•ฝ์„ ์ง€ํ‚ค๊ณ  ์„ฑ์‹คํ•˜๊ฒŒ ์ดํ–‰ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.',
SENTENCE2: "์ด ๊ณ„์•ฝ์—์„œ ์ •ํ•˜์ง€ ์•Š์€ ์‚ฌํ•ญ์€ '๊ทผ๋กœ๊ธฐ์ค€๋ฒ•'์—์„œ ์ •ํ•˜๋Š” ๋ฐ”์— ๋”ฐ๋ฅธ๋‹ค.",
SIGN: '์„œ๋ช…ํ•˜๊ธฐ',
SUBMIT_CHECK: '์ •๋ง ์ œ์ถœํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?',
SUBMIT: '์ œ์ถœํ•˜๊ธฐ',
ERROR: '* ๊ทผ๋กœ๊ณ„์•ฝ์„œ์— ์„œ๋ช…ํ•ด์ฃผ์„ธ์š”!',
ERROR: {
WORKING_PLACE: '๊ทผ๋ฌด์žฅ์†Œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.',
RESPONSIBILITIES: '์ƒ์„ธ ์—…๋ฌด ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.',
WORKING_HOURS: '๊ทผ๋กœ์ผ ๋ฐ ๊ทผ๋กœ์ผ๋ณ„ ๊ทผ๋กœ์‹œ๊ฐ„์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.',
DAY_OFF: '์ฃผํœด์ผ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.',
SALARY: '์ž„๊ธˆ์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.',
ANNUAL_PAID_LEAVE: '์—ฐ์ฐจ์œ ๊ธ‰ํœด๊ฐ€์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.',
RULE: '์ทจ์—…๊ทœ์น™์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.',
NUMBER: '์ˆซ์ž๋กœ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.',
SIGN: '* ๊ทผ๋กœ๊ณ„์•ฝ์„œ์— ์„œ๋ช…ํ•ด์ฃผ์„ธ์š”!',
},
},
[Languages.VE]: {
CONTRACT: 'Hแปฃp ฤ‘แป“ng lao ฤ‘แป™ng',
Expand All @@ -29,7 +40,17 @@ export const contractData = {
'Ngฦฐแปi sแปญ dแปฅng lao ฤ‘แป™ng vร  ngฦฐแปi lao ฤ‘แป™ng cแบงn tuรขn thแปง hแปฃp ฤ‘แป“ng lao ฤ‘แป™ng, quy tแบฏc lao ฤ‘แป™ng vร  thแปa thuแบญn tแบญp thแปƒ mแป™t cรกch nghiรชm tรบc.',
SENTENCE2: 'Cรกc ฤ‘iแปu khoแบฃn khรดng ฤ‘ฦฐแปฃc quy ฤ‘แป‹nh trong hแปฃp ฤ‘แป“ng nร y sแบฝ ฤ‘ฦฐแปฃc ฤ‘iแปu chแป‰nh theo "Luแบญt lao ฤ‘แป™ng".',
SIGN: 'Kรฝ tรชn',
SUBMIT_CHECK: 'Bแบกn cรณ chแบฏc chแบฏn muแป‘n nแป™p khรดng?',
SUBMIT: 'Gแปญi ฤ‘i',
ERROR: '* Vui lรฒng kรฝ vร o hแปฃp ฤ‘แป“ng lao ฤ‘แป™ng!',
ERROR: {
WORKING_PLACE: 'Vui lรฒng ฤ‘iแปn nฦกi lร m viแป‡c.',
RESPONSIBILITIES: 'Vui lรฒng mรด tแบฃ chi tiแบฟt cรดng viแป‡c.',
WORKING_HOURS: 'Vui lรฒng ghi rรต ngร y lร m viแป‡c vร  giแป lร m viแป‡c hร ng ngร y.',
DAY_OFF: 'Vui lรฒng ghi thรดng tin vแป ngร y nghแป‰ hร ng tuแบงn.',
SALARY: 'Vui lรฒng ฤ‘iแปn thรดng tin lฦฐฦกng.',
ANNUAL_PAID_LEAVE: 'Vui lรฒng ghi thรดng tin vแป nghแป‰ phรฉp cรณ lฦฐฦกng hร ng nฤƒm.',
RULE: 'Vui lรฒng ฤ‘iแปn quy tแบฏc lร m viแป‡c.',
SIGN: '* Vui lรฒng kรฝ vร o hแปฃp ฤ‘แป“ng lao ฤ‘แป™ng!',
},
},
};
34 changes: 34 additions & 0 deletions src/assets/translator/PostNotice/postNoticeData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ export const postNoticeData = {
REQUESTED_CAREER: '์ง€์›์กฐ๊ฑด',
ELIGIBILITY_CRITERIA: '๋น„์ž์กฐ๊ฑด',
PREFERRED_CONDITIONS: '์šฐ๋Œ€์‚ฌํ•ญ',
ERROR: {
NOTICE_TITLE: '๊ตฌ์ธ๊ธ€ ์ œ๋ชฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
COMPANY_NAME: 'ํšŒ์‚ฌ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
EMPLOYER_NAME: '๊ณ ์šฉ์ฃผ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
COMPANY_SCALE: 'ํšŒ์‚ฌ ๊ทœ๋ชจ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
AREA: '์ง€์—ญ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
SALARY: '๊ธ‰์—ฌ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
MAJOR_BUSINESS: '์ฃผ์š” ์—…๋ฌด ๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
WORKDURATION: '๊ทผ๋ฌด ๊ธฐ๊ฐ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
WORKDAYS: '๊ทผ๋ฌด ์š”์ผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
WORKHOURS: '๊ทผ๋ฌด ์‹œ๊ฐ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
WORKTYPE: '๊ณ ์šฉ ํ˜•ํƒœ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
REQUESTED_CAREER: '์ง€์›์กฐ๊ฑด์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
ELIGIBILITY_CRITERIA: '๋น„์ž ์ž๊ฒฉ ์š”๊ฑด์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
PREFERRED_CONDITIONS: '์šฐ๋Œ€์‚ฌํ•ญ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
},
SUBMIT_CHECK: '๊ตฌ์ธ๊ธ€์„ ๋“ฑ๋กํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?',
SUBMIT: '๋“ฑ๋กํ•˜๊ธฐ',
},
[Languages.VE]: {
Expand All @@ -35,6 +52,23 @@ export const postNoticeData = {
REQUESTED_CAREER: 'Yรชu cแบงu kinh nghiแป‡m',
ELIGIBILITY_CRITERIA: 'ฤiแปu kiแป‡n vแป visa',
PREFERRED_CONDITIONS: 'ฦฏu tiรชn',
ERROR: {
NOTICE_TITLE: 'Vui lรฒng nhแบญp tiรชu ฤ‘แป bร i ฤ‘ฤƒng tuyแปƒn dแปฅng.',
COMPANY_NAME: 'Vui lรฒng nhแบญp tรชn cรดng ty.',
EMPLOYER_NAME: 'Vui lรฒng nhแบญp tรชn nhร  tuyแปƒn dแปฅng.',
COMPANY_SCALE: 'Vui lรฒng nhแบญp quy mรด cรดng ty.',
AREA: 'Vui lรฒng nhแบญp khu vแปฑc.',
SALARY: 'Vui lรฒng nhแบญp mแปฉc lฦฐฦกng.',
MAJOR_BUSINESS: 'Vui lรฒng nhแบญp nแป™i dung cรดng viแป‡c chรญnh.',
WORKDURATION: 'Vui lรฒng nhแบญp thแปi gian lร m viแป‡c.',
WORKDAYS: 'Vui lรฒng nhแบญp ngร y lร m viแป‡c.',
WORKHOURS: 'Vui lรฒng nhแบญp giแป lร m viแป‡c.',
WORKTYPE: 'Vui lรฒng nhแบญp hรฌnh thแปฉc lร m viแป‡c.',
REQUESTED_CAREER: 'Vui lรฒng nhแบญp ฤ‘iแปu kiแป‡n แปฉng tuyแปƒn.',
ELIGIBILITY_CRITERIA: 'Vui lรฒng nhแบญp yรชu cแบงu vแป ฤ‘iแปu kiแป‡n visa.',
PREFERRED_CONDITIONS: 'Vui lรฒng nhแบญp ฤ‘iแปu kiแป‡n ฦฐu tiรชn.',
},
SUBMIT_CHECK: 'Bแบกn cรณ muแป‘n ฤ‘ฤƒng bร i tuyแปƒn dแปฅng khรดng?',
SUBMIT: 'ฤฤƒng kรฝ',
},
};
16 changes: 16 additions & 0 deletions src/assets/translator/RegisterCompany/registerCompanyData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ export const registerCompanyData = {
BRAND: '๋ธŒ๋žœ๋“œ',
REVENUE_PERYEAR: '์—ฐ ํ‰๊ท  ๋งค์ถœ์•ก',
SUBMIT: '๋“ฑ๋กํ•˜๊ธฐ',
SUBMIT_CHECK: 'ํšŒ์‚ฌ๋ฅผ ๋“ฑ๋กํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?',
ERROR: {
COMPANYNAME: 'ํšŒ์‚ฌ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
INDUSTRY_OCCUPATION: '์‚ฐ์—…/์ง์ข…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
BRAND: '๋ธŒ๋žœ๋“œ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
REVENUE_PERYEAR: '์—ฐ ๋งค์ถœ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
NUMBER: '์ˆซ์ž๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
},
},
[Languages.VE]: {
TITLE: 'ฤฤƒng kรฝ cรดng ty',
Expand All @@ -18,5 +26,13 @@ export const registerCompanyData = {
BRAND: 'Thฦฐฦกng hiแป‡u',
REVENUE_PERYEAR: 'Doanh thu hร ng nฤƒm',
SUBMIT: 'ฤฤƒng kรฝ',
SUBMIT_CHECK: 'Bแบกn cรณ muแป‘n ฤ‘ฤƒng kรฝ cรดng ty khรดng?',
ERROR: {
COMPANYNAME: 'Vui lรฒng nhแบญp tรชn cรดng ty.',
INDUSTRY_OCCUPATION: 'Vui lรฒng nhแบญp ngร nh nghแป.',
BRAND: 'Vui lรฒng nhแบญp tรชn thฦฐฦกng hiแป‡u.',
REVENUE_PERYEAR: 'Vui lรฒng nhแบญp doanh thu hร ng nฤƒm.',
NUMBER: 'Vui lรฒng nhแบญp bแบฑng sแป‘.',
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { fireEvent, screen } from '@testing-library/react';
import { server } from '@/mocks/server';
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
import { renderWithProviders } from '@/__test__/test-utils';
import ContractSection from '../components/ContractSection';
import { useNavigate } from 'react-router-dom';
import ROUTE_PATH from '@/routes/path';

const mockNavigate = vi.fn();
vi.mock('react-router-dom', async () => {
return {
...(await vi.importActual('react-router-dom')),
useNavigate: vi.fn(),
};
});

describe('employeeContract', () => {
beforeAll(() => {
server.listen();
vi.mocked(useNavigate).mockImplementation(() => mockNavigate);
});
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

beforeEach(() => {
vi.clearAllMocks();
});

const renderContract = () => {
return renderWithProviders(<ContractSection />);
};

it('๊ทผ๋กœ๊ณ„์•ฝ์„œ ๋ฐ์ดํ„ฐ ์ž˜ ๋ถˆ๋ ค์™€์ง', async () => {
renderContract();

expect(screen.getByText('contract.WORKING_PLACE')).toBeInTheDocument();
expect(screen.getByText('contract.RESPONSIBILITIES')).toBeInTheDocument();
expect(screen.getByText('contract.WORKING_HOURS')).toBeInTheDocument();
expect(screen.getByText('contract.DAY_OFF')).toBeInTheDocument();
expect(screen.getByText('contract.SALARY')).toBeInTheDocument();
expect(screen.getByText('contract.ANNUAL_PAID_LEAVE')).toBeInTheDocument();
expect(screen.getByText('contract.RULE')).toBeInTheDocument();
});

it('์„œ๋ช…ํ•˜์ง€ ์•Š๊ณ  ์ œ์ถœํ•˜๋ฉด ๋ฉ”์„ธ์ง€๋ฅผ ๋„์šด๋‹ค.', async () => {
const { getByRole } = renderContract();

fireEvent.click(getByRole('button', { name: 'contract.SUBMIT' }));

await vi.waitFor(() => {
const errorMessage = screen.getByText('contract.ERROR.SIGN');
expect(errorMessage).toBeInTheDocument();
});
});

it('์„œ๋ช… ํ›„ ์ œ์ถœํ•œ๋‹ค.', async () => {
const { getByRole } = renderContract();

fireEvent.click(getByRole('button', { name: 'contract.SIGN' }));
fireEvent.click(getByRole('button', { name: 'contract.SUBMIT' }));

await vi.waitFor(() => {
expect(mockNavigate).toHaveBeenCalledWith(ROUTE_PATH.HOME);
});
});
});
153 changes: 153 additions & 0 deletions src/features/contract/EmployeeContract/components/ContractSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { useState } from 'react';
import { useGetMyContract } from '@/apis/contract/hooks/useGetMyContract';
import { Button, Typo } from '@/components/common';
import ROUTE_PATH from '@/routes/path';
import styled from '@emotion/styled';
import { useTranslation } from 'react-i18next';
import { useNavigate, useParams } from 'react-router-dom';
import { usePostSignEmployeeContract } from '@/apis/contract/hooks/usePostEmployeeSign';

export type ContractResponseData = {
salary: string;
workingHours: string;
dayOff: string;
annualPaidLeave: string;
workingPlace: string;
responsibilities: string;
rule: string;
};

export default function ContractSection() {
const { t } = useTranslation();
const { applyId } = useParams();
const applicationId = Number(applyId);
const { data: contract } = useGetMyContract(applicationId);
const mutation = usePostSignEmployeeContract();
const navigate = useNavigate();
const contractData: ContractResponseData = contract || {};

const [isSigned, setIsSigned] = useState(false);
const [showSignError, setShowSignError] = useState(false);

const handlePostSignEmployeeContract = () => {
if (!isSigned) {
setShowSignError(true);
return;
}
mutation.mutate(
{ applyId: applicationId },
{
onSuccess: () => {
navigate(ROUTE_PATH.HOME);
},
onError: () => {
alert('๊ฐ’์ด ์ •์ƒ์ ์œผ๋กœ ์ €์žฅ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.');
},
},
);
};

const handleSign = () => {
setIsSigned(!isSigned);
setShowSignError(false);
};

return (
<>
<InputWrapper>
<InputContainer>
<Typo>{t('contract.WORKING_PLACE')}</Typo>
<Typo>{contractData.workingPlace}</Typo>
</InputContainer>
<InputContainer>
<Typo>{t('contract.RESPONSIBILITIES')}</Typo>
<Typo>{contractData.responsibilities}</Typo>
</InputContainer>
<InputContainer>
<Typo>{t('contract.WORKING_HOURS')}</Typo>
<Typo>{contractData.workingHours}</Typo>
</InputContainer>
<InputContainer>
<Typo>{t('contract.DAY_OFF')}</Typo>
<Typo>{contractData.dayOff}</Typo>
</InputContainer>
<InputContainer>
<Typo>{t('contract.SALARY')}</Typo>
<Typo>{contractData.salary}</Typo>
</InputContainer>
<InputContainer>
<Typo>{t('contract.ANNUAL_PAID_LEAVE')}</Typo>
<Typo>{contractData.annualPaidLeave}</Typo>
</InputContainer>
<InputContainer>
<Typo>{t('contract.RULE')}</Typo>
<Typo>{contractData.rule}</Typo>
</InputContainer>
</InputWrapper>
<Typo element="p" size="16px" style={{ fontWeight: 'bold', marginTop: '24px' }}>
{t('contract.SENTENCE1')}
</Typo>
<Typo element="p" size="16px" style={{ fontWeight: 'bold', marginTop: '24px' }}>
{t('contract.SENTENCE2')}
</Typo>
<ButtonWrapper>
<SignButton design="outlined" isSigned={isSigned} onClick={handleSign}>
<TypoWrapper isSigned={isSigned}>{t('contract.SIGN')}</TypoWrapper>
{isSigned && <CheckIcon>โœ…</CheckIcon>}
</SignButton>
<Button design="default" onClick={handlePostSignEmployeeContract}>
{t('contract.SUBMIT')}
</Button>
</ButtonWrapper>
{showSignError && !isSigned && <ErrorText>{t('contract.ERROR.SIGN')}</ErrorText>}
</>
);
}

const InputWrapper = styled.div`
margin-top: 28px;
`;

const InputContainer = styled.div`
width: 700px;
display: flex;
align-items: center;
justify-content: space-between;
margin: 24px 0;
`;

const ButtonWrapper = styled.div`
width: 700px;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 52px;
`;

const SignButton = styled(Button)<{ isSigned: boolean }>`
width: 150px;
background-color: ${({ isSigned }) => (isSigned ? '#3960d7' : 'white')};
color: ${({ isSigned }) => (isSigned ? 'white' : 'black')};
padding: 10px 0;
display: flex;
align-items: center;
transition:
background-color 0.3s,
color 0.3s;
`;

const TypoWrapper = styled.span<{ isSigned: boolean }>`
margin-right: ${({ isSigned }) => (isSigned ? '8px' : '0')};
transition: margin-right 0.3s;
`;

const CheckIcon = styled.span`
transition: opacity 0.3s;
opacity: 1;
`;

const ErrorText = styled.span`
color: red;
font-size: 12px;
margin-top: 8px;
`;
Loading

0 comments on commit 6e19f8b

Please sign in to comment.