Skip to content

Commit d532a2b

Browse files
committed
yay
1 parent 6443abc commit d532a2b

File tree

5 files changed

+183
-13
lines changed

5 files changed

+183
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { CreateOrganizationPageView } from "./CreateOrganizationPageView";
3+
4+
const meta: Meta<typeof CreateOrganizationPageView> = {
5+
title: "pages/CreateOrganizationPageView",
6+
component: CreateOrganizationPageView,
7+
};
8+
9+
export default meta;
10+
type Story = StoryObj<typeof CreateOrganizationPageView>;
11+
12+
export const Example: Story = {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { type Interpolation, type Theme } from "@emotion/react";
2+
import { type FC, type HTMLAttributes, type ReactNode } from "react";
3+
4+
export const HorizontalContainer: FC<HTMLAttributes<HTMLDivElement>> = ({
5+
...attrs
6+
}) => {
7+
return <div css={styles.horizontalContainer} {...attrs} />;
8+
};
9+
10+
interface HorizontalSectionProps
11+
extends Omit<HTMLAttributes<HTMLElement>, "title"> {
12+
title: ReactNode;
13+
description: ReactNode;
14+
children?: ReactNode;
15+
}
16+
17+
export const HorizontalSection: FC<HorizontalSectionProps> = ({
18+
children,
19+
title,
20+
description,
21+
...attrs
22+
}) => {
23+
return (
24+
<section css={styles.formSection} {...attrs}>
25+
<div css={styles.formSectionInfo}>
26+
<h2 css={styles.formSectionInfoTitle}>{title}</h2>
27+
<div css={styles.formSectionInfoDescription}>{description}</div>
28+
</div>
29+
30+
{children}
31+
</section>
32+
);
33+
};
34+
35+
const styles = {
36+
horizontalContainer: (theme) => ({
37+
display: "flex",
38+
flexDirection: "column",
39+
gap: 80,
40+
41+
[theme.breakpoints.down("md")]: {
42+
gap: 64,
43+
},
44+
}),
45+
46+
formSection: (theme) => ({
47+
display: "flex",
48+
flexDirection: "row",
49+
gap: 120,
50+
51+
[theme.breakpoints.down("lg")]: {
52+
flexDirection: "column",
53+
gap: 16,
54+
},
55+
}),
56+
57+
formSectionInfo: (theme) => ({
58+
width: "100%",
59+
flexShrink: 0,
60+
top: 24,
61+
maxWidth: 312,
62+
position: "sticky",
63+
64+
[theme.breakpoints.down("md")]: {
65+
width: "100%",
66+
position: "initial" as const,
67+
},
68+
}),
69+
70+
formSectionInfoTitle: (theme) => ({
71+
fontSize: 20,
72+
color: theme.palette.text.primary,
73+
fontWeight: 400,
74+
margin: 0,
75+
marginBottom: 8,
76+
display: "flex",
77+
flexDirection: "row",
78+
alignItems: "center",
79+
gap: 12,
80+
}),
81+
82+
formSectionInfoDescription: (theme) => ({
83+
fontSize: 14,
84+
color: theme.palette.text.secondary,
85+
lineHeight: "160%",
86+
margin: 0,
87+
}),
88+
} satisfies Record<string, Interpolation<Theme>>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { OrganizationSettingsPageView } from "./OrganizationSettingsPageView";
3+
import { MockOrganization } from "testHelpers/entities";
4+
5+
const meta: Meta<typeof OrganizationSettingsPageView> = {
6+
title: "pages/OrganizationSettingsPageView",
7+
component: OrganizationSettingsPageView,
8+
args: {
9+
org: MockOrganization,
10+
},
11+
};
12+
13+
export default meta;
14+
type Story = StoryObj<typeof OrganizationSettingsPageView>;
15+
16+
export const Example: Story = {};

site/src/pages/ManagementSettingsPage/OrganizationSettingsPageView.tsx

+58-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Interpolation, Theme } from "@emotion/react";
22
import Button from "@mui/material/Button";
33
import TextField from "@mui/material/TextField";
44
import { useFormik } from "formik";
5-
import type { FC } from "react";
5+
import { type FC, useState } from "react";
66
import * as Yup from "yup";
77
import type {
88
Organization,
@@ -22,6 +22,8 @@ import {
2222
displayNameValidator,
2323
onChangeTrimmed,
2424
} from "utils/formUtils";
25+
import { HorizontalContainer, HorizontalSection } from "./Horizontal";
26+
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
2527

2628
const MAX_DESCRIPTION_CHAR_LIMIT = 128;
2729
const MAX_DESCRIPTION_MESSAGE = `Please enter a description that is no longer than ${MAX_DESCRIPTION_CHAR_LIMIT} characters.`;
@@ -59,6 +61,8 @@ export const OrganizationSettingsPageView: FC<
5961
});
6062
const getFieldHelpers = getFormHelpers(form, error);
6163

64+
const [isDeleting, setIsDeleting] = useState(false);
65+
6266
return (
6367
<div>
6468
<PageHeader>
@@ -70,7 +74,7 @@ export const OrganizationSettingsPageView: FC<
7074
aria-label="Organization settings form"
7175
>
7276
<FormSection
73-
title="General info"
77+
title="Info"
7478
description="Change the name or description of the organization."
7579
>
7680
<fieldset
@@ -110,14 +114,59 @@ export const OrganizationSettingsPageView: FC<
110114
</HorizontalForm>
111115

112116
{!org.is_default && (
113-
<Button
114-
css={styles.dangerButton}
115-
variant="contained"
116-
onClick={onDeleteOrg}
117-
>
118-
Delete this organization
119-
</Button>
117+
<HorizontalContainer css={{ marginTop: 48 }}>
118+
<HorizontalSection
119+
title="Settings"
120+
description="Change or delete your organization."
121+
>
122+
<div
123+
css={(theme) => ({
124+
display: "flex",
125+
backgroundColor: theme.roles.danger.background,
126+
alignItems: "center",
127+
justifyContent: "space-between",
128+
border: `1px solid ${theme.roles.danger.outline}`,
129+
borderRadius: 8,
130+
padding: 12,
131+
paddingLeft: 18,
132+
gap: 8,
133+
lineHeight: "18px",
134+
flexGrow: 1,
135+
136+
"& .option": {
137+
color: theme.roles.danger.fill.solid,
138+
"&.Mui-checked": {
139+
color: theme.roles.danger.fill.solid,
140+
},
141+
},
142+
143+
"& .info": {
144+
fontSize: 14,
145+
fontWeight: 600,
146+
color: theme.roles.danger.text,
147+
},
148+
})}
149+
>
150+
<span>Deleting an organization is irreversible.</span>
151+
<Button
152+
css={styles.dangerButton}
153+
variant="contained"
154+
onClick={() => setIsDeleting(true)}
155+
>
156+
Delete this organization
157+
</Button>
158+
</div>
159+
</HorizontalSection>
160+
</HorizontalContainer>
120161
)}
162+
163+
<DeleteDialog
164+
isOpen={isDeleting}
165+
onConfirm={onDeleteOrg}
166+
onCancel={() => setIsDeleting(false)}
167+
entity="organization"
168+
name={org.name}
169+
/>
121170
</div>
122171
);
123172
};

site/src/testHelpers/entities.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,17 @@ import type { TemplateVersionFiles } from "utils/templateVersion";
1313

1414
export const MockOrganization: TypesGen.Organization = {
1515
id: "fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0",
16-
name: "test-organization",
17-
display_name: "Test Organization",
18-
description: "",
19-
icon: "",
16+
name: "my-organization",
17+
display_name: "My Organization",
18+
description: "An organization that gets used for stuff.",
19+
icon: "/emojis/1f957.png",
2020
created_at: "",
2121
updated_at: "",
22+
is_default: false,
23+
};
24+
25+
export const MockDefaultOrganization: TypesGen.Organization = {
26+
...MockOrganization,
2227
is_default: true,
2328
};
2429

0 commit comments

Comments
 (0)