mirror of
https://github.com/coder/coder.git
synced 2026-10-28 02:42:54 +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:
+23
-58
@@ -1,43 +1,10 @@
|
||||
import React from "react"
|
||||
import CssBaseline from "@material-ui/core/CssBaseline"
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import ThemeProvider from "@material-ui/styles/ThemeProvider"
|
||||
|
||||
import { dark } from "../theme"
|
||||
import { SWRConfig } from "swr"
|
||||
import { AppProps } from "next/app"
|
||||
import { Navbar } from "../components/Navbar"
|
||||
import { Footer } from "../components/Page"
|
||||
|
||||
/**
|
||||
* `Contents` is the wrapper around the core app UI,
|
||||
* containing common UI elements like the footer and navbar.
|
||||
*
|
||||
* This can't be inlined in `MyApp` because it requires styling,
|
||||
* and `useStyles` needs to be inside a `<ThemeProvider />`
|
||||
*/
|
||||
const Contents: React.FC<AppProps> = ({ Component, pageProps }) => {
|
||||
const styles = useStyles()
|
||||
|
||||
const header = (
|
||||
<div className={styles.header}>
|
||||
<Navbar />
|
||||
</div>
|
||||
)
|
||||
|
||||
const footer = (
|
||||
<div className={styles.footer}>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
{header}
|
||||
<Component {...pageProps} />
|
||||
{footer}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
import { UserProvider } from "../contexts/UserContext"
|
||||
import { light } from "../theme"
|
||||
|
||||
/**
|
||||
* ClientRender is a component that only allows its children to be rendered
|
||||
@@ -52,32 +19,30 @@ const ClientRender: React.FC = ({ children }) => (
|
||||
* <App /> is the root rendering logic of the application - setting up our router
|
||||
* and any contexts / global state management.
|
||||
*/
|
||||
const MyApp: React.FC<AppProps> = (appProps) => {
|
||||
const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {
|
||||
return (
|
||||
<ClientRender>
|
||||
<ThemeProvider theme={dark}>
|
||||
<CssBaseline />
|
||||
<Contents {...appProps} />
|
||||
</ThemeProvider>
|
||||
<SWRConfig
|
||||
value={{
|
||||
fetcher: async (url: string) => {
|
||||
const res = await fetch(url)
|
||||
if (!res.ok) {
|
||||
const err = new Error((await res.json()).error?.message || res.statusText)
|
||||
throw err
|
||||
}
|
||||
return res.json()
|
||||
},
|
||||
}}
|
||||
>
|
||||
<UserProvider>
|
||||
<ThemeProvider theme={light}>
|
||||
<CssBaseline />
|
||||
<Component {...pageProps} />
|
||||
</ThemeProvider>
|
||||
</UserProvider>
|
||||
</SWRConfig>
|
||||
</ClientRender>
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
root: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
},
|
||||
header: {
|
||||
flex: 0,
|
||||
},
|
||||
body: {
|
||||
height: "100%",
|
||||
flex: 1,
|
||||
},
|
||||
footer: {
|
||||
flex: 0,
|
||||
},
|
||||
}))
|
||||
|
||||
export default MyApp
|
||||
|
||||
+17
-2
@@ -5,9 +5,18 @@ import Paper from "@material-ui/core/Paper"
|
||||
import AddWorkspaceIcon from "@material-ui/icons/AddToQueue"
|
||||
|
||||
import { EmptyState, SplitButton } from "../components"
|
||||
import { Navbar } from "../components/Navbar"
|
||||
import { Footer } from "../components/Page"
|
||||
import { useUser } from "../contexts/UserContext"
|
||||
import { FullScreenLoader } from "../components/Loader/FullScreenLoader"
|
||||
|
||||
const WorkspacesPage: React.FC = () => {
|
||||
const styles = useStyles()
|
||||
const { me } = useUser(true)
|
||||
|
||||
if (!me) {
|
||||
return <FullScreenLoader />
|
||||
}
|
||||
|
||||
const createWorkspace = () => {
|
||||
alert("create")
|
||||
@@ -19,7 +28,8 @@ const WorkspacesPage: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.root}>
|
||||
<Navbar user={me} />
|
||||
<div className={styles.header}>
|
||||
<SplitButton<string>
|
||||
color="primary"
|
||||
@@ -44,11 +54,16 @@ const WorkspacesPage: React.FC = () => {
|
||||
<EmptyState message="No workspaces available." button={button} />
|
||||
</Box>
|
||||
</Paper>
|
||||
</>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
},
|
||||
header: {
|
||||
display: "flex",
|
||||
flexDirection: "row-reverse",
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import React from "react"
|
||||
import { SignInForm } from "./../components/SignIn"
|
||||
|
||||
export const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
container: {
|
||||
marginTop: theme.spacing(-8),
|
||||
minWidth: "320px",
|
||||
maxWidth: "320px",
|
||||
},
|
||||
}))
|
||||
|
||||
export const SignInPage: React.FC = () => {
|
||||
const styles = useStyles()
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.container}>
|
||||
<SignInForm />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SignInPage
|
||||
Reference in New Issue
Block a user