mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: Initial Login flow (#42)
This just implements a basic sign-in flow, using the new endpoints in #29 :  This brings over several dependencies that are necessary: - `formik` - `yep` Ports over some v1 code to bootstrap it: - `FormTextField` - `PasswordField` - `CoderIcon` And implements basic sign-in: Fixes #37 Fixes #43 This does not implement it navbar integration (importantly - there is no way to sign out yet, unless you manually delete your `session_token`). I'll do that in the next PR - figured this was big enough to get reviewed.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
import { render, screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { LoadingButton } from "./LoadingButton"
|
||||
|
||||
describe("LoadingButton", () => {
|
||||
it("renders", async () => {
|
||||
// When
|
||||
render(<LoadingButton>Sign In</LoadingButton>)
|
||||
|
||||
// Then
|
||||
const element = await screen.findByText("Sign In")
|
||||
expect(element).toBeDefined()
|
||||
})
|
||||
|
||||
it("shows spinner if loading is set to true", async () => {
|
||||
// When
|
||||
render(<LoadingButton loading>Sign in</LoadingButton>)
|
||||
|
||||
// Then
|
||||
const spinnerElement = await screen.findByRole("progressbar")
|
||||
expect(spinnerElement).toBeDefined()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
import Button, { ButtonProps } from "@material-ui/core/Button"
|
||||
import CircularProgress from "@material-ui/core/CircularProgress"
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import * as React from "react"
|
||||
|
||||
export interface LoadingButtonProps extends ButtonProps {
|
||||
/** Whether or not to disable the button and show a spinner */
|
||||
loading?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* LoadingButton is a small wrapper around Material-UI's button to show a loading spinner
|
||||
*
|
||||
* In Material-UI 5+ - this is built-in, but since we're on an earlier version,
|
||||
* we have to roll our own.
|
||||
*/
|
||||
export const LoadingButton: React.FC<LoadingButtonProps> = ({ loading = false, children, ...rest }) => {
|
||||
const styles = useStyles()
|
||||
const hidden = loading ? { opacity: 0 } : undefined
|
||||
|
||||
return (
|
||||
<Button {...rest} disabled={rest.disabled || loading}>
|
||||
<span style={hidden}>{children}</span>
|
||||
{loading && (
|
||||
<div className={styles.loader}>
|
||||
<CircularProgress size={18} className={styles.spinner} />
|
||||
</div>
|
||||
)}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
loader: {
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
height: 18,
|
||||
width: 18,
|
||||
},
|
||||
spinner: {
|
||||
color: theme.palette.text.disabled,
|
||||
},
|
||||
}))
|
||||
@@ -1 +1,2 @@
|
||||
export { SplitButton } from "./SplitButton"
|
||||
export * from "./SplitButton"
|
||||
export * from "./LoadingButton"
|
||||
|
||||
Reference in New Issue
Block a user