Skip to content

Commit 501d3de

Browse files
committed
fix: vercel integration, website service, cleanup
1 parent c40ae78 commit 501d3de

File tree

10 files changed

+675
-416
lines changed

10 files changed

+675
-416
lines changed

apps/dashboard/app/(main)/settings/integrations/vercel/_components/create-website-dialog.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,9 @@ import {
1919
SheetHeader,
2020
SheetTitle,
2121
} from '@/components/ui/sheet';
22-
import type { Domain, Project } from './types';
22+
import type { Domain, Project, WebsiteConfig } from './types';
2323
import { generateWebsiteName, generateWebsitePlaceholder } from './utils';
2424

25-
interface WebsiteConfig {
26-
domain: Domain;
27-
name: string;
28-
target: string[];
29-
}
30-
3125
interface CreateWebsiteDialogProps {
3226
isOpen: boolean;
3327
onClose: () => void;

apps/dashboard/app/(main)/settings/integrations/vercel/_components/project-row.tsx

Lines changed: 38 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { authClient } from '@databuddy/auth/client';
12
import {
23
ArrowRightIcon,
34
CaretRightIcon,
@@ -7,7 +8,6 @@ import {
78
PlusIcon,
89
TrashIcon,
910
WarningIcon,
10-
WrenchIcon,
1111
XCircleIcon,
1212
} from '@phosphor-icons/react';
1313
import { AnimatePresence, motion } from 'framer-motion';
@@ -25,7 +25,7 @@ import {
2525
} from '@/components/ui/dropdown-menu';
2626
import { Skeleton } from '@/components/ui/skeleton';
2727
import { trpc } from '@/lib/trpc';
28-
import type { Domain, Project } from './types';
28+
import type { Domain, Project, TriageAction } from './types';
2929

3030
interface ProjectRowProps {
3131
project: Project;
@@ -106,11 +106,7 @@ const TriageMenu = ({
106106
domain: any;
107107
triageIssueMutation: any;
108108
onTriageAction: (
109-
action:
110-
| 'remove_orphaned'
111-
| 'fix_domain_mismatch'
112-
| 'remove_duplicates'
113-
| 'create_missing_website',
109+
action: TriageAction,
114110
domainName: string,
115111
envVarId?: string,
116112
websiteId?: string
@@ -127,17 +123,6 @@ const TriageMenu = ({
127123
});
128124
}
129125

130-
if (
131-
domainStatus.status === 'invalid' &&
132-
domainStatus.issues[0]?.includes('Domain mismatch')
133-
) {
134-
actions.push({
135-
label: 'Fix',
136-
icon: WrenchIcon,
137-
action: 'fix_domain_mismatch' as const,
138-
});
139-
}
140-
141126
if (
142127
domainStatus.status === 'invalid' &&
143128
domainStatus.issues[0]?.includes('Multiple')
@@ -149,14 +134,11 @@ const TriageMenu = ({
149134
});
150135
}
151136

152-
if (
153-
domainStatus.status === 'not_integrated' &&
154-
domainStatus.issues[0]?.includes('Website exists')
155-
) {
137+
if (domainStatus.status === 'integrated') {
156138
actions.push({
157-
label: 'Create Website',
158-
icon: PlusIcon,
159-
action: 'create_missing_website' as const,
139+
label: 'Unintegrate',
140+
icon: TrashIcon,
141+
action: 'unintegrate' as const,
160142
});
161143
}
162144

@@ -214,11 +196,7 @@ const TriageMenu = ({
214196
key={action.action}
215197
onClick={() => {
216198
onTriageAction(
217-
action.action as
218-
| 'remove_orphaned'
219-
| 'fix_domain_mismatch'
220-
| 'remove_duplicates'
221-
| 'create_missing_website',
199+
action.action,
222200
domain.name,
223201
domainStatus.envVarId,
224202
domainStatus.websiteId
@@ -251,11 +229,7 @@ const DomainRow = ({
251229
isIntegrated: boolean;
252230
onSelectionChange: (domainName: string, checked: boolean) => void;
253231
onTriageAction: (
254-
action:
255-
| 'remove_orphaned'
256-
| 'fix_domain_mismatch'
257-
| 'remove_duplicates'
258-
| 'create_missing_website',
232+
action: TriageAction,
259233
domainName: string,
260234
envVarId?: string,
261235
websiteId?: string
@@ -377,6 +351,8 @@ export function ProjectRow({
377351
new Set()
378352
);
379353

354+
const { data: activeOrganization } = authClient.useActiveOrganization();
355+
380356
const { data: domainsData, isLoading: isLoadingDomains } =
381357
trpc.vercel.getProjectDomains.useQuery(
382358
{ projectId: project.id },
@@ -428,24 +404,39 @@ export function ProjectRow({
428404
}
429405
};
430406

407+
const unintegrateMutation = trpc.vercel.unintegrate.useMutation();
408+
431409
const handleTriageAction = async (
432-
action:
433-
| 'remove_orphaned'
434-
| 'fix_domain_mismatch'
435-
| 'remove_duplicates'
436-
| 'create_missing_website',
410+
action: TriageAction,
437411
domainName: string,
438412
envVarId?: string,
439413
websiteId?: string
440414
) => {
441415
try {
442-
await triageIssueMutation.mutateAsync({
443-
projectId: project.id,
444-
action,
445-
domainName,
446-
envVarId,
447-
websiteId,
448-
});
416+
if (action === 'unintegrate') {
417+
if (!envVarId) {
418+
throw new Error(
419+
'Environment variable ID is required for unintegrate action'
420+
);
421+
}
422+
await unintegrateMutation.mutateAsync({
423+
projectId: project.id,
424+
domainName,
425+
envVarId,
426+
websiteId,
427+
deleteWebsite: false, // Default to keeping the website
428+
organizationId: activeOrganization?.id,
429+
});
430+
} else {
431+
await triageIssueMutation.mutateAsync({
432+
projectId: project.id,
433+
action,
434+
domainName,
435+
envVarId,
436+
websiteId,
437+
organizationId: activeOrganization?.id,
438+
});
439+
}
449440

450441
// Refresh the projects data to show updated status
451442
await utils.vercel.getProjects.invalidate();
@@ -454,53 +445,6 @@ export function ProjectRow({
454445
}
455446
};
456447

457-
const getTriageActions = (domainStatus: any) => {
458-
const actions = [];
459-
460-
if (domainStatus.status === 'orphaned') {
461-
actions.push({
462-
label: 'Remove',
463-
icon: TrashIcon,
464-
action: 'remove_orphaned' as const,
465-
});
466-
}
467-
468-
if (
469-
domainStatus.status === 'invalid' &&
470-
domainStatus.issues[0]?.includes('Domain mismatch')
471-
) {
472-
actions.push({
473-
label: 'Fix',
474-
icon: WrenchIcon,
475-
action: 'fix_domain_mismatch' as const,
476-
});
477-
}
478-
479-
if (
480-
domainStatus.status === 'invalid' &&
481-
domainStatus.issues[0]?.includes('Multiple')
482-
) {
483-
actions.push({
484-
label: 'Remove Duplicates',
485-
icon: TrashIcon,
486-
action: 'remove_duplicates' as const,
487-
});
488-
}
489-
490-
if (
491-
domainStatus.status === 'not_integrated' &&
492-
domainStatus.issues[0]?.includes('Website exists')
493-
) {
494-
actions.push({
495-
label: 'Create Website',
496-
icon: PlusIcon,
497-
action: 'create_missing_website' as const,
498-
});
499-
}
500-
501-
return actions;
502-
};
503-
504448
return (
505449
<motion.div
506450
animate={{
@@ -582,16 +526,6 @@ export function ProjectRow({
582526
)}
583527
</div>
584528

585-
<div className="flex justify-center truncate">
586-
{project.live ? (
587-
<span className="text-blue-600">fix: meta</span>
588-
) : (
589-
<span className="text-muted-foreground">
590-
No Production Deployment
591-
</span>
592-
)}
593-
</div>
594-
595529
<div className="hidden justify-center sm:flex">
596530
{project.link?.productionBranch ? (
597531
<div className="flex min-w-0 items-center space-x-1">
Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,6 @@
1-
export interface Project {
2-
id: string;
3-
name: string;
4-
framework?: string | null;
5-
accountId: string;
6-
directoryListing: boolean;
7-
nodeVersion: string;
8-
live?: boolean;
9-
createdAt?: number;
10-
updatedAt?: number;
11-
primaryDomain?: string;
12-
productionUrl?: string;
13-
link?: {
14-
type: string;
15-
repo?: string;
16-
org?: string;
17-
productionBranch?: string;
18-
};
19-
}
20-
21-
export interface Domain {
22-
name: string;
23-
apexName: string;
24-
projectId: string;
25-
redirect?: string | null;
26-
redirectStatusCode?: number | null;
27-
gitBranch?: string | null;
28-
customEnvironmentId?: string | null;
29-
updatedAt: number;
30-
createdAt: number;
31-
verified: boolean;
32-
verification?: Array<{
33-
type: string;
34-
domain: string;
35-
value: string;
36-
reason: string;
37-
}>;
38-
}
1+
export type {
2+
Domain,
3+
Project,
4+
TriageAction,
5+
WebsiteConfig,
6+
} from '@databuddy/shared';

apps/dashboard/app/(main)/settings/integrations/vercel/page.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client';
22

3+
import { authClient } from '@databuddy/auth/client';
34
import { RocketLaunchIcon } from '@phosphor-icons/react';
45
import { useState } from 'react';
56
import { trpc } from '@/lib/trpc';
@@ -20,11 +21,21 @@ export default function VercelConfigPage() {
2021
const [selectedDomains, setSelectedDomains] = useState<Domain[]>([]);
2122
const [isDialogOpen, setIsDialogOpen] = useState(false);
2223

24+
const { data: activeOrganization, isPending: isLoadingOrganization } =
25+
authClient.useActiveOrganization();
26+
2327
const {
2428
data: projectsData,
2529
isLoading: isLoadingProjects,
2630
error: projectsError,
27-
} = trpc.vercel.getProjects.useQuery({ limit: '20' });
31+
} = trpc.vercel.getProjects.useQuery(
32+
{
33+
limit: '20',
34+
includeIntegrationStatus: true,
35+
organizationId: activeOrganization?.id,
36+
},
37+
{ enabled: !isLoadingOrganization }
38+
);
2839

2940
const toggleProjectExpansion = (projectId: string) => {
3041
setExpandedProjects((prev) => {
@@ -64,6 +75,7 @@ export default function VercelConfigPage() {
6475
verified: config.domain.verified,
6576
gitBranch: config.domain.gitBranch,
6677
})),
78+
organizationId: activeOrganization?.id,
6779
});
6880

6981
if (result.success) {
@@ -127,7 +139,7 @@ export default function VercelConfigPage() {
127139

128140
<main className="flex-1 overflow-y-auto">
129141
<div>
130-
{isLoadingProjects ? (
142+
{isLoadingProjects || isLoadingOrganization ? (
131143
<LoadingSkeleton />
132144
) : projectsError ? (
133145
<ErrorState message="Failed to load projects" />

packages/db/src/drizzle/schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ export const websites = pgTable(
284284
updatedAt: timestamp({ precision: 3 }).defaultNow().notNull(),
285285
deletedAt: timestamp({ precision: 3 }),
286286
organizationId: text('organization_id'),
287+
integrations: jsonb(),
287288
},
288289
(table) => [
289290
uniqueIndex('websites_user_domain_unique')

0 commit comments

Comments
 (0)