diff --git a/components/popup.tsx b/components/popup.tsx index 090dd7a..e4f497e 100644 --- a/components/popup.tsx +++ b/components/popup.tsx @@ -1,9 +1,18 @@ import React, { FC, ReactNode, useCallback, useState } from 'react' import { Modal } from 'antd' +import classNames from 'classnames' -export const FullMask: FC<{ transparent?: boolean; width?: number; maskClosable?: boolean; onCancel?: () => void}> = ({ children, transparent = false, width = 375, maskClosable = false, onCancel }) => { +export const FullMask: FC<{ + centered?: boolean + transparent?: boolean + width?: number + className?: string + maskClosable?: boolean + onCancel?: () => void +}> = ({ children, centered, transparent = false, className, width = 375, maskClosable = false, onCancel }) => { return ( diff --git a/features/jobs/Banner.tsx b/features/jobs/Banner.tsx new file mode 100644 index 0000000..8985491 --- /dev/null +++ b/features/jobs/Banner.tsx @@ -0,0 +1,15 @@ +import React from 'react' + +const bg = 'https://assets.lbctrl.com/uploads/66944006-30cf-464c-b535-ba4c2246b400/whale-job.png' +const JobBanner: React.FC = () => { + return ( +
+
+
Join Us
+
+ {/* job-bg */} +
+ ) +} + +export default JobBanner diff --git a/features/jobs/List.tsx b/features/jobs/List.tsx new file mode 100644 index 0000000..3050862 --- /dev/null +++ b/features/jobs/List.tsx @@ -0,0 +1,113 @@ +import { JobItem, CityItem } from '@/hooks/use-jobs' +import React from 'react' +import get from 'lodash/get' +import { useTranslation } from 'next-i18next' +import { FullMask } from '@/components/popup' +import Icon from '@/components/icon' +import style from './index.module.scss' +import { Modal } from 'antd' + +interface JobProps { + jobs: JobItem[] + cities: CityItem[] +} +const JobList: React.FC = props => { + const i18n = useTranslation('common') + const language = i18n.i18n?.language + const { jobs, cities } = props + const [visible, setVisible] = React.useState(false) + const [detailJob, setDetailJob] = React.useState() + + const getLocation = (_cities: string) => { + const city = _cities + .split(',') + .map(city => { + const cityItem = cities.find(c => c.key === city) + return get(cityItem, `address.${language}`, get(cityItem, 'address')) + }) + .filter(Boolean) + + console.log('🚀 ~ getLocation ~ city:', city) + return city.join(' ') + } + + const handleJob = job => { + setDetailJob(job) + setVisible(true) + } + return ( +
+ {jobs.map(job => { + return ( +
handleJob(job)} + > +
+ {get(job, `title.${language}`, get(job, 'title'))} +
+
+ {getLocation(get(job, 'cities'))} +
+
+ {get(job, `jobResponsibility.${language}`, get(job, 'jobResponsibility'))} +
+
+ ) + })} + {visible && ( + setVisible(false)} + getContainer={'#__next'} + bodyStyle={{ padding: 0 }} + className={style['job-detail-modal']} + maskStyle={{ backgroundColor: 'rgba(0,0,0,.5)' }} + > +
+ setVisible(false)} + > +
+
+ {get(detailJob, `title.${language}`, get(detailJob, 'title'))} +
+
+
+
+
+
Job Requirements
+
+ {get(detailJob, `jobRequirements.${language}`, get(detailJob, 'jobRequirements'))} +
+
+
+
Job Responsibilities
+
+ {get(detailJob, `jobResponsibility.${language}`, get(detailJob, 'jobResponsibility'))} +
+
+
+
Work Location
+
+ {getLocation(get(detailJob, 'cities'))} +
+
+
+
+
+
+ )} +
+ ) +} + +export default JobList diff --git a/features/jobs/index.module.scss b/features/jobs/index.module.scss new file mode 100644 index 0000000..281d823 --- /dev/null +++ b/features/jobs/index.module.scss @@ -0,0 +1,10 @@ +:local(.job-detail-modal) { + .ant-modal-content { + @apply rounded-lg; + .job-detail { + &::-webkit-scrollbar { + @apply hidden; + } + } + } +} diff --git a/hooks/use-jobs.ts b/hooks/use-jobs.ts new file mode 100644 index 0000000..bc932e6 --- /dev/null +++ b/hooks/use-jobs.ts @@ -0,0 +1,53 @@ +import { useEffect } from 'react' +import { useSafeState } from 'ahooks' +import { getAppConfig } from '@/services' +import get from 'lodash/get' + +/** + * 获取媒体报道 + * @returns ReportItem[] + */ +interface LocaleItem { + 'zh-CN': string + 'zh-HK': string + 'en': string +} +export interface JobItem { + site: string + city: string + goodImpression: string + id: string + jobRequirements: string | LocaleItem + jobResponsibility: string | LocaleItem + title: string | LocaleItem +} +export interface CityItem { + address: string + key: string + name: string +} +let jobsState: JobItem[] = [] +const filterSite = 'whale' +export function useJobs() { + const [jobs, setJobs] = useSafeState(jobsState) + const [cities, setCities] = useSafeState([]) + + useEffect(() => { + if (!!jobsState.length) return + fetchJobs() + }, []) + + const fetchJobs = async () => { + const key = 'jobs' + const resp = await getAppConfig([key]) + const _jobConfig = resp?.config?.[key] + if (_jobConfig) { + const whaleJobs = get(_jobConfig, 'jobs', []).filter((job: JobItem) => job.site === filterSite) + setCities(get(_jobConfig, 'cities', [])) + setJobs(whaleJobs) + jobsState = whaleJobs + } + } + + return [jobs, cities, setJobs] as const +} diff --git a/pages/[locale]/jobs/index.tsx b/pages/[locale]/jobs/index.tsx new file mode 100644 index 0000000..13dc059 --- /dev/null +++ b/pages/[locale]/jobs/index.tsx @@ -0,0 +1,40 @@ +import React from 'react' +import { serverSideTranslations } from 'next-i18next/serverSideTranslations' +import { useTranslation } from 'next-i18next' +import { i18nPaths } from '@/utils/i18n-paths' +import i18nextConfig from '@/next-i18next.config' +import { useJobs } from '@/hooks/use-jobs' +import { SEOMeta } from '@/utils/seo' +import { getAppConfig } from '@/services' +import { Layout, PageLayout } from '@/features/common/page-layout' +import JobBanner from '@/features/jobs/Banner' +import JobList from '@/features/jobs/List' + +export const getStaticPaths = () => ({ + fallback: false, + paths: i18nPaths(), +}) +export const getStaticProps = async (ctx: any) => ({ + props: { + ...(await serverSideTranslations(ctx?.params?.locale, ['common', 'seo'], i18nextConfig)), + }, +}) + +const Jobs: React.FC = () => { + const [jobs, cities] = useJobs() + const seoI18n = useTranslation(['seo']) + const i18n = useTranslation('common') + return ( + + + +
+
+ +
+
+
+ ) +} + +export default Jobs diff --git a/routes/index.tsx b/routes/index.tsx index 99dd76e..2bb52ab 100644 --- a/routes/index.tsx +++ b/routes/index.tsx @@ -25,6 +25,7 @@ import FrontDesk from '@/pages/[locale]/front-desk' import VirtualAssetTradingSystem from '@/pages/[locale]/virtual-asset-trading-system' import PortAI from '@/pages/[locale]/portai' import Account from '@/pages/[locale]/account' +import Jobs from '@/pages/[locale]/jobs' import Brokerages from '@/pages/[locale]/solutions/brokerages' import SmallBrokeragesPage from '@/pages/[locale]/solutions/small-brokerages' import UsStock from '@/pages/[locale]/solutions/us-stock' @@ -68,6 +69,7 @@ export const RouteList = ({ pageProps }: { pageProps: any }) => { } /> } /> } /> + } /> )