Skip to content

Commit 5922a2a

Browse files
committed
Updates slack integration page layout
1 parent 9c264b5 commit 5922a2a

1 file changed

Lines changed: 139 additions & 121 deletions

File tree

apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.integrations.slack.tsx

Lines changed: 139 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node";
2-
import { json, redirect } from "@remix-run/node";
1+
import { type ActionFunctionArgs, type LoaderFunctionArgs, json, redirect } from "@remix-run/node";
32
import { fromPromise } from "neverthrow";
43
import { Form, useActionData, useNavigation } from "@remix-run/react";
54
import { typedjson, useTypedLoaderData } from "remix-typedjson";
65
import { z } from "zod";
76
import { DialogClose } from "@radix-ui/react-dialog";
8-
import { SlackIcon } from "@trigger.dev/companyicons";
97
import { TrashIcon } from "@heroicons/react/20/solid";
108
import { Button } from "~/components/primitives/Buttons";
9+
import { DateTime } from "~/components/primitives/DateTime";
1110
import {
1211
Dialog,
1312
DialogContent,
@@ -17,8 +16,14 @@ import {
1716
DialogTrigger,
1817
} from "~/components/primitives/Dialog";
1918
import { FormButtons } from "~/components/primitives/FormButtons";
20-
import { Header1 } from "~/components/primitives/Headers";
21-
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
19+
import { Header2, Header3 } from "~/components/primitives/Headers";
20+
import { Hint } from "~/components/primitives/Hint";
21+
import {
22+
MainHorizontallyCenteredContainer,
23+
PageBody,
24+
PageContainer,
25+
} from "~/components/layout/AppLayout";
26+
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
2227
import { Paragraph } from "~/components/primitives/Paragraph";
2328
import {
2429
Table,
@@ -34,18 +39,6 @@ import { requireOrganization } from "~/services/org.server";
3439
import { OrganizationParamsSchema, organizationSettingsPath } from "~/utils/pathBuilder";
3540
import { logger } from "~/services/logger.server";
3641

37-
function formatDate(date: Date): string {
38-
return new Intl.DateTimeFormat("en-US", {
39-
month: "short",
40-
day: "numeric",
41-
year: "numeric",
42-
hour: "numeric",
43-
minute: "2-digit",
44-
second: "2-digit",
45-
hour12: true,
46-
}).format(date);
47-
}
48-
4942
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
5043
const { organizationSlug } = OrganizationParamsSchema.parse(params);
5144
const { organization } = await requireOrganization(request, organizationSlug);
@@ -187,8 +180,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
187180
};
188181

189182
export default function SlackIntegrationPage() {
190-
const { slackIntegration, alertChannels, teamName } =
191-
useTypedLoaderData<typeof loader>();
183+
const { slackIntegration, alertChannels, teamName } = useTypedLoaderData<typeof loader>();
192184
const actionData = useActionData<typeof action>();
193185
const navigation = useNavigation();
194186
const isUninstalling =
@@ -197,129 +189,155 @@ export default function SlackIntegrationPage() {
197189
if (!slackIntegration) {
198190
return (
199191
<PageContainer>
192+
<NavBar>
193+
<PageTitle title="Slack integration" />
194+
</NavBar>
200195
<PageBody>
201-
<div className="flex flex-col items-center justify-center py-8">
202-
<Header1>No Slack Integration Found</Header1>
203-
<Paragraph className="mt-2 text-center text-text-dimmed">
204-
This organization doesn't have a Slack integration configured. You can connect Slack
205-
when setting up alert channels in your project settings.
206-
</Paragraph>
207-
</div>
196+
<MainHorizontallyCenteredContainer>
197+
<div className="flex h-full items-center justify-center">
198+
<div className="text-center">
199+
<Header3 className="mb-2">No Slack integration found</Header3>
200+
<Paragraph variant="small">
201+
This organization doesn't have a Slack integration configured. You can connect
202+
Slack when setting up alert channels in your project settings.
203+
</Paragraph>
204+
</div>
205+
</div>
206+
</MainHorizontallyCenteredContainer>
208207
</PageBody>
209208
</PageContainer>
210209
);
211210
}
212211

213212
return (
214213
<PageContainer>
214+
<NavBar>
215+
<PageTitle title="Slack integration" />
216+
</NavBar>
215217
<PageBody>
216-
<div className="mb-8">
217-
<Header1>Slack Integration</Header1>
218-
<Paragraph className="mt-2 text-text-dimmed">
219-
Manage your organization's Slack integration and connected alert channels.
220-
</Paragraph>
221-
</div>
222-
223-
{/* Integration Info Section */}
224-
<div className="mb-8 rounded-lg border border-grid-bright bg-background-bright p-6">
225-
<div className="flex items-center justify-between">
218+
<MainHorizontallyCenteredContainer>
219+
<div className="flex flex-col gap-6">
226220
<div>
227-
<h2 className="text-lg font-medium text-text-bright">Integration Details</h2>
228-
<div className="mt-2 space-y-1 text-sm text-text-dimmed">
221+
<div className="mb-3 border-b border-grid-dimmed pb-3">
222+
<Header2>Integration details</Header2>
223+
</div>
224+
<div className="flex flex-col gap-1">
229225
{teamName && (
230-
<div>
231-
<span className="font-medium">Slack Workspace:</span> {teamName}
232-
</div>
226+
<Paragraph variant="small">
227+
<span className="text-text-dimmed">Workspace:</span>{" "}
228+
<span className="text-text-bright">{teamName}</span>
229+
</Paragraph>
233230
)}
234-
<div>
235-
<span className="font-medium">Installed:</span>{" "}
236-
{formatDate(new Date(slackIntegration.createdAt))}
237-
</div>
231+
<Paragraph variant="small">
232+
<span className="text-text-dimmed">Installed:</span>{" "}
233+
<span className="text-text-bright">
234+
<DateTime date={slackIntegration.createdAt} />
235+
</span>
236+
</Paragraph>
238237
</div>
239238
</div>
240-
<div className="flex flex-col items-end gap-2">
241-
<Dialog>
242-
<DialogTrigger asChild>
243-
<Button variant="danger/medium" LeadingIcon={TrashIcon} disabled={isUninstalling}>
244-
Remove Integration
245-
</Button>
246-
</DialogTrigger>
247-
<DialogContent>
248-
<DialogHeader>
249-
<DialogTitle>Remove Slack Integration</DialogTitle>
250-
</DialogHeader>
251-
<DialogDescription>
252-
This will remove the Slack integration and disable all connected alert channels.
253-
This action cannot be undone.
254-
</DialogDescription>
255-
<FormButtons
256-
confirmButton={
257-
<Form method="post">
258-
<input type="hidden" name="intent" value="uninstall" />
239+
240+
<div>
241+
<div className="mb-3 border-b border-grid-dimmed pb-3">
242+
<Header3>
243+
Connected alert channels
244+
<span className="ml-1 text-text-dimmed">({alertChannels.length})</span>
245+
</Header3>
246+
</div>
247+
{alertChannels.length === 0 ? (
248+
<Paragraph variant="small" className="text-text-dimmed">
249+
No alert channels are currently connected to this Slack integration.
250+
</Paragraph>
251+
) : (
252+
<Table>
253+
<TableHeader>
254+
<TableRow>
255+
<TableHeaderCell>Channel</TableHeaderCell>
256+
<TableHeaderCell>Project</TableHeaderCell>
257+
<TableHeaderCell>Status</TableHeaderCell>
258+
<TableHeaderCell>Created</TableHeaderCell>
259+
</TableRow>
260+
</TableHeader>
261+
<TableBody>
262+
{alertChannels.map((channel) => (
263+
<TableRow key={channel.id}>
264+
<TableCell>{channel.name}</TableCell>
265+
<TableCell>{channel.project.name}</TableCell>
266+
<TableCell>
267+
<EnabledStatus enabled={channel.enabled} />
268+
</TableCell>
269+
<TableCell>
270+
<DateTime date={channel.createdAt} />
271+
</TableCell>
272+
</TableRow>
273+
))}
274+
</TableBody>
275+
</Table>
276+
)}
277+
</div>
278+
279+
<div>
280+
<Header2 spacing>Danger zone</Header2>
281+
<div className="w-full rounded-sm border border-rose-500/40 p-4">
282+
<Header3 spacing>Remove integration</Header3>
283+
<Hint>
284+
This will remove the Slack integration and disable all connected alert channels.
285+
This action cannot be undone.
286+
</Hint>
287+
{actionData?.error && (
288+
<Paragraph variant="small" className="mt-2 text-error">
289+
{actionData.error}
290+
</Paragraph>
291+
)}
292+
<FormButtons
293+
className="mt-2"
294+
confirmButton={
295+
<Dialog>
296+
<DialogTrigger asChild>
259297
<Button
260-
variant="danger/medium"
298+
variant="danger/small"
261299
LeadingIcon={TrashIcon}
262-
type="submit"
263300
disabled={isUninstalling}
264301
>
265-
{isUninstalling ? "Removing..." : "Remove Integration"}
302+
Remove integration
266303
</Button>
267-
</Form>
268-
}
269-
cancelButton={
270-
<DialogClose asChild>
271-
<Button variant="tertiary/medium">Cancel</Button>
272-
</DialogClose>
273-
}
274-
/>
275-
</DialogContent>
276-
</Dialog>
277-
{actionData?.error && (
278-
<Paragraph variant="small" className="text-error">
279-
{actionData.error}
280-
</Paragraph>
281-
)}
304+
</DialogTrigger>
305+
<DialogContent>
306+
<DialogHeader>
307+
<DialogTitle>Remove Slack integration</DialogTitle>
308+
</DialogHeader>
309+
<DialogDescription className="mb-2">
310+
This will remove the Slack integration and disable all connected alert
311+
channels. This action cannot be undone.
312+
</DialogDescription>
313+
<FormButtons
314+
confirmButton={
315+
<Form method="post">
316+
<input type="hidden" name="intent" value="uninstall" />
317+
<Button
318+
variant="danger/medium"
319+
LeadingIcon={TrashIcon}
320+
type="submit"
321+
disabled={isUninstalling}
322+
>
323+
{isUninstalling ? "Removing…" : "Remove integration"}
324+
</Button>
325+
</Form>
326+
}
327+
cancelButton={
328+
<DialogClose asChild>
329+
<Button variant="tertiary/medium">Cancel</Button>
330+
</DialogClose>
331+
}
332+
/>
333+
</DialogContent>
334+
</Dialog>
335+
}
336+
/>
337+
</div>
282338
</div>
283339
</div>
284-
</div>
285-
286-
{/* Connected Alert Channels Section */}
287-
<div>
288-
<h2 className="mb-4 text-lg font-medium text-text-bright">
289-
Connected Alert Channels ({alertChannels.length})
290-
</h2>
291-
292-
{alertChannels.length === 0 ? (
293-
<div className="rounded-lg border border-grid-bright bg-background-bright p-6 text-center">
294-
<Paragraph className="text-text-dimmed">
295-
No alert channels are currently connected to this Slack integration.
296-
</Paragraph>
297-
</div>
298-
) : (
299-
<Table>
300-
<TableHeader>
301-
<TableRow>
302-
<TableHeaderCell>Channel Name</TableHeaderCell>
303-
<TableHeaderCell>Project</TableHeaderCell>
304-
<TableHeaderCell>Status</TableHeaderCell>
305-
<TableHeaderCell>Created</TableHeaderCell>
306-
</TableRow>
307-
</TableHeader>
308-
<TableBody>
309-
{alertChannels.map((channel) => (
310-
<TableRow key={channel.id}>
311-
<TableCell>{channel.name}</TableCell>
312-
<TableCell>{channel.project.name}</TableCell>
313-
<TableCell>
314-
<EnabledStatus enabled={channel.enabled} />
315-
</TableCell>
316-
<TableCell>{formatDate(new Date(channel.createdAt))}</TableCell>
317-
</TableRow>
318-
))}
319-
</TableBody>
320-
</Table>
321-
)}
322-
</div>
340+
</MainHorizontallyCenteredContainer>
323341
</PageBody>
324342
</PageContainer>
325343
);

0 commit comments

Comments
 (0)