StripeSyncSettingsPage.tsx126 lines · main
1import { useParams } from 'common'
2import { formatRelative } from 'date-fns'
3import { BadgeCheck, RefreshCwIcon } from 'lucide-react'
4import Link from 'next/link'
5import { Button, Card, CardContent, CardHeader, CardTitle } from 'ui'
6import { Admonition, ShimmeringLoader, TimestampInfo } from 'ui-patterns'
7import {
8 PageSection,
9 PageSectionContent,
10 PageSectionDescription,
11 PageSectionMeta,
12 PageSectionSummary,
13 PageSectionTitle,
14} from 'ui-patterns/PageSection'
15
16import { isInstalled, isSyncRunning, isUninstalling } from './stripe-sync-status'
17import { ConstrainedIntegrationTabScaffold } from '@/components/interfaces/Integrations/ConstrainedIntegrationTabScaffold'
18import { useStripeSyncStatus } from '@/components/interfaces/Integrations/templates/StripeSyncEngine/useStripeSyncStatus'
19
20export const StripeSyncSettingsPage = () => {
21 const { ref } = useParams()
22
23 const {
24 schemaComment: { status: installationStatus },
25 syncState,
26 } = useStripeSyncStatus()
27 const installed = isInstalled(installationStatus)
28 const isSyncing = isSyncRunning(syncState)
29 const uninstalling = isUninstalling(installationStatus)
30
31 if (!installed || uninstalling) {
32 return (
33 <ConstrainedIntegrationTabScaffold>
34 <PageSection>
35 <Admonition type="default" description="Stripe Sync Engine is not installed." />
36 </PageSection>
37 </ConstrainedIntegrationTabScaffold>
38 )
39 }
40
41 return (
42 <ConstrainedIntegrationTabScaffold>
43 <PageSection className="py-0!">
44 <PageSectionMeta>
45 <PageSectionSummary>
46 <PageSectionTitle>Manage Stripe data</PageSectionTitle>
47 <PageSectionDescription>
48 Access and manage the synced Stripe data in your database.
49 </PageSectionDescription>
50 </PageSectionSummary>
51 </PageSectionMeta>
52 <PageSectionContent>
53 <Card>
54 <CardHeader>
55 <CardTitle className="text-foreground-lighter">
56 {!syncState ? (
57 <ShimmeringLoader className="py-2" />
58 ) : (
59 <div className="flex items-center justify-between gap-2">
60 {isSyncing ? (
61 <>
62 <div className="flex items-center gap-x-3 text-foreground-light">
63 <RefreshCwIcon size={14} className="animate-spin" />
64 <p>Sync in progress</p>
65 </div>
66 {syncState.started_at && (
67 <p className="text-foreground-light">
68 Started{' '}
69 <TimestampInfo
70 utcTimestamp={syncState.started_at}
71 label={
72 syncState.started_at
73 ? formatRelative(new Date(syncState.started_at), new Date())
74 : 'recently'
75 }
76 />
77 </p>
78 )}
79 </>
80 ) : (
81 <>
82 <div className="flex items-center gap-x-3 text-foreground-light">
83 <BadgeCheck size={14} />
84 <p>All up to date</p>
85 </div>
86 {syncState.closed_at && (
87 <p className="text-foreground-light">
88 Last synced{' '}
89 <TimestampInfo
90 utcTimestamp={syncState.closed_at}
91 label={
92 syncState.closed_at
93 ? formatRelative(new Date(syncState.closed_at), new Date())
94 : 'recently'
95 }
96 />
97 </p>
98 )}
99 </>
100 )}
101 </div>
102 )}
103 </CardTitle>
104 </CardHeader>
105 <CardContent className="@container">
106 <div className="flex flex-col items-start justify-between gap-4 @md:flex-row @md:items-center">
107 <div className="flex flex-col gap-1">
108 <h5 className="text-sm">View Stripe data in Table Editor</h5>
109 <p className="text-sm text-foreground-light text-balance">
110 The Stripe Sync Engine stores all synced data in the{' '}
111 <code className="text-code-inline break-keep!">stripe</code> schema. You can
112 view and query this data directly in the Table Editor.
113 </p>
114 </div>
115
116 <Button asChild type="default" className="ml-8 @md:ml-0">
117 <Link href={`/project/${ref}/editor?schema=stripe`}>Open Table Editor</Link>
118 </Button>
119 </div>
120 </CardContent>
121 </Card>
122 </PageSectionContent>
123 </PageSection>
124 </ConstrainedIntegrationTabScaffold>
125 )
126}