mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
refactor: remove index files from components (#1086)
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
import React from "react"
|
||||
import { Route, Routes } from "react-router-dom"
|
||||
import { RequireAuth } from "./components"
|
||||
import { AuthAndFrame } from "./components/AuthAndFrame/AuthAndFrame"
|
||||
import { RequireAuth } from "./components/Page/RequireAuth"
|
||||
import { PreferencesLayout } from "./components/Preferences/Layout"
|
||||
import { IndexPage } from "./pages"
|
||||
import { NotFoundPage } from "./pages/404"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react"
|
||||
import { Navbar } from "../Navbar"
|
||||
import { Navbar } from "../Navbar/Navbar"
|
||||
import { Footer } from "../Page/Footer"
|
||||
import { RequireAuth } from "../Page/RequireAuth"
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
export * from "./CopyButton"
|
||||
export * from "./LoadingButton"
|
||||
export * from "./SplitButton"
|
@ -1,6 +1,6 @@
|
||||
import { Story } from "@storybook/react"
|
||||
import React from "react"
|
||||
import { CodeBlock, CodeBlockProps } from "./index"
|
||||
import { CodeBlock, CodeBlockProps } from "./CodeBlock"
|
||||
|
||||
const sampleLines = `Successfully assigned coder/image-jcws7 to cluster-1
|
||||
Container image "gcr.io/coder-dogfood/master/coder-dev-ubuntu@sha256" already present on machine
|
@ -1,7 +1,7 @@
|
||||
import { screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { render } from "../../testHelpers"
|
||||
import { CodeBlock } from "./index"
|
||||
import { CodeBlock } from "./CodeBlock"
|
||||
|
||||
describe("CodeBlock", () => {
|
||||
it("renders lines)", async () => {
|
@ -1,7 +1,7 @@
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import React from "react"
|
||||
import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
|
||||
import { CopyButton } from "../Button"
|
||||
import { CopyButton } from "../Button/CopyButton"
|
||||
|
||||
export interface CodeExampleProps {
|
||||
code: string
|
||||
|
@ -1 +0,0 @@
|
||||
export * from "./CodeExample"
|
@ -1,7 +1,7 @@
|
||||
import { screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { render } from "../../testHelpers"
|
||||
import { EmptyState } from "./index"
|
||||
import { EmptyState } from "./EmptyState"
|
||||
|
||||
describe("EmptyState", () => {
|
||||
it("renders (smoke test)", async () => {
|
@ -1,6 +1,6 @@
|
||||
import { ComponentMeta, Story } from "@storybook/react"
|
||||
import React from "react"
|
||||
import { ErrorSummary, ErrorSummaryProps } from "."
|
||||
import { ErrorSummary, ErrorSummaryProps } from "./ErrorSummary"
|
||||
|
||||
export default {
|
||||
title: "components/ErrorSummary",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { render, screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { ErrorSummary } from "./index"
|
||||
import { ErrorSummary } from "./ErrorSummary"
|
||||
|
||||
describe("ErrorSummary", () => {
|
||||
it("renders", async () => {
|
@ -1,5 +1,5 @@
|
||||
import { FormikContextType } from "formik/dist/types"
|
||||
import { getFormHelpers, onChangeTrimmed } from "./index"
|
||||
import { getFormHelpers, onChangeTrimmed } from "./utils"
|
||||
|
||||
interface TestType {
|
||||
untouchedGoodField: string
|
@ -1,12 +1,6 @@
|
||||
import { FormikContextType, getIn } from "formik"
|
||||
import { ChangeEvent, ChangeEventHandler, FocusEventHandler } from "react"
|
||||
|
||||
export * from "./FormCloseButton"
|
||||
export * from "./FormDropdownField"
|
||||
export * from "./FormSection"
|
||||
export * from "./FormTextField"
|
||||
export * from "./FormTitle"
|
||||
|
||||
interface FormHelpers {
|
||||
name: string
|
||||
onBlur: FocusEventHandler
|
@ -1,7 +1,7 @@
|
||||
import { screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { render } from "../../testHelpers"
|
||||
import { Header } from "./index"
|
||||
import { Header } from "./Header"
|
||||
|
||||
describe("Header", () => {
|
||||
it("renders title and subtitle", async () => {
|
@ -1,7 +1,7 @@
|
||||
import { useActor } from "@xstate/react"
|
||||
import React, { useContext } from "react"
|
||||
import { XServiceContext } from "../../xServices/StateContext"
|
||||
import { NavbarView } from "./NavbarView"
|
||||
import { NavbarView } from "./NavbarView/NavbarView"
|
||||
|
||||
export const Navbar: React.FC = () => {
|
||||
const xServices = useContext(XServiceContext)
|
@ -1,6 +1,6 @@
|
||||
import { Story } from "@storybook/react"
|
||||
import React from "react"
|
||||
import { NavbarView, NavbarViewProps } from "."
|
||||
import { NavbarView, NavbarViewProps } from "./NavbarView"
|
||||
|
||||
export default {
|
||||
title: "components/NavbarView",
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { NavbarView } from "."
|
||||
import { render } from "../../../testHelpers"
|
||||
import { MockUser } from "../../../testHelpers/entities"
|
||||
import { NavbarView } from "./NavbarView"
|
||||
|
||||
describe("NavbarView", () => {
|
||||
const noop = () => {
|
||||
|
@ -7,7 +7,7 @@ import { UserResponse } from "../../../api/types"
|
||||
import { navHeight } from "../../../theme/constants"
|
||||
import { AdminDropdown } from "../../AdminDropdown/AdminDropdown"
|
||||
import { Logo } from "../../Icons/Logo"
|
||||
import { UserDropdown } from "../UserDropdown"
|
||||
import { UserDropdown } from "../UserDropdown/UsersDropdown"
|
||||
|
||||
export interface NavbarViewProps {
|
||||
user?: UserResponse
|
@ -1,7 +1,7 @@
|
||||
import Box from "@material-ui/core/Box"
|
||||
import { Story } from "@storybook/react"
|
||||
import React from "react"
|
||||
import { UserDropdown, UserDropdownProps } from "."
|
||||
import { UserDropdown, UserDropdownProps } from "./UsersDropdown"
|
||||
|
||||
export default {
|
||||
title: "components/UserDropdown",
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { Language, UserDropdown, UserDropdownProps } from "."
|
||||
import { render } from "../../../testHelpers"
|
||||
import { MockUser } from "../../../testHelpers/entities"
|
||||
import { Language, UserDropdown, UserDropdownProps } from "./UsersDropdown"
|
||||
|
||||
const renderAndClick = async (props: Partial<UserDropdownProps> = {}) => {
|
||||
render(<UserDropdown user={props.user ?? MockUser} onSignOut={props.onSignOut ?? jest.fn()} />)
|
||||
|
@ -12,7 +12,7 @@ import { BorderedMenu } from "../../BorderedMenu/BorderedMenu"
|
||||
import { CloseDropdown, OpenDropdown } from "../../DropdownArrows/DropdownArrows"
|
||||
import { DocsIcon } from "../../Icons/DocsIcon"
|
||||
import { LogoutIcon } from "../../Icons/LogoutIcon"
|
||||
import { UserAvatar } from "../../User"
|
||||
import { UserAvatar } from "../../User/UserAvatar"
|
||||
import { UserProfileCard } from "../../User/UserProfileCard"
|
||||
|
||||
export const Language = {
|
@ -1,2 +0,0 @@
|
||||
export * from "./Footer"
|
||||
export * from "./RequireAuth"
|
@ -3,9 +3,9 @@ import TextField from "@material-ui/core/TextField"
|
||||
import { FormikContextType, FormikErrors, useFormik } from "formik"
|
||||
import React from "react"
|
||||
import * as Yup from "yup"
|
||||
import { getFormHelpers, onChangeTrimmed } from "../Form"
|
||||
import { getFormHelpers, onChangeTrimmed } from "../Form/utils"
|
||||
import { Stack } from "../Stack/Stack"
|
||||
import { LoadingButton } from "./../Button"
|
||||
import { LoadingButton } from "./../Button/LoadingButton"
|
||||
|
||||
interface AccountFormValues {
|
||||
name: string
|
||||
|
@ -2,7 +2,7 @@ import Box from "@material-ui/core/Box"
|
||||
import React from "react"
|
||||
import { Outlet } from "react-router-dom"
|
||||
import { AuthAndFrame } from "../AuthAndFrame/AuthAndFrame"
|
||||
import { TabPanel } from "../TabPanel"
|
||||
import { TabPanel } from "../TabPanel/TabPanel"
|
||||
|
||||
export const Language = {
|
||||
accountLabel: "Account",
|
||||
|
@ -2,7 +2,7 @@ import Button from "@material-ui/core/Button"
|
||||
import TextField from "@material-ui/core/TextField"
|
||||
import { Story } from "@storybook/react"
|
||||
import React from "react"
|
||||
import { Section, SectionProps } from "./"
|
||||
import { Section, SectionProps } from "./Section"
|
||||
|
||||
export default {
|
||||
title: "components/Section",
|
||||
|
@ -2,7 +2,7 @@ import Paper from "@material-ui/core/Paper"
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import Typography from "@material-ui/core/Typography"
|
||||
import React from "react"
|
||||
import { CodeExample } from "../CodeExample"
|
||||
import { CodeExample } from "../CodeExample/CodeExample"
|
||||
|
||||
export interface CliAuthTokenProps {
|
||||
sessionToken: string
|
||||
|
@ -4,8 +4,8 @@ import TextField from "@material-ui/core/TextField"
|
||||
import { FormikContextType, useFormik } from "formik"
|
||||
import React from "react"
|
||||
import * as Yup from "yup"
|
||||
import { getFormHelpers, onChangeTrimmed } from "../Form"
|
||||
import { LoadingButton } from "./../Button"
|
||||
import { getFormHelpers, onChangeTrimmed } from "../Form/utils"
|
||||
import { LoadingButton } from "./../Button/LoadingButton"
|
||||
import { Welcome } from "./Welcome"
|
||||
|
||||
/**
|
||||
|
@ -1,2 +0,0 @@
|
||||
export * from "./CliAuthToken"
|
||||
export * from "./SignInForm"
|
@ -1,5 +1,10 @@
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import React, { useCallback, useState } from "react"
|
||||
import { useCustomEvent } from "../../hooks/events"
|
||||
import { CustomEventListener } from "../../util/events"
|
||||
import { ErrorIcon } from "../Icons/ErrorIcon"
|
||||
import { Typography } from "../Typography/Typography"
|
||||
import { EnterpriseSnackbar } from "./EnterpriseSnackbar"
|
||||
import {
|
||||
AdditionalMessage,
|
||||
isNotificationList,
|
||||
@ -8,12 +13,7 @@ import {
|
||||
MsgType,
|
||||
NotificationMsg,
|
||||
SnackbarEventType,
|
||||
} from "."
|
||||
import { useCustomEvent } from "../../hooks/events"
|
||||
import { CustomEventListener } from "../../util/events"
|
||||
import { ErrorIcon } from "../Icons/ErrorIcon"
|
||||
import { Typography } from "../Typography/Typography"
|
||||
import { EnterpriseSnackbar } from "./EnterpriseSnackbar"
|
||||
} from "./utils"
|
||||
|
||||
export const GlobalSnackbar: React.FC = () => {
|
||||
const styles = useStyles()
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { displaySuccess, isNotificationTextPrefixed, MsgType, NotificationMsg } from "./index"
|
||||
import { displaySuccess, isNotificationTextPrefixed, MsgType, NotificationMsg } from "./utils"
|
||||
|
||||
describe("Snackbar", () => {
|
||||
describe("isNotificationTextPrefixed", () => {
|
@ -1,11 +1,5 @@
|
||||
import { dispatchCustomEvent } from "../../util/events"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Notification Component
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
export { GlobalSnackbar } from "./GlobalSnackbar"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Notification Types
|
||||
///////////////////////////////////////////////////////////////////////////////
|
@ -1,6 +1,6 @@
|
||||
import { Story } from "@storybook/react"
|
||||
import React from "react"
|
||||
import { TabPanel, TabPanelProps } from "."
|
||||
import { TabPanel, TabPanelProps } from "./TabPanel"
|
||||
|
||||
export default {
|
||||
title: "components/TabPanel",
|
||||
|
@ -3,7 +3,7 @@ import Link from "@material-ui/core/Link"
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import Typography from "@material-ui/core/Typography"
|
||||
import React from "react"
|
||||
import { UserAvatar, UserAvatarProps } from "../../User"
|
||||
import { UserAvatar, UserAvatarProps } from "../../User/UserAvatar"
|
||||
|
||||
export interface UserCellProps {
|
||||
Avatar: UserAvatarProps
|
||||
|
@ -1 +0,0 @@
|
||||
export * from "./Table"
|
@ -1,2 +0,0 @@
|
||||
export * from "./UserAvatar"
|
||||
export * from "./UserProfileCard"
|
@ -1,7 +1,7 @@
|
||||
import React from "react"
|
||||
import { UserResponse } from "../../api/types"
|
||||
import { Column, Table } from "../../components/Table"
|
||||
import { EmptyState } from "../EmptyState"
|
||||
import { Column, Table } from "../../components/Table/Table"
|
||||
import { EmptyState } from "../EmptyState/EmptyState"
|
||||
import { UserCell } from "../Table/Cells/UserCell"
|
||||
|
||||
const Language = {
|
||||
|
@ -1 +0,0 @@
|
||||
export * from "./Workspace"
|
@ -1,3 +0,0 @@
|
||||
export * from "./Button"
|
||||
export * from "./EmptyState"
|
||||
export * from "./Page"
|
@ -4,15 +4,12 @@ import { FormikContextType, useFormik } from "formik"
|
||||
import React from "react"
|
||||
import * as Yup from "yup"
|
||||
import { CreateTemplateRequest, Organization, Provisioner, Template } from "../api/types"
|
||||
import { LoadingButton } from "../components/Button"
|
||||
import {
|
||||
DropdownItem,
|
||||
FormCloseButton,
|
||||
FormDropdownField,
|
||||
FormSection,
|
||||
FormTextField,
|
||||
FormTitle,
|
||||
} from "../components/Form"
|
||||
import { LoadingButton } from "../components/Button/LoadingButton"
|
||||
import { FormCloseButton } from "../components/Form/FormCloseButton"
|
||||
import { DropdownItem, FormDropdownField } from "../components/Form/FormDropdownField"
|
||||
import { FormSection } from "../components/Form/FormSection"
|
||||
import { FormTextField } from "../components/Form/FormTextField"
|
||||
import { FormTitle } from "../components/Form/FormTitle"
|
||||
|
||||
export interface CreateTemplateFormProps {
|
||||
provisioners: Provisioner[]
|
||||
|
@ -4,8 +4,11 @@ import { FormikContextType, useFormik } from "formik"
|
||||
import React from "react"
|
||||
import * as Yup from "yup"
|
||||
import { CreateWorkspaceRequest, Template, Workspace } from "../api/types"
|
||||
import { LoadingButton } from "../components/Button"
|
||||
import { FormCloseButton, FormSection, FormTextField, FormTitle } from "../components/Form"
|
||||
import { LoadingButton } from "../components/Button/LoadingButton"
|
||||
import { FormCloseButton } from "../components/Form/FormCloseButton"
|
||||
import { FormSection } from "../components/Form/FormSection"
|
||||
import { FormTextField } from "../components/Form/FormTextField"
|
||||
import { FormTitle } from "../components/Form/FormTitle"
|
||||
|
||||
export interface CreateWorkspaceForm {
|
||||
template: Template
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useActor } from "@xstate/react"
|
||||
import React, { useContext } from "react"
|
||||
import { ErrorSummary } from "../../components/ErrorSummary"
|
||||
import { ErrorSummary } from "../../components/ErrorSummary/ErrorSummary"
|
||||
import { XServiceContext } from "../../xServices/StateContext"
|
||||
import { UsersPageView } from "./UsersPageView"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import React from "react"
|
||||
import { Pager, UserResponse } from "../../api/types"
|
||||
import { Header } from "../../components/Header"
|
||||
import { Header } from "../../components/Header/Header"
|
||||
import { UsersTable } from "../../components/UsersTable/UsersTable"
|
||||
|
||||
export const Language = {
|
||||
|
@ -3,7 +3,7 @@ import { useActor } from "@xstate/react"
|
||||
import React, { useContext, useEffect, useState } from "react"
|
||||
import { getApiKey } from "../api"
|
||||
import { FullScreenLoader } from "../components/Loader/FullScreenLoader"
|
||||
import { CliAuthToken } from "../components/SignIn"
|
||||
import { CliAuthToken } from "../components/SignIn/CliAuthToken"
|
||||
import { XServiceContext } from "../xServices/StateContext"
|
||||
|
||||
export const CliAuthenticationPage: React.FC = () => {
|
||||
|
@ -5,7 +5,7 @@ import { Navigate, useLocation } from "react-router-dom"
|
||||
import { Footer } from "../components/Page/Footer"
|
||||
import { retrieveRedirect } from "../util/redirect"
|
||||
import { XServiceContext } from "../xServices/StateContext"
|
||||
import { SignInForm } from "./../components/SignIn"
|
||||
import { SignInForm } from "./../components/SignIn/SignInForm"
|
||||
|
||||
export const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -2,7 +2,7 @@ import { useActor } from "@xstate/react"
|
||||
import React, { useContext } from "react"
|
||||
import { isApiError, mapApiErrorToFieldErrors } from "../../api/errors"
|
||||
import { AccountForm } from "../../components/Preferences/AccountForm"
|
||||
import { Section } from "../../components/Section"
|
||||
import { Section } from "../../components/Section/Section"
|
||||
import { XServiceContext } from "../../xServices/StateContext"
|
||||
|
||||
export const Language = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react"
|
||||
import { Section } from "../../components/Section"
|
||||
import { Section } from "../../components/Section/Section"
|
||||
|
||||
const Language = {
|
||||
title: "Linked Accounts",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react"
|
||||
import { Section } from "../../components/Section"
|
||||
import { Section } from "../../components/Section/Section"
|
||||
|
||||
const Language = {
|
||||
title: "Security",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react"
|
||||
import { Section } from "../../components/Section"
|
||||
import { Section } from "../../components/Section/Section"
|
||||
|
||||
const Language = {
|
||||
title: "SSH Keys",
|
||||
|
@ -4,7 +4,7 @@ import { useNavigate, useParams } from "react-router-dom"
|
||||
import useSWR from "swr"
|
||||
import * as API from "../../../../api"
|
||||
import * as Types from "../../../../api/types"
|
||||
import { ErrorSummary } from "../../../../components/ErrorSummary"
|
||||
import { ErrorSummary } from "../../../../components/ErrorSummary/ErrorSummary"
|
||||
import { FullScreenLoader } from "../../../../components/Loader/FullScreenLoader"
|
||||
import { CreateWorkspaceForm } from "../../../../forms/CreateWorkspaceForm"
|
||||
import { unsafeSWRArgument } from "../../../../util"
|
||||
|
@ -4,11 +4,11 @@ import React from "react"
|
||||
import { Link, useNavigate, useParams } from "react-router-dom"
|
||||
import useSWR from "swr"
|
||||
import { Organization, Template, Workspace } from "../../../../api/types"
|
||||
import { EmptyState } from "../../../../components/EmptyState"
|
||||
import { ErrorSummary } from "../../../../components/ErrorSummary"
|
||||
import { Header } from "../../../../components/Header"
|
||||
import { EmptyState } from "../../../../components/EmptyState/EmptyState"
|
||||
import { ErrorSummary } from "../../../../components/ErrorSummary/ErrorSummary"
|
||||
import { Header } from "../../../../components/Header/Header"
|
||||
import { FullScreenLoader } from "../../../../components/Loader/FullScreenLoader"
|
||||
import { Column, Table } from "../../../../components/Table"
|
||||
import { Column, Table } from "../../../../components/Table/Table"
|
||||
import { unsafeSWRArgument } from "../../../../util"
|
||||
import { firstOrItem } from "../../../../util/array"
|
||||
|
||||
|
@ -4,12 +4,12 @@ import React from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import useSWR from "swr"
|
||||
import { Organization, Template } from "../../api/types"
|
||||
import { EmptyState } from "../../components"
|
||||
import { CodeExample } from "../../components/CodeExample/CodeExample"
|
||||
import { ErrorSummary } from "../../components/ErrorSummary"
|
||||
import { Header } from "../../components/Header"
|
||||
import { EmptyState } from "../../components/EmptyState/EmptyState"
|
||||
import { ErrorSummary } from "../../components/ErrorSummary/ErrorSummary"
|
||||
import { Header } from "../../components/Header/Header"
|
||||
import { FullScreenLoader } from "../../components/Loader/FullScreenLoader"
|
||||
import { Column, Table } from "../../components/Table"
|
||||
import { Column, Table } from "../../components/Table/Table"
|
||||
|
||||
export const TemplatesPage: React.FC = () => {
|
||||
const styles = useStyles()
|
||||
|
@ -3,9 +3,9 @@ import React from "react"
|
||||
import { useParams } from "react-router-dom"
|
||||
import useSWR from "swr"
|
||||
import * as Types from "../../api/types"
|
||||
import { ErrorSummary } from "../../components/ErrorSummary"
|
||||
import { ErrorSummary } from "../../components/ErrorSummary/ErrorSummary"
|
||||
import { FullScreenLoader } from "../../components/Loader/FullScreenLoader"
|
||||
import { Workspace } from "../../components/Workspace"
|
||||
import { Workspace } from "../../components/Workspace/Workspace"
|
||||
import { unsafeSWRArgument } from "../../util"
|
||||
import { firstOrItem } from "../../util/array"
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { render as wrappedRender, RenderResult } from "@testing-library/react"
|
||||
import { createMemoryHistory } from "history"
|
||||
import React from "react"
|
||||
import { MemoryRouter, Route, Routes, unstable_HistoryRouter as HistoryRouter } from "react-router-dom"
|
||||
import { RequireAuth } from "../components"
|
||||
import { RequireAuth } from "../components/Page/RequireAuth"
|
||||
import { dark } from "../theme"
|
||||
import { XServiceProvider } from "../xServices/StateContext"
|
||||
import { MockUser } from "./entities"
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { assign, createMachine } from "xstate"
|
||||
import * as API from "../../api"
|
||||
import * as Types from "../../api/types"
|
||||
import { displaySuccess } from "../../components/Snackbar"
|
||||
import { displaySuccess } from "../../components/Snackbar/utils"
|
||||
|
||||
export const Language = {
|
||||
successProfileUpdate: "Updated preferences.",
|
||||
|
Reference in New Issue
Block a user