@ant-design/icons#UserOutlined TypeScript Examples
The following examples show how to use
@ant-design/icons#UserOutlined.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MobileUserMenu.tsx From condo with MIT License | 6 votes |
MobileUserMenu: React.FC = () => {
const intl = useIntl()
const SignInMessage = intl.formatMessage({ id: 'SignIn' })
const auth = useAuth()
const [showModal, setShowModal] = useState(false)
const modalView = useCallback(() => <ModalView setShowModal={setShowModal} />, [setShowModal])
return (
auth.isAuthenticated
? (
<>
<Button
type={'inlineLink'}
icon={<Avatar size={40} icon={<UserOutlined />} />}
onClick={() => setShowModal(true)}
/>
<Modal
transitionName=""
centered
visible={showModal}
modalRender={modalView}
style={modalStyle}
onCancel={()=> setShowModal(false)}
/>
</>
)
: <Button type='inlineLink' onClick={goToSignin}>{SignInMessage}</Button>
)
}
Example #2
Source File: personalizationOptions.tsx From posthog-foss with MIT License | 6 votes |
TEAM_SIZES: RadioSelectType[] = [
{
key: 'me',
label: 'Just me',
icon: <UserOutlined />,
},
{
key: '1_10',
label: '1 - 10',
icon: <TeamOutlined />,
},
{
key: '11_50',
label: '11 - 50',
icon: <TeamOutlined />,
},
{
key: '51_100',
label: '51 - 100',
icon: <TeamOutlined />,
},
{
key: '100_250',
label: '100 - 250',
icon: <TeamOutlined />,
},
{
key: '250+',
label: '250+',
icon: <TeamOutlined />,
},
]
Example #3
Source File: Bread.tsx From react_admin with MIT License | 6 votes |
Breads: React.FC<{}> = () => {
return (
<div className="bread">
<Breadcrumb>
<Breadcrumb.Item href="">
<HomeOutlined className="bread-icon" />
</Breadcrumb.Item>
<Breadcrumb.Item href="">
<UserOutlined />
<span>Application List</span>
</Breadcrumb.Item>
<Breadcrumb.Item>Application</Breadcrumb.Item>
</Breadcrumb>
</div>
);
}
Example #4
Source File: UserOverlay.tsx From mayoor with MIT License | 6 votes |
UserOverlay: React.FC = () => {
const [isOpen, setIsOpen] = useState(false);
const { currentUser } = useAppState();
return (
<>
<Button icon={<UserOutlined />} onClick={() => setIsOpen(true)} type="link">
{currentUser?.name}
</Button>
<Modal
visible={isOpen}
onCancel={() => setIsOpen(false)}
title={currentUser?.name}
footer={null}
>
<ChangePassword />
</Modal>
</>
);
}
Example #5
Source File: Login.tsx From vite-react-ts with MIT License | 6 votes |
Login: React.FC = () => {
const { login, loading } = useStore((state) => ({ ...state }));
return (
<div className={cls.loginBox}>
<Card className="_bg" bordered={false}>
<Form
onFinish={({ username, password }) => {
if (username === 'admin' && password === '123456') {
return login({ username, password });
}
message.error('账号或密码错误,请重试!');
}}>
<Form.Item
name="username"
rules={[{ required: true, message: '请输入用户名' }]}>
<Input prefix={<UserOutlined />} placeholder="请输入用户名:admin" />
</Form.Item>
<Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}>
<Input prefix={<LockOutlined />} placeholder="请输入密码:123456" />
</Form.Item>
<Form.Item>
<Button
loading={loading}
type="primary"
htmlType="submit"
className={cls.button}>
登陆
</Button>
</Form.Item>
</Form>
</Card>
</div>
);
}
Example #6
Source File: Layout.tsx From jitsu with MIT License | 6 votes |
PageHeader: React.FC<PageHeaderProps> = ({ plan, user, children }) => {
const [dropdownVisible, setDropdownVisible] = useState(false)
return (
<div className="border-b border-splitBorder mb-0 h-14 flex flex-nowrap">
<div className="flex-grow">
<div className="h-14 flex items-center">{children}</div>
</div>
<div className={`flex-shrink flex justify-center items-center mx-1`}>
<NotificationsWidget />
</div>
<div className="flex-shrink flex justify-center items-center">
<Dropdown
key={"userMenuDropdown"}
trigger={["click"]}
visible={dropdownVisible}
overlay={<DropdownMenu user={user} plan={plan} hideMenu={() => setDropdownVisible(false)} />}
onVisibleChange={vis => setDropdownVisible(vis)}
>
<Button
className="ml-1 border-primary border-2 hover:border-text text-text hover:text-text"
size="large"
shape="circle"
>
{abbr(user) || <UserOutlined />}
</Button>
</Dropdown>
</div>
</div>
)
}
Example #7
Source File: Header.tsx From nodestatus with MIT License | 6 votes |
Header: FC<Props> = props => {
const navigate = useNavigate();
const { isCollapsed, toggleCollapsed } = props.collapsed;
const menu = (
<Menu
items={[
{
key: 'logout',
label: 'Logout',
icon: <LogoutOutlined className="mr-2 align-middle" />,
className: 'align-middle'
}
]}
onClick={({ key }) => {
if (key === 'logout') {
localStorage.removeItem('token');
navigate('/login');
}
}}
/>
);
return (
<div className="h-full flex items-center justify-between">
{React.createElement(isCollapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
className: 'text-2xl',
onClick: toggleCollapsed
})}
<Dropdown overlay={menu} placement="bottom">
<Avatar size={40} icon={<UserOutlined />} />
</Dropdown>
</div>
);
}
Example #8
Source File: index.tsx From tinyhouse with MIT License | 6 votes |
export function ListingCard({ listing }: ListingCardProps) {
const { id, title, image, address, price, numOfGuests } = listing;
return (
<NavLink to={`/listing/${id}`}>
<Card
hoverable
cover={
<div
style={{ backgroundImage: `url(${image})` }}
className="listing-card__cover-img"
/>
}
>
<div className="listing-card__details">
<div className="listing-card__description">
<Title level={4} className="listing-card__price">
{formatListingPrice(price)}
<span>/day</span>
</Title>
<Text strong ellipsis className="listing-card__title">
{title}
</Text>
<Text ellipsis className="listing-card__address">
{address}
</Text>
</div>
<div className="listing-card__dimensions listing-card__dimensions--guests">
<UserOutlined style={{ color: iconColor }} />
<Text>{numOfGuests} guests</Text>
</div>
</div>
</Card>
</NavLink>
);
}
Example #9
Source File: SelfAvatar.tsx From office-hours with GNU General Public License v3.0 | 6 votes |
export function KOHAvatar({
size,
photoURL,
name,
style,
className,
}: KOHAvatarProps): ReactElement {
return photoURL ? (
<Avatar
icon={<UserOutlined />}
src={"/api/v1/profile/get_picture/" + photoURL}
size={size}
style={style}
className={className}
/>
) : (
<AvatarWithInitals
name={name}
size={size}
fontSize={(3 / 7) * size}
style={style}
className={className}
/>
);
}
Example #10
Source File: index.tsx From electron with MIT License | 6 votes |
SettingWrap: React.FC = () => {
return (
<Layout>
<ScrollTools
source={[
{
Key: 'SettingsUser',
Label: (
<React.Fragment>
<UserOutlined size={18} />
<span>导航预览</span>
</React.Fragment>
),
Content: <SettingNavigator />
},
{
Key: 'SettingsOther',
Label: (
<React.Fragment>
<SettingOutlined size={18} />
<span>关于</span>
</React.Fragment>
),
Content: <SettingAbout />
}
]}
isFullScreen
></ScrollTools>
</Layout>
);
}
Example #11
Source File: Footer.tsx From disco-cube-admin with MIT License | 6 votes |
Footer: React.FC<Props> = ({ currentPath, onGotoPath }) => {
console.log("currentPath", currentPath);
return (
<Segment style={{ padding: 8 }} spacing={10} width="100%" maxWidth={500}>
<Horizontal horizontalAlign="center">
<Menu selectedKeys={["/" + currentPath.split("/")[1]]} mode="horizontal">
<Menu.Item key="/stats" onClick={() => onGotoPath(routes.stats.path())}>
<DashboardOutlined style={{ fontSize: "2em" }} />
</Menu.Item>
<Menu.Item key="/terminal" onClick={() => onGotoPath(routes.terminal.path())}>
<CodeOutlined style={{ fontSize: "2em" }} />
</Menu.Item>
<Menu.Item key="/apps" onClick={() => onGotoPath(routes.apps.path())}>
<AppstoreOutlined style={{ fontSize: "2em" }} />
</Menu.Item>
<Menu.Item key="/account" onClick={() => onGotoPath(routes.account.path())}>
<UserOutlined style={{ fontSize: "2em" }} />
</Menu.Item>
</Menu>
</Horizontal>
</Segment>
);
}
Example #12
Source File: DetailDescription.tsx From mayoor with MIT License | 6 votes |
DetailDescription: React.FC<Props> = ({ createdByName, createdAt, updatedAt }) => {
const { t } = useTranslation();
const { f } = useDateFormatter();
return (
<StyledDescriptions>
<Descriptions.Item label={t('Created By')} key="createdBy">
<UserOutlined />
{createdByName}
</Descriptions.Item>
<Descriptions.Item label={t('Created At')} key="createdAt">
{createdAt && (
<>
<CalendarOutlined /> {f(createdAt, 'datetime')}
</>
)}
</Descriptions.Item>
<Descriptions.Item label={t('Last Updated At')} key="lastUpdatedAt">
{updatedAt && (
<>
<CalendarOutlined /> {f(updatedAt, 'datetime')}
</>
)}
</Descriptions.Item>
</StyledDescriptions>
);
}
Example #13
Source File: NodeTemplate.tsx From jetlinks-ui-antd with MIT License | 6 votes |
NodeTemplate = (props: Props) => {
const { data, action } = props;
return (
<div>
<div className={styles.node}>
<div className={styles.top}>
<span className={styles.title}>{data.name}</span>
<Avatar size="small" icon={<UserOutlined />} />
</div>
<div className={styles.content}>
<div className={styles.item}>
{data.code!==null&&(<div>
<span className={styles.mark}>编码</span>
<span>{data.code}</span>
</div>)}
<div>
<span className={styles.mark}>下级数量</span>
<span>{data?.children?.length || 0}</span>
</div>
</div>
<div className={styles.action}>
<Dropdown overlay={action}>
<a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
<SmallDashOutlined />
</a>
</Dropdown>
</div>
</div>
</div>
</div>
);
}
Example #14
Source File: BatchExecutorPage.tsx From yakit with GNU Affero General Public License v3.0 | 6 votes |
YakScriptWithCheckboxLine: React.FC<YakScriptWithCheckboxLineProp> = (props) => {
const {plugin} = props;
const script = plugin;
return <Card
key={plugin.ScriptName} style={{marginBottom: 6}} size={"small"}
bodyStyle={{paddingLeft: 12, paddingTop: 8, paddingBottom: 8, paddingRight: 12}}
hoverable={true}
>
<div style={{width: "100%", display: "flex", flexDirection: "row"}}>
<Checkbox style={{marginBottom: 0}} checked={props.selected} onChange={r => {
if (r.target.checked) {
props.onSelected(plugin)
} else {
props.onUnselected(plugin)
}
}}>
<Space>
<OneLine maxWidth={270} overflow={"hidden"} title={plugin.ScriptName}>{plugin.ScriptName}</OneLine>
{script.Help && <Button
size={"small"} type={"link"} onClick={() => {
showModal({
width: "40%",
title: "Help", content: <>
{script.Help}
</>
})
}}
icon={<QuestionCircleOutlined/>}/>}
</Space>
</Checkbox>
<div style={{flex: 1, textAlign: "right"}}>
{script.Author && <Tooltip title={script.Author}>
<Button size={"small"} type={"link"} icon={<UserOutlined/>}/>
</Tooltip>}
</div>
</div>
</Card>
}
Example #15
Source File: CustomerPicker.tsx From mayoor with MIT License | 5 votes |
CustomerPicker: React.FC<{ extraCustomer: CustomerOption | null }> = ({
extraCustomer,
}) => {
const { t } = useTranslation();
const [{ value }, { touched, error }, { setValue }] = useField('customerId');
const errorMessage = touched && error;
const status = errorMessage ? 'error' : '';
const { data, loading, refetch } = useQuery<FindCustomerQuery, FindCustomerQueryVariables>(
FIND_CUSTOMER_QUERY,
{
fetchPolicy: 'network-only',
},
);
const searchHandler = (search: string) => {
refetch({ search });
};
const debouncedSearchHandler = debounce(searchHandler, 500);
const customers = data?.getAllCustomers.items ?? [];
const renderCustomerOption = (customer: CustomerOption) => {
return (
<Select.Option key={customer.id} value={customer.id}>
<UserOutlined style={{ marginRight: 5 }}></UserOutlined>
<span>{customer.name}</span>{' '}
{customer.identificationNumber && (
<StyledSubName>{customer.identificationNumber}</StyledSubName>
)}
</Select.Option>
);
};
return (
<StyledFormItem validateStatus={status} help={errorMessage}>
<StyledLabel>{t('Customer')}</StyledLabel>
<Select
filterOption={false}
onChange={(value) => setValue(value)}
placeholder={t('Select a customer')}
onSearch={debouncedSearchHandler}
showSearch
value={value}
loading={loading}
allowClear
notFoundContent={t('Not found')}
data-test-id="customer-picker"
>
{extraCustomer && renderCustomerOption(extraCustomer)}
{customers.map(renderCustomerOption)}
</Select>
</StyledFormItem>
);
}
Example #16
Source File: AvatarDropdown.tsx From ui-visualization with MIT License | 5 votes |
render(): React.ReactNode {
const {
currentUser = {
avatar: '',
name: '',
},
menu,
} = this.props;
const menuHeaderDropdown = (
<Menu className={styles.menu} selectedKeys={[]} onClick={this.onMenuClick}>
{menu && (
<Menu.Item key="center">
<UserOutlined />
个人中心
</Menu.Item>
)}
{menu && (
<Menu.Item key="settings">
<SettingOutlined />
个人设置
</Menu.Item>
)}
{menu && <Menu.Divider />}
<Menu.Item key="logout">
<LogoutOutlined />
退出登录
</Menu.Item>
</Menu>
);
return currentUser && currentUser.name ? (
<HeaderDropdown overlay={menuHeaderDropdown}>
<span className={`${styles.action} ${styles.account}`}>
<Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
<span className={styles.name}>{currentUser.name}</span>
</span>
</HeaderDropdown>
) : (
<span className={`${styles.action} ${styles.account}`}>
<Spin
size="small"
style={{
marginLeft: 8,
marginRight: 8,
}}
/>
</span>
);
}
Example #17
Source File: Login.tsx From nodestatus with MIT License | 5 votes |
Login: FC = () => {
const navigate = useNavigate();
const { mutate } = useSWRConfig();
const onFinish = useCallback(async (values: { username: string, password: string }) => {
const { username, password } = values;
const res = await axios.post<IResp<string>>('/api/session', { username, password });
const { data } = res;
if (!data.code) {
notify('Success', undefined, 'success');
localStorage.setItem('token', data.data);
mutate('/api/session', { code: 0, msg: 'OK', data: null }, false).then(() => navigate('/dashboard'));
}
}, [navigate, mutate]);
return (
<div
className="flex items-center min-h-screen p-6 bg-violet-50"
style={{ backgroundImage: `url(${loginBackground})` }}
>
<div className="flex-1 h-full max-w-xl md:max-w-4xl mx-auto overflow-hidden bg-white rounded-lg shadow-xl">
<div className="flex flex-col md:flex-row">
<div className="h-60 md:h-auto md:w-1/2">
<img
aria-hidden="true"
className="object-cover w-full h-full"
src={cherry}
alt="Office"
/>
</div>
<div className="flex flex-col items-center justify-center p-6 sm:p-16 md:w-1/2">
<h1 className="text-2xl font-semibold text-gray-700 mb-6">NodeStatus</h1>
<Form
className="w-full"
initialValues={{ remember: true }}
onFinish={onFinish}
>
<Form.Item
name="username"
rules={[{ required: true, message: 'Please input your Username!' }]}
>
<Input size="large" prefix={<UserOutlined />} placeholder="Username" />
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: 'Please input your Password!' }]}
>
<Input
size="large"
prefix={<LockOutlined />}
type="password"
placeholder="Password"
/>
</Form.Item>
<Form.Item>
<Button type="primary" size="large" htmlType="submit" block>
Log in
</Button>
</Form.Item>
</Form>
</div>
</div>
</div>
</div>
);
}
Example #18
Source File: Layout.tsx From yugong with MIT License | 5 votes |
MainLayout: React.FC<Props> = ({ children }) => {
const [collapsed, setCollapsed] = useState(true);
let location = useLocation();
const history = useHistory();
const { auth } = useSelector((state: RootState) => state.controller);
const { loginOut } = useDispatch<Dispatch>().controller;
return (
<Layout>
<Sider
theme="light"
className={s.side}
trigger={null}
collapsible
collapsed={collapsed}
>
<div className={s.logo}>
<GroupOutlined /> {collapsed ? "" : "YuGong"}
</div>
<Menu
theme="light"
mode="inline"
defaultSelectedKeys={[location.pathname]}
>
{menus.map((item) => (
<Menu.Item key={item.path} icon={item.icon}>
{item.name}
<Link to={item.path || "/"} />
</Menu.Item>
))}
</Menu>
</Sider>
<Layout className="site-layout">
<Header className={s.layout} style={{ padding: 0 }}>
{React.createElement(
collapsed ? MenuUnfoldOutlined : MenuFoldOutlined,
{
className: s.trigger,
onClick: () => setCollapsed(!collapsed),
}
)}
<div className={s.auto} />
<div className={s.auth}>
{auth?.isLogin ? (
<div>
<Avatar size="small" icon={<UserOutlined />} />
{auth.session?.username}
<Button type="link" onClick={loginOut}>退出</Button>
</div>
) : (
<>
{location.pathname !== '/login' ? <Button type="link" onClick={() => history.push('/login')}>登录</Button> : null}
{location.pathname !== '/register' ? <Button type="link" onClick={() => history.push('/register')}>注册</Button> : null}
</>
)}
</div>
</Header>
<Content className={s.content}>{children}</Content>
</Layout>
</Layout>
);
}
Example #19
Source File: AvatarDropdown.tsx From ant-design-pro-V4 with MIT License | 5 votes |
render(): React.ReactNode {
const { todoList } = this.props?.todo
// const todoNum = todoList.filter((item: any) => item.status === 0).length
const todoNum = todoList?.filter((item: any) => {
if (item != null) {
return item.status === 0
}
}).length
const {
currentUser = {
avatar: '',
name: '',
},
menu,
} = this.props;
const menuHeaderDropdown = (
<Menu className={styles.menu} selectedKeys={[]} onClick={this.onMenuClick}>
{menu && (
<Menu.Item key="center">
<UserOutlined />
个人中心
</Menu.Item>
)}
{menu && (
<Menu.Item key="settings">
<SettingOutlined />
个人设置
</Menu.Item>
)}
{menu && <Menu.Divider />}
<Menu.Item key="todo">
<UnorderedListOutlined />
待办事项
<Badge count={todoNum} offset={[10, -5]} />
</Menu.Item>
{menu && <Menu.Divider />}
<Menu.Item key="logout">
<LogoutOutlined />
退出登录
</Menu.Item>
</Menu>
);
return currentUser && currentUser.name ? (
<HeaderDropdown overlay={menuHeaderDropdown}>
<span className={`${styles.action} ${styles.account}`}>
<Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
<span className={`${styles.name} anticon`}>{currentUser.name}
<Badge count={todoNum} dot={true} /></span>
</span>
</HeaderDropdown>
) : (
<span className={`${styles.action} ${styles.account}`}>
<Spin
size="small"
style={{
marginLeft: 8,
marginRight: 8,
}}
/>
</span>
);
}
Example #20
Source File: index.tsx From datart with Apache License 2.0 | 5 votes |
Sidebar = memo(() => {
const [selectedKey, setSelectedKey] = useState('');
const history = useHistory();
const orgId = useSelector(selectOrgId);
const { url } = useRouteMatch();
const t = useI18NPrefix('member.sidebar');
useEffect(() => {
const urlArr = url.split('/');
setSelectedKey(urlArr[urlArr.length - 1]);
}, [url]);
const titles = useMemo(
() => [
{ key: 'members', icon: <UserOutlined />, text: t('member') },
{
key: 'roles',
icon: <TeamOutlined />,
text: t('role'),
},
],
[t],
);
const switchSelect = useCallback(
key => {
history.push(`/organizations/${orgId}/${key}`);
},
[history, orgId],
);
return (
<Wrapper>
<ListSwitch
titles={titles}
selectedKey={selectedKey}
onSelect={switchSelect}
/>
{selectedKey === 'members' && <MemberList />}
{selectedKey === 'roles' && <RoleList />}
</Wrapper>
);
})
Example #21
Source File: Login.tsx From jmix-frontend with Apache License 2.0 | 5 votes |
Login = observer(() => {
const intl = useIntl();
const mainStore = useMainStore();
const [login, setLogin] = useState("");
const [password, setPassword] = useState("");
const [performingLoginRequest, setPerformingLoginRequest] = useState(false);
const changeLogin = useCallback((e: ChangeEvent<HTMLInputElement>) => setLogin(e.target.value), [setLogin]);
const changePassword = useCallback((e: ChangeEvent<HTMLInputElement>) => setPassword(e.target.value), [setPassword]);
const doLogin = useCallback(() => {
setPerformingLoginRequest(true);
mainStore
.login(login, password)
.then(action(() => {
setPerformingLoginRequest(false);
}))
.catch(action((error: JmixServerError) => {
setPerformingLoginRequest(false);
const loginMessageErrorIntlId = loginMapJmixRestErrorToIntlId(error);
message.error(intl.formatMessage({id: loginMessageErrorIntlId}));
}));
}, [setPerformingLoginRequest, mainStore, intl, login, password]);
return (
<Card className={styles.loginForm}>
<JmixDarkIcon className={styles.logo} />
<div className={styles.title}>
<%= title %>
</div>
<Form layout='vertical' onFinish={doLogin}>
<Form.Item>
<Input id='input_login'
placeholder={intl.formatMessage({id: 'login.placeholder.login'})}
onChange={changeLogin}
value={login}
prefix={<UserOutlined style={{ margin: "0 11px 0 0" }}/>}
size='large'/>
</Form.Item>
<Form.Item>
<Input id='input_password'
placeholder={intl.formatMessage({id: 'login.placeholder.password'})}
onChange={changePassword}
value={password}
type='password'
prefix={<LockOutlined style={{ margin: "0 11px 0 0" }}/>}
size='large'/>
</Form.Item>
<Form.Item>
<div className={styles.languageSwitcherContainer}>
<LanguageSwitcher />
</div>
</Form.Item>
<Form.Item>
<Button type='primary'
htmlType='submit'
size='large'
block={true}
loading={performingLoginRequest}>
<FormattedMessage id='login.loginBtn'/>
</Button>
</Form.Item>
</Form>
</Card>
);
})
Example #22
Source File: AvatarDropdown.tsx From ant-design-pro-V5-multitab with MIT License | 5 votes |
AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => {
const { initialState, setInitialState } = useModel('@@initialState');
const onMenuClick = useCallback(
(event: {
key: React.Key;
keyPath: React.Key[];
item: React.ReactInstance;
domEvent: React.MouseEvent<HTMLElement>;
}) => {
const { key } = event;
if (key === 'logout' && initialState) {
setInitialState({ ...initialState, currentUser: undefined });
loginOut();
return;
}
history.push(`/account/${key}`);
},
[initialState, setInitialState],
);
const loading = (
<span className={`${styles.action} ${styles.account}`}>
<Spin
size="small"
style={{
marginLeft: 8,
marginRight: 8,
}}
/>
</span>
);
if (!initialState) {
return loading;
}
const { currentUser } = initialState;
if (!currentUser || !currentUser.name) {
return loading;
}
const menuHeaderDropdown = (
<Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}>
{menu && (
<Menu.Item key="center">
<UserOutlined />
个人中心
</Menu.Item>
)}
{menu && (
<Menu.Item key="settings">
<SettingOutlined />
个人设置
</Menu.Item>
)}
{menu && <Menu.Divider />}
<Menu.Item key="logout">
<LogoutOutlined />
退出登录
</Menu.Item>
</Menu>
);
return (
<HeaderDropdown overlay={menuHeaderDropdown}>
<span className={`${styles.action} ${styles.account}`}>
<Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
<span className={`${styles.name} anticon`}>{currentUser.name}</span>
</span>
</HeaderDropdown>
);
}
Example #23
Source File: index.tsx From tinyhouse with MIT License | 5 votes |
export function MenuItems({ viewer, setViewer }: MenuItemsProps) {
const [logOut] = useMutation<LogOutData>(LOG_OUT, {
onCompleted: (data) => {
if (data && data.logOut) {
setViewer(data.logOut);
sessionStorage.removeItem("token");
displaySuccessNotification("You've successfully logged out!");
}
},
onError: (error) => {
displayErrorMessage(
"Sorry, we weren't able to to log you out. Please try again later!"
);
},
});
const handleLogout = async () => {
await logOut();
};
const subMenuLogin =
viewer.id && viewer.avatar ? (
<SubMenu key={viewer.id} title={<Avatar src={viewer.avatar} />}>
<Item key="/user">
<NavLink to={`/user/${viewer.id}`}>
<UserOutlined></UserOutlined>
Profile
</NavLink>
</Item>
<Item key="/logout" onClick={handleLogout}>
<LogoutOutlined></LogoutOutlined>
Log out
</Item>
</SubMenu>
) : (
<Item>
<NavLink to="/login">
<Button type="primary">Sign In</Button>
</NavLink>
</Item>
);
return (
<Menu mode="horizontal" selectable={false} className="menu">
<Item key="/host">
<NavLink to="/host">
<HomeOutlined />
Host
</NavLink>
</Item>
{subMenuLogin}
</Menu>
);
}
Example #24
Source File: PluginList.tsx From yakit with GNU Affero General Public License v3.0 | 5 votes |
YakScriptCheckbox: React.FC<YakScriptCheckboxProp> = React.memo((props) => {
const {info, selected, vlistWidth, selectScript, unSelectScript,} = props;
return <div key={info.ScriptName} className='list-opt'>
{props.readOnly ? <OneLine width={vlistWidth} overflow={"hidden"}>
<div>
{info.ScriptName}
</div>
</OneLine> : <Checkbox
disabled={props.disabled}
checked={selected.includes(info.ScriptName)}
onChange={(r) => {
if (r.target.checked) selectScript(info)
else unSelectScript(info)
}}
>
<OneLine width={vlistWidth} overflow={"hidden"}>
<div>
{info.ScriptName}
</div>
</OneLine>
</Checkbox>}
<div style={{flex: 1, textAlign: "right"}}>
{info.Help && (
<a
onClick={() => {
showModal({
width: "40%",
title: "Help",
content: <>{info.Help}</>
})
}}
href={"#"} style={{marginLeft: 2, marginRight: 2}}
><QuestionCircleOutlined/></a>
)}
{info.Author && (
<Tooltip title={info.Author}>
<a href={"#"} style={{marginRight: 2, marginLeft: 2}}><UserOutlined/></a>
</Tooltip>
)}
{!!info.Content && props.readOnly && (
<a href={"#"}
style={{marginRight: 2, marginLeft: 2}}
onClick={() => {
showModal({
title: info.ScriptName, width: "60%",
content: (
<div style={{height: 400}}>
<YakEditor
type={info.Type === "nuclei" ? "yaml" : "yak"}
readOnly={true}
value={info.Content}
/>
</div>
)
})
}}
><CodeOutlined/></a>
)}
</div>
</div>
})
Example #25
Source File: users.tsx From fe-v5 with Apache License 2.0 | 4 votes |
Resource: React.FC = () => {
const { t } = useTranslation();
const [activeKey, setActiveKey] = useState<UserType>(UserType.User);
const [visible, setVisible] = useState<boolean>(false);
const [action, setAction] = useState<ActionType>();
const [userId, setUserId] = useState<string>('');
const [teamId, setTeamId] = useState<string>('');
const [memberId, setMemberId] = useState<string>('');
const [allMemberList, setAllMemberList] = useState<User[]>([]);
const [teamList, setTeamList] = useState<Team[]>([]);
const [query, setQuery] = useState<string>('');
const [searchValue, setSearchValue] = useState<string>('');
const userRef = useRef(null as any);
let { profile } = useSelector<RootState, accountStoreState>((state) => state.account);
const userColumn: ColumnsType<User> = [
{
title: t('用户名'),
dataIndex: 'username',
ellipsis: true,
},
{
title: t('显示名'),
dataIndex: 'nickname',
ellipsis: true,
render: (text: string, record) => record.nickname || '-',
},
{
title: t('邮箱'),
dataIndex: 'email',
render: (text: string, record) => record.email || '-',
},
{
title: t('手机'),
dataIndex: 'phone',
render: (text: string, record) => record.phone || '-',
},
];
const userColumns: ColumnsType<User> = [
...userColumn,
{
title: t('角色'),
dataIndex: 'roles',
render: (text: [], record) => text.join(', '),
},
{
title: t('操作'),
width: '240px',
render: (text: string, record) => (
<>
<Button className='oper-name' type='link' onClick={() => handleClick(ActionType.EditUser, record.id)}>
{t('编辑')}
</Button>
<Button className='oper-name' type='link' onClick={() => handleClick(ActionType.Reset, record.id)}>
{t('重置密码')}
</Button>
{/* <DelPopover
userId={record.id}
userType='user'
onClose={() => handleClose()}
></DelPopover> */}
<a
style={{
color: 'red',
marginLeft: '16px',
}}
onClick={() => {
confirm({
title: t('是否删除该用户'),
onOk: () => {
deleteUser(record.id).then((_) => {
message.success(t('用户删除成功'));
handleClose();
});
},
onCancel: () => {},
});
}}
>
{t('删除')}
</a>
</>
),
},
];
if (!profile.roles.includes('Admin')) {
userColumns.pop(); //普通用户不展示操作列
}
const getList = () => {
userRef.current.refreshList();
};
const handleClick = (type: ActionType, id?: string, memberId?: string) => {
if (id) {
activeKey === UserType.User ? setUserId(id) : setTeamId(id);
} else {
activeKey === UserType.User ? setUserId('') : setTeamId('');
}
if (memberId) {
setMemberId(memberId);
} else {
setMemberId('');
}
setAction(type);
setVisible(true);
};
// 弹窗关闭回调
const handleClose = () => {
setVisible(false);
getList();
};
const onSearchQuery = (e) => {
let val = e.target.value;
setQuery(val);
};
return (
<PageLayout title={t('用户管理')} icon={<UserOutlined />} hideCluster>
<div className='user-manage-content'>
<div className='user-content'>
<Row className='event-table-search'>
<div className='event-table-search-left'>
<Input className={'searchInput'} prefix={<SearchOutlined />} onPressEnter={onSearchQuery} placeholder={t('用户名、邮箱或手机')} />
</div>
<div className='event-table-search-right'>
{activeKey === UserType.User && profile.roles.includes('Admin') && (
<div className='user-manage-operate'>
<Button type='primary' onClick={() => handleClick(activeKey === UserType.User ? ActionType.CreateUser : t('创建团队'))} ghost>
{t('创建用户')}
</Button>
</div>
)}
</div>
</Row>
<BaseTable
ref={userRef}
fetchHandle={getUserInfoList}
columns={userColumns}
rowKey='id'
needPagination={true}
fetchParams={{
query,
}}
></BaseTable>
</div>
<UserInfoModal
visible={visible}
action={action as ActionType}
width={activeKey === UserType.User ? 500 : 700}
userType={activeKey}
onClose={handleClose}
userId={userId}
teamId={teamId}
memberId={memberId}
/>
</div>
</PageLayout>
);
}
Example #26
Source File: index.tsx From foodie with MIT License | 4 votes |
PostItem: React.FC<IProps> = (props) => {
const { post, likeCallback, isAuth } = props;
const [isCommentVisible, setCommentVisible] = useState(false);
const deleteModal = useModal();
const updateModal = useModal();
const commentInputRef = useRef<HTMLInputElement | null>(null);
const dispatch = useDispatch();
const handleToggleComment = () => {
if (!isAuth) return;
if (!isCommentVisible) setCommentVisible(true);
if (commentInputRef.current) commentInputRef.current.focus();
}
const displayLikeMetric = (likesCount: number, isLiked: boolean) => {
const like = likesCount > 1 ? 'like' : 'likes';
const likeMinusSelf = (likesCount - 1) > 1 ? 'like' : 'likes';
const people = likesCount > 1 ? 'people' : 'person';
const peopleMinusSelf = (likesCount - 1) > 1 ? 'people' : 'person';
if (isLiked && likesCount <= 1) {
return 'You like this.'
} else if (isLiked && likesCount > 1) {
return `You and ${likesCount - 1} other ${peopleMinusSelf} ${likeMinusSelf} this.`;
} else {
return `${likesCount} ${people} ${like} this.`;
}
}
const handleClickLikes = () => {
if (isAuth) {
dispatch(showModal(EModalType.POST_LIKES));
dispatch(setTargetPost(props.post));
}
}
const handleClickPrivacyChange = () => {
if (post.isOwnPost) {
dispatch(setTargetPost(post));
dispatch(showModal(EModalType.EDIT_POST));
}
}
return (
<div className="flex flex-col bg-white rounded-lg my-4 p-4 first:mt-0 shadow-lg dark:bg-indigo-1000">
{/* --- AVATAR AND OPTIONS */}
<div className="flex justify-between items-center w-full">
<div className="flex">
<Avatar
url={post.author.profilePicture?.url}
className="mr-3"
/>
<div className="flex flex-col">
<Link className="dark:text-indigo-400" to={`/user/${post.author.username}`}>
<h5 className="font-bold">{post.author.username}</h5>
</Link>
<div className="flex items-center space-x-1">
<span className="text-sm text-gray-500">{dayjs(post.createdAt).fromNow()}</span>
<div
className={`w-4 h-4 rounded-full flex items-center justify-center ${post.isOwnPost && 'cursor-pointer hover:bg-gray-100 dark:hover:bg-indigo-900'}`}
onClick={handleClickPrivacyChange}
title={post.isOwnPost ? 'Change Privacy' : ''}
>
{post.privacy === 'private'
? <LockOutlined className="text-xs text-gray-500 dark:text-white" />
: post.privacy === 'follower'
? <UserOutlined className="text-xs text-gray-500 dark:text-white" />
: <GlobalOutlined className="text-xs text-gray-500 dark:text-white" />
}
</div>
</div>
</div>
</div>
{isAuth && (
<PostOptions
openDeleteModal={deleteModal.openModal}
openUpdateModal={updateModal.openModal}
post={post}
/>
)}
</div>
{/* --- DESCRIPTION */}
<div className="mb-3 mt-2">
<p className="text-gray-700 dark:text-gray-300 break-words">{post.description}</p>
</div>
{/* --- IMAGE GRID ----- */}
{post.photos.length !== 0 && <ImageGrid images={post.photos.map(img => img.url)} />}
{/* ---- LIKES/COMMENTS DETAILS ---- */}
<div className="flex justify-between px-2 my-2">
<div onClick={handleClickLikes}>
{post.likesCount > 0 && (
<span className="text-gray-500 text-sm cursor-pointer hover:underline hover:text-gray-800 dark:hover:text-white">
{displayLikeMetric(post.likesCount, post.isLiked)}
</span>
)}
</div>
{/* --- COMMENTS COUNT ----- */}
<div>
{post.commentsCount > 0 && (
<span
className="text-gray-500 hover:text-gray-800 cursor-pointer text-sm hover:underline dark:text-gray-500 dark:hover:text-white"
onClick={handleToggleComment}
>
{post.commentsCount} {post.commentsCount === 1 ? 'comment' : 'comments'}
</span>
)}
</div>
</div>
{/* --- LIKE/COMMENT BUTTON */}
{isAuth ? (
<div className="flex items-center justify-around py-2 border-t border-gray-200 dark:border-gray-800">
<LikeButton postID={post.id} isLiked={post.isLiked} likeCallback={likeCallback} />
<span
className="py-2 rounded-md flex items-center justify-center text-gray-700 hover:text-gray-800 700 dark:text-gray-400 dark:hover:text-white dark:hover:bg-indigo-1100 cursor-pointer hover:bg-gray-100 text-l w-2/4"
onClick={handleToggleComment}
>
<CommentOutlined /> Comment
</span>
</div>
) : (
<div className="text-center py-2">
<span className="text-gray-400 text-sm">
<Link className="font-medium underline dark:text-indigo-400" to={LOGIN}>Login</Link> to like or comment on post.
</span>
</div>
)}
{isAuth && (
<Suspense fallback={<LoadingOutlined className="text-gray-800 dark:text-white" />}>
<Comments
postID={post.id}
authorID={post.author.id}
isCommentVisible={isCommentVisible}
commentInputRef={commentInputRef}
setInputCommentVisible={setCommentVisible}
/>
</Suspense>
)}
</div>
);
}
Example #27
Source File: business.tsx From fe-v5 with Apache License 2.0 | 4 votes |
Resource: React.FC = () => {
const { t } = useTranslation();
const urlQuery = useQuery();
const id = urlQuery.get('id');
const [visible, setVisible] = useState<boolean>(false);
const [action, setAction] = useState<ActionType>();
const [teamId, setTeamId] = useState<string>(id || '');
const [memberId, setMemberId] = useState<string>('');
const [memberList, setMemberList] = useState<{ user_group: any }[]>([]);
const [memberTotal, setMemberTotal] = useState<number>(0);
const [allMemberList, setAllMemberList] = useState<User[]>([]);
const [teamInfo, setTeamInfo] = useState<{ name: string; id: number }>();
const [teamList, setTeamList] = useState<Team[]>([]);
const [query, setQuery] = useState<string>('');
const [memberLoading, setMemberLoading] = useState<boolean>(false);
const [searchValue, setSearchValue] = useState<string>('');
const [searchMemberValue, setSearchMemberValue] = useState<string>('');
const userRef = useRef(null as any);
let { profile } = useSelector<RootState, accountStoreState>((state) => state.account);
const dispatch = useDispatch();
const teamMemberColumns: ColumnsType<any> = [
{
title: t('团队名称'),
dataIndex: ['user_group', 'name'],
ellipsis: true,
},
{
title: t('团队备注'),
dataIndex: ['user_group', 'note'],
ellipsis: true,
render: (text: string, record) => record['user_group'].note || '-',
},
{
title: t('权限'),
dataIndex: 'perm_flag',
},
{
title: t('操作'),
width: '100px',
render: (text: string, record) => (
<a
style={{
color: memberList.length > 1 ? 'red' : '#00000040',
}}
onClick={() => {
if (memberList.length <= 1) return;
let params = [
{
user_group_id: record['user_group'].id,
busi_group_id: teamId,
},
];
confirm({
title: t('是否删除该团队'),
onOk: () => {
deleteBusinessTeamMember(teamId, params).then((_) => {
message.success(t('团队删除成功'));
handleClose('deleteMember');
});
},
onCancel: () => {},
});
}}
>
{t('删除')}
</a>
),
},
];
useEffect(() => {
teamId && getTeamInfoDetail(teamId);
}, [teamId]);
useEffect(() => {
getTeamList();
}, []);
const getList = (action) => {
getTeamList(undefined, action === 'delete');
};
// 获取业务组列表
const getTeamList = (search?: string, isDelete?: boolean) => {
let params = {
query: search === undefined ? searchValue : search,
limit: PAGE_SIZE,
};
getBusinessTeamList(params).then((data) => {
setTeamList(data.dat || []);
if ((!teamId || isDelete) && data.dat.length > 0) {
setTeamId(data.dat[0].id);
}
});
};
// 获取业务组详情
const getTeamInfoDetail = (id: string) => {
setMemberLoading(true);
getBusinessTeamInfo(id).then((data) => {
dispatch({
type: 'common/saveData',
prop: 'curBusiItem',
data: data,
});
setTeamInfo(data);
setMemberList(data.user_groups);
setMemberLoading(false);
});
};
const handleClick = (type: ActionType, id?: string, memberId?: string) => {
if (memberId) {
setMemberId(memberId);
} else {
setMemberId('');
}
setAction(type);
setVisible(true);
};
// 弹窗关闭回调
const handleClose = (action) => {
setVisible(false);
if (['create', 'delete', 'update'].includes(action)) {
getList(action);
dispatch({ type: 'common/getBusiGroups' });
}
if (teamId && ['update', 'addMember', 'deleteMember'].includes(action)) {
getTeamInfoDetail(teamId);
}
};
return (
<PageLayout title={t('业务组管理')} icon={<UserOutlined />} hideCluster>
<div className='user-manage-content'>
<div style={{ display: 'flex', height: '100%' }}>
<div className='left-tree-area'>
<div className='sub-title'>
{t('业务组列表')}
<Button
style={{
height: '30px',
}}
size='small'
type='link'
onClick={() => {
handleClick(ActionType.CreateBusiness);
}}
>
{t('新建业务组')}
</Button>
</div>
<div style={{ display: 'flex', margin: '5px 0px 12px' }}>
<Input
prefix={<SearchOutlined />}
placeholder={t('搜索业务组名称')}
onPressEnter={(e) => {
// @ts-ignore
getTeamList(e.target.value);
}}
onBlur={(e) => {
// @ts-ignore
getTeamList(e.target.value);
}}
/>
</div>
<List
style={{
marginBottom: '12px',
flex: 1,
overflow: 'auto',
}}
dataSource={teamList}
size='small'
renderItem={(item) => (
<List.Item key={item.id} className={teamId == item.id ? 'is-active' : ''} onClick={() => setTeamId(item.id)}>
{item.name}
</List.Item>
)}
/>
</div>
{teamList.length > 0 ? (
<div className='resource-table-content'>
<Row className='team-info'>
<Col
span='24'
style={{
color: '#000',
fontSize: '14px',
fontWeight: 'bold',
display: 'inline',
}}
>
{teamInfo && teamInfo.name}
<EditOutlined
title={t('刷新')}
style={{
marginLeft: '8px',
fontSize: '14px',
}}
onClick={() => handleClick(ActionType.EditBusiness, teamId)}
></EditOutlined>
<DeleteOutlined
style={{
marginLeft: '8px',
fontSize: '14px',
}}
onClick={() => {
confirm({
title: t('是否删除该业务组'),
onOk: () => {
deleteBusinessTeam(teamId).then((_) => {
message.success(t('业务组删除成功'));
handleClose('delete');
});
},
onCancel: () => {},
});
}}
/>
</Col>
<Col
style={{
marginTop: '8px',
color: '#666',
}}
>
{t('备注')}:{t('告警规则,告警事件,监控对象,自愈脚本等都归属业务组,是一个在系统里可以自闭环的组织')}
</Col>
</Row>
<Row justify='space-between' align='middle'>
<Col span='12'>
<Input
prefix={<SearchOutlined />}
value={searchMemberValue}
className={'searchInput'}
onChange={(e) => setSearchMemberValue(e.target.value)}
placeholder={t('搜索团队名称')}
/>
</Col>
<Button
type='primary'
ghost
onClick={() => {
handleClick(ActionType.AddBusinessMember, teamId);
}}
>
{t('添加团队')}
</Button>
</Row>
<Table
rowKey='id'
columns={teamMemberColumns}
dataSource={memberList && memberList.length > 0 ? memberList.filter((item) => item.user_group && item.user_group.name.indexOf(searchMemberValue) !== -1) : []}
loading={memberLoading}
/>
</div>
) : (
<div className='blank-busi-holder'>
<p style={{ textAlign: 'left', fontWeight: 'bold' }}>
<InfoCircleOutlined style={{ color: '#1473ff' }} /> {t('提示信息')}
</p>
<p>
业务组(监控对象、监控大盘、告警规则、自愈脚本都要归属某个业务组)为空,请先
<a onClick={() => handleClick(ActionType.CreateBusiness)}>创建业务组</a>
</p>
</div>
)}
</div>
</div>
<UserInfoModal
visible={visible}
action={action as ActionType}
userType={'business'}
onClose={handleClose}
teamId={teamId}
onSearch={(val) => {
setTeamId(val);
}}
/>
</PageLayout>
);
}
Example #28
Source File: structure.tsx From ui with GNU Affero General Public License v3.0 | 4 votes |
Structure: FunctionComponent<Props> = (props) => {
const { t, i18n } = useTranslation()
const size = useWindowSize()
const [userMenu, setUserMenu] = React.useState(false)
const [open, setOpen] = React.useState<string[]>()
const [selected, setSelected] = React.useState<string[]>()
const [sidebar, setSidebar] = React.useState(size.width < 700)
const router = useRouter()
const user = useMeQuery()
React.useEffect(() => {
if (sidebar !== size.width < 700) {
setSidebar(size.width < 700)
}
}, [size.width])
React.useEffect(() => {
if (props.selected) {
const parts = props.selected.split('.')
const last = parts.pop()
if (parts.length > 0) {
setOpen(parts)
}
setSelected([last])
}
}, [props.selected])
const buildMenu = (data: SideMenuElement[]): JSX.Element[] => {
return data
.filter((element) => {
if (!element.role) {
return true
}
if (user.loading) {
return false
}
return user.data?.me.roles.includes(element.role)
})
.map(
(element): JSX.Element => {
if (element.items && element.items.length > 0) {
if (element.group) {
return (
<ItemGroup
key={element.key}
title={
<Space
style={{
textTransform: 'uppercase',
paddingTop: 16,
fontWeight: 'bold',
color: '#444',
}}
>
{element.icon}
<div>
{t(element.name)}
</div>
</Space>
}
>
{buildMenu(element.items)}
</ItemGroup>
)
}
return (
<SubMenu
key={element.key}
title={
<Space>
{element.icon}
<div>
{t(element.name)}
</div>
</Space>
}
>
{buildMenu(element.items)}
</SubMenu>
)
}
return (
<Menu.Item
onClick={async () => {
if (element.href) {
await router.push(element.href)
}
}}
key={element.key}
>
<Space>
{element.icon}
<div>
{t(element.name)}
</div>
</Space>
</Menu.Item>
)
}
)
}
const signOut = (): void => {
clearAuth()
router.reload()
}
return (
<Layout style={{ height: '100vh' }} className={'admin'}>
<Header
style={{
paddingLeft: 0,
}}
>
<Space
style={{
float: 'left',
color: '#FFF',
fontSize: 14,
marginRight: 26,
fontWeight: 'bold',
}}
>
{React.createElement(sidebar ? MenuUnfoldOutlined : MenuFoldOutlined, {
className: 'sidebar-toggle',
onClick: () => setSidebar(!sidebar),
})}
<div style={{
display: 'flex',
alignItems: 'center',
}}>
<img
height={40}
src={require('../assets/images/logo_white.png?resize&size=256')}
alt={'OhMyForm'}
/>
</div>
</Space>
<div style={{ float: 'right', display: 'flex', height: '100%' }}>
<Dropdown
overlay={
<Menu>
<Menu.Item key={'profile'} onClick={() => router.push('/admin/profile')}>Profile</Menu.Item>
<Menu.Divider key={'d1'} />
<Menu.Item key={'logout'} onClick={signOut}>Logout</Menu.Item>
</Menu>
}
onVisibleChange={setUserMenu}
visible={userMenu}
>
<Space
style={{
color: '#FFF',
alignItems: 'center',
display: 'inline-flex',
}}
>
<div>Hi {user.data && user.data.me.username},</div>
<UserOutlined style={{ fontSize: 24 }} />
<CaretDownOutlined />
</Space>
</Dropdown>
</div>
</Header>
<Layout
style={{
height: '100%',
}}
>
<Sider
collapsed={sidebar}
trigger={null}
collapsedWidth={0}
breakpoint={'xs'}
width={200}
style={{
background: '#fff',
maxHeight: '100%',
overflow: 'auto',
}}
className={'sidemenu'}
>
<Menu
mode="inline"
style={{ flex: 1 }}
defaultSelectedKeys={['1']}
selectedKeys={selected}
onSelect={(s): void => setSelected(s.keyPath )}
openKeys={open}
onOpenChange={(open): void => setOpen(open )}
>
{buildMenu(sideMenu)}
</Menu>
<Menu mode="inline" selectable={false}>
<Menu.Item className={'language-selector'} key={'language-selector'}>
<Select
bordered={false}
value={i18n.language.replace(/-.*/, '')}
onChange={(next) => i18n.changeLanguage(next)}
style={{
width: '100%',
}}
>
{languages.map((language) => (
<Select.Option value={language} key={language}>
{t(`language:${language}`)}
</Select.Option>
))}
</Select>
</Menu.Item>
<Menu.Item style={{ display: 'flex', alignItems: 'center' }} key={'github'}>
<GitHubButton type="stargazers" namespace="ohmyform" repo="ohmyform" />
</Menu.Item>
<Menu.Item key={'version'}>
Version: <Tag color="gold">{process.env.version}</Tag>
</Menu.Item>
</Menu>
</Sider>
<Layout
style={{ padding: '0 24px 24px', minHeight: 500, height: '100%', overflow: 'auto' }}
>
{props.title && (
<PageHeader
title={props.title}
subTitle={props.subTitle}
extra={props.extra}
breadcrumb={{
routes: [
...(props.breadcrumbs || []).map((b) => ({
breadcrumbName: b.name,
path: '',
})),
{
breadcrumbName: props.title,
path: '',
},
],
params: props.breadcrumbs,
itemRender(route, params: BreadcrumbEntry[], routes) {
if (routes.indexOf(route) === routes.length - 1) {
return <span>{route.breadcrumbName}</span>
}
const entry = params[routes.indexOf(route)]
return (
<Link href={entry.href} as={entry.as || entry.href}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a>{entry.name}</a>
</Link>
)
},
}}
/>
)}
{props.error && (
<Alert message={props.error} type={'error'} style={{ marginBottom: 24 }} />
)}
<Spin spinning={!!props.loading}>
<Content
style={{
background: props.padded ? '#fff' : null,
padding: props.padded ? 24 : 0,
...props.style,
}}
>
{props.children}
</Content>
</Spin>
</Layout>
</Layout>
</Layout>
)
}
Example #29
Source File: CustomerForm.tsx From mayoor with MIT License | 4 votes |
CustomerForm: React.FC<Props> = (props) => {
const { t } = useTranslation();
return (
<Formik<UserFormValues>
initialValues={props.initialValues}
onSubmit={async (values, { resetForm }) => {
await props.onSubmit(values, resetForm);
}}
validate={(values) => {
const errors: FormikErrors<UserFormValues> = {};
if (!values.name) {
errors.name = t('missing_company_name');
}
return errors;
}}
>
{({ values, setFieldValue, handleChange, handleSubmit }) => (
<StyledForm onSubmit={handleSubmit}>
<Row gutter={32}>
<Col xs={24} md={12}>
<FormInput
name="name"
label={t('Company name')}
icon={<ContactsOutlined />}
/>
<Row gutter={16}>
<Col span={12}>
<IdentificationNumberInput />
</Col>
<Col span={12}>
<FormInput
name="taxIdentificationNumber"
label={t('Tax identification number')}
icon={<HddOutlined />}
/>
</Col>
</Row>
<StyledDivider orientation="left">{t('Contact person')}</StyledDivider>
<FormInput
name="personName"
label={t('Contact person name')}
icon={<UserOutlined />}
/>
<Row gutter={16}>
<Col span={12}>
<FormInput
name="email"
label={t('Email')}
icon={<MailOutlined />}
/>
</Col>
<Col span={12}>
<FormInput
name="phone"
label={t('Phone')}
icon={<PhoneOutlined />}
/>
</Col>
</Row>
</Col>
<Col xs={24} md={12}>
<Checkbox
name="allowedBankPayments"
onClick={() =>
setFieldValue(
'allowedBankPayments',
!values.allowedBankPayments,
)
}
checked={values.allowedBankPayments}
>
{t('Allow bank payments')}
</Checkbox>
<StyledFormItem label={t('Note')}>
<Input.TextArea
rows={4}
name="note"
placeholder={t('customer_note_placeholder')}
onChange={handleChange}
value={values.note || ''}
/>
</StyledFormItem>
</Col>
</Row>
<Row gutter={32}>
{values.addresses
.sort(({ isPrimary }) => (isPrimary ? -1 : 1))
.map((_, i) => (
<Col xs={24} md={12} key={i}>
<StyledDivider orientation="left">
{i === 0 ? t('Shipping address') : t('Billing address')}
</StyledDivider>
<StyledFormItem>
<Input
name={`addresses.${i}.street`}
prefix={<EnvironmentOutlined />}
placeholder={t('Street')}
onChange={handleChange}
value={values.addresses[i].street || ''}
/>
</StyledFormItem>
<Row gutter={12}>
<Col span={16}>
<StyledFormItem>
<Input
name={`addresses.${i}.city`}
prefix={<HomeOutlined />}
placeholder={t('City')}
onChange={handleChange}
value={values.addresses[i].city || ''}
/>
</StyledFormItem>
</Col>
<Col span={8}>
<StyledFormItem>
<Input
name={`addresses.${i}.postNumber`}
prefix={<NumberOutlined />}
placeholder={t('Post Number')}
onChange={handleChange}
value={values.addresses[i].postNumber || ''}
/>
</StyledFormItem>
</Col>
</Row>
</Col>
))}
</Row>
{props.submitButton}
</StyledForm>
)}
</Formik>
);
}