Skip to content

Commit bb28b81

Browse files
committed
feat(integrations): added integrations page
1 parent 9d35c23 commit bb28b81

4 files changed

Lines changed: 121 additions & 3 deletions

File tree

apps/web/app/(main)/projects/[project]/settings/page-client.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import type React from "react";
66
import { useMemo, useState } from "react";
77
import { DangerZone } from "@/components/settings/danger-zone";
88
import { GeneralSettings } from "@/components/settings/general-settings";
9+
import { IntegrationSettings } from "@/components/settings/integrations";
910
import { MemberSettings } from "@/components/settings/member/member-settings";
1011
import PageLoader from "@/components/shared/page-loader";
1112
import { useProjectSettings } from "@/lib/queries/project";
1213
import { useProject } from "@/providers/project";
1314

14-
type SettingTab = "general" | "members" | "danger";
15+
type SettingTab = "general" | "members" | "integrations" | "danger";
1516

1617
export default function PageClient() {
1718
const { projectId } = useProject();
@@ -28,6 +29,7 @@ export default function PageClient() {
2829
() => [
2930
{ key: "general", label: "General", Icon: Settings },
3031
{ key: "members", label: "Members", Icon: Users },
32+
{ key: "integrations", label: "Integrations", Icon: Users },
3133
{ key: "danger", label: "Danger Zone", Icon: Trash2 },
3234
],
3335
[]
@@ -59,6 +61,8 @@ export default function PageClient() {
5961
);
6062
case "members":
6163
return <MemberSettings members={members} />;
64+
case "integrations":
65+
return <IntegrationSettings />;
6266
case "danger":
6367
return (
6468
<DangerZone

apps/web/components/settings/danger-zone.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const DangerZone = ({
6464
)}
6565
</div>
6666
<Button
67-
className="ml-4 flex-shrink-0 bg-red-600 p-2 text-sm text-white hover:bg-red-700 disabled:bg-gray-400"
67+
className="ml-4 shrink-0 bg-red-600 p-2 text-sm text-white hover:bg-red-700 disabled:bg-gray-400"
6868
disabled={!isOwner || isPending}
6969
onClick={handleDeleteClick}
7070
>
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"use client";
2+
3+
import { Button } from "@flagix/ui/components/button";
4+
import Image from "next/image";
5+
6+
interface Integration {
7+
id: string;
8+
name: string;
9+
description: string;
10+
logo: string;
11+
}
12+
13+
const INTEGRATIONS: Integration[] = [
14+
{
15+
id: "slack",
16+
name: "Slack",
17+
description:
18+
"Get real-time notifications in your Slack channels whenever flags are toggled.",
19+
logo: "https://svgl.app/library/slack.svg",
20+
},
21+
{
22+
id: "datadog",
23+
name: "Datadog",
24+
description:
25+
"Sync feature flag events with your Datadog event stream to correlate rollouts with system performance.",
26+
logo: "https://svgl.app/library/datadog.svg",
27+
},
28+
{
29+
id: "sentry",
30+
name: "Sentry",
31+
description:
32+
"Automatically tag Sentry events with the state of feature flags to debug crashes faster.",
33+
logo: "https://svgl.app/library/sentry.svg",
34+
},
35+
{
36+
id: "github",
37+
name: "GitHub",
38+
description:
39+
"Link feature flags to pull requests and automate flag cleanup after code is merged.",
40+
logo: "https://cdn.simpleicons.org/github",
41+
},
42+
{
43+
id: "webhooks",
44+
name: "Webhooks",
45+
description:
46+
"Build custom automation. Send flag change events to any URL via secure POST requests.",
47+
logo: "https://unpkg.com/lucide-static@latest/icons/webhook.svg",
48+
},
49+
];
50+
51+
export function IntegrationSettings() {
52+
return (
53+
<div className="space-y-6">
54+
<div className="flex flex-col space-y-1">
55+
<h2 className="font-semibold text-gray-900 text-lg">Integrations</h2>
56+
<p className="text-gray-600 text-sm">
57+
Connect Flagix with the tools your team already uses.
58+
</p>
59+
</div>
60+
61+
<div className="divide-y divide-gray-100 overflow-hidden rounded-xl border border-gray-200 bg-white">
62+
{INTEGRATIONS.map((app) => (
63+
<div
64+
className="flex flex-col items-start justify-between gap-4 p-5 transition-colors hover:bg-gray-50/50 md:flex-row md:items-center"
65+
key={app.id}
66+
>
67+
<div className="flex items-start gap-4">
68+
<div className="relative mt-1 flex h-12 w-12 shrink-0 items-center justify-center rounded-lg border border-gray-100 bg-white p-2.5 shadow-sm">
69+
<Image
70+
alt={`${app.name} icon`}
71+
className="object-contain"
72+
height={28}
73+
src={app.logo}
74+
unoptimized
75+
width={28}
76+
/>
77+
</div>
78+
79+
<div className="flex flex-col space-y-1">
80+
<div className="flex items-center gap-2">
81+
<h3 className="font-semibold text-gray-900 text-sm">
82+
{app.name}
83+
</h3>
84+
<span className="inline-flex items-center rounded-full bg-emerald-50 px-2 py-0.5 font-medium text-[10px] text-emerald-700 ring-1 ring-emerald-600/20 ring-inset">
85+
Coming Soon
86+
</span>
87+
</div>
88+
<p className="max-w-xl text-[13px] text-gray-600 leading-relaxed">
89+
{app.description}
90+
</p>
91+
</div>
92+
</div>
93+
94+
<Button
95+
className="rounded-sm bg-emerald-600 px-5 py-2 font-medium text-white text-xs hover:bg-emerald-700 disabled:bg-gray-100 disabled:text-gray-400"
96+
disabled={true}
97+
>
98+
Connect
99+
</Button>
100+
</div>
101+
))}
102+
</div>
103+
</div>
104+
);
105+
}

apps/web/next.config.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
/** @type {import('next').NextConfig} */
2-
const nextConfig = {};
2+
const nextConfig = {
3+
images: {
4+
remotePatterns: [
5+
{
6+
protocol: "https",
7+
hostname: "svgl.app",
8+
},
9+
],
10+
},
11+
};
312

413
export default nextConfig;

0 commit comments

Comments
 (0)