Implement new structure
This commit is contained in:
34
src/browser/pages/browse.tsx
Normal file
34
src/browser/pages/browse.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import * as React from "react"
|
||||
import { RouteComponentProps } from "react-router"
|
||||
import { FilesResponse } from "../../common/api"
|
||||
import { HttpError } from "../../common/http"
|
||||
import { getFiles } from "../api"
|
||||
import { RequestError } from "../components/error"
|
||||
|
||||
/**
|
||||
* File browser.
|
||||
*/
|
||||
export const Browse: React.FunctionComponent<RouteComponentProps> = (props) => {
|
||||
const [response, setResponse] = React.useState<FilesResponse>()
|
||||
const [error, setError] = React.useState<HttpError>()
|
||||
|
||||
React.useEffect(() => {
|
||||
getFiles()
|
||||
.then(setResponse)
|
||||
.catch((e) => setError(e.message))
|
||||
}, [props])
|
||||
|
||||
return (
|
||||
<>
|
||||
{error || (response && response.files.length === 0) ? (
|
||||
<RequestError error={error || "Empty directory"} />
|
||||
) : (
|
||||
<ul>
|
||||
{((response && response.files) || []).map((f, i) => (
|
||||
<li key={i}>{f.name}</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
8
src/browser/pages/home.css
Normal file
8
src/browser/pages/home.css
Normal file
@ -0,0 +1,8 @@
|
||||
.orientation-guide {
|
||||
align-items: center;
|
||||
color: #b6b6b6;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
22
src/browser/pages/home.tsx
Normal file
22
src/browser/pages/home.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import * as React from "react"
|
||||
import { RouteComponentProps } from "react-router"
|
||||
import { authenticate } from "../api"
|
||||
|
||||
export const Home: React.FunctionComponent<RouteComponentProps> = (props) => {
|
||||
React.useEffect(() => {
|
||||
authenticate()
|
||||
.then(() => {
|
||||
// TEMP: Always redirect to VS Code.
|
||||
props.history.push("./vscode/")
|
||||
})
|
||||
.catch(() => {
|
||||
props.history.push("./login/")
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="orientation-guide">
|
||||
<div className="welcome">Welcome to code-server.</div>
|
||||
</div>
|
||||
)
|
||||
}
|
35
src/browser/pages/login.css
Normal file
35
src/browser/pages/login.css
Normal file
@ -0,0 +1,35 @@
|
||||
.login-form {
|
||||
align-items: center;
|
||||
color: rgba(0, 0, 0, 0.37);
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
font-weight: 700;
|
||||
justify-content: center;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.login-form > .field {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-form > .field-error {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.login-form > .field > .input {
|
||||
border: 1px solid #b6b6b6;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.login-form > .field > .submit {
|
||||
background-color: transparent;
|
||||
border: 1px solid #b6b6b6;
|
||||
box-sizing: border-box;
|
||||
margin-left: -1px;
|
||||
padding: 10px 20px;
|
||||
}
|
55
src/browser/pages/login.tsx
Normal file
55
src/browser/pages/login.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import * as React from "react"
|
||||
import { RouteComponentProps } from "react-router"
|
||||
import { HttpError } from "../../common/http"
|
||||
import { authenticate } from "../api"
|
||||
import { FieldError } from "../components/error"
|
||||
|
||||
/**
|
||||
* Login page. Will redirect on success.
|
||||
*/
|
||||
export const Login: React.FunctionComponent<RouteComponentProps> = (props) => {
|
||||
const [password, setPassword] = React.useState<string>("")
|
||||
const [error, setError] = React.useState<HttpError>()
|
||||
|
||||
function redirect(): void {
|
||||
// TEMP: Always redirect to VS Code.
|
||||
console.log("is authed")
|
||||
props.history.push("../vscode/")
|
||||
// const params = new URLSearchParams(window.location.search)
|
||||
// props.history.push(params.get("to") || "/")
|
||||
}
|
||||
|
||||
async function handleSubmit(event: React.FormEvent<HTMLFormElement>): Promise<void> {
|
||||
event.preventDefault()
|
||||
authenticate({ password })
|
||||
.then(redirect)
|
||||
.catch(setError)
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
authenticate()
|
||||
.then(redirect)
|
||||
.catch(() => {
|
||||
// Do nothing; we're already at the login page.
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<form className="login-form" onSubmit={handleSubmit}>
|
||||
<div className="field">
|
||||
<input
|
||||
autoFocus
|
||||
className="input"
|
||||
type="password"
|
||||
placeholder="password"
|
||||
autoComplete="current-password"
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>): void => setPassword(event.target.value)}
|
||||
/>
|
||||
<button className="submit" type="submit">
|
||||
Log In
|
||||
</button>
|
||||
</div>
|
||||
{error ? <FieldError error={error} /> : undefined}
|
||||
</form>
|
||||
)
|
||||
}
|
29
src/browser/pages/open.tsx
Normal file
29
src/browser/pages/open.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import * as React from "react"
|
||||
import { Application } from "../../common/api"
|
||||
import { getApplications } from "../api"
|
||||
import { ApplicationSection, AppLoader } from "../components/list"
|
||||
|
||||
export interface OpenProps {
|
||||
app?: Application
|
||||
setApp(app: Application): void
|
||||
}
|
||||
|
||||
/**
|
||||
* Display recently used applications.
|
||||
*/
|
||||
export const Open: React.FunctionComponent<OpenProps> = (props) => {
|
||||
return (
|
||||
<AppLoader
|
||||
getApps={async (): Promise<ReadonlyArray<ApplicationSection>> => {
|
||||
const response = await getApplications()
|
||||
return [
|
||||
{
|
||||
header: "Applications",
|
||||
apps: response && response.applications,
|
||||
},
|
||||
]
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
33
src/browser/pages/recent.tsx
Normal file
33
src/browser/pages/recent.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import * as React from "react"
|
||||
import { Application } from "../../common/api"
|
||||
import { getRecent } from "../api"
|
||||
import { ApplicationSection, AppLoader } from "../components/list"
|
||||
|
||||
export interface RecentProps {
|
||||
app?: Application
|
||||
setApp(app: Application): void
|
||||
}
|
||||
|
||||
/**
|
||||
* Display recently used applications.
|
||||
*/
|
||||
export const Recent: React.FunctionComponent<RecentProps> = (props) => {
|
||||
return (
|
||||
<AppLoader
|
||||
getApps={async (): Promise<ReadonlyArray<ApplicationSection>> => {
|
||||
const response = await getRecent()
|
||||
return [
|
||||
{
|
||||
header: "Running Applications",
|
||||
apps: response && response.running,
|
||||
},
|
||||
{
|
||||
header: "Recent Applications",
|
||||
apps: response && response.recent,
|
||||
},
|
||||
]
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
Reference in New Issue
Block a user