scoped.tsx94 lines · main
1import { ExternalLink, Search } from 'lucide-react'
2import { useState } from 'react'
3import { Button } from 'ui'
4import { Input } from 'ui-patterns/DataInputs/Input'
5
6import { AccessTokenNewBanner } from '@/components/interfaces/Account/AccessTokens/AccessTokenNewBanner/AccessTokenNewBanner'
7import { NewScopedTokenButton } from '@/components/interfaces/Account/AccessTokens/Scoped/NewScopedTokenButton'
8import { ScopedTokenList } from '@/components/interfaces/Account/AccessTokens/Scoped/ScopedTokenList'
9import { AccessTokensLayout } from '@/components/layouts/AccessTokens/AccessTokensLayout'
10import AccountLayout from '@/components/layouts/AccountLayout/AccountLayout'
11import { AppLayout } from '@/components/layouts/AppLayout/AppLayout'
12import { DefaultLayout } from '@/components/layouts/DefaultLayout'
13import { NewScopedAccessToken } from '@/data/scoped-access-tokens/scoped-access-token-create-mutation'
14import type { NextPageWithLayout } from '@/types'
15
16const ScopedTokens: NextPageWithLayout = () => {
17 const [searchString, setSearchString] = useState('')
18 const [newToken, setNewToken] = useState<NewScopedAccessToken | undefined>()
19
20 return (
21 <AccessTokensLayout>
22 <div className="space-y-4">
23 {newToken && (
24 <AccessTokenNewBanner
25 token={newToken}
26 onClose={() => setNewToken(undefined)}
27 getTokenValue={(token) => token.token}
28 getTokenPermissions={(token) => token.permissions}
29 />
30 )}
31 <div className="flex items-center justify-between gap-x-2 mb-3">
32 <Input
33 size="tiny"
34 autoComplete="off"
35 icon={<Search size={12} />}
36 value={searchString}
37 onChange={(e) => setSearchString(e.target.value)}
38 name="search"
39 id="search"
40 placeholder="Filter by name"
41 />
42 <div className="flex items-center gap-x-2">
43 <Button asChild type="default" icon={<ExternalLink />}>
44 <a
45 href="https://supabase.com/docs/reference/api/introduction"
46 target="_blank"
47 rel="noreferrer"
48 >
49 API Docs
50 </a>
51 </Button>
52 <Button asChild type="default" icon={<ExternalLink />}>
53 <a
54 href="https://supabase.com/docs/reference/cli/start"
55 target="_blank"
56 rel="noreferrer"
57 >
58 CLI docs
59 </a>
60 </Button>
61 <NewScopedTokenButton onCreateToken={setNewToken} />
62 </div>
63 </div>
64
65 <ScopedTokenList
66 searchString={searchString}
67 onDeleteSuccess={(id) => {
68 if (id === newToken?.id) setNewToken(undefined)
69 }}
70 />
71
72 <p className="text-sm text-foreground-muted text-center mt-6">
73 Looking for Private Apps?{' '}
74 <a
75 href="/org"
76 className="text-foreground-light underline hover:text-foreground transition-colors"
77 >
78 Go to Organization Settings → Connections → Private Apps
79 </a>
80 </p>
81 </div>
82 </AccessTokensLayout>
83 )
84}
85
86ScopedTokens.getLayout = (page) => (
87 <AppLayout>
88 <DefaultLayout headerTitle="Account">
89 <AccountLayout title="Access Tokens">{page}</AccountLayout>
90 </DefaultLayout>
91 </AppLayout>
92)
93
94export default ScopedTokens