diff --git a/site/components/Workspace/Workspace.stories.tsx b/site/components/Workspace/Workspace.stories.tsx new file mode 100644 index 0000000000000..4e03c3b456e4e --- /dev/null +++ b/site/components/Workspace/Workspace.stories.tsx @@ -0,0 +1,17 @@ +import { Story } from "@storybook/react" +import React from "react" +import { Workspace, WorkspaceProps } from "./Workspace" +import { MockWorkspace } from "../../test_helpers" + +export default { + title: "Workspace", + component: Workspace, + argTypes: {}, +} + +const Template: Story = (args) => + +export const Example = Template.bind({}) +Example.args = { + workspace: MockWorkspace, +} diff --git a/site/components/Workspace/Workspace.test.tsx b/site/components/Workspace/Workspace.test.tsx new file mode 100644 index 0000000000000..245455e729da1 --- /dev/null +++ b/site/components/Workspace/Workspace.test.tsx @@ -0,0 +1,15 @@ +import { render, screen } from "@testing-library/react" +import React from "react" +import { Workspace } from "./Workspace" +import { MockWorkspace } from "../../test_helpers" + +describe("Workspace", () => { + it("renders", async () => { + // When + render() + + // Then + const element = await screen.findByText(MockWorkspace.name) + expect(element).toBeDefined() + }) +}) diff --git a/site/components/Workspace/Workspace.tsx b/site/components/Workspace/Workspace.tsx new file mode 100644 index 0000000000000..23d9cf07d32d9 --- /dev/null +++ b/site/components/Workspace/Workspace.tsx @@ -0,0 +1,90 @@ +import Box from "@material-ui/core/Box" +import Paper from "@material-ui/core/Paper" +import Typography from "@material-ui/core/Typography" +import { makeStyles } from "@material-ui/core/styles" +import CloudCircleIcon from "@material-ui/icons/CloudCircle" +import Link from "next/link" +import React from "react" + +import * as API from "../../api" + +export interface WorkspaceProps { + workspace: API.Workspace +} + +namespace Constants { + export const TitleIconSize = 48 + export const CardRadius = 8 + export const CardPadding = 20 +} + +/** + * Workspace is the top-level component for viewing an individual workspace + */ +export const Workspace: React.FC = ({ workspace }) => { + const styles = useStyles() + + return ( +
+ +
+ ) +} + +/** + * Component for the header at the top of the workspace page + */ +export const WorkspaceHeader: React.FC = ({ workspace }) => { + const styles = useStyles() + + return ( + +
+ +
+ {workspace.name} + + {workspace.project_id} + +
+
+
+ ) +} + +/** + * Component to render the 'Hero Icon' in the header of a workspace + */ +export const WorkspaceHeroIcon: React.FC = () => { + return ( + + + + ) +} + +export const useStyles = makeStyles((theme) => { + return { + root: { + display: "flex", + flexDirection: "column", + }, + horizontal: { + display: "flex", + flexDirection: "row", + }, + vertical: { + display: "flex", + flexDirection: "column", + }, + section: { + border: `1px solid ${theme.palette.divider}`, + borderRadius: Constants.CardRadius, + padding: Constants.CardPadding, + }, + icon: { + width: Constants.TitleIconSize, + height: Constants.TitleIconSize, + }, + } +}) diff --git a/site/components/Workspace/index.ts b/site/components/Workspace/index.ts new file mode 100644 index 0000000000000..4c8c38cc721c8 --- /dev/null +++ b/site/components/Workspace/index.ts @@ -0,0 +1 @@ +export * from "./Workspace" diff --git a/site/pages/workspaces/[user]/[workspace].tsx b/site/pages/workspaces/[user]/[workspace].tsx new file mode 100644 index 0000000000000..6ae0c52713697 --- /dev/null +++ b/site/pages/workspaces/[user]/[workspace].tsx @@ -0,0 +1,68 @@ +import React from "react" +import useSWR from "swr" +import { makeStyles } from "@material-ui/core/styles" +import { useRouter } from "next/router" +import { Navbar } from "../../../components/Navbar" +import { Footer } from "../../../components/Page" +import { useUser } from "../../../contexts/UserContext" +import { firstOrItem } from "../../../util/array" +import { ErrorSummary } from "../../../components/ErrorSummary" +import { FullScreenLoader } from "../../../components/Loader/FullScreenLoader" +import { Workspace } from "../../../components/Workspace" + +import * as API from "../../../api" + +const WorkspacesPage: React.FC = () => { + const styles = useStyles() + const router = useRouter() + const { me, signOut } = useUser(true) + + const { user: userQueryParam, workspace: workspaceQueryParam } = router.query + + const { data: workspace, error: workspaceError } = useSWR(() => { + const userParam = firstOrItem(userQueryParam, null) + const workspaceParam = firstOrItem(workspaceQueryParam, null) + + // TODO(Bryan): Getting non-personal users isn't supported yet in the backend. + // So if the user is the same as 'me', use 'me' as the parameter + const normalizedUserParam = me && userParam === me.id ? "me" : userParam + + // The SWR API expects us to 'throw' if the query isn't ready yet, so these casts to `any` are OK + // because the API expects exceptions. + return `/api/v2/workspaces/${(normalizedUserParam as any).toString()}/${(workspaceParam as any).toString()}` + }) + + if (workspaceError) { + return + } + + if (!me || !workspace) { + return + } + + return ( +
+ + +
+ +
+ +
+
+ ) +} + +const useStyles = makeStyles(() => ({ + root: { + display: "flex", + flexDirection: "column", + }, + inner: { + maxWidth: "1380px", + margin: "1em auto", + width: "100%", + }, +})) + +export default WorkspacesPage pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy