AccountConnections.tsx166 lines · main
1import { ChevronDown, RefreshCw, Unlink } from 'lucide-react'
2import Image from 'next/image'
3import { useState } from 'react'
4import { toast } from 'sonner'
5import {
6 Badge,
7 Button,
8 Card,
9 CardContent,
10 cn,
11 DropdownMenu,
12 DropdownMenuContent,
13 DropdownMenuItem,
14 DropdownMenuSeparator,
15 DropdownMenuTrigger,
16} from 'ui'
17import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
18import {
19 PageSection,
20 PageSectionContent,
21 PageSectionDescription,
22 PageSectionMeta,
23 PageSectionSummary,
24 PageSectionTitle,
25} from 'ui-patterns/PageSection'
26import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
27
28import { useGitHubAuthorizationDeleteMutation } from '@/data/integrations/github-authorization-delete-mutation'
29import { useGitHubAuthorizationQuery } from '@/data/integrations/github-authorization-query'
30import { BASE_PATH } from '@/lib/constants'
31import { openInstallGitHubIntegrationWindow } from '@/lib/github'
32
33export const AccountConnections = () => {
34 const {
35 data: gitHubAuthorization,
36 isPending: isLoading,
37 isSuccess,
38 isError,
39 error,
40 } = useGitHubAuthorizationQuery()
41
42 const [isRemoveModalOpen, setIsRemoveModalOpen] = useState(false)
43
44 const isConnected = gitHubAuthorization !== null
45
46 const { mutate: removeAuthorization, isPending: isRemoving } =
47 useGitHubAuthorizationDeleteMutation({
48 onSuccess: () => {
49 toast.success('GitHub authorization removed successfully')
50 setIsRemoveModalOpen(false)
51 },
52 })
53
54 const handleConnect = () => {
55 openInstallGitHubIntegrationWindow('authorize')
56 }
57
58 const handleReauthenticate = () => {
59 openInstallGitHubIntegrationWindow('authorize')
60 }
61
62 const handleRemove = () => {
63 removeAuthorization()
64 }
65
66 return (
67 <PageSection>
68 <PageSectionMeta>
69 <PageSectionSummary>
70 <PageSectionTitle>Connections</PageSectionTitle>
71 <PageSectionDescription>
72 Connect your Briven account with other services.
73 </PageSectionDescription>
74 </PageSectionSummary>
75 </PageSectionMeta>
76 <PageSectionContent>
77 <Card>
78 {isLoading && (
79 <CardContent>
80 <ShimmeringLoader />
81 </CardContent>
82 )}
83 {isError && (
84 <CardContent>
85 <p className="text-sm text-destructive">
86 Failed to load GitHub connection status: {error?.message}
87 </p>
88 </CardContent>
89 )}
90 {isSuccess && (
91 <CardContent className="flex justify-between items-center">
92 <div className="flex gap-x-4 items-center">
93 <Image
94 className={cn('dark:invert')}
95 src={`${BASE_PATH}/img/icons/github-icon.svg`}
96 width={30}
97 height={30}
98 alt={`GitHub icon`}
99 />
100 <div>
101 <p className="text-sm">GitHub</p>
102 <p className="text-sm text-foreground-lighter">
103 Sync repos to Briven projects for automatic branch creation and merging
104 </p>
105 </div>
106 </div>
107 <div className="flex items-center gap-x-2 ml-2">
108 {isConnected ? (
109 <>
110 <Badge variant="success">Connected</Badge>
111 <DropdownMenu>
112 <DropdownMenuTrigger asChild>
113 <Button iconRight={<ChevronDown size={14} />} type="default">
114 <span>Manage</span>
115 </Button>
116 </DropdownMenuTrigger>
117 <DropdownMenuContent side="bottom" align="end" className="w-44">
118 <DropdownMenuItem
119 className="space-x-2"
120 onSelect={(event) => {
121 event.preventDefault()
122 handleReauthenticate()
123 }}
124 >
125 <RefreshCw size={14} />
126 <p>Re-authenticate</p>
127 </DropdownMenuItem>
128 <DropdownMenuSeparator />
129 <DropdownMenuItem
130 className="space-x-2"
131 onSelect={() => setIsRemoveModalOpen(true)}
132 >
133 <Unlink size={14} />
134 <p>Remove connection</p>
135 </DropdownMenuItem>
136 </DropdownMenuContent>
137 </DropdownMenu>
138 </>
139 ) : (
140 <Button type="primary" onClick={handleConnect}>
141 Connect
142 </Button>
143 )}
144 </div>
145 </CardContent>
146 )}
147 </Card>
148 <ConfirmationModal
149 variant="destructive"
150 size="small"
151 visible={isRemoveModalOpen}
152 title="Confirm to remove GitHub authorization"
153 confirmLabel="Remove connection"
154 onCancel={() => setIsRemoveModalOpen(false)}
155 onConfirm={handleRemove}
156 loading={isRemoving}
157 >
158 <p className="text-sm text-foreground-light">
159 Removing this authorization will disconnect your GitHub account from Briven. You can
160 reconnect at any time.
161 </p>
162 </ConfirmationModal>
163 </PageSectionContent>
164 </PageSection>
165 )
166}