Skip to content

Commit 315bb10

Browse files
committed
Extract Dashboard URL to display within anchor tag
1 parent 2ad4dc1 commit 315bb10

File tree

5 files changed

+100
-59
lines changed

5 files changed

+100
-59
lines changed

packages/clerk-js/src/core/clerk.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ export class Clerk implements ClerkInterface {
746746
): { status: 'enabled' | 'prompt-shown' } => {
747747
const { for: setting, caller } = params;
748748

749-
// If not in development instance, return enabled status in order to not open the in-app prompt
749+
// If not in development instance, return enabled status in order to not open the prompt
750750
if (this.#instanceType !== 'development') {
751751
return { status: 'enabled' };
752752
}

packages/clerk-js/src/ui/components/devPrompts/EnableOrganizationsPrompt/index.tsx

Lines changed: 73 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,28 @@ import { useClerk } from '@clerk/shared/react';
22
import type { __internal_EnableOrganizationsPromptProps } from '@clerk/shared/types';
33
// eslint-disable-next-line no-restricted-imports
44
import { css } from '@emotion/react';
5-
import { useState } from 'react';
5+
import { useMemo, useState } from 'react';
66

7+
import { Animated } from '@/ui/elements/Animated';
78
import { Modal } from '@/ui/elements/Modal';
89
import { InternalThemeProvider } from '@/ui/styledSystem';
910

1011
import { DevTools } from '../../../../core/resources/DevTools';
12+
import type { Environment } from '../../../../core/resources/Environment';
1113
import { Flex } from '../../../customizables';
1214
import { Portal } from '../../../elements/Portal';
13-
import { basePromptElementStyles, PromptContainer, PromptSuccessIcon } from '../shared';
15+
import { basePromptElementStyles, handleDashboardUrlParsing, PromptContainer, PromptSuccessIcon } from '../shared';
16+
17+
/**
18+
* If we cannot reconstruct the url properly, then simply fallback to Clerk Dashboard
19+
*/
20+
function withLastActiveFallback(cb: () => string): string {
21+
try {
22+
return cb();
23+
} catch {
24+
return 'https://dashboard.clerk.com/last-active?path=organization-settings';
25+
}
26+
}
1427

1528
const EnableOrganizationsPromptInternal = ({
1629
caller,
@@ -21,6 +34,28 @@ const EnableOrganizationsPromptInternal = ({
2134
const [isLoading, setIsLoading] = useState(false);
2235
const [isEnabled, setIsEnabled] = useState(false);
2336

37+
// @ts-expect-error - __unstable__environment is not typed
38+
const environment = clerk?.__unstable__environment as Environment | undefined;
39+
40+
const organizationSettingsUrl = useMemo(() => {
41+
return withLastActiveFallback(() => {
42+
const currentUrl = window.location.href;
43+
try {
44+
const redirectUrlParts = handleDashboardUrlParsing(currentUrl);
45+
const url = new URL(
46+
`${redirectUrlParts.baseDomain}/apps/${redirectUrlParts.appId}/instances/${redirectUrlParts.instanceId}/organization-settings`,
47+
);
48+
return url.href;
49+
} catch {
50+
if (!environment?.id) {
51+
throw new Error('Cannot construct dashboard URL');
52+
}
53+
54+
return 'https://dashboard.clerk.com/last-active?path=organization-settings';
55+
}
56+
});
57+
}, [environment?.id]);
58+
2459
const handleEnableOrganizations = () => {
2560
setIsLoading(true);
2661

@@ -193,8 +228,7 @@ const EnableOrganizationsPromptInternal = ({
193228
font-size: 0.8125rem;
194229
`,
195230
]}
196-
/* TODO - Generate URL to Dashboard */
197-
href='https://clerk.com/docs/guides/organizations'
231+
href={organizationSettingsUrl}
198232
target='_blank'
199233
rel='noopener noreferrer'
200234
tabIndex={-1}
@@ -264,43 +298,45 @@ const EnableOrganizationsPromptInternal = ({
264298
`}
265299
/>
266300

267-
<Flex
268-
direction='col'
269-
justify='center'
270-
sx={t => ({
271-
padding: `${t.sizes.$4} ${t.sizes.$6}`,
272-
gap: t.sizes.$3,
273-
})}
274-
>
275-
{isEnabled ? (
276-
<PromptButton
277-
variant='outline'
278-
onClick={() => onSuccess?.()}
279-
>
280-
Continue
281-
</PromptButton>
282-
) : (
283-
<>
284-
<PromptButton
285-
variant='solid'
286-
onClick={handleEnableOrganizations}
287-
disabled={isLoading}
288-
>
289-
Enable Organizations
290-
</PromptButton>
291-
301+
<Animated asChild>
302+
<Flex
303+
direction='col'
304+
justify='center'
305+
sx={t => ({
306+
padding: `${t.sizes.$4} ${t.sizes.$6}`,
307+
gap: t.sizes.$3,
308+
})}
309+
>
310+
{isEnabled ? (
292311
<PromptButton
293312
variant='outline'
294-
onClick={() => {
295-
clerk?.__internal_closeEnableOrganizationsPrompt?.();
296-
onClose?.();
297-
}}
313+
onClick={() => onSuccess?.()}
298314
>
299-
I&apos;ll remove it myself
315+
Continue
300316
</PromptButton>
301-
</>
302-
)}
303-
</Flex>
317+
) : (
318+
<>
319+
<PromptButton
320+
variant='solid'
321+
onClick={handleEnableOrganizations}
322+
disabled={isLoading}
323+
>
324+
Enable Organizations
325+
</PromptButton>
326+
327+
<PromptButton
328+
variant='outline'
329+
onClick={() => {
330+
clerk?.__internal_closeEnableOrganizationsPrompt?.();
331+
onClose?.();
332+
}}
333+
>
334+
I&apos;ll remove it myself
335+
</PromptButton>
336+
</>
337+
)}
338+
</Flex>
339+
</Animated>
304340
</PromptContainer>
305341
</Modal>
306342
</Portal>

packages/clerk-js/src/ui/components/devPrompts/KeylessPrompt/index.tsx

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ import { createPortal } from 'react-dom';
88
import { Flex, Link } from '../../../customizables';
99
import { Portal } from '../../../elements/Portal';
1010
import { InternalThemeProvider } from '../../../styledSystem';
11-
import { basePromptElementStyles, PromptContainer, PromptSuccessIcon } from '../shared';
11+
import {
12+
basePromptElementStyles,
13+
handleDashboardUrlParsing,
14+
handleDashboardUrlParsing,
15+
PromptContainer,
16+
PromptSuccessIcon,
17+
} from '../shared';
1218
import { ClerkLogoIcon } from './ClerkLogoIcon';
1319
import { KeySlashIcon } from './KeySlashIcon';
1420
import { useRevalidateEnvironment } from './use-revalidate-environment';
@@ -34,25 +40,6 @@ function withLastActiveFallback(cb: () => string): string {
3440
}
3541
}
3642

37-
function handleDashboardUrlParsing(url: string) {
38-
// make sure this is a valid url
39-
const __url = new URL(url);
40-
const regex = /^https?:\/\/(.*?)\/apps\/app_(.+?)\/instances\/ins_(.+?)(?:\/.*)?$/;
41-
42-
const match = __url.href.match(regex);
43-
44-
if (!match) {
45-
throw new Error('invalid value dashboard url structure');
46-
}
47-
48-
// Extracting base domain, app ID with prefix, and instanceId with prefix
49-
return {
50-
baseDomain: `https://${match[1]}`,
51-
appId: `app_${match[2]}`,
52-
instanceId: `ins_${match[3]}`,
53-
};
54-
}
55-
5643
const KeylessPromptInternal = (_props: KeylessPromptProps) => {
5744
const { isSignedIn } = useUser();
5845
const [isExpanded, setIsExpanded] = useState(false);

packages/clerk-js/src/ui/components/devPrompts/shared.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,22 @@ export function PromptSuccessIcon(props: React.ComponentProps<'svg'>) {
8181
</svg>
8282
);
8383
}
84+
85+
export function handleDashboardUrlParsing(url: string) {
86+
// make sure this is a valid url
87+
const __url = new URL(url);
88+
const regex = /^https?:\/\/(.*?)\/apps\/app_(.+?)\/instances\/ins_(.+?)(?:\/.*)?$/;
89+
90+
const match = __url.href.match(regex);
91+
92+
if (!match) {
93+
throw new Error('invalid value dashboard url structure');
94+
}
95+
96+
// Extracting base domain, app ID with prefix, and instanceId with prefix
97+
return {
98+
baseDomain: `https://${match[1]}`,
99+
appId: `app_${match[2]}`,
100+
instanceId: `ins_${match[3]}`,
101+
};
102+
}

packages/shared/src/organization.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export function useAttemptToEnableOrganizations(caller: 'useOrganization' | 'use
3838
clerk.__internal_attemptToEnableEnvironmentSetting({
3939
for: 'organizations',
4040
caller,
41-
onSuccess: () => {},
4241
});
4342
}, [clerk, caller]);
4443
}

0 commit comments

Comments
 (0)