@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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 />} />&nbsp;&nbsp;
                {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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 />&nbsp;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 vote down vote up
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>
                业务组(监控对象、监控大盘、告警规则、自愈脚本都要归属某个业务组)为空,请先&nbsp;
                <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 vote down vote up
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 vote down vote up
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>
	);
}