mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Fix/helptext to ts (#20108)
* migrate help-text to TS delete story with js format Update ui/components/component-library/help-text/help-text.types.ts Co-authored-by: George Marshall <georgewrmarshall@gmail.com> add forwardRef add ref in forwardRef final updates to HelpText to TS update HelpText props * form text field * Removing some unused example code --------- Co-authored-by: taeslee <64485716+taeslee@users.noreply.github.com> Co-authored-by: georgewrmarshall <george.marshall@consensys.net>
This commit is contained in:
parent
8ee733c0d5
commit
e923110092
@ -5,14 +5,13 @@ import classnames from 'classnames';
|
|||||||
import {
|
import {
|
||||||
Display,
|
Display,
|
||||||
FlexDirection,
|
FlexDirection,
|
||||||
Severity,
|
|
||||||
Size,
|
Size,
|
||||||
} from '../../../helpers/constants/design-system';
|
} from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
import Box from '../../ui/box/box';
|
import Box from '../../ui/box/box';
|
||||||
|
|
||||||
import { TextField } from '../text-field';
|
import { TextField } from '../text-field';
|
||||||
import { HelpText } from '../help-text';
|
import { HelpText, HelpTextSeverity } from '../help-text';
|
||||||
import { Label } from '../label';
|
import { Label } from '../label';
|
||||||
|
|
||||||
export const FormTextField = ({
|
export const FormTextField = ({
|
||||||
@ -102,7 +101,7 @@ export const FormTextField = ({
|
|||||||
/>
|
/>
|
||||||
{helpText && (
|
{helpText && (
|
||||||
<HelpText
|
<HelpText
|
||||||
severity={error && Severity.Danger}
|
severity={error && HelpTextSeverity.Danger}
|
||||||
marginTop={1}
|
marginTop={1}
|
||||||
{...helpTextProps}
|
{...helpTextProps}
|
||||||
className={classnames(
|
className={classnames(
|
||||||
|
@ -27,7 +27,7 @@ The `HelpText` accepts all props below as well as all [Box](/docs/components-ui-
|
|||||||
`HelpText` renders as a `<p>` tag if the child is a `string` or a `<div>` if the child is an `object`.
|
`HelpText` renders as a `<p>` tag if the child is a `string` or a `<div>` if the child is an `object`.
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Size, IconColor } from '../../../helpers/constants/design-system';
|
import { IconColor } from '../../../helpers/constants/design-system';
|
||||||
import { HelpText, Icon, IconName, IconSize } from '../../component-library';
|
import { HelpText, Icon, IconName, IconSize } from '../../component-library';
|
||||||
|
|
||||||
<HelpText>Plain text</HelpText> // renders as <p>Plain text</p>
|
<HelpText>Plain text</HelpText> // renders as <p>Plain text</p>
|
||||||
@ -44,41 +44,40 @@ import { HelpText, Icon, IconName, IconSize } from '../../component-library';
|
|||||||
|
|
||||||
### Severity
|
### Severity
|
||||||
|
|
||||||
Use the `severity` prop and `SEVERITIES` object to change the severity of the `HelpText`
|
Use the `severity` prop and `HelpTextSeverity` enum to change the severity of the `HelpText`
|
||||||
|
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Story id="components-componentlibrary-helptext--severity-story" />
|
<Story id="components-componentlibrary-helptext--severity-story" />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { SEVERITIES } from '../../../helpers/constants/design-system';
|
import { HelpText, HelpTextSeverity } from '../../component-library';
|
||||||
import { HelpText } from '../../component-library';
|
|
||||||
|
|
||||||
<HelpText>HelpText without severity prop</HelpText>
|
<HelpText>HelpText without severity prop</HelpText>
|
||||||
<HelpText severity={SEVERITIES.DANGER}>
|
<HelpText severity={HelpTextSeverity.Danger}>
|
||||||
HelpText with severity: SEVERITY.DANGER
|
HelpText with severity: SEVERITY.DANGER
|
||||||
</HelpText>
|
</HelpText>
|
||||||
<HelpText severity={SEVERITIES.SUCCESS}>
|
<HelpText severity={HelpTextSeverity.Success}>
|
||||||
HelpText with severity: SEVERITY.SUCCESS
|
HelpText with severity: SEVERITY.SUCCESS
|
||||||
</HelpText>
|
</HelpText>
|
||||||
<HelpText severity={SEVERITIES.WARNING}>
|
<HelpText severity={HelpTextSeverity.Warning}>
|
||||||
HelpText with severity: SEVERITY.WARNING
|
HelpText with severity: SEVERITY.WARNING
|
||||||
</HelpText>
|
</HelpText>
|
||||||
<HelpText severity={SEVERITIES.INFO}>
|
<HelpText severity={HelpTextSeverity.Info}>
|
||||||
HelpText with severity: SEVERITY.INFO
|
HelpText with severity: SEVERITY.INFO
|
||||||
</HelpText>
|
</HelpText>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Color
|
### Color
|
||||||
|
|
||||||
It may be useful to change the color of the `HelpText`. Use the `color` prop and the `Color` object to change the color of the `HelpText`. Defaults to `Color.textDefault`.
|
It may be useful to change the color of the `HelpText`. Use the `color` prop and the `TextColor` enum to change the color of the `HelpText`. Defaults to `TextColor.textDefault`.
|
||||||
|
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Story id="components-componentlibrary-helptext--color-story" />
|
<Story id="components-componentlibrary-helptext--color-story" />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Color } from '../../../helpers/constants/design-system';
|
import { TextColor } from '../../../helpers/constants/design-system';
|
||||||
import { HelpText } from '../../component-library';
|
import { HelpText } from '../../component-library';
|
||||||
|
|
||||||
<HelpText color={TextColor.textDefault}>
|
<HelpText color={TextColor.textDefault}>
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import classnames from 'classnames';
|
|
||||||
|
|
||||||
import {
|
|
||||||
Color,
|
|
||||||
TextVariant,
|
|
||||||
TextColor,
|
|
||||||
SEVERITIES,
|
|
||||||
} from '../../../helpers/constants/design-system';
|
|
||||||
|
|
||||||
import Box from '../../ui/box';
|
|
||||||
|
|
||||||
import { Text } from '../text';
|
|
||||||
|
|
||||||
export const HelpText = ({
|
|
||||||
severity,
|
|
||||||
color = Color.textDefault,
|
|
||||||
className,
|
|
||||||
children,
|
|
||||||
...props
|
|
||||||
}) => {
|
|
||||||
const severityColor = () => {
|
|
||||||
switch (severity) {
|
|
||||||
case SEVERITIES.DANGER:
|
|
||||||
return TextColor.errorDefault;
|
|
||||||
case SEVERITIES.WARNING:
|
|
||||||
return TextColor.warningDefault;
|
|
||||||
case SEVERITIES.SUCCESS:
|
|
||||||
return TextColor.successDefault;
|
|
||||||
case SEVERITIES.INFO:
|
|
||||||
return TextColor.infoDefault;
|
|
||||||
// Defaults to SEVERITIES.INFO
|
|
||||||
default:
|
|
||||||
return TextColor.textDefault;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<Text
|
|
||||||
className={classnames('mm-help-text', className)}
|
|
||||||
as={children && typeof children === 'object' ? 'div' : 'p'}
|
|
||||||
variant={TextVariant.bodyXs}
|
|
||||||
color={severity ? severityColor() : color}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Text>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
HelpText.propTypes = {
|
|
||||||
/**
|
|
||||||
* The color of the HelpText will be overridden if there is a severity passed
|
|
||||||
* Defaults to Color.textDefault
|
|
||||||
*/
|
|
||||||
color: PropTypes.oneOf(Object.values(TextColor)),
|
|
||||||
/**
|
|
||||||
* The content of the help-text
|
|
||||||
*/
|
|
||||||
children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
||||||
/**
|
|
||||||
* Additional classNames to be added to the HelpText component
|
|
||||||
*/
|
|
||||||
className: PropTypes.string,
|
|
||||||
/**
|
|
||||||
* HelpText also accepts all Box props
|
|
||||||
*/
|
|
||||||
...Box.propTypes,
|
|
||||||
};
|
|
@ -1,23 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { StoryFn, Meta } from '@storybook/react';
|
||||||
import {
|
import {
|
||||||
DISPLAY,
|
Display,
|
||||||
FLEX_DIRECTION,
|
FlexDirection,
|
||||||
IconColor,
|
IconColor,
|
||||||
TextColor,
|
TextColor,
|
||||||
SEVERITIES,
|
|
||||||
} from '../../../helpers/constants/design-system';
|
} from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
import Box from '../../ui/box';
|
import { Box, Icon, IconName, IconSize } from '..';
|
||||||
|
|
||||||
import { Icon, IconName, IconSize } from '..';
|
|
||||||
|
|
||||||
import { HelpText } from './help-text';
|
import { HelpText } from './help-text';
|
||||||
|
import { HelpTextSeverity } from './help-text.types';
|
||||||
|
|
||||||
import README from './README.mdx';
|
import README from './README.mdx';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Components/ComponentLibrary/HelpText',
|
title: 'Components/ComponentLibrary/HelpText',
|
||||||
|
|
||||||
component: HelpText,
|
component: HelpText,
|
||||||
parameters: {
|
parameters: {
|
||||||
docs: {
|
docs: {
|
||||||
@ -33,7 +31,7 @@ export default {
|
|||||||
},
|
},
|
||||||
severity: {
|
severity: {
|
||||||
control: 'select',
|
control: 'select',
|
||||||
options: Object.values(SEVERITIES),
|
options: Object.values(HelpTextSeverity),
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
control: 'select',
|
control: 'select',
|
||||||
@ -43,15 +41,15 @@ export default {
|
|||||||
args: {
|
args: {
|
||||||
children: 'Help text',
|
children: 'Help text',
|
||||||
},
|
},
|
||||||
};
|
} as Meta<typeof HelpText>;
|
||||||
|
|
||||||
const Template = (args) => <HelpText {...args} />;
|
const Template: StoryFn<typeof HelpText> = (args) => <HelpText {...args} />;
|
||||||
|
|
||||||
export const DefaultStory = Template.bind({});
|
export const DefaultStory = Template.bind({});
|
||||||
DefaultStory.storyName = 'Default';
|
DefaultStory.storyName = 'Default';
|
||||||
|
|
||||||
export const Children = (args) => (
|
export const Children: StoryFn<typeof HelpText> = (args) => (
|
||||||
<Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.COLUMN} gap={2}>
|
<Box display={Display.Flex} flexDirection={FlexDirection.Column} gap={2}>
|
||||||
<HelpText {...args}>Plain text</HelpText>
|
<HelpText {...args}>Plain text</HelpText>
|
||||||
<HelpText>
|
<HelpText>
|
||||||
<span>Text and icon</span>
|
<span>Text and icon</span>
|
||||||
@ -66,28 +64,28 @@ export const Children = (args) => (
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const SeverityStory = (args) => (
|
export const SeverityStory: StoryFn<typeof HelpText> = (args) => (
|
||||||
<>
|
<>
|
||||||
<HelpText {...args}>HelpText without severity prop</HelpText>
|
<HelpText {...args}>HelpText without severity prop</HelpText>
|
||||||
<HelpText {...args} severity={SEVERITIES.DANGER}>
|
<HelpText {...args} severity={HelpTextSeverity.Danger}>
|
||||||
HelpText with severity: SEVERITY.DANGER
|
HelpText with severity: HelpTextSeverity.Danger
|
||||||
</HelpText>
|
</HelpText>
|
||||||
<HelpText {...args} severity={SEVERITIES.SUCCESS}>
|
<HelpText {...args} severity={HelpTextSeverity.Success}>
|
||||||
HelpText with severity: SEVERITY.SUCCESS
|
HelpText with severity: HelpTextSeverity.Success
|
||||||
</HelpText>
|
</HelpText>
|
||||||
<HelpText {...args} severity={SEVERITIES.WARNING}>
|
<HelpText {...args} severity={HelpTextSeverity.Warning}>
|
||||||
HelpText with severity: SEVERITY.WARNING
|
HelpText with severity: HelpTextSeverity.Warning
|
||||||
</HelpText>
|
</HelpText>
|
||||||
<HelpText {...args} severity={SEVERITIES.INFO}>
|
<HelpText {...args} severity={HelpTextSeverity.Info}>
|
||||||
HelpText with severity: SEVERITY.INFO
|
HelpText with severity: HelpTextSeverity.Info
|
||||||
</HelpText>
|
</HelpText>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
SeverityStory.storyName = 'Severity';
|
SeverityStory.storyName = 'Severity';
|
||||||
|
|
||||||
export const ColorStory = (args) => (
|
export const ColorStory: StoryFn<typeof HelpText> = (args) => (
|
||||||
<Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.COLUMN} gap={2}>
|
<Box display={Display.Flex} flexDirection={FlexDirection.Column} gap={2}>
|
||||||
<HelpText color={TextColor.textDefault} {...args}>
|
<HelpText color={TextColor.textDefault} {...args}>
|
||||||
This HelpText default color is TextColor.textDefault
|
This HelpText default color is TextColor.textDefault
|
||||||
</HelpText>
|
</HelpText>
|
@ -1,10 +1,9 @@
|
|||||||
/* eslint-disable jest/require-top-level-describe */
|
/* eslint-disable jest/require-top-level-describe */
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Color, SEVERITIES } from '../../../helpers/constants/design-system';
|
import { TextColor } from '../../../helpers/constants/design-system';
|
||||||
import { Icon, IconName } from '..';
|
import { Icon, IconName } from '..';
|
||||||
|
import { HelpText, HelpTextSeverity } from '.';
|
||||||
import { HelpText } from './help-text';
|
|
||||||
|
|
||||||
describe('HelpText', () => {
|
describe('HelpText', () => {
|
||||||
it('should render with text inside the HelpText', () => {
|
it('should render with text inside the HelpText', () => {
|
||||||
@ -34,10 +33,10 @@ describe('HelpText', () => {
|
|||||||
it('should render with severities', () => {
|
it('should render with severities', () => {
|
||||||
const { getByText } = render(
|
const { getByText } = render(
|
||||||
<>
|
<>
|
||||||
<HelpText severity={SEVERITIES.DANGER}>error</HelpText>
|
<HelpText severity={HelpTextSeverity.Danger}>error</HelpText>
|
||||||
<HelpText severity={SEVERITIES.SUCCESS}>success</HelpText>
|
<HelpText severity={HelpTextSeverity.Success}>success</HelpText>
|
||||||
<HelpText severity={SEVERITIES.WARNING}>warning</HelpText>
|
<HelpText severity={HelpTextSeverity.Warning}>warning</HelpText>
|
||||||
<HelpText severity={SEVERITIES.INFO}>info</HelpText>
|
<HelpText severity={HelpTextSeverity.Info}>info</HelpText>
|
||||||
</>,
|
</>,
|
||||||
);
|
);
|
||||||
expect(getByText('error')).toHaveClass('mm-box--color-error-default');
|
expect(getByText('error')).toHaveClass('mm-box--color-error-default');
|
||||||
@ -49,9 +48,9 @@ describe('HelpText', () => {
|
|||||||
const { getByText } = render(
|
const { getByText } = render(
|
||||||
<>
|
<>
|
||||||
<HelpText>default</HelpText>
|
<HelpText>default</HelpText>
|
||||||
<HelpText color={Color.textDefault}>text default</HelpText>
|
<HelpText color={TextColor.textDefault}>text default</HelpText>
|
||||||
<HelpText color={Color.textAlternative}>text alternative</HelpText>
|
<HelpText color={TextColor.textAlternative}>text alternative</HelpText>
|
||||||
<HelpText color={Color.textMuted}>text muted</HelpText>
|
<HelpText color={TextColor.textMuted}>text muted</HelpText>
|
||||||
</>,
|
</>,
|
||||||
);
|
);
|
||||||
expect(getByText('default')).toHaveClass('mm-box--color-text-default');
|
expect(getByText('default')).toHaveClass('mm-box--color-text-default');
|
53
ui/components/component-library/help-text/help-text.tsx
Normal file
53
ui/components/component-library/help-text/help-text.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import React, { forwardRef } from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import {
|
||||||
|
TextVariant,
|
||||||
|
TextColor,
|
||||||
|
} from '../../../helpers/constants/design-system';
|
||||||
|
import { Text } from '../text';
|
||||||
|
import type { PolymorphicRef } from '../box';
|
||||||
|
import type { TextProps } from '../text';
|
||||||
|
import type { HelpTextProps, HelpTextComponent } from './help-text.types';
|
||||||
|
import { HelpTextSeverity } from '.';
|
||||||
|
|
||||||
|
export const HelpText: HelpTextComponent = forwardRef(
|
||||||
|
<C extends React.ElementType = 'p'>(
|
||||||
|
{
|
||||||
|
severity,
|
||||||
|
color = TextColor.textDefault,
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: HelpTextProps<C>,
|
||||||
|
ref?: PolymorphicRef<C>,
|
||||||
|
) => {
|
||||||
|
const severityColor = () => {
|
||||||
|
switch (severity) {
|
||||||
|
case HelpTextSeverity.Danger:
|
||||||
|
return TextColor.errorDefault;
|
||||||
|
case HelpTextSeverity.Warning:
|
||||||
|
return TextColor.warningDefault;
|
||||||
|
case HelpTextSeverity.Success:
|
||||||
|
return TextColor.successDefault;
|
||||||
|
case HelpTextSeverity.Info:
|
||||||
|
return TextColor.infoDefault;
|
||||||
|
// Defaults to HelpTextSeverity.Info
|
||||||
|
default:
|
||||||
|
return TextColor.textDefault;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
className={classnames('mm-help-text', className ?? '')}
|
||||||
|
ref={ref}
|
||||||
|
as={children && typeof children === 'object' ? 'div' : 'p'}
|
||||||
|
variant={TextVariant.bodyXs}
|
||||||
|
color={severity ? severityColor() : color}
|
||||||
|
{...(props as TextProps<C>)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
35
ui/components/component-library/help-text/help-text.types.ts
Normal file
35
ui/components/component-library/help-text/help-text.types.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import type { TextStyleUtilityProps } from '../text';
|
||||||
|
import type { PolymorphicComponentPropWithRef } from '../box';
|
||||||
|
import { Severity, TextColor } from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
|
export enum HelpTextSeverity {
|
||||||
|
Danger = Severity.Danger,
|
||||||
|
Warning = Severity.Warning,
|
||||||
|
Success = Severity.Success,
|
||||||
|
Info = Severity.Info,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HelpTextStyleUtilityProps extends TextStyleUtilityProps {
|
||||||
|
severity?: HelpTextSeverity | Severity;
|
||||||
|
/**
|
||||||
|
* The color of the HelpText will be overridden if there is a severity passed
|
||||||
|
* Defaults to Color.textDefault
|
||||||
|
*/
|
||||||
|
color?: TextColor;
|
||||||
|
/**
|
||||||
|
* The content of the help-text
|
||||||
|
*/
|
||||||
|
children: string | PropTypes.ReactNodeLike;
|
||||||
|
/**
|
||||||
|
* Additional classNames to be added to the HelpText component
|
||||||
|
*/
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HelpTextProps<C extends React.ElementType> =
|
||||||
|
PolymorphicComponentPropWithRef<C, HelpTextStyleUtilityProps>;
|
||||||
|
|
||||||
|
export type HelpTextComponent = <C extends React.ElementType = 'span'>(
|
||||||
|
props: HelpTextProps<C>,
|
||||||
|
) => React.ReactElement | null;
|
@ -1 +0,0 @@
|
|||||||
export { HelpText } from './help-text';
|
|
3
ui/components/component-library/help-text/index.ts
Normal file
3
ui/components/component-library/help-text/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export { HelpText } from './help-text';
|
||||||
|
export { HelpTextSeverity } from './help-text.types';
|
||||||
|
export type { HelpTextProps } from './help-text.types';
|
@ -24,7 +24,7 @@ export { ButtonSecondary, BUTTON_SECONDARY_SIZES } from './button-secondary';
|
|||||||
export { Checkbox } from './checkbox';
|
export { Checkbox } from './checkbox';
|
||||||
export { FormTextField } from './form-text-field';
|
export { FormTextField } from './form-text-field';
|
||||||
export { HeaderBase } from './header-base';
|
export { HeaderBase } from './header-base';
|
||||||
export { HelpText } from './help-text';
|
export { HelpText, HelpTextSeverity } from './help-text';
|
||||||
export { Icon, IconName, IconSize } from './icon';
|
export { Icon, IconName, IconSize } from './icon';
|
||||||
export { Label } from './label';
|
export { Label } from './label';
|
||||||
export { PickerNetwork } from './picker-network';
|
export { PickerNetwork } from './picker-network';
|
||||||
|
@ -27,6 +27,7 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
TextField,
|
TextField,
|
||||||
HelpText,
|
HelpText,
|
||||||
|
HelpTextSeverity,
|
||||||
BUTTON_VARIANT,
|
BUTTON_VARIANT,
|
||||||
TEXT_FIELD_SIZES,
|
TEXT_FIELD_SIZES,
|
||||||
TEXT_FIELD_TYPES,
|
TEXT_FIELD_TYPES,
|
||||||
@ -143,7 +144,9 @@ const RevealSeedPage = () => {
|
|||||||
error={error}
|
error={error}
|
||||||
width={BLOCK_SIZES.FULL}
|
width={BLOCK_SIZES.FULL}
|
||||||
/>
|
/>
|
||||||
{error && <HelpText severity={SEVERITIES.DANGER}>{error}</HelpText>}
|
{error && (
|
||||||
|
<HelpText severity={HelpTextSeverity.Danger}>{error}</HelpText>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user