-
- Connected alert channels
- ({alertChannels.length})
-
- {alertChannels.length === 0 ? (
-
- No alert channels are currently connected to this Slack integration.
-
- ) : (
-
-
-
- Channel
- Project
- Status
- Created
+
+
+ {alertChannels.length === 0 ? (
+
+ No alert channels are connected to this Slack integration yet.
+
+ ) : (
+
+
+
+ Channel
+ Project
+ Status
+ Created
+
+
+
+ {alertChannels.map((channel) => (
+
+ {channel.name}
+ {channel.project.name}
+
+
+
+
+
+
-
-
- {alertChannels.map((channel) => (
-
- {channel.name}
- {channel.project.name}
-
-
-
-
-
-
-
- ))}
-
-
- )}
-
-
-
-
Danger zone
-
-
Remove integration
-
- This will remove the Slack integration and disable all connected alert channels.
- This action cannot be undone.
-
- {actionData?.error && (
-
- {actionData.error}
-
- )}
-
-
-
- Remove integration
-
-
-
-
- Remove Slack integration
-
-
- This will remove the Slack integration and disable all connected alert
- channels. This action cannot be undone.
-
-
-
-
- {isUninstalling ? "Removing…" : "Remove integration"}
-
-
- }
- cancelButton={
-
- Cancel
-
- }
- />
-
-
- }
- />
-
-
-
-
+ ))}
+
+
+ )}
+
+
);
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.integrations.vercel.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.integrations.vercel.tsx
index 15241df2fb3..3df17cb75bc 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.integrations.vercel.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.integrations.vercel.tsx
@@ -1,4 +1,4 @@
-import { TrashIcon } from "@heroicons/react/20/solid";
+import { Cog6ToothIcon } from "@heroicons/react/24/outline";
import { DialogClose } from "@radix-ui/react-dialog";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { json, redirect } from "@remix-run/node";
@@ -6,6 +6,8 @@ import { Form, useActionData, useNavigation } from "@remix-run/react";
import { fromPromise } from "neverthrow";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { z } from "zod";
+import { ProjectConnectSelect } from "~/components/integrations/ProjectConnectSelect";
+import { VercelLogo } from "~/components/integrations/VercelLogo";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
import { Button, LinkButton } from "~/components/primitives/Buttons";
import {
@@ -16,9 +18,19 @@ import {
DialogTitle,
DialogTrigger,
} from "~/components/primitives/Dialog";
+import { CopyableText } from "~/components/primitives/CopyableText";
+import { DateTime } from "~/components/primitives/DateTime";
import { FormButtons } from "~/components/primitives/FormButtons";
-import { Header1 } from "~/components/primitives/Headers";
+import { Header2 } from "~/components/primitives/Headers";
+import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
+import {
+ SettingsContainer,
+ SettingsHeader,
+ SettingsRow,
+ SettingsSection,
+} from "~/components/primitives/SettingsLayout";
+import { SimpleTooltip } from "~/components/primitives/Tooltip";
import {
Table,
TableBody,
@@ -36,21 +48,10 @@ import { rbac } from "~/services/rbac.server";
import { dashboardAction } from "~/services/routeBuilders/dashboardBuilder";
import { OrganizationParamsSchema, v3ProjectSettingsIntegrationsPath } from "~/utils/pathBuilder";
import { pageMeta } from "~/utils/pageTitle";
+import { useOrganization } from "~/hooks/useOrganizations";
export const meta = pageMeta("Vercel integration");
-function formatDate(date: Date): string {
- return new Intl.DateTimeFormat("en-US", {
- month: "short",
- day: "numeric",
- year: "numeric",
- hour: "numeric",
- minute: "2-digit",
- second: "2-digit",
- hour12: true,
- }).format(date);
-}
-
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const { organizationSlug } = OrganizationParamsSchema.parse(params);
const url = new URL(request.url);
@@ -259,15 +260,30 @@ export default function VercelIntegrationPage() {
const isUninstalling =
navigation.state === "submitting" && navigation.formData?.get("intent") === "uninstall";
+ const { projects } = useOrganization();
+
if (!vercelIntegration) {
return (
+
+
+
-
-
No Vercel Integration Found
-
- This organization doesn't have a Vercel integration configured.
+
+
+
No Vercel integration found
+
+ Your organization doesn't have a Vercel integration. Configure it in your projects
+ integrations page.
+ {projects.length > 0 ? (
+
+ v3ProjectSettingsIntegrationsPath(organization, project, { slug: "prod" })
+ }
+ />
+ ) : null}
@@ -276,139 +292,157 @@ export default function VercelIntegrationPage() {
return (
+
+
+
-
-
Vercel Integration
-
- Manage your organization's Vercel integration and connected projects.
-
-
-
- {/* Integration Info Section */}
-
-
-
-
Integration Details
-
- {teamId && (
-
- Vercel Team ID: {teamId}
-
- )}
- {installationId && (
-
- Installation ID: {installationId}
-
- )}
-
- Installed: {" "}
- {formatDate(new Date(vercelIntegration.createdAt))}
-
-
-
-
-
-
-
- Remove Integration
-
-
-
-
- Remove Vercel Integration
-
-
- This will permanently remove the Vercel integration and disconnect all projects.
- This action cannot be undone.
-
-
-
-
- {isUninstalling ? "Removing..." : "Remove Integration"}
-
-
- }
- cancelButton={
-
- Cancel
-
- }
+
+
+
+ {teamId ? (
+
-
-
- {actionData?.error && (
-
- {actionData.error}
-
- )}
-
-
-
-
- {/* Connected Projects Section */}
-
-
- Connected Projects ({connectedProjects.length})
-
+ }
+ />
+ ) : null}
+ {installationId ? (
+
+ }
+ />
+ ) : null}
+
+
+
+ }
+ />
+
+
+
+
+ Remove integration…
+
+
+
+
+ Remove Vercel integration
+
+
+ This will permanently remove the Vercel integration and disconnect all
+ projects. This action cannot be undone.
+
+
+
+
+ {isUninstalling ? "Removing…" : "Remove integration"}
+
+
+ }
+ cancelButton={
+
+ Cancel
+
+ }
+ />
+
+
+ {actionData?.error ? (
+
+ {actionData.error}
+
+ ) : null}
+
+ }
+ />
+
- {connectedProjects.length === 0 ? (
-
-
- No projects are currently connected to this Vercel integration.
+
+
+ {connectedProjects.length === 0 ? (
+
+ No projects are connected to this Vercel integration yet.
-
- ) : (
-
-
-
- Project Name
- Vercel Project ID
- Connected
- Actions
-
-
-
- {connectedProjects.map((projectIntegration) => (
-
- {projectIntegration.project.name}
-
- {projectIntegration.externalEntityId}
-
- {formatDate(new Date(projectIntegration.createdAt))}
-
-
- Configure
-
-
+ ) : (
+
+
+
+ Project name
+ Vercel project ID
+ Connected
+ Actions
- ))}
-
-
- )}
-
+
+
+ {connectedProjects.map((projectIntegration) => (
+
+ {projectIntegration.project.name}
+
+ {projectIntegration.externalEntityId}
+
+
+
+
+
+
+
+
+ }
+ />
+
+
+ ))}
+
+
+ )}
+
+
);