开发: 添加eslint两个package
This commit is contained in:
12
.eslintrc.js
12
.eslintrc.js
@@ -1,7 +1,17 @@
|
||||
module.exports = {
|
||||
extends: [require.resolve('@umijs/lint/dist/config/eslint')],
|
||||
extends: [
|
||||
require.resolve('@umijs/lint/dist/config/eslint'),
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
],
|
||||
globals: {
|
||||
page: true,
|
||||
REACT_APP_ENV: true,
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['react', '@typescript-eslint'],
|
||||
rules: {
|
||||
'react/self-closing-comp': ['error'],
|
||||
eqeqeq: 'off',
|
||||
},
|
||||
};
|
||||
|
@@ -49,9 +49,12 @@
|
||||
"@ant-design/icons": "^5.0.1",
|
||||
"@ant-design/pro-components": "^2.3.57",
|
||||
"@ant-design/use-emotion-css": "1.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.0",
|
||||
"@typescript-eslint/parser": "^5.59.0",
|
||||
"@umijs/route-utils": "^4.0.1",
|
||||
"antd": "^5.2.2",
|
||||
"classnames": "^2.3.2",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
"omit.js": "^2.0.2",
|
||||
@@ -94,4 +97,4 @@
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
src/app.tsx
20
src/app.tsx
@@ -4,7 +4,7 @@ import { Settings as LayoutSettings } from '@ant-design/pro-components';
|
||||
import type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max';
|
||||
import { history, Link } from '@umijs/max';
|
||||
import { App } from 'antd';
|
||||
import React, { useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import defaultSettings from '../config/defaultSettings';
|
||||
import AvatarSvg from '../public/avatar.svg';
|
||||
import { AvatarDropdown, AvatarName } from './components/RightContent/AvatarDropdown';
|
||||
@@ -54,15 +54,15 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) =
|
||||
const { notification } = App.useApp();
|
||||
window.NotificationCF = notification;
|
||||
|
||||
useEffect(() => {
|
||||
// 小屏幕刷新页面
|
||||
// if (window.matchMedia) {
|
||||
// const mql = window.matchMedia('(max-width: 768px)');
|
||||
// mql.addEventListener('change', () => {
|
||||
// location.reload();
|
||||
// });
|
||||
// }
|
||||
}, []);
|
||||
// useEffect(() => {
|
||||
// 小屏幕刷新页面
|
||||
// if (window.matchMedia) {
|
||||
// const mql = window.matchMedia('(max-width: 768px)');
|
||||
// mql.addEventListener('change', () => {
|
||||
// location.reload();
|
||||
// });
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
return {
|
||||
// actionsRender: () => [<Question key="doc" />, <SelectLang key="SelectLang" />],
|
||||
|
@@ -42,16 +42,13 @@ const StrokeCheck: React.FC<IProps2> = (props) => {
|
||||
|
||||
return (
|
||||
<div className={styles.passwordStrong}>
|
||||
<div
|
||||
className={styles.strokeColorMask}
|
||||
style={{ width: `${((5 - strong) / 5) * 100}%` }}
|
||||
></div>
|
||||
<div className={styles.mark}></div>
|
||||
<div className={styles.mark}></div>
|
||||
<div className={styles.mark}></div>
|
||||
<div className={styles.mark}></div>
|
||||
<div className={styles.strokeColorMask} style={{ width: `${((5 - strong) / 5) * 100}%` }} />
|
||||
<div className={styles.mark} />
|
||||
<div className={styles.mark} />
|
||||
<div className={styles.mark} />
|
||||
<div className={styles.mark} />
|
||||
{strokeColor.map((item) => {
|
||||
return <div className={styles.strokeColor} key={item} style={{ background: item }}></div>;
|
||||
return <div className={styles.strokeColor} key={item} style={{ background: item }} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { getDevice } from '@/services/utils';
|
||||
import { Button, Drawer } from 'antd';
|
||||
|
||||
import React, { useRef, useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface IProps {
|
||||
body: React.ReactNode;
|
||||
@@ -12,7 +12,7 @@ export const SearchBarPlugin: React.FC<IProps> = (props) => {
|
||||
// const [device, setDevice] = useState(window.innerWidth);
|
||||
const isPhone = getDevice() === 'phone';
|
||||
const [open, setOpen] = useState(false);
|
||||
const [searchBarText, setSearchBarText] = useState('展开');
|
||||
// const [searchBarText, setSearchBarText] = useState('展开');
|
||||
// useEffect(() => {
|
||||
// const handleResize = (e: any) => {
|
||||
// const currDevice = e && e.target && e.target.innerWidth;
|
||||
@@ -24,20 +24,20 @@ export const SearchBarPlugin: React.FC<IProps> = (props) => {
|
||||
// window.addEventListener('optimizedResize', handleResize);
|
||||
// return () => window.removeEventListener('optimizedResize', handleResize);
|
||||
// }, [device]);
|
||||
const searchBarContentRef = useRef<any>(null);
|
||||
const changeSearchbar = () => {
|
||||
if (searchBarText === '展开') {
|
||||
setSearchBarText('收起');
|
||||
searchBarContentRef.current.style.height = `${
|
||||
searchBarContentRef.current.children[0].clientHeight + 10
|
||||
}px`;
|
||||
searchBarContentRef.current.style.transition = 'height .4s';
|
||||
} else {
|
||||
setSearchBarText('展开');
|
||||
searchBarContentRef.current.style.height = `${isPhone ? 76 : 94}px`;
|
||||
searchBarContentRef.current.style.transition = 'height .4s';
|
||||
}
|
||||
};
|
||||
// const searchBarContentRef = useRef<any>(null);
|
||||
// const changeSearchbar = () => {
|
||||
// if (searchBarText === '展开') {
|
||||
// setSearchBarText('收起');
|
||||
// searchBarContentRef.current.style.height = `${
|
||||
// searchBarContentRef.current.children[0].clientHeight + 10
|
||||
// }px`;
|
||||
// searchBarContentRef.current.style.transition = 'height .4s';
|
||||
// } else {
|
||||
// setSearchBarText('展开');
|
||||
// searchBarContentRef.current.style.height = `${isPhone ? 76 : 94}px`;
|
||||
// searchBarContentRef.current.style.transition = 'height .4s';
|
||||
// }
|
||||
// };
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -79,9 +79,9 @@ export const SearchBarPlugin: React.FC<IProps> = (props) => {
|
||||
style={{ background: '#fff', padding: 16, paddingBottom: 0, borderRadius: 6 }}
|
||||
>
|
||||
<div
|
||||
// className={styles.searchBarContent}
|
||||
// style={{ height: isPhone ? 76 : 'auto' }}
|
||||
ref={searchBarContentRef}
|
||||
// className={styles.searchBarContent}
|
||||
// style={{ height: isPhone ? 76 : 'auto' }}
|
||||
// ref={searchBarContentRef}
|
||||
>
|
||||
{props.body}
|
||||
</div>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { Button, message, notification } from 'antd';
|
||||
import React from 'react';
|
||||
import defaultSettings from '../config/defaultSettings';
|
||||
|
||||
const { pwa } = defaultSettings;
|
||||
@@ -53,7 +54,7 @@ if (pwa) {
|
||||
return true;
|
||||
};
|
||||
const key = `open${Date.now()}`;
|
||||
const btn = (
|
||||
const btn: React.ReactNode = (
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
|
@@ -144,7 +144,9 @@ export const getAdminList = (data: any) => {
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
@@ -171,7 +173,9 @@ export const formatTags = (data: any) => {
|
||||
</>
|
||||
);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
}
|
||||
return <div>无标签</div>;
|
||||
};
|
||||
@@ -235,9 +239,7 @@ export const GroupIcon: React.FC<IGroupIcon> = (props) => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
) : null;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
@@ -1,19 +1,17 @@
|
||||
import { groupStatus } from '@/services/config';
|
||||
import { DownOutlined, UpOutlined } from '@ant-design/icons';
|
||||
import { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { IGroup } from './ChatLogsType';
|
||||
import { GroupIcon } from './ChatUtils';
|
||||
import styles from './index.module.scss';
|
||||
type IGroupAvatar = {
|
||||
avatar: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
type IProps = {
|
||||
groupList: IGroup[];
|
||||
searchWord: string;
|
||||
selectGroup: IGroup | undefined;
|
||||
onClick: Function;
|
||||
groupAvatar: {};
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onClick: (arg0: IGroup) => any;
|
||||
groupAvatar: any;
|
||||
};
|
||||
|
||||
type IGroupObj = {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
interface IProps {
|
||||
msg_type: string;
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
import { ChatAgreeOrNot } from './ChatAgreeOrNot';
|
||||
import { ChatCard } from './ChatCard';
|
||||
@@ -26,50 +27,50 @@ export const ChatBar: React.FC<IChatItem> = (props) => {
|
||||
|
||||
const chatContent = () => {
|
||||
if (chat?.msg_type == 'text') {
|
||||
return <ChatText from={from} to={to} chat={chat}></ChatText>;
|
||||
return <ChatText from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'file') {
|
||||
return <ChatFile from={from} to={to} chat={chat}></ChatFile>;
|
||||
return <ChatFile from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'emotion') {
|
||||
return <ChatEmotion from={from} to={to} chat={chat}></ChatEmotion>;
|
||||
return <ChatEmotion from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'card') {
|
||||
return <ChatCard from={from} to={to} chat={chat}></ChatCard>;
|
||||
return <ChatCard from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'external_redpacket' || chat?.msg_type == 'redpacket') {
|
||||
return <ChatRedpacket from={from} to={to} chat={chat}></ChatRedpacket>;
|
||||
return <ChatRedpacket from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'image') {
|
||||
return <ChatImage from={from} to={to} chat={chat}></ChatImage>;
|
||||
return <ChatImage from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'link') {
|
||||
return <ChatLink from={from} to={to} chat={chat}></ChatLink>;
|
||||
return <ChatLink from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'location') {
|
||||
return <ChatLocation from={from} to={to} chat={chat}></ChatLocation>;
|
||||
return <ChatLocation from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'video') {
|
||||
return <ChatVideo from={from} to={to} chat={chat}></ChatVideo>;
|
||||
return <ChatVideo from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'voice') {
|
||||
return <ChatVoice from={from} to={to} chat={chat}></ChatVoice>;
|
||||
return <ChatVoice from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'chatrecord') {
|
||||
return <ChatRecord from={from} to={to} chat={chat}></ChatRecord>;
|
||||
return <ChatRecord from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'meeting_voice_call') {
|
||||
return <ChatMeetingVoiceCall from={from} to={to} chat={chat}></ChatMeetingVoiceCall>;
|
||||
return <ChatMeetingVoiceCall from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'voiptext') {
|
||||
return <ChatVoiptext from={from} to={to} chat={chat}></ChatVoiptext>;
|
||||
return <ChatVoiptext from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'weapp') {
|
||||
return <ChatWeapp from={from} to={to} chat={chat}></ChatWeapp>;
|
||||
return <ChatWeapp from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'todo') {
|
||||
return <ChatTodo from={from} to={to} chat={chat}></ChatTodo>;
|
||||
return <ChatTodo from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'vote') {
|
||||
return <ChatVote from={from} to={to} chat={chat}></ChatVote>;
|
||||
return <ChatVote from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'collect') {
|
||||
return <ChatCollect from={from} to={to} chat={chat}></ChatCollect>;
|
||||
return <ChatCollect from={from} to={to} chat={chat} />;
|
||||
} else if (chat?.msg_type == 'docmsg') {
|
||||
return <ChatDocmsg from={from} to={to} chat={chat}></ChatDocmsg>;
|
||||
return <ChatDocmsg from={from} to={to} chat={chat} />;
|
||||
} else {
|
||||
return <>未解析的数据类型</>;
|
||||
}
|
||||
};
|
||||
|
||||
if (chat?.msg_type == 'revoke') {
|
||||
return <ChatRevoke></ChatRevoke>;
|
||||
return <ChatRevoke />;
|
||||
} else if (chat?.msg_type == 'agree' || chat?.msg_type == 'disagree') {
|
||||
return <ChatAgreeOrNot msg_type={chat?.msg_type}></ChatAgreeOrNot>;
|
||||
return <ChatAgreeOrNot msg_type={chat?.msg_type} />;
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
|
@@ -1,18 +1,7 @@
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
export const ChatCard: React.FC<IChatItem> = (props) => {
|
||||
function content() {
|
||||
// <div style={{ display: 'flex' }}>
|
||||
// <div className={styles.chatAvatar} style={{ marginRight: 12 }}>
|
||||
// <img
|
||||
// src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg"
|
||||
// alt=""
|
||||
// />
|
||||
// </div>
|
||||
// <div className={styles.corpname}>腾讯</div>
|
||||
// </div>
|
||||
// <div>corpname</div>
|
||||
// <div style={{ color: '#999' }}>corpname2</div>
|
||||
// <div style={{ color: '#999', borderTop: '1px solid #ddd' }}>个人名片</div>
|
||||
try {
|
||||
const msg = JSON.parse(props.chat?.content as string);
|
||||
return (
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatCollect: React.FC<IChatItem> = (props) => {
|
||||
function content() {
|
||||
try {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatDocmsg: React.FC<IChatItem> = (props) => {
|
||||
@@ -5,7 +6,7 @@ export const ChatDocmsg: React.FC<IChatItem> = (props) => {
|
||||
try {
|
||||
const msg = JSON.parse(props.chat?.doc as string);
|
||||
return (
|
||||
<a href={msg.link_url} target="_blank">
|
||||
<a href={msg.link_url} target="_blank" rel="noreferrer">
|
||||
<div style={{ display: 'flex', color: '#000', flexDirection: 'column' }}>
|
||||
<div style={{ wordBreak: 'break-all' }}>标题:{msg.title}</div>
|
||||
<div style={{ wordBreak: 'break-all' }}>链接:{msg.link_url}</div>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { FileTextFilled } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatFile: React.FC<IChatItem> = (props) => {
|
||||
|
@@ -1,8 +1,7 @@
|
||||
import { Image } from 'antd';
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
import styles from './index.module.scss';
|
||||
|
||||
export const ChatImage: React.FC<IChatItem> = (props) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
function content() {
|
||||
@@ -23,7 +22,7 @@ export const ChatImage: React.FC<IChatItem> = (props) => {
|
||||
<Image
|
||||
preview={{
|
||||
visible: visible,
|
||||
onVisibleChange: (value, prevValue, currentIndex) => {
|
||||
onVisibleChange: (value) => {
|
||||
setVisible(value);
|
||||
},
|
||||
}}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { IeSquareFilled } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatLink: React.FC<IChatItem> = (props) => {
|
||||
@@ -11,7 +12,7 @@ export const ChatLink: React.FC<IChatItem> = (props) => {
|
||||
<div style={{ wordBreak: 'break-all', paddingRight: 8 }}>
|
||||
<div>{msg.title}</div>
|
||||
<div>{msg.description}</div>
|
||||
<a href={msg.link_url} target="_blank">
|
||||
<a href={msg.link_url} target="_blank" rel="noreferrer">
|
||||
{msg.link_url}
|
||||
</a>
|
||||
</div>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { EnvironmentFilled } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatLocation: React.FC<IChatItem> = (props) => {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatMeetingVoiceCall: React.FC<IChatItem> = (props) => {
|
||||
@@ -18,7 +19,7 @@ export const ChatMeetingVoiceCall: React.FC<IChatItem> = (props) => {
|
||||
});
|
||||
}
|
||||
}}
|
||||
></audio>
|
||||
/>
|
||||
);
|
||||
} catch (e) {
|
||||
return <div style={{ wordBreak: 'break-all' }}>{props.chat?.content}</div>;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { Modal } from 'antd';
|
||||
import { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
import { EmojiFormat } from './EmojiFormat';
|
||||
|
||||
@@ -45,7 +45,9 @@ export const ChatRecord: React.FC<IChatItem> = (props) => {
|
||||
try {
|
||||
const msg = JSON.parse(props.chat?.content as string);
|
||||
setRecord(msg);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
}, [props.chat]);
|
||||
|
||||
function content() {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { RedEnvelopeFilled } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatRedpacket: React.FC<IChatItem> = (props) => {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
export const ChatRevoke: React.FC = () => {
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: 12 }}>
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
import { EmojiFormat } from './EmojiFormat';
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
interface IChatTimeProps {
|
||||
msgtime: string;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatTodo: React.FC<IChatItem> = (props) => {
|
||||
function content() {
|
||||
return (
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import { CloseOutlined, PlayCircleOutlined } from '@ant-design/icons';
|
||||
|
||||
import { useRef, useState } from 'react';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
import styles from './index.module.scss';
|
||||
|
||||
export const ChatVideo: React.FC<IChatItem> = (props) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const videoRef = useRef<any>();
|
||||
@@ -36,7 +35,7 @@ export const ChatVideo: React.FC<IChatItem> = (props) => {
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
videoRef.current.play().catch((error) => {
|
||||
videoRef.current.play().catch((error: any) => {
|
||||
console.log(error);
|
||||
});
|
||||
}, 100);
|
||||
@@ -58,7 +57,7 @@ export const ChatVideo: React.FC<IChatItem> = (props) => {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
videoRef.current.pause();
|
||||
}}
|
||||
@@ -81,7 +80,7 @@ export const ChatVideo: React.FC<IChatItem> = (props) => {
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
></video>
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@@ -1,15 +1,17 @@
|
||||
import { FileTextFilled } from '@ant-design/icons';
|
||||
import { useRef, useState } from 'react';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatVoice: React.FC<IChatItem> = (props) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const audioRef = useRef<any>();
|
||||
function readBlob(blob: Blob, callback: Function) {
|
||||
function readBlob(blob: Blob, callback: any) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
const data = new Uint8Array(e.target.result);
|
||||
callback(data);
|
||||
if (e.target && e.target.result) {
|
||||
const data = new Uint8Array(e.target.result as ArrayBuffer);
|
||||
callback(data);
|
||||
}
|
||||
};
|
||||
reader.readAsArrayBuffer(blob);
|
||||
}
|
||||
@@ -42,8 +44,8 @@ export const ChatVoice: React.FC<IChatItem> = (props) => {
|
||||
let blob = new Blob([res]);
|
||||
readBlob(blob, function (data: any) {
|
||||
if (window.AMR) {
|
||||
var buffer = window.AMR.toWAV(data);
|
||||
var url = URL.createObjectURL(new Blob([buffer], { type: 'audio/x-wav' }));
|
||||
let buffer = window.AMR.toWAV(data);
|
||||
let url = URL.createObjectURL(new Blob([buffer], { type: 'audio/x-wav' }));
|
||||
audioRef.current.src = url;
|
||||
audioRef.current.play().catch((err: any) => {
|
||||
console.log(err);
|
||||
@@ -60,20 +62,20 @@ export const ChatVoice: React.FC<IChatItem> = (props) => {
|
||||
}}
|
||||
>
|
||||
<span style={{ lineHeight: 1, marginRight: 4, minWidth: 100, textAlign: 'right' }}>
|
||||
{msg.play_length}"
|
||||
{msg.play_length}"
|
||||
</span>
|
||||
<svg viewBox="0 0 1024 1024" width="18" height="18">
|
||||
<path
|
||||
d="M913.568627 518.334145C913.568627 483.422393 894.958532 451.162604 864.748584 433.706729 834.538616 416.250852 797.318425 416.250852 767.108477 433.706729 736.89851 451.162604 718.288414 483.422393 718.288414 518.334145 718.288414 553.245895 736.89851 585.505684 767.108477 602.961559 797.318425 620.417436 834.538616 620.417436 864.748584 602.961559 894.958532 585.505684 913.568627 553.245895 913.568627 518.334145L913.568627 518.334145ZM581.566143 215.288946C581.566143 215.288946 593.269057 203.098427 620.669932 203.098427 650.6546 203.098427 674.950626 227.414165 674.950626 257.423171 674.950626 290.452615 648.917554 305.250663 636.758739 309.031723 568.451875 353.599725 523.116685 430.436655 523.116685 518.116824 523.116685 605.970743 568.603889 682.938067 637.149606 727.440872 650.915177 731.852057 674.950626 743.064634 674.950626 778.940765 674.950626 808.949772 650.6546 833.265507 620.669932 833.265507 593.269057 833.265507 581.566143 821.07499 581.566143 821.07499 481.233659 757.536806 414.403283 645.801687 414.403283 518.181916 414.403283 390.562145 481.233659 278.805502 581.566143 215.288946L581.566143 215.288946ZM348.376225 14.135304C348.376225 14.135304 365.941399 7.529394 392.690949 7.529394 428.668185 7.529394 457.82781 36.73442 457.82781 72.719107 457.82781 98.186537 406.282822 128.195544 388.54391 137.474179 297.265513 229.695819 240.704994 356.381112 240.704994 496.452082 240.704994 650.321426 309.055287 787.849957 416.661363 881.418878 440.740242 890.980031 457.82781 914.426591 457.82781 941.914889 457.82781 977.899576 428.668185 1007.104602 392.690949 1007.104602 363.314276 1007.104602 345.336511 998.13011 345.336511 998.13011 202.12236 882.635664 110.431373 705.732666 110.431373 507.316947 110.431373 307.532423 203.446734 129.564556 348.376225 14.135304L348.376225 14.135304Z"
|
||||
fill="#000000"
|
||||
></path>
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<audio
|
||||
controls
|
||||
style={{ display: open ? 'block' : 'none', marginTop: 8 }}
|
||||
ref={audioRef}
|
||||
></audio>
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} catch (_e) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { durationFormat } from '@/services/utils';
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatVoiptext: React.FC<IChatItem> = (props) => {
|
||||
const invitetype: any = {
|
||||
'1': '单人视频通话',
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { SignalFilled } from '@ant-design/icons';
|
||||
import { Modal } from 'antd';
|
||||
import { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
import styles from './index.module.scss';
|
||||
|
||||
@@ -13,7 +13,9 @@ export const ChatVote: React.FC<IChatItem> = (props) => {
|
||||
try {
|
||||
const msg = JSON.parse(props.chat?.content as string);
|
||||
setVoteitem(msg?.voteitem);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
}, [props.chat]);
|
||||
|
||||
function content() {
|
||||
@@ -70,7 +72,9 @@ export const ChatVote: React.FC<IChatItem> = (props) => {
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', color: '#000', flexDirection: 'column' }}>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { IChatItem } from '../ChatLogsType';
|
||||
|
||||
export const ChatWeapp: React.FC<IChatItem> = (props) => {
|
||||
function content() {
|
||||
try {
|
||||
@@ -9,7 +9,7 @@ export const ChatWeapp: React.FC<IChatItem> = (props) => {
|
||||
return (
|
||||
<div style={{ display: 'flex', color: '#000' }}>
|
||||
<svg viewBox="0 0 1024 1024" width="40" height="40">
|
||||
<path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m256.717 460.186a151.962 151.962 0 0 1-87.347 65.74 83.251 83.251 0 0 1-24.474 4.096 29.082 29.082 0 0 1 0-58.163 15.667 15.667 0 0 0 6.451-1.229 91.443 91.443 0 0 0 55.91-40.96 75.264 75.264 0 0 0 11.06-39.628c0-45.978-42.496-83.866-94.31-83.866a105.267 105.267 0 0 0-51.2 13.414 81.92 81.92 0 0 0-43.725 70.452v244.224a138.445 138.445 0 0 1-72.704 120.422 159.642 159.642 0 0 1-79.77 20.48c-84.378 0-153.6-63.488-153.6-142.029a136.192 136.192 0 0 1 19.763-69.837 151.962 151.962 0 0 1 87.347-65.74 85.914 85.914 0 0 1 24.474-4.096 29.082 29.082 0 1 1 0 58.163 15.667 15.667 0 0 0-6.451 1.229 95.949 95.949 0 0 0-55.91 40.96 75.264 75.264 0 0 0-11.06 39.628c0 45.978 42.496 83.866 94.925 83.866a105.267 105.267 0 0 0 51.2-13.414 81.92 81.92 0 0 0 43.622-70.452V390.35a138.752 138.752 0 0 1 72.807-120.525 151.245 151.245 0 0 1 79.155-21.504c84.378 0 153.6 63.488 153.6 142.029a136.192 136.192 0 0 1-19.763 69.837z"></path>
|
||||
<path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m256.717 460.186a151.962 151.962 0 0 1-87.347 65.74 83.251 83.251 0 0 1-24.474 4.096 29.082 29.082 0 0 1 0-58.163 15.667 15.667 0 0 0 6.451-1.229 91.443 91.443 0 0 0 55.91-40.96 75.264 75.264 0 0 0 11.06-39.628c0-45.978-42.496-83.866-94.31-83.866a105.267 105.267 0 0 0-51.2 13.414 81.92 81.92 0 0 0-43.725 70.452v244.224a138.445 138.445 0 0 1-72.704 120.422 159.642 159.642 0 0 1-79.77 20.48c-84.378 0-153.6-63.488-153.6-142.029a136.192 136.192 0 0 1 19.763-69.837 151.962 151.962 0 0 1 87.347-65.74 85.914 85.914 0 0 1 24.474-4.096 29.082 29.082 0 1 1 0 58.163 15.667 15.667 0 0 0-6.451 1.229 95.949 95.949 0 0 0-55.91 40.96 75.264 75.264 0 0 0-11.06 39.628c0 45.978 42.496 83.866 94.925 83.866a105.267 105.267 0 0 0 51.2-13.414 81.92 81.92 0 0 0 43.622-70.452V390.35a138.752 138.752 0 0 1 72.807-120.525 151.245 151.245 0 0 1 79.155-21.504c84.378 0 153.6 63.488 153.6 142.029a136.192 136.192 0 0 1-19.763 69.837z" />
|
||||
</svg>
|
||||
<div style={{ wordBreak: 'break-all', paddingLeft: 12, minWidth: 100 }}>
|
||||
<div>{msg.title}</div>
|
||||
@@ -21,7 +21,7 @@ export const ChatWeapp: React.FC<IChatItem> = (props) => {
|
||||
return (
|
||||
<div>
|
||||
<svg viewBox="0 0 1024 1024" width="40" height="40">
|
||||
<path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m256.717 460.186a151.962 151.962 0 0 1-87.347 65.74 83.251 83.251 0 0 1-24.474 4.096 29.082 29.082 0 0 1 0-58.163 15.667 15.667 0 0 0 6.451-1.229 91.443 91.443 0 0 0 55.91-40.96 75.264 75.264 0 0 0 11.06-39.628c0-45.978-42.496-83.866-94.31-83.866a105.267 105.267 0 0 0-51.2 13.414 81.92 81.92 0 0 0-43.725 70.452v244.224a138.445 138.445 0 0 1-72.704 120.422 159.642 159.642 0 0 1-79.77 20.48c-84.378 0-153.6-63.488-153.6-142.029a136.192 136.192 0 0 1 19.763-69.837 151.962 151.962 0 0 1 87.347-65.74 85.914 85.914 0 0 1 24.474-4.096 29.082 29.082 0 1 1 0 58.163 15.667 15.667 0 0 0-6.451 1.229 95.949 95.949 0 0 0-55.91 40.96 75.264 75.264 0 0 0-11.06 39.628c0 45.978 42.496 83.866 94.925 83.866a105.267 105.267 0 0 0 51.2-13.414 81.92 81.92 0 0 0 43.622-70.452V390.35a138.752 138.752 0 0 1 72.807-120.525 151.245 151.245 0 0 1 79.155-21.504c84.378 0 153.6 63.488 153.6 142.029a136.192 136.192 0 0 1-19.763 69.837z"></path>
|
||||
<path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m256.717 460.186a151.962 151.962 0 0 1-87.347 65.74 83.251 83.251 0 0 1-24.474 4.096 29.082 29.082 0 0 1 0-58.163 15.667 15.667 0 0 0 6.451-1.229 91.443 91.443 0 0 0 55.91-40.96 75.264 75.264 0 0 0 11.06-39.628c0-45.978-42.496-83.866-94.31-83.866a105.267 105.267 0 0 0-51.2 13.414 81.92 81.92 0 0 0-43.725 70.452v244.224a138.445 138.445 0 0 1-72.704 120.422 159.642 159.642 0 0 1-79.77 20.48c-84.378 0-153.6-63.488-153.6-142.029a136.192 136.192 0 0 1 19.763-69.837 151.962 151.962 0 0 1 87.347-65.74 85.914 85.914 0 0 1 24.474-4.096 29.082 29.082 0 1 1 0 58.163 15.667 15.667 0 0 0-6.451 1.229 95.949 95.949 0 0 0-55.91 40.96 75.264 75.264 0 0 0-11.06 39.628c0 45.978 42.496 83.866 94.925 83.866a105.267 105.267 0 0 0 51.2-13.414 81.92 81.92 0 0 0 43.622-70.452V390.35a138.752 138.752 0 0 1 72.807-120.525 151.245 151.245 0 0 1 79.155-21.504c84.378 0 153.6 63.488 153.6 142.029a136.192 136.192 0 0 1-19.763 69.837z" />
|
||||
</svg>
|
||||
<div style={{ wordBreak: 'break-all', paddingLeft: 12 }}>{props.chat?.content}</div>
|
||||
</div>
|
||||
|
@@ -23,7 +23,7 @@ export const EmojiFormat: React.FC<IProps> = (props) => {
|
||||
return (
|
||||
<>
|
||||
{typeof props.content === 'string' ? (
|
||||
<div dangerouslySetInnerHTML={{ __html: format() }}></div>
|
||||
<div dangerouslySetInnerHTML={{ __html: format() }} />
|
||||
) : (
|
||||
props.content
|
||||
)}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
type IProps = {
|
||||
gender: string | undefined | number;
|
||||
};
|
||||
@@ -12,7 +13,7 @@ export const Gender: React.FC<IProps> = (props) => {
|
||||
<path
|
||||
d="M828.875 765.657c-191.159-16.86-202.516-102.922-202.516-102.922v-85.997c111.656-43.063 145.76-207.699 145.76-207.699 0-65.457-32.153-67.281-32.153-67.281V195.093c7.486-177.753-100.33-136.61-102.25-136.61-1.791 0-60.466-46.774-60.466-46.774-41.751-31.8-134.499 11.262-134.499 11.262l-3.839 0.064c-104.937 2.751-132.387 78.479-132.387 78.479l1.92 196.437c-54.804 0-47.35 76.719-47.35 76.719 0 84.142 147.616 200.148 147.616 200.148 9.47 110.472-49.174 166.46-49.174 166.46s-100.266 3.711-213.84 37.432c-2.72 0.863-5.344 1.6-7.967 2.463C30.617 817.421 0 920.855 0 920.855v101.033l463.579 1.888 68.465-1.92h491.732V943.25c1.92-115.815-194.901-177.593-194.901-177.593z m-244.65 129.22l-71.25 128.675-69.616-128.676-16.124-64.05 30.68-136.354h111.656l29.178 136.354-14.525 64.05z"
|
||||
fill="#1890ff"
|
||||
></path>
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
) : (
|
||||
@@ -21,7 +22,7 @@ export const Gender: React.FC<IProps> = (props) => {
|
||||
<path
|
||||
d="M613.312 626.496v-11.2h151.296V318.08c0-124.736-113.152-225.856-252.608-225.856S259.392 193.344 259.392 318.08v297.216h151.36v11.072h-0.256L115.648 820.16v107.136H908.48v-105.92l-295.168-194.88z m7.68 186.752c-72.192 69.824-109.504-36.416-109.504-36.416s-37.312 106.24-109.568 36.416c0 0-31.744-20.544-35.136-158.208l144.704 121.728L656.192 655.04c-3.392 137.6-35.2 158.208-35.2 158.208z"
|
||||
fill="#1890ff"
|
||||
></path>
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
)}
|
||||
@@ -32,7 +33,7 @@ export const Gender: React.FC<IProps> = (props) => {
|
||||
<path
|
||||
d="M880.864 704.346c-56.813-25.397-141.118-90.818-265.945-113.298 31.924-34.36 56.084-88.097 80.937-151.754 14.403-36.893 11.935-68.343 11.935-113.121 0-33.073 6.193-86.156-1.97-115.329-27.533-98.59-97.1-125.79-178.61-125.79-81.577 0-151.229 27.328-178.71 126.087-8.097 29.083-1.888 82.044-1.888 115.037 0 44.875-2.422 76.432 12.019 113.383 25.044 63.984 48.854 117.644 80.655 151.86-123.826 22.89-207.498 87.822-263.95 113.138C58.523 756.945 57.95 814.296 57.95 814.296v97.42l940.724-0.112v-97.308s-0.547-57.548-117.809-109.95z"
|
||||
fill="#1890ff"
|
||||
></path>
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
)}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
export const OwnerSvg = () => {
|
||||
import React from 'react';
|
||||
export const OwnerSvg: React.FC = () => {
|
||||
return (
|
||||
<span
|
||||
title="群主"
|
||||
@@ -14,13 +15,13 @@ export const OwnerSvg = () => {
|
||||
<path
|
||||
d="M880.864 704.346c-56.813-25.397-141.118-90.818-265.945-113.298 31.924-34.36 56.084-88.097 80.937-151.754 14.403-36.893 11.935-68.343 11.935-113.121 0-33.073 6.193-86.156-1.97-115.329-27.533-98.59-97.1-125.79-178.61-125.79-81.577 0-151.229 27.328-178.71 126.087-8.097 29.083-1.888 82.044-1.888 115.037 0 44.875-2.422 76.432 12.019 113.383 25.044 63.984 48.854 117.644 80.655 151.86-123.826 22.89-207.498 87.822-263.95 113.138C58.523 756.945 57.95 814.296 57.95 814.296v97.42l940.724-0.112v-97.308s-0.547-57.548-117.809-109.95z"
|
||||
fill="#f4ea2a"
|
||||
></path>
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export const AdminSvg = () => {
|
||||
export const AdminSvg: React.FC = () => {
|
||||
return (
|
||||
<span
|
||||
title="管理员"
|
||||
@@ -36,7 +37,7 @@ export const AdminSvg = () => {
|
||||
<path
|
||||
d="M880.864 704.346c-56.813-25.397-141.118-90.818-265.945-113.298 31.924-34.36 56.084-88.097 80.937-151.754 14.403-36.893 11.935-68.343 11.935-113.121 0-33.073 6.193-86.156-1.97-115.329-27.533-98.59-97.1-125.79-178.61-125.79-81.577 0-151.229 27.328-178.71 126.087-8.097 29.083-1.888 82.044-1.888 115.037 0 44.875-2.422 76.432 12.019 113.383 25.044 63.984 48.854 117.644 80.655 151.86-123.826 22.89-207.498 87.822-263.95 113.138C58.523 756.945 57.95 814.296 57.95 814.296v97.42l940.724-0.112v-97.308s-0.547-57.548-117.809-109.95z"
|
||||
fill="#1890ff"
|
||||
></path>
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
);
|
||||
|
@@ -240,14 +240,14 @@ const CustomList: React.FC = () => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Image width={56} height={56} src={record.avatar}></Image>
|
||||
<Image width={56} height={56} src={record.avatar} />
|
||||
</div>
|
||||
<div style={{ marginLeft: 8 }}>
|
||||
<div style={{ color: '#1890ff', wordBreak: 'break-all' }}>
|
||||
{value}[{record.remark}]
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Gender gender={record.gender}></Gender>
|
||||
<Gender gender={record.gender} />
|
||||
<span style={{ marginLeft: 4, color: '#389e0d' }}>
|
||||
@{CustType[record.type]}
|
||||
</span>
|
||||
@@ -337,7 +337,9 @@ const CustomList: React.FC = () => {
|
||||
</>
|
||||
);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
return <div style={{ marginBottom: 4 }}>无标签</div>;
|
||||
}}
|
||||
dataIndex={'tags'}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { IStaffsItem } from '@/pages/ChatLogs/ChatLogsType';
|
||||
import { Gender } from '@/pages/ChatLogs/components/Gender';
|
||||
import { Image } from 'antd';
|
||||
import React from 'react';
|
||||
import styles from '../index.module.scss';
|
||||
|
||||
type IProps = {
|
||||
record: IStaffsItem;
|
||||
};
|
||||
@@ -23,7 +23,7 @@ export const DepartmentMembersDetail: React.FC<IProps> = (props) => {
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div style={{ marginRight: 12 }}>
|
||||
{record?.avatar ? (
|
||||
<Image width={80} height={80} style={{ borderRadius: 4 }} src={record.avatar}></Image>
|
||||
<Image width={80} height={80} style={{ borderRadius: 4 }} src={record.avatar} />
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
@@ -44,12 +44,12 @@ export const DepartmentMembersDetail: React.FC<IProps> = (props) => {
|
||||
<div style={{ marginRight: 32 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<span style={{ marginRight: 8, fontSize: 18 }}>{record?.name}</span>
|
||||
<Gender gender={record?.gender}></Gender>
|
||||
<Gender gender={record?.gender} />
|
||||
</div>
|
||||
<div>别名:{fomatStr(record?.alias)}</div>
|
||||
</div>
|
||||
{record?.qr_code ? (
|
||||
<Image width={80} height={80} style={{ borderRadius: 4 }} src={record.qr_code}></Image>
|
||||
<Image width={80} height={80} style={{ borderRadius: 4 }} src={record.qr_code} />
|
||||
) : null}
|
||||
</div>
|
||||
<div style={{ marginTop: 24, borderTop: '1px solid #ddd', paddingTop: 24 }}>
|
||||
|
@@ -320,7 +320,7 @@ const DepartmentsList: React.FC = () => {
|
||||
</Button>
|
||||
</Row>
|
||||
}
|
||||
></SearchBarPlugin>
|
||||
/>
|
||||
|
||||
<Table
|
||||
tableLayout="fixed"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { IGroup, IGroupMembers } from '@/pages/ChatLogs/ChatLogsType';
|
||||
import { post } from '@/services/ajax';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import {
|
||||
adminList,
|
||||
@@ -23,11 +23,6 @@ export const GroupDetailContent: React.FC<Iprops> = (props) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const groupMembersObjRef = useRef<any>({});
|
||||
|
||||
useEffect(() => {
|
||||
record.adminUserIDs = getAdminList(record.admin_list);
|
||||
getList();
|
||||
}, [props.record]);
|
||||
|
||||
const getList = () => {
|
||||
setLoading(true);
|
||||
post({
|
||||
@@ -59,6 +54,11 @@ export const GroupDetailContent: React.FC<Iprops> = (props) => {
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
record.adminUserIDs = getAdminList(record.admin_list);
|
||||
getList();
|
||||
}, [props.record]);
|
||||
|
||||
return (
|
||||
<Spin spinning={loading} style={{ minHeight: 400, display: 'block' }}>
|
||||
{groupMembersList.length ? (
|
||||
|
@@ -101,7 +101,7 @@ const Login: React.FC = () => {
|
||||
}}
|
||||
logo={<img alt="logo" src="/logo.svg" />}
|
||||
title="scrm.antd"
|
||||
subTitle={<div style={{ height: 30 }}></div>}
|
||||
subTitle={<div style={{ height: 30 }} />}
|
||||
initialValues={{
|
||||
autoLogin: true,
|
||||
}}
|
||||
@@ -268,7 +268,7 @@ const Login: React.FC = () => {
|
||||
</LoginForm>
|
||||
</div>
|
||||
<Footer />
|
||||
<div style={{ height: 12 }}></div>
|
||||
<div style={{ height: 12 }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@@ -20,7 +20,7 @@ export const DataItemCard: React.FC<IProps> = (props) => {
|
||||
</Popover>
|
||||
</div>
|
||||
<div className={styles.dataCount}>
|
||||
<CountUp end={props.count} duration={2}></CountUp>
|
||||
<CountUp end={props.count} duration={2} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
interface IGetDevice {
|
||||
(): 'phone' | 'tablet' | 'desktop';
|
||||
}
|
||||
|
Reference in New Issue
Block a user