diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 0de266fa2..b7043778e 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -20,9 +20,7 @@ jobs: with: fetch-depth: 2 - - uses: pnpm/action-setup@v2 - with: - version: 8 + - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: @@ -62,9 +60,7 @@ jobs: with: fetch-depth: 2 - - uses: pnpm/action-setup@v2 - with: - version: 8 + - uses: pnpm/action-setup@v4 - uses: actions/cache@v4 with: diff --git a/apps/web/app/home/(user)/layout.tsx b/apps/web/app/home/(user)/layout.tsx index 228ea90c2..0e6684940 100644 --- a/apps/web/app/home/(user)/layout.tsx +++ b/apps/web/app/home/(user)/layout.tsx @@ -2,6 +2,7 @@ import { use } from 'react'; import { cookies } from 'next/headers'; +import { UserWorkspaceContextProvider } from '@kit/accounts/components'; import { If } from '@kit/ui/if'; import { Page, @@ -41,7 +42,9 @@ function UserHomeLayout({ children }: React.PropsWithChildren) { - {children} + + {children} + ); } diff --git a/apps/web/app/home/[account]/layout.tsx b/apps/web/app/home/[account]/layout.tsx index 7be08f0ad..8bf2ee4a5 100644 --- a/apps/web/app/home/[account]/layout.tsx +++ b/apps/web/app/home/[account]/layout.tsx @@ -2,6 +2,7 @@ import { use } from 'react'; import { cookies } from 'next/headers'; +import { TeamAccountWorkspaceContextProvider } from '@kit/team-accounts/components'; import { If } from '@kit/ui/if'; import { Page, @@ -69,7 +70,9 @@ function TeamWorkspaceLayout({ - {children} + + {children} + ); } diff --git a/packages/features/accounts/package.json b/packages/features/accounts/package.json index a5ca9b7b5..a0276e631 100644 --- a/packages/features/accounts/package.json +++ b/packages/features/accounts/package.json @@ -12,6 +12,7 @@ "./personal-account-dropdown": "./src/components/personal-account-dropdown.tsx", "./account-selector": "./src/components/account-selector.tsx", "./personal-account-settings": "./src/components/personal-account-settings/index.ts", + "./components": "./src/components/index.ts", "./hooks/*": "./src/hooks/*.ts", "./api": "./src/server/api.ts" }, diff --git a/packages/features/accounts/src/components/index.ts b/packages/features/accounts/src/components/index.ts new file mode 100644 index 000000000..a5795bec0 --- /dev/null +++ b/packages/features/accounts/src/components/index.ts @@ -0,0 +1 @@ +export * from './user-workspace-context'; \ No newline at end of file diff --git a/packages/features/accounts/src/components/user-workspace-context.tsx b/packages/features/accounts/src/components/user-workspace-context.tsx new file mode 100644 index 000000000..aced8d41c --- /dev/null +++ b/packages/features/accounts/src/components/user-workspace-context.tsx @@ -0,0 +1,40 @@ +'use client'; + +import { createContext } from 'react'; + +import { User } from '@supabase/supabase-js'; + +import { Tables } from '@kit/supabase/database'; + +interface UserWorkspace { + accounts: Array<{ + label: string | null; + value: string | null; + image: string | null; + }>; + + workspace: { + id: string | null; + name: string | null; + picture_url: string | null; + subscription_status: Tables<'subscriptions'>['status'] | null; + }; + + user: User; +} + +export const UserWorkspaceContext = createContext( + {} as UserWorkspace, +); + +export function UserWorkspaceContextProvider( + props: React.PropsWithChildren<{ + value: UserWorkspace; + }>, +) { + return ( + + {props.children} + + ); +} diff --git a/packages/features/accounts/src/hooks/use-user-workspace.ts b/packages/features/accounts/src/hooks/use-user-workspace.ts new file mode 100644 index 000000000..d8793d4f1 --- /dev/null +++ b/packages/features/accounts/src/hooks/use-user-workspace.ts @@ -0,0 +1,17 @@ +'use client'; + +import { useContext } from 'react'; + +import { UserWorkspaceContext } from '../components'; + +export function useUserWorkspace() { + const ctx = useContext(UserWorkspaceContext); + + if (!ctx) { + throw new Error( + 'useUserWorkspace must be used within a UserWorkspaceProvider. This is only provided within the user workspace /home', + ); + } + + return ctx; +} diff --git a/packages/features/auth/src/components/magic-link-auth-container.tsx b/packages/features/auth/src/components/magic-link-auth-container.tsx index 3b5b1f8dc..bb48bc910 100644 --- a/packages/features/auth/src/components/magic-link-auth-container.tsx +++ b/packages/features/auth/src/components/magic-link-auth-container.tsx @@ -49,8 +49,13 @@ export function MagicLinkAuthContainer({ }); const onSubmit = ({ email }: { email: string }) => { - const queryParams = inviteToken ? `?invite_token=${inviteToken}` : ''; - const emailRedirectTo = [redirectUrl, queryParams].join(''); + const url = new URL(redirectUrl); + + if (inviteToken) { + url.searchParams.set('invite_token', inviteToken); + } + + const emailRedirectTo = url.href; const promise = () => signInWithOtpMutation.mutateAsync({ diff --git a/packages/features/team-accounts/package.json b/packages/features/team-accounts/package.json index 72582e3fd..e187dcf93 100644 --- a/packages/features/team-accounts/package.json +++ b/packages/features/team-accounts/package.json @@ -11,6 +11,7 @@ "exports": { "./api": "./src/server/api.ts", "./components": "./src/components/index.ts", + "./hooks/*": "./src/hooks/*.ts", "./webhooks": "./src/server/services/webhooks/index.ts" }, "dependencies": { diff --git a/packages/features/team-accounts/src/components/index.ts b/packages/features/team-accounts/src/components/index.ts index 3ed2dd258..afa8a53b9 100644 --- a/packages/features/team-accounts/src/components/index.ts +++ b/packages/features/team-accounts/src/components/index.ts @@ -5,3 +5,4 @@ export * from './invitations/account-invitations-table'; export * from './settings/team-account-settings-container'; export * from './invitations/accept-invitation-container'; export * from './create-team-account-dialog'; +export * from './team-account-workspace-context'; \ No newline at end of file diff --git a/packages/features/team-accounts/src/components/team-account-workspace-context.tsx b/packages/features/team-accounts/src/components/team-account-workspace-context.tsx new file mode 100644 index 000000000..c3fa685d9 --- /dev/null +++ b/packages/features/team-accounts/src/components/team-account-workspace-context.tsx @@ -0,0 +1,27 @@ +'use client'; + +import { createContext } from 'react'; + +import { User } from '@supabase/supabase-js'; + +import { Database } from '@kit/supabase/database'; + +interface AccountWorkspace { + accounts: Database['public']['Views']['user_accounts']['Row'][]; + account: Database['public']['Functions']['team_account_workspace']['Returns'][0]; + user: User; +} + +export const TeamAccountWorkspaceContext = createContext( + {} as AccountWorkspace, +); + +export function TeamAccountWorkspaceContextProvider( + props: React.PropsWithChildren<{ value: AccountWorkspace }>, +) { + return ( + + {props.children} + + ); +} diff --git a/packages/features/team-accounts/src/hooks/use-team-account-workspace.ts b/packages/features/team-accounts/src/hooks/use-team-account-workspace.ts new file mode 100644 index 000000000..ec29b899a --- /dev/null +++ b/packages/features/team-accounts/src/hooks/use-team-account-workspace.ts @@ -0,0 +1,22 @@ +'use client'; + +import { useContext } from 'react'; + +import { TeamAccountWorkspaceContext } from '../components'; + +/** + * @name useAccountWorkspace + * @description A hook to access the account workspace data. + * @returns The account workspace data. + */ +export function useAccountWorkspace() { + const ctx = useContext(TeamAccountWorkspaceContext); + + if (!ctx) { + throw new Error( + 'useAccountWorkspace must be used within a TeamAccountWorkspaceContext.Provider. This is only provided within the account workspace /home/[account]', + ); + } + + return ctx; +}