Files
boluo-app-main/src/pages/certification-manage/index.tsx
2025-07-28 23:35:51 +08:00

130 lines
4.2 KiB
TypeScript

import { Button, Image } from '@tarojs/components';
import { NodesRef } from '@tarojs/taro';
import { Tabs } from '@taroify/core';
import classNames from 'classnames';
import { useCallback, useEffect, useState } from 'react';
import JobManageList, { IJobManageListProps } from '@/components/job-manage-list';
import SafeBottomPadding from '@/components/safe-bottom-padding';
import { PageUrl } from '@/constants/app';
import { ReportEventId } from '@/constants/event';
import { JOB_MANAGE_TABS, JobManageStatus, JobManageType } from '@/constants/job';
import useListHeight, { IUseListHeightProps } from '@/hooks/use-list-height';
import useUserInfo from '@/hooks/use-user-info';
import { logWithPrefix } from '@/utils/common';
import { reportEvent } from '@/utils/event';
import { navigateTo } from '@/utils/route';
import { ensureUserInfo } from '@/utils/user';
import './index.less';
const PREFIX = 'page-certification-manage';
const LIST_CONTAINER_CLASS = `${PREFIX}__list-container`;
const BUTTON_CLASS = `${PREFIX}__button`;
const SAFE_BOTTOM_PADDING_CLASS = `${PREFIX}__sbpc`;
const CALC_LIST_PROPS: IUseListHeightProps = {
selectors: [
`.${PREFIX}`,
`.${PREFIX} .taroify-tabs__wrap__scroll`,
`.${BUTTON_CLASS}`,
`.${SAFE_BOTTOM_PADDING_CLASS}`,
],
calc: (
rects: [
NodesRef.BoundingClientRectCallbackResult,
NodesRef.BoundingClientRectCallbackResult,
NodesRef.BoundingClientRectCallbackResult,
NodesRef.BoundingClientRectCallbackResult,
]
) => {
const [page, tabs, button, safePadding] = rects;
return page.height - tabs.height - button.height - safePadding.height - 10;
},
};
const log = logWithPrefix(PREFIX);
const tab2Status = (tabType: JobManageType) => {
switch (tabType) {
case JobManageType.Open:
return JobManageStatus.Open;
case JobManageType.Pending:
return JobManageStatus.Pending;
case JobManageType.Error:
return JobManageStatus.Error;
case JobManageType.All:
default:
return;
}
};
const EmptyTips = (props: { className?: string; height?: number }) => {
const { className, height } = props;
return (
<div className={classNames(`${PREFIX}__empty-tips`, className)} style={height ? { height } : undefined}>
<Image className={`${PREFIX}__empty-tips__icon`} src={require('@/statics/svg/empty-box.svg')} mode="aspectFit" />
<div className={`${PREFIX}__empty-tips__describe`}></div>
</div>
);
};
function ListWrapper(props: IJobManageListProps) {
const { className, listHeight, visible } = props;
const [isEmpty, setIsEmpty] = useState(false);
const handleListEmpty = useCallback(() => {
setIsEmpty(true);
}, []);
useEffect(() => {
if (visible) {
setIsEmpty(false);
}
}, [visible]);
if (isEmpty) {
return <EmptyTips className={className} height={listHeight} />;
}
return <JobManageList {...props} onListEmpty={handleListEmpty} />;
}
export default function CertificationManage() {
const userInfo = useUserInfo();
const listHeight = useListHeight(CALC_LIST_PROPS);
const [tabType, setTabType] = useState<JobManageType>(JobManageType.All);
const handleTypeChange = useCallback(value => setTabType(value), []);
const handlePublishJob = useCallback(async () => {
log('handlePublishJob');
reportEvent(ReportEventId.CLICK_GO_TO_PUBLISH_JOB);
if (!(await ensureUserInfo(userInfo))) {
return;
}
navigateTo(PageUrl.JobPublish);
}, [userInfo]);
return (
<div className={PREFIX}>
<Tabs swipeable value={tabType} className={`${PREFIX}__tabs`} onChange={handleTypeChange}>
{JOB_MANAGE_TABS.map(tab => (
<Tabs.TabPane value={tab.type} title={tab.title} key={tab.type}>
<ListWrapper
status={tab2Status(tab.type)}
listHeight={listHeight}
className={LIST_CONTAINER_CLASS}
visible={tabType === tab.type}
/>
</Tabs.TabPane>
))}
</Tabs>
<div className={`${PREFIX}__footer`}>
<Button className={BUTTON_CLASS} onClick={handlePublishJob}>
</Button>
</div>
<SafeBottomPadding className={SAFE_BOTTOM_PADDING_CLASS} />
</div>
);
}