Skip to content

Commit 0a5c48a

Browse files
committed
Start scaffolding project selection
1 parent 56f7515 commit 0a5c48a

File tree

7 files changed

+132
-18
lines changed

7 files changed

+132
-18
lines changed

site/api.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
export interface Project {
22
id: string
3+
icon: string
34
name: string
45
description: string
56
}
67

78
export namespace Project {
8-
export const get = async (org: string): Promise<Project[]> => {
9+
export const get = (org: string): Promise<Project[]> => {
910
const project1: Project = {
1011
id: "test-terraform-1",
12+
icon: "https://www.datocms-assets.com/2885/1620155117-brandhcterraformverticalcolorwhite.svg",
1113
name: "Terraform Project 1",
1214
description: "Simple terraform project that deploys a kubernetes provider",
1315
}
1416

1517
const project2: Project = {
1618
id: "test-echo-1",
19+
icon: "https://www.datocms-assets.com/2885/1620155117-brandhcterraformverticalcolorwhite.svg",
1720
name: "Echo Project",
1821
description: "Project built on echo provisioner",
1922
}

site/components/Navbar/index.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ export const Navbar: React.FC = () => {
1818
</Link>
1919
</div>
2020
<div className={styles.fullWidth} />
21-
<div className={styles.fixed}>
22-
<List>
23-
<ListSubheader>Manage</ListSubheader>
24-
</List>
25-
</div>
21+
<div className={styles.fixed} />
2622
</div>
2723
)
2824
}

site/components/Page/FormPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const useStyles = makeStyles(() => ({
1717
marginTop: "1em",
1818
},
1919
body: {
20+
padding: "2em",
2021
flex: "1",
2122
overflowY: "auto",
2223
},
@@ -58,7 +59,6 @@ export const FormPage: React.FC<FormPageProps> = ({ title, organization, childre
5859
{actualButtons.map(({ props, title }) => {
5960
return (
6061
<Button {...props} className={styles.button}>
61-
{" "}
6262
{title}
6363
</Button>
6464
)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from "react"
2+
import { Box, Typography } from "@material-ui/core"
3+
4+
export interface ProjectIconProps {
5+
title: string
6+
icon: string
7+
description?: string
8+
onClick: () => void
9+
}
10+
11+
export const ProjectIcon: React.FC<ProjectIconProps> = ({ title, icon, onClick }) => {
12+
return (
13+
<Box
14+
css={{
15+
flex: "0",
16+
margin: "1em",
17+
display: "flex",
18+
flexDirection: "column",
19+
justifyContent: "center",
20+
alignItems: "center",
21+
border: "1px solid red",
22+
}}
23+
onClick={onClick}
24+
>
25+
<img src={icon} width={"128px"} height={"128px"} />
26+
<Typography>{title}</Typography>
27+
</Box>
28+
)
29+
}

site/hooks/useRequest.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useState, useEffect } from "react"
2+
3+
export type RequestState<TPayload> =
4+
| {
5+
state: "loading"
6+
}
7+
| {
8+
state: "error"
9+
error: Error
10+
}
11+
| {
12+
state: "success"
13+
payload: TPayload
14+
}
15+
16+
export const useRequestor = <TPayload>(fn: () => Promise<TPayload>) => {
17+
const [requestState, setRequestState] = useState<RequestState<TPayload>>({ state: "loading" })
18+
19+
useEffect(() => {
20+
const f = async () => {
21+
try {
22+
const response = await fn()
23+
setRequestState({ state: "success", payload: response })
24+
} catch (err) {
25+
setRequestState({ state: "error", error: err })
26+
}
27+
}
28+
f()
29+
})
30+
31+
return requestState
32+
}
Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,41 @@
11
import React from "react"
22
import { useRouter } from "next/router"
33

4+
import { FormPage, FormButton } from "../../../components/Page"
5+
46
const CreateProjectPage: React.FC = () => {
57
const router = useRouter()
68
const { projectId } = router.query
79

8-
const createWorkspace = () => {
9-
alert("create")
10+
const cancel = () => {
11+
router.back()
1012
}
1113

12-
const button = {
13-
children: "New Workspace",
14-
onClick: createWorkspace,
14+
const submit = () => {
15+
alert("Submitting workspace")
1516
}
1617

17-
return <div>Create Page: {projectId}</div>
18+
const buttons: FormButton[] = [
19+
{
20+
title: "Cancel",
21+
props: {
22+
variant: "outlined",
23+
onClick: cancel,
24+
},
25+
},
26+
{
27+
title: "Submit",
28+
props: {
29+
variant: "contained",
30+
color: "primary",
31+
disabled: false,
32+
type: "submit",
33+
onClick: submit,
34+
},
35+
},
36+
]
37+
38+
return <FormPage title={"Create Project"} organization={"test-org"} buttons={buttons}></FormPage>
1839
}
1940

2041
export default CreateProjectPage

site/pages/workspaces/create/index.tsx

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,44 @@ import React from "react"
22

33
import { useRouter } from "next/router"
44
import { FormPage, FormButton } from "../../../components/Page"
5+
import { useRequestor } from "../../../hooks/useRequest"
6+
import * as Api from "./../../../api"
7+
import CircularProgress from "@material-ui/core/CircularProgress"
8+
import { ProjectIcon } from "../../../components/Project/ProjectIcon"
9+
import Box from "@material-ui/core/Box"
510

611
const CreateSelectProjectPage: React.FC = () => {
712
const router = useRouter()
8-
9-
const createWorkspace = () => {
10-
alert("create")
11-
}
13+
const requestState = useRequestor(() => Api.Project.get("test-org"))
1214

1315
const cancel = () => {
1416
router.back()
1517
}
1618

19+
const next = (projectId: string) => () => {
20+
router.push(`/workspaces/create/${projectId}`)
21+
}
22+
23+
let body
24+
25+
switch (requestState.state) {
26+
case "loading":
27+
body = <CircularProgress />
28+
break
29+
case "error":
30+
body = <>{requestState.error.toString()}</>
31+
break
32+
case "success":
33+
body = (
34+
<>
35+
{requestState.payload.map((project) => {
36+
return <ProjectIcon title={project.name} icon={project.icon} onClick={() => alert("clicked")} />
37+
})}
38+
</>
39+
)
40+
break
41+
}
42+
1743
const buttons: FormButton[] = [
1844
{
1945
title: "Cancel",
@@ -29,11 +55,18 @@ const CreateSelectProjectPage: React.FC = () => {
2955
color: "primary",
3056
disabled: false,
3157
type: "submit",
58+
onClick: next("test1"),
3259
},
3360
},
3461
]
3562

36-
return <FormPage title={"Select Project"} organization={"test-org"} buttons={buttons}></FormPage>
63+
return (
64+
<FormPage title={"Select Project"} organization={"test-org"} buttons={buttons}>
65+
<Box style={{ display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center" }}>
66+
{body}
67+
</Box>
68+
</FormPage>
69+
)
3770
}
3871

3972
export default CreateSelectProjectPage

0 commit comments

Comments
 (0)