AccountConnections.tsx 5.4 KB

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