oak-general-business/src/components/user/info/web.tsx

288 lines
9.4 KiB
TypeScript

import React, { RefObject } from 'react';
import {
List,
DatePicker,
Tag,
Button,
Input,
Radio,
Space,
} from 'antd-mobile';
import ExtraFileCommit from '../../extraFile/commit';
import dayjs from 'dayjs';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import OakAvatar from '../../../components/extraFile/avatar';
import Style from './mobile.module.less';
type DataProps = {
visible: boolean;
nickname: string;
name: string;
birth: string;
gender: string;
mobile: string;
genderOptions: Array<{ label: string; value: 'male' | 'female' }>;
attrs: Record<string, string>;
id: string;
refreshing: boolean;
canSyncWechat: boolean;
appId: string;
editAttr: string;
executable: boolean | Error;
nnDirty: boolean;
nameDirty: boolean;
birthDirty: boolean;
genderDirty: boolean;
userStateStr: string;
userStateColor: string;
idStateStr: string;
idStateColor: string;
idState: EntityDict['user']['Schema']['idState'];
isCreation: boolean;
authenticateUrl: string;
changeMobileUrl: string,
changePasswordUrl: string,
editable: boolean;
};
type MethodsProps = {
editMobile: () => void;
editPassword: () => void;
goAuthenticate: () => void;
setAvatar: () => void;
refreshWechatPublicUserInfo: () => void;
editNickname: () => void;
editName: () => void;
editGender: () => void;
cancelEdit: () => void;
editBirth: () => void;
};
export default function render(
props: WebComponentProps<EntityDict, 'user', false, DataProps, MethodsProps>
) {
const { data, methods } = props;
const {
t,
clean,
editMobile,
goAuthenticate,
refreshWechatPublicUserInfo,
editPassword,
editNickname,
editName,
editGender,
cancelEdit,
update,
editBirth,
execute,
} = methods;
const {
oakFullpath,
executable,
nickname,
name,
birth,
gender,
mobile,
isCreation,
id,
canSyncWechat,
refreshing,
editAttr,
genderOptions,
oakDirty,
nnDirty,
birthDirty,
nameDirty,
genderDirty,
userStateColor,
userStateStr,
idStateColor,
idStateStr,
idState,
editable,
changeMobileUrl,
changePasswordUrl,
authenticateUrl,
} = data;
return (
<div className={Style.container}>
<div
className={Style['avatar_container']}
>
<OakAvatar
oakAutoUnmount={true}
oakPath={oakFullpath + '.extraFile$entity'}
entity="user"
entityId={id}
autoUpload={true}
/>
</div>
<List className={Style.list}>
<List.Item
extra={editAttr !== 'nickname' ? (
<div className={nnDirty ? Style.dirty : undefined}>
{nickname ? nickname : t('unset')}
</div>
) : (
<Input
disabled={!editable}
placeholder={t('placeholder.nickname')}
autoFocus
value={nickname}
onChange={(value) => update({
nickname: value,
})}
onBlur={() => cancelEdit()}
onEnterPress={() => cancelEdit()}
/>
)}
onClick={editAttr === 'nickname' ? undefined : () => editNickname()}
>
{t('user:attr.nickname')}
</List.Item>
<List.Item
extra={editAttr !== 'name' ? (
<div className={nameDirty ? Style.dirty : undefined}>
{name ? name : t('unset')}
</div>
) : (
<Input
disabled={!editable}
placeholder={t('placeholder.name')}
autoFocus
value={name}
onChange={(value) => update({
name: value,
})}
onBlur={() => cancelEdit()}
onEnterPress={() => cancelEdit()}
/>
)}
onClick={editAttr === 'name' ? undefined : () => editName()}
clickable={editable && idState !== 'verified'}
>
{t('user:attr.name')}
</List.Item>
<List.Item
extra={editAttr !== 'gender' ? (
<div className={genderDirty ? Style.dirty : undefined}>
{gender ? t(`user:v.gender.${gender}`) : t('unset')}
</div>
) : (
<Radio.Group
disabled={!editable}
value={gender}
onChange={(value) => {
update({
gender: value as 'male',
});
cancelEdit();
}}
>
<Space
direction="horizontal"
>
{genderOptions.map(
(ele: { value: string; label: string }) => (
<Radio key={ele.value} value={ele.value}>
{ele.label}
</Radio>
)
)}
</Space>
</Radio.Group>
)}
onClick={editAttr === 'gender' ? undefined : () => editGender()}
clickable={editable && idState !== 'verified'}
>
{t('user:attr.gender')}
</List.Item>
<List.Item
extra={
<div className={birthDirty ? Style.dirty : undefined}>
{birth ? dayjs(birth).format('YYYY-MM-DD') : t('unset')}
</div>
}
onClick={editAttr === 'birth' ? undefined : () => editBirth()}
clickable={editable && idState !== 'verified'}
>
{t('user:attr.birth')}
</List.Item>
{!isCreation && !changeMobileUrl && <List.Item
extra={mobile ? mobile : t('unset')}
onClick={() => {
editMobile();
}}
>
{t('mobile')}
</List.Item>}
{!isCreation && !!changePasswordUrl && <List.Item
extra={'********'}
onClick={() => {
editPassword();
}}
>
{t('password')}
</List.Item>}
<List.Item
extra={
<Tag fill="outline" color={userStateColor}>
{userStateStr}
</Tag>
}
>
{t('user:attr.userState')}
</List.Item>
{!isCreation && !authenticateUrl && <List.Item
extra={
<Tag fill="outline" color={idStateColor}>
{idStateStr}
</Tag>
}
onClick={() => goAuthenticate()}
>
{t('user:attr.idState')}
</List.Item>}
</List>
<DatePicker
visible={editAttr === 'birth'}
onClose={() => cancelEdit()}
precision='day'
min={new Date('1900-01-01')}
max={new Date()}
value={new Date(birth)}
onConfirm={(value) => {
update({
birth: dayjs(value).startOf('day').valueOf(),
});
}}
/>
<div className={Style.btnContainer}>
{!oakDirty && canSyncWechat && editable && <Button
className={Style.syncWechat}
block
onClick={() => refreshWechatPublicUserInfo()}
>
{t('syncWeChat')}
</Button>}
{executable === true && <ExtraFileCommit
buttonProps={{
color: 'primary',
block: true,
}}
oakPath={oakFullpath}
entity="user"
/>}
</div>
</div>
);
}