feat: first commit
This commit is contained in:
145
src/components/material-card/index.tsx
Normal file
145
src/components/material-card/index.tsx
Normal file
@ -0,0 +1,145 @@
|
||||
import { Image, ScrollView } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
|
||||
import { Loading } from '@taroify/core';
|
||||
import { ArrowRight } from '@taroify/icons';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import LoginButton from '@/components/login-button';
|
||||
import { EventName, PageUrl } from '@/constants/app';
|
||||
import { CollectEventName, ReportEventId } from '@/constants/event';
|
||||
import useUserInfo from '@/hooks/use-user-info';
|
||||
import { MaterialProfile } from '@/types/material';
|
||||
import { logWithPrefix } from '@/utils/common';
|
||||
import { collectEvent, reportEvent } from '@/utils/event';
|
||||
import { requestProfileDetail, sortVideos } from '@/utils/material';
|
||||
import { navigateTo } from '@/utils/route';
|
||||
import Toast from '@/utils/toast';
|
||||
import { isValidUserInfo } from '@/utils/user';
|
||||
|
||||
import './index.less';
|
||||
|
||||
interface IProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const PREFIX = 'material-card';
|
||||
const log = logWithPrefix(PREFIX);
|
||||
const realtimeLogger = Taro.getRealtimeLogManager();
|
||||
realtimeLogger.tag(PREFIX);
|
||||
|
||||
function MaterialCard(props: IProps) {
|
||||
const { className } = props;
|
||||
const userInfo = useUserInfo();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [profile, setProfile] = useState<MaterialProfile | null>(null);
|
||||
const refreshRef = useRef((_f?: boolean) => { });
|
||||
const hasMaterial = !!profile;
|
||||
|
||||
const handleGoCreateProfile = useCallback(() => {
|
||||
reportEvent(ReportEventId.CLICK_GO_TO_CREATE_MATERIAL);
|
||||
navigateTo(PageUrl.MaterialUploadVideo);
|
||||
}, []);
|
||||
|
||||
const handleGoProfile = useCallback(() => {
|
||||
if (!hasMaterial) {
|
||||
realtimeLogger.info('handleGoProfile noMaterial')
|
||||
return;
|
||||
}
|
||||
navigateTo(PageUrl.MaterialProfile).catch(err => {
|
||||
realtimeLogger.error('handleGoProfile Failed', err);
|
||||
});
|
||||
}, [hasMaterial]);
|
||||
|
||||
useEffect(() => {
|
||||
refreshRef.current = async (force: boolean = false) => {
|
||||
collectEvent(CollectEventName.MATERIAL_CARD_VIEW, {
|
||||
status: 'refresh',
|
||||
info: { force, isCreateResume: userInfo.isCreateResume },
|
||||
});
|
||||
setLoading(true);
|
||||
if (!userInfo.isCreateResume && !force) {
|
||||
log('refresh break by is not create resume');
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const profileDetail = await requestProfileDetail();
|
||||
if (!profileDetail) {
|
||||
realtimeLogger.info('getProfileDetail no profileDetail')
|
||||
}
|
||||
setProfile(profileDetail);
|
||||
} catch (e) {
|
||||
realtimeLogger.error('getProfileDetail Failed', e);
|
||||
Toast.error('加载失败');
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
}, [userInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isValidUserInfo(userInfo)) {
|
||||
return;
|
||||
}
|
||||
refreshRef.current?.(true);
|
||||
}, [userInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
const callback = async () => {
|
||||
refreshRef.current?.(true);
|
||||
};
|
||||
Taro.eventCenter.on(EventName.CREATE_PROFILE, callback);
|
||||
return () => {
|
||||
Taro.eventCenter.off(EventName.CREATE_PROFILE, callback);
|
||||
};
|
||||
}, [userInfo]);
|
||||
|
||||
return (
|
||||
<div className={classNames(PREFIX, className)} onClick={handleGoProfile}>
|
||||
<div className={`${PREFIX}__header`}>
|
||||
<div className={`${PREFIX}__header__left`}>
|
||||
<div className={`${PREFIX}__header__title`}>我的模卡</div>
|
||||
{/* {profile && (
|
||||
<div
|
||||
className={`${PREFIX}__header__progress`}
|
||||
>{`完成度${Math.min((profile.progressBar || 0) * 100, 100)}%`}</div>
|
||||
)} */}
|
||||
</div>
|
||||
{profile && (
|
||||
<div className={`${PREFIX}__header__right`}>
|
||||
{/* <div className={`${PREFIX}__header__status`}>{profile?.isOpen ? '开放中' : '关闭'}</div> */}
|
||||
<ArrowRight className={`${PREFIX}__header__icon`} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={`${PREFIX}__body`}>
|
||||
{!loading && !hasMaterial && (
|
||||
<div className={`${PREFIX}__placeholder`}>
|
||||
<div className={`${PREFIX}__placeholder__tips`}>创建模卡更容易被老板挑中哦</div>
|
||||
<LoginButton className={`${PREFIX}__placeholder__create-button`} onClick={handleGoCreateProfile}>
|
||||
去创建
|
||||
</LoginButton>
|
||||
</div>
|
||||
)}
|
||||
{!loading && hasMaterial && (
|
||||
<ScrollView className={`${PREFIX}__scroll-view`} showScrollbar={false} enableFlex enhanced scrollX>
|
||||
<div className={`${PREFIX}__cover-list`}>
|
||||
{sortVideos(profile?.materialVideoInfoList || []).map(video => (
|
||||
<Image
|
||||
className={`${PREFIX}__cover-image`}
|
||||
mode="aspectFit"
|
||||
key={video.coverUrl}
|
||||
src={video.coverUrl}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</ScrollView>
|
||||
)}
|
||||
{loading && <Loading />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MaterialCard;
|
||||
Reference in New Issue
Block a user