Skip to content

Commit

Permalink
[公司職稱頁面] 面試經驗分頁 (#1412)
Browse files Browse the repository at this point in the history
  • Loading branch information
peteranny authored and mark86092 committed Aug 27, 2024
1 parent 845c60b commit a5320ad
Show file tree
Hide file tree
Showing 16 changed files with 537 additions and 91 deletions.
68 changes: 67 additions & 1 deletion src/actions/company.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@ import {
companyIndexesBoxSelectorAtPage,
companyOverviewBoxSelectorByName,
companyTimeAndSalaryBoxSelectorByName,
companyInterviewExperiencesBoxSelectorByName,
companyWorkExperiencesBoxSelectorByName,
} from 'selectors/companyAndJobTitle';
import {
getCompany as getCompanyApi,
queryCompanyOverview as queryCompanyOverviewApi,
getCompanyTimeAndSalary,
getCompanyInterviewExperiences,
getCompanyWorkExperiences,
queryCompaniesApi,
} from 'apis/company';

export const SET_STATUS = '@@company/SET_STATUS';
export const SET_OVERVIEW = '@@COMPANY/SET_OVERVIEW';
export const SET_TIME_AND_SALARY = '@@COMPANY/SET_TIME_AND_SALARY';
export const SET_INTERVIEW_EXPERIENCES = '@@COMPANY/SET_INTERVIEW_EXPERIENCES';
export const SET_WORK_EXPERIENCES = '@@COMPANY/SET_WORK_EXPERIENCES';
export const SET_INDEX = '@@COMPANY/SET_INDEX';
export const SET_INDEX_COUNT = '@@COMPANY/SET_INDEX_COUNT';
Expand Down Expand Up @@ -158,6 +161,12 @@ const setTimeAndSalary = (companyName, box) => ({
box,
});

const setInterviewExperiences = (companyName, box) => ({
type: SET_INTERVIEW_EXPERIENCES,
companyName,
box,
});

export const queryCompanyTimeAndSalary = ({
companyName,
jobTitle,
Expand All @@ -168,7 +177,7 @@ export const queryCompanyTimeAndSalary = ({
if (
isFetching(box) ||
(isFetched(box) &&
box.name === companyName &&
box.data.name === companyName &&
box.data.jobTitle === jobTitle &&
box.data.start === start &&
box.data.limit === limit)
Expand Down Expand Up @@ -207,6 +216,63 @@ export const queryCompanyTimeAndSalary = ({
}
};

export const queryCompanyInterviewExperiences = ({
companyName,
jobTitle,
start,
limit,
}) => async (dispatch, getState) => {
const box = companyInterviewExperiencesBoxSelectorByName(companyName)(
getState(),
);
if (
isFetching(box) ||
(isFetched(box) &&
box.data.name === companyName &&
box.data.jobTitle === jobTitle &&
box.data.start === start &&
box.data.limit === limit)
) {
return;
}

dispatch(setInterviewExperiences(companyName, toFetching()));

try {
const data = await getCompanyInterviewExperiences({
companyName,
jobTitle,
start,
limit,
});

// Not found case
if (data == null) {
return dispatch(setInterviewExperiences(companyName, getFetched(data)));
}

const interviewExperiencesData = {
name: data.name,
jobTitle,
start,
limit,
interview_experiences:
data.interviewExperiencesResult.interviewExperiences,
interview_experiences_count: data.interviewExperiencesResult.count,
};

dispatch(
setInterviewExperiences(
companyName,
getFetched(interviewExperiencesData),
),
);
} catch (error) {
dispatch(setInterviewExperiences(companyName, getError(error)));
throw error;
}
};

const setWorkExperiences = (companyName, box) => ({
type: SET_WORK_EXPERIENCES,
companyName,
Expand Down
62 changes: 62 additions & 0 deletions src/actions/jobTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,23 @@ import {
jobTitleIndexesBoxSelectorAtPage,
jobTitleOverviewBoxSelectorByName,
jobTitleTimeAndSalaryBoxSelectorByName,
jobTitleInterviewExperiencesBoxSelectorByName,
jobTitleWorkExperiencesBoxSelectorByName,
} from 'selectors/companyAndJobTitle';
import {
getJobTitle as getJobTitleApi,
queryJobTitleOverview as queryJobTitleOverviewApi,
getJobTitleTimeAndSalary,
getJobTitleInterviewExperiences,
getJobTitleWorkExperiences,
queryJobTitlesApi,
} from 'apis/jobTitle';

export const SET_STATUS = '@@JOB_TITLE/SET_STATUS';
export const SET_OVERVIEW = '@@JOB_TITLE/SET_OVERVIEW';
export const SET_TIME_AND_SALARY = '@@JOB_TITLE/SET_TIME_AND_SALARY';
export const SET_INTERVIEW_EXPERIENCES =
'@@JOB_TITLE/SET_INTERVIEW_EXPERIENCES';
export const SET_WORK_EXPERIENCES = '@@JOB_TITLE/SET_WORK_EXPERIENCES';
export const SET_INDEX = '@@JOB_TITLE/SET_INDEX';
export const SET_INDEX_COUNT = '@@JOB_TITLE/SET_INDEX_COUNT';
Expand Down Expand Up @@ -205,6 +209,64 @@ export const queryJobTitleTimeAndSalary = ({
}
};

const setInterviewExperiences = (jobTitle, box) => ({
type: SET_INTERVIEW_EXPERIENCES,
jobTitle,
box,
});

export const queryJobTitleInterviewExperiences = ({
companyName,
jobTitle,
start,
limit,
}) => async (dispatch, getState) => {
const box = jobTitleInterviewExperiencesBoxSelectorByName(jobTitle)(
getState(),
);
if (
isFetching(box) ||
(isFetched(box) &&
box.data.companyName === companyName &&
box.data.start === start &&
box.data.limit === limit)
) {
return;
}

dispatch(setInterviewExperiences(jobTitle, toFetching()));

try {
const data = await getJobTitleInterviewExperiences({
jobTitle,
companyName,
start,
limit,
});

// Not found case
if (data == null) {
return dispatch(setInterviewExperiences(jobTitle, getFetched(data)));
}

const interviewExperiencesyData = {
name: data.name,
companyName,
start,
limit,
interview_experiences:
data.interviewExperiencesResult.interviewExperiences,
interview_experiences_count: data.interviewExperiencesResult.count,
};

dispatch(
setInterviewExperiences(jobTitle, getFetched(interviewExperiencesyData)),
);
} catch (error) {
dispatch(setInterviewExperiences(jobTitle, getError(error)));
}
};

const setWorkExperiences = (jobTitle, box) => ({
type: SET_WORK_EXPERIENCES,
jobTitle,
Expand Down
12 changes: 12 additions & 0 deletions src/apis/company.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getCompanyQuery,
queryCompanyOverviewGql,
getCompanyTimeAndSalaryQuery,
getCompanyInterviewExperiencesQuery,
getCompanyWorkExperiencesQuery,
queryCompaniesHavingDataGql,
} from 'graphql/company';
Expand Down Expand Up @@ -42,6 +43,17 @@ export const getCompanyTimeAndSalary = ({
variables: { companyName, jobTitle, start, limit },
}).then(R.prop('company'));

export const getCompanyInterviewExperiences = ({
companyName,
jobTitle,
start,
limit,
}) =>
graphqlClient({
query: getCompanyInterviewExperiencesQuery,
variables: { companyName, jobTitle, start, limit },
}).then(R.prop('company'));

export const getCompanyWorkExperiences = ({
companyName,
jobTitle,
Expand Down
12 changes: 12 additions & 0 deletions src/apis/jobTitle.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import R from 'ramda';
import graphqlClient from 'utils/graphqlClient';
import {
getJobTitleInterviewExperiencesQuery,
getJobTitleQuery,
queryJobTitleOverviewGql,
getJobTitleTimeAndSalaryQuery,
Expand Down Expand Up @@ -42,6 +43,17 @@ export const getJobTitleTimeAndSalary = ({
variables: { jobTitle, companyName, start, limit },
}).then(R.prop('job_title'));

export const getJobTitleInterviewExperiences = ({
jobTitle,
companyName,
start,
limit,
}) =>
graphqlClient({
query: getJobTitleInterviewExperiencesQuery,
variables: { jobTitle, companyName, start, limit },
}).then(R.prop('job_title'));

export const getJobTitleWorkExperiences = ({
jobTitle,
companyName,
Expand Down
108 changes: 108 additions & 0 deletions src/components/Company/CompanyInterviewExperiencesProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import React, { useCallback, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import InterviewExperiences from '../CompanyAndJobTitle/InterviewExperiences';
import { paramsSelector, querySelector } from 'common/routing/selectors';
import usePermission from 'hooks/usePermission';
import { usePage } from 'hooks/routing/page';
import { tabType, pageType as PAGE_TYPE } from 'constants/companyJobTitle';
import { queryCompanyInterviewExperiences } from 'actions/company';
import {
interviewExperiences as interviewExperiencesSelector,
interviewExperiencesCount as interviewExperiencesCountSelector,
status as statusSelector,
companyInterviewExperiencesBoxSelectorByName,
} from 'selectors/companyAndJobTitle';
import { usePageName, pageNameSelector } from './usePageName';
import {
searchTextFromQuerySelector,
useSearchTextFromQuery,
} from 'components/CompanyAndJobTitle/useSearchbar';
import { pageFromQuerySelector } from 'selectors/routing/page';

const useInterviewExperiencesBox = pageName => {
const selector = useCallback(
state => {
const company = companyInterviewExperiencesBoxSelectorByName(pageName)(
state,
);
return {
status: statusSelector(company),
interviewExperiences: interviewExperiencesSelector(company),
interviewExperiencesCount: interviewExperiencesCountSelector(company),
};
},
[pageName],
);
return useSelector(selector);
};

const PAGE_SIZE = 10;

const CompanyInterviewExperiencesProvider = () => {
const dispatch = useDispatch();
const pageType = PAGE_TYPE.COMPANY;
const pageName = usePageName();
const [jobTitle] = useSearchTextFromQuery();
const page = usePage();
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;

useEffect(() => {
dispatch(
queryCompanyInterviewExperiences({
companyName: pageName,
jobTitle: jobTitle || undefined,
start,
limit,
}),
);
}, [dispatch, pageName, jobTitle, start, limit]);

const [, fetchPermission, canView] = usePermission();
useEffect(() => {
fetchPermission();
}, [pageType, pageName, fetchPermission]);

const {
status,
interviewExperiences,
interviewExperiencesCount,
} = useInterviewExperiencesBox(pageName);

return (
<InterviewExperiences
pageType={pageType}
pageName={pageName}
page={page}
pageSize={PAGE_SIZE}
totalCount={interviewExperiencesCount}
canView={canView}
tabType={tabType.INTERVIEW_EXPERIENCE}
status={status}
interviewExperiences={interviewExperiences}
/>
);
};

CompanyInterviewExperiencesProvider.fetchData = ({
store: { dispatch },
...props
}) => {
const params = paramsSelector(props);
const pageName = pageNameSelector(params);
const query = querySelector(props);
const page = pageFromQuerySelector(query);
const jobTitle = searchTextFromQuerySelector(query) || undefined;
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;
return dispatch(
queryCompanyInterviewExperiences({
companyName: pageName,
jobTitle,
start,
limit,
}),
);
};

export default CompanyInterviewExperiencesProvider;
Loading

0 comments on commit a5320ad

Please sign in to comment.