Skip to content

Commit

Permalink
[公司頁面] 加上平均分 (#1443)
Browse files Browse the repository at this point in the history
  • Loading branch information
peteranny authored Oct 17, 2024
1 parent efa7ac5 commit ba36b0d
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 23 deletions.
36 changes: 36 additions & 0 deletions src/actions/company.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
companyTimeAndSalaryStatisticsBoxSelectorByName,
companyInterviewExperiencesBoxSelectorByName,
companyWorkExperiencesBoxSelectorByName,
companyRatingStatisticsBoxSelectorByName,
} from 'selectors/companyAndJobTitle';
import {
queryCompanyOverview as queryCompanyOverviewApi,
Expand All @@ -21,8 +22,10 @@ import {
getCompanyWorkExperiences,
queryCompaniesApi,
getCompanyTimeAndSalaryStatistics,
queryCompanyRatingStatisticsApi,
} from 'apis/company';

export const SET_RATING_STATISTICS = '@@COMPANY/SET_RATING_STATISTICS';
export const SET_OVERVIEW = '@@COMPANY/SET_OVERVIEW';
export const SET_TIME_AND_SALARY = '@@COMPANY/SET_TIME_AND_SALARY';
export const SET_TIME_AND_SALARY_STATISTICS =
Expand Down Expand Up @@ -70,6 +73,39 @@ export const fetchCompanyNames = ({ page, pageSize }) => async (
}
};

const setRatingStatistcs = (companyName, box) => ({
type: SET_RATING_STATISTICS,
companyName,
box,
});

export const queryRatingStatistics = pageName => async (dispatch, getState) => {
const box = companyRatingStatisticsBoxSelectorByName(pageName)(getState());
if (isFetching(box) || isFetched(box)) {
return;
}

dispatch(setRatingStatistcs(pageName, toFetching()));

try {
const data = await queryCompanyRatingStatisticsApi({
companyName: pageName,
});

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

dispatch(setRatingStatistcs(pageName, getFetched(data)));
} catch (error) {
if (isGraphqlError(error)) {
dispatch(setRatingStatistcs(pageName, getError(error)));
}
throw error;
}
};

const SALARY_WORK_TIMES_LIMIT = 5;
const WORK_EXPERIENCES_LIMIT = 3;
const INTERVIEW_EXPERIENCES_LIMIT = 3;
Expand Down
7 changes: 7 additions & 0 deletions src/apis/company.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 {
queryCompanyRatingStatisticsGql,
queryCompanyOverviewGql,
getCompanyTimeAndSalaryQuery,
getCompanyInterviewExperiencesQuery,
Expand All @@ -9,6 +10,12 @@ import {
getCompanyTimeAndSalaryStatisticsQuery,
} from 'graphql/company';

export const queryCompanyRatingStatisticsApi = ({ companyName }) =>
graphqlClient({
query: queryCompanyRatingStatisticsGql,
variables: { companyName },
}).then(R.path(['company', 'companyRatingStatistics']));

export const queryCompanyOverview = ({
companyName,
interviewExperiencesLimit,
Expand Down
53 changes: 52 additions & 1 deletion src/components/CompanyAndJobTitle/CompanyAndJobTitleWrapper.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,66 @@
import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { toPairs, compose, map } from 'ramda';

import Heading from 'common/base/Heading';
import FanPageBlock from 'common/FanPageBlock';
import BreadCrumb from 'common/BreadCrumb';

import { tabTypeTranslation, generateTabURL } from 'constants/companyJobTitle';
import { companyRatingStatisticsBoxSelectorByName } from 'selectors/companyAndJobTitle';
import {
tabTypeTranslation,
generateTabURL,
pageType as PAGE_TYPE,
} from 'constants/companyJobTitle';
import { isFetched } from 'utils/fetchBox';
import { generateBreadCrumbData } from './utils';

import TabLinkGroup from 'common/TabLinkGroup';
import styles from './CompanyAndJobTitleWrapper.module.css';
import Glike from 'common/icons/Glike';
import Seo from 'common/Seo/SeoStructure';

const AverageRating = ({ pageType, pageName }) => {
const ratingStatistcsBox = useSelector(
companyRatingStatisticsBoxSelectorByName(pageName),
);

if (pageType !== PAGE_TYPE.COMPANY || !isFetched(ratingStatistcsBox)) {
return null;
}

const data = ratingStatistcsBox.data;
if (!data) {
return null;
}

const { averageRating, ratingCount } = data;
return (
<div className={styles.ratingStatistics}>
<Seo
data={{
'@context': 'https://schema.org/',
'@type': 'EmployerAggregateRating',
itemReviewed: {
'@type': 'Organization',
name: pageName,
},
ratingValue: averageRating,
ratingCount: ratingCount,
}}
/>
<span className={styles.averageRating}>{averageRating.toFixed(1)}</span>
<Glike className={styles.icon} />
<span className={styles.ratingCount}>({ratingCount})</span>
</div>
);
};

AverageRating.propTypes = {
pageName: PropTypes.string.isRequired,
pageType: PropTypes.string.isRequired,
};

const CompanyAndJobTitleWrapper = ({
children,
Expand Down Expand Up @@ -43,6 +93,7 @@ const CompanyAndJobTitleWrapper = ({
</div>
<Heading style={{ color: '#000000', marginBottom: '30px' }}>
{pageName}
<AverageRating pageType={pageType} pageName={pageName} />
</Heading>
<TabLinkGroup
options={tabLinkOptions}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@value below-small, above-small from '../common/variables.module.css';

.fanPageBlock {
margin-bottom: 60px;
}
Expand All @@ -6,3 +8,31 @@
margin-top: -30px;
margin-bottom: 30px;
}

.ratingStatistics {
align-items: center;

@media (max-width: below-small) {
display: flex;
margin-top: 16px;
}

@media (min-width: above-small) {
display: inline-flex;
margin-left: 34px;
}

.averageRating {
font-size: 17px;
font-weight: 500;
}

.icon {
width: 20px;
height: 20px;
}

.ratingCount {
font-size: 15px;
}
}
16 changes: 16 additions & 0 deletions src/graphql/company.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
export const queryCompanyRatingStatisticsGql = /* GraphQL */ `
query($companyName: String!) {
company(name: $companyName) {
name
companyRatingStatistics {
averageRating
ratingDistribution {
rating
count
}
ratingCount
}
}
}
`;

export const queryCompanyOverviewGql = /* GraphQL */ `
query(
$companyName: String!
Expand Down
28 changes: 19 additions & 9 deletions src/pages/Company/CompanyInterviewExperiencesProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ 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 {
queryCompanyInterviewExperiences,
queryRatingStatistics,
} from 'actions/company';
import {
interviewExperiences as interviewExperiencesSelector,
interviewExperiencesCount as interviewExperiencesCountSelector,
Expand Down Expand Up @@ -47,6 +50,10 @@ const CompanyInterviewExperiencesProvider = () => {
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;

useEffect(() => {
dispatch(queryRatingStatistics(pageName));
}, [dispatch, pageName]);

useEffect(() => {
dispatch(
queryCompanyInterviewExperiences({
Expand Down Expand Up @@ -95,14 +102,17 @@ CompanyInterviewExperiencesProvider.fetchData = ({
const jobTitle = searchTextFromQuerySelector(query) || undefined;
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;
return dispatch(
queryCompanyInterviewExperiences({
companyName: pageName,
jobTitle,
start,
limit,
}),
);
return Promise.all([
dispatch(
queryCompanyInterviewExperiences({
companyName: pageName,
jobTitle,
start,
limit,
}),
),
dispatch(queryRatingStatistics(pageName)),
]);
};

export default CompanyInterviewExperiencesProvider;
11 changes: 9 additions & 2 deletions src/pages/Company/CompanyOverviewProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Overview from 'components/CompanyAndJobTitle/Overview';
import usePermission from 'hooks/usePermission';
import { usePage } from 'hooks/routing/page';
import { tabType, pageType as PAGE_TYPE } from 'constants/companyJobTitle';
import { queryCompanyOverview } from 'actions/company';
import { queryCompanyOverview, queryRatingStatistics } from 'actions/company';
import {
jobAverageSalaries,
averageWeekWorkTime,
Expand Down Expand Up @@ -44,6 +44,10 @@ const CompanyOverviewProvider = () => {
const pageName = usePageName();
const page = usePage();

useEffect(() => {
dispatch(queryRatingStatistics(pageName));
}, [dispatch, pageName]);

useEffect(() => {
dispatch(queryCompanyOverview(pageName));
}, [dispatch, pageName]);
Expand All @@ -70,7 +74,10 @@ const CompanyOverviewProvider = () => {
CompanyOverviewProvider.fetchData = ({ store: { dispatch }, ...props }) => {
const params = paramsSelector(props);
const pageName = pageNameSelector(params);
return dispatch(queryCompanyOverview(pageName));
return Promise.all([
dispatch(queryCompanyOverview(pageName)),
dispatch(queryRatingStatistics(pageName)),
]);
};

export default CompanyOverviewProvider;
12 changes: 11 additions & 1 deletion src/pages/Company/CompanyTimeAndSalaryProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { tabType, pageType as PAGE_TYPE } from 'constants/companyJobTitle';
import {
queryCompanyTimeAndSalary,
queryCompanyTimeAndSalaryStatistics,
queryRatingStatistics,
} from 'actions/company';
import {
salaryWorkTimes as salaryWorkTimesSelector,
Expand Down Expand Up @@ -62,6 +63,10 @@ const CompanyTimeAndSalaryProvider = () => {
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;

useEffect(() => {
dispatch(queryRatingStatistics(pageName));
}, [dispatch, pageName]);

useEffect(() => {
dispatch(
queryCompanyTimeAndSalaryStatistics({
Expand Down Expand Up @@ -131,7 +136,12 @@ CompanyTimeAndSalaryProvider.fetchData = ({
limit,
}),
);
return Promise.all([dispatchTimeAndSalary, dispatchTimeAndSalaryStatistics]);
const dispatchRatingStatistics = dispatch(queryRatingStatistics(pageName));
return Promise.all([
dispatchTimeAndSalary,
dispatchTimeAndSalaryStatistics,
dispatchRatingStatistics,
]);
};

export default CompanyTimeAndSalaryProvider;
28 changes: 19 additions & 9 deletions src/pages/Company/CompanyWorkExperiencesProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import WorkExperiences from 'components/CompanyAndJobTitle/WorkExperiences';
import usePermission from 'hooks/usePermission';
import { usePage } from 'hooks/routing/page';
import { tabType, pageType as PAGE_TYPE } from 'constants/companyJobTitle';
import { queryCompanyWorkExperiences } from 'actions/company';
import {
queryCompanyWorkExperiences,
queryRatingStatistics,
} from 'actions/company';
import {
workExperiences as workExperiencesSelector,
workExperiencesCount as workExperiencesCountSelector,
Expand Down Expand Up @@ -46,6 +49,10 @@ const CompanyWorkExperiencesProvider = () => {
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;

useEffect(() => {
dispatch(queryRatingStatistics(pageName));
}, [dispatch, pageName]);

useEffect(() => {
dispatch(
queryCompanyWorkExperiences({
Expand Down Expand Up @@ -94,14 +101,17 @@ CompanyWorkExperiencesProvider.fetchData = ({
const jobTitle = searchTextFromQuerySelector(query) || undefined;
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;
return dispatch(
queryCompanyWorkExperiences({
companyName: pageName,
jobTitle,
start,
limit,
}),
);
return Promise.all([
dispatch(
queryCompanyWorkExperiences({
companyName: pageName,
jobTitle,
start,
limit,
}),
),
dispatch(queryRatingStatistics(pageName)),
]);
};

export default CompanyWorkExperiencesProvider;
Loading

0 comments on commit ba36b0d

Please sign in to comment.