From 5e8e01e34078b0121f172f2390efa43f6734a652 Mon Sep 17 00:00:00 2001 From: Giancarlo Buomprisco Date: Tue, 30 Apr 2024 22:54:33 +0700 Subject: [PATCH] New Layout (#22) New layout --- .../home/(user)/_components/home-sidebar.tsx | 54 - .../_components/user-account-header.tsx | 26 - .../app/(dashboard)/home/(user)/layout.tsx | 11 - .../_components/account-layout-header.tsx | 30 - .../app/(dashboard)/home/[account]/layout.tsx | 44 - apps/web/app/admin/layout.tsx | 19 +- apps/web/app/error.tsx | 2 +- .../_components/home-account-selector.tsx} | 2 +- .../_components/home-menu-navigation.tsx | 62 + .../_components/home-mobile-navigation.tsx} | 31 +- .../(user)/_components/home-page-header.tsx | 14 + .../home/(user)/_components/home-sidebar.tsx | 47 + .../(user)/_components/user-notifications.tsx | 10 +- .../(user)/_lib/server/load-user-workspace.ts | 2 + .../personal-account-checkout-form.tsx | 0 .../personal-account-checkout.schema.ts | 0 .../personal-account-billing-page.loader.ts | 0 .../billing/_lib/server/server-actions.ts | 0 .../_lib/server/user-billing.service.ts | 0 .../home/(user)/billing/error.tsx | 2 +- .../home/(user)/billing/layout.tsx | 0 .../home/(user)/billing/page.tsx | 6 +- .../home/(user)/billing/return/page.tsx | 2 +- apps/web/app/home/(user)/layout.tsx | 43 + .../{(dashboard) => }/home/(user)/loading.tsx | 0 .../{(dashboard) => }/home/(user)/page.tsx | 6 +- .../home/(user)/settings/layout.tsx | 6 +- .../home/(user)/settings/page.tsx | 2 +- .../[account]/_components/dashboard-demo.tsx | 0 .../team-account-accounts-selector.tsx | 39 + ...team-account-layout-mobile-navigation.tsx} | 4 +- .../team-account-layout-page-header.tsx | 15 + ...eam-account-layout-sidebar-navigation.tsx} | 4 +- .../team-account-layout-sidebar.tsx} | 47 +- .../team-account-navigation-menu.tsx | 71 + .../team-account-notifications.tsx} | 13 +- .../team-account-billing-page.loader.ts | 0 .../server/team-account-workspace.loader.ts | 4 + .../team-account-checkout-form.tsx | 0 .../_lib/schema/team-billing.schema.ts | 0 .../billing/_lib/server/server-actions.ts | 0 .../_lib/server/team-billing.service.ts | 0 .../home/[account]/billing/error.tsx | 0 .../home/[account]/billing/layout.tsx | 0 .../home/[account]/billing/page.tsx | 7 +- .../home/[account]/billing/return/page.tsx | 0 apps/web/app/home/[account]/layout.tsx | 65 + .../home/[account]/loading.tsx | 0 .../_lib/server/members-page.loader.ts | 0 .../home/[account]/members/page.tsx | 11 +- .../{(dashboard) => }/home/[account]/page.tsx | 25 +- .../home/[account]/settings/page.tsx | 13 +- .../app/{(dashboard) => }/home/loading.tsx | 0 apps/web/app/not-found.tsx | 4 +- apps/web/components/app-logo.tsx | 29 +- apps/web/config/feature-flags.config.ts | 7 +- ...=> personal-account-navigation.config.tsx} | 5 +- ...tsx => team-account-navigation.config.tsx} | 5 +- apps/web/lib/database.types.ts | 2095 ++- apps/web/next.config.mjs | 2 +- .../src/components/account-selector.tsx | 6 +- .../components/personal-account-dropdown.tsx | 6 +- .../mfa/multi-factor-auth-list.tsx | 4 +- .../multi-factor-challenge-container.tsx | 2 +- packages/features/notifications/package.json | 1 + .../src/components/notifications-popover.tsx | 10 +- .../src/hooks/use-fetch-notifications.ts | 53 +- .../invitations/account-invitations-table.tsx | 1 - .../invitations/update-invitation-dialog.tsx | 13 +- packages/supabase/src/database.types.ts | 2095 ++- packages/ui/package.json | 3 +- .../src/makerkit/bordered-navigation-menu.tsx | 50 + packages/ui/src/makerkit/loading-overlay.tsx | 2 +- ...-schema.ts => navigation-config.schema.ts} | 3 +- packages/ui/src/makerkit/page.tsx | 195 +- packages/ui/src/makerkit/profile-avatar.tsx | 4 +- packages/ui/src/makerkit/sidebar.tsx | 6 +- packages/ui/src/makerkit/spinner.tsx | 6 +- packages/ui/src/shadcn/switch.tsx | 21 +- pnpm-lock.yaml | 13608 +++++++--------- 80 files changed, 8880 insertions(+), 10095 deletions(-) delete mode 100644 apps/web/app/(dashboard)/home/(user)/_components/home-sidebar.tsx delete mode 100644 apps/web/app/(dashboard)/home/(user)/_components/user-account-header.tsx delete mode 100644 apps/web/app/(dashboard)/home/(user)/layout.tsx delete mode 100644 apps/web/app/(dashboard)/home/[account]/_components/account-layout-header.tsx delete mode 100644 apps/web/app/(dashboard)/home/[account]/layout.tsx rename apps/web/app/{(dashboard)/home/(user)/_components/home-sidebar-account-selector.tsx => home/(user)/_components/home-account-selector.tsx} (94%) create mode 100644 apps/web/app/home/(user)/_components/home-menu-navigation.tsx rename apps/web/app/{(dashboard)/home/(user)/_components/user-layout-mobile-navigation.tsx => home/(user)/_components/home-mobile-navigation.tsx} (67%) create mode 100644 apps/web/app/home/(user)/_components/home-page-header.tsx create mode 100644 apps/web/app/home/(user)/_components/home-sidebar.tsx rename apps/web/app/{(dashboard) => }/home/(user)/_components/user-notifications.tsx (59%) rename apps/web/app/{(dashboard) => }/home/(user)/_lib/server/load-user-workspace.ts (94%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/_components/personal-account-checkout-form.tsx (100%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/_lib/schema/personal-account-checkout.schema.ts (100%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts (100%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/_lib/server/server-actions.ts (100%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/_lib/server/user-billing.service.ts (100%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/error.tsx (64%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/layout.tsx (100%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/page.tsx (96%) rename apps/web/app/{(dashboard) => }/home/(user)/billing/return/page.tsx (59%) create mode 100644 apps/web/app/home/(user)/layout.tsx rename apps/web/app/{(dashboard) => }/home/(user)/loading.tsx (100%) rename apps/web/app/{(dashboard) => }/home/(user)/page.tsx (84%) rename apps/web/app/{(dashboard) => }/home/(user)/settings/layout.tsx (76%) rename apps/web/app/{(dashboard) => }/home/(user)/settings/page.tsx (92%) rename apps/web/app/{(dashboard) => }/home/[account]/_components/dashboard-demo.tsx (100%) create mode 100644 apps/web/app/home/[account]/_components/team-account-accounts-selector.tsx rename apps/web/app/{(dashboard)/home/[account]/_components/account-layout-mobile-navigation.tsx => home/[account]/_components/team-account-layout-mobile-navigation.tsx} (98%) create mode 100644 apps/web/app/home/[account]/_components/team-account-layout-page-header.tsx rename apps/web/app/{(dashboard)/home/[account]/_components/account-layout-sidebar-navigation.tsx => home/[account]/_components/team-account-layout-sidebar-navigation.tsx} (95%) rename apps/web/app/{(dashboard)/home/[account]/_components/account-layout-sidebar.tsx => home/[account]/_components/team-account-layout-sidebar.tsx} (74%) create mode 100644 apps/web/app/home/[account]/_components/team-account-navigation-menu.tsx rename apps/web/app/{(dashboard)/home/[account]/_components/account-notifications.tsx => home/[account]/_components/team-account-notifications.tsx} (51%) rename apps/web/app/{(dashboard) => }/home/[account]/_lib/server/team-account-billing-page.loader.ts (100%) rename apps/web/app/{(dashboard) => }/home/[account]/_lib/server/team-account-workspace.loader.ts (93%) rename apps/web/app/{(dashboard) => }/home/[account]/billing/_components/team-account-checkout-form.tsx (100%) rename apps/web/app/{(dashboard) => }/home/[account]/billing/_lib/schema/team-billing.schema.ts (100%) rename apps/web/app/{(dashboard) => }/home/[account]/billing/_lib/server/server-actions.ts (100%) rename apps/web/app/{(dashboard) => }/home/[account]/billing/_lib/server/team-billing.service.ts (100%) rename apps/web/app/{(dashboard) => }/home/[account]/billing/error.tsx (100%) rename apps/web/app/{(dashboard) => }/home/[account]/billing/layout.tsx (100%) rename apps/web/app/{(dashboard) => }/home/[account]/billing/page.tsx (96%) rename apps/web/app/{(dashboard) => }/home/[account]/billing/return/page.tsx (100%) create mode 100644 apps/web/app/home/[account]/layout.tsx rename apps/web/app/{(dashboard) => }/home/[account]/loading.tsx (100%) rename apps/web/app/{(dashboard) => }/home/[account]/members/_lib/server/members-page.loader.ts (100%) rename apps/web/app/{(dashboard) => }/home/[account]/members/page.tsx (94%) rename apps/web/app/{(dashboard) => }/home/[account]/page.tsx (79%) rename apps/web/app/{(dashboard) => }/home/[account]/settings/page.tsx (82%) rename apps/web/app/{(dashboard) => }/home/loading.tsx (100%) rename apps/web/config/{personal-account-sidebar.config.tsx => personal-account-navigation.config.tsx} (78%) rename apps/web/config/{team-account-sidebar.config.tsx => team-account-navigation.config.tsx} (89%) create mode 100644 packages/ui/src/makerkit/bordered-navigation-menu.tsx rename packages/ui/src/makerkit/{sidebar-schema.ts => navigation-config.schema.ts} (84%) diff --git a/apps/web/app/(dashboard)/home/(user)/_components/home-sidebar.tsx b/apps/web/app/(dashboard)/home/(user)/_components/home-sidebar.tsx deleted file mode 100644 index acf6901fb..000000000 --- a/apps/web/app/(dashboard)/home/(user)/_components/home-sidebar.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { use } from 'react'; - -import { cookies } from 'next/headers'; - -import { If } from '@kit/ui/if'; -import { Sidebar, SidebarContent, SidebarNavigation } from '@kit/ui/sidebar'; - -import { loadUserWorkspace } from '~/(dashboard)/home/(user)/_lib/server/load-user-workspace'; -import { AppLogo } from '~/components/app-logo'; -import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container'; -import featuresFlagConfig from '~/config/feature-flags.config'; -import { personalAccountSidebarConfig } from '~/config/personal-account-sidebar.config'; - -// home imports -import { HomeSidebarAccountSelector } from '../_components/home-sidebar-account-selector'; - -export function HomeSidebar() { - const collapsed = getSidebarCollapsed(); - const { accounts, user, workspace } = use(loadUserWorkspace()); - - return ( - - - } - > - - - - - - - - -
- - - -
-
- ); -} - -function getSidebarCollapsed() { - return cookies().get('sidebar-collapsed')?.value === 'true'; -} diff --git a/apps/web/app/(dashboard)/home/(user)/_components/user-account-header.tsx b/apps/web/app/(dashboard)/home/(user)/_components/user-account-header.tsx deleted file mode 100644 index e258c0fd7..000000000 --- a/apps/web/app/(dashboard)/home/(user)/_components/user-account-header.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { PageHeader } from '@kit/ui/page'; - -import { UserNotifications } from '~/(dashboard)/home/(user)/_components/user-notifications'; - -import { UserLayoutMobileNavigation } from './user-layout-mobile-navigation'; - -export function UserAccountHeader( - props: React.PropsWithChildren<{ - title: string | React.ReactNode; - description?: string | React.ReactNode; - }>, -) { - return ( - } - > -
- {props.children} - - -
-
- ); -} diff --git a/apps/web/app/(dashboard)/home/(user)/layout.tsx b/apps/web/app/(dashboard)/home/(user)/layout.tsx deleted file mode 100644 index 5c50d9374..000000000 --- a/apps/web/app/(dashboard)/home/(user)/layout.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Page } from '@kit/ui/page'; - -import { withI18n } from '~/lib/i18n/with-i18n'; - -import { HomeSidebar } from './_components/home-sidebar'; - -function UserHomeLayout({ children }: React.PropsWithChildren) { - return }>{children}; -} - -export default withI18n(UserHomeLayout); diff --git a/apps/web/app/(dashboard)/home/[account]/_components/account-layout-header.tsx b/apps/web/app/(dashboard)/home/[account]/_components/account-layout-header.tsx deleted file mode 100644 index bc2a6cc62..000000000 --- a/apps/web/app/(dashboard)/home/[account]/_components/account-layout-header.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { PageHeader } from '@kit/ui/page'; - -import { AccountNotifications } from '~/(dashboard)/home/[account]/_components/account-notifications'; - -import { AccountLayoutMobileNavigation } from './account-layout-mobile-navigation'; - -export function AccountLayoutHeader({ - children, - title, - description, - account, -}: React.PropsWithChildren<{ - title: string | React.ReactNode; - description?: string | React.ReactNode; - account: string; -}>) { - return ( - } - > -
- {children} - - -
-
- ); -} diff --git a/apps/web/app/(dashboard)/home/[account]/layout.tsx b/apps/web/app/(dashboard)/home/[account]/layout.tsx deleted file mode 100644 index 5cf0438ec..000000000 --- a/apps/web/app/(dashboard)/home/[account]/layout.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { use } from 'react'; - -import { Page } from '@kit/ui/page'; - -import { withI18n } from '~/lib/i18n/with-i18n'; - -import { AccountLayoutSidebar } from './_components/account-layout-sidebar'; -import { loadTeamWorkspace } from './_lib/server/team-account-workspace.loader'; - -interface Params { - account: string; -} - -function TeamWorkspaceLayout({ - children, - params, -}: React.PropsWithChildren<{ - params: Params; -}>) { - const data = use(loadTeamWorkspace(params.account)); - - const accounts = data.accounts.map(({ name, slug, picture_url }) => ({ - label: name, - value: slug, - image: picture_url, - })); - - return ( - - } - > - {children} - - ); -} - -export default withI18n(TeamWorkspaceLayout); diff --git a/apps/web/app/admin/layout.tsx b/apps/web/app/admin/layout.tsx index 880f4398b..e2cab237d 100644 --- a/apps/web/app/admin/layout.tsx +++ b/apps/web/app/admin/layout.tsx @@ -1,4 +1,10 @@ -import { Page, PageBody, PageHeader } from '@kit/ui/page'; +import { + Page, + PageBody, + PageHeader, + PageMobileNavigation, + PageNavigation, +} from '@kit/ui/page'; import { AdminSidebar } from '~/admin/_components/admin-sidebar'; import { AdminMobileNavigation } from '~/admin/_components/mobile-navigation'; @@ -9,13 +15,20 @@ export const metadata = { export default function AdminLayout(props: React.PropsWithChildren) { return ( - }> + } title={'Super Admin'} description={`Your SaaS stats at a glance`} /> + + + + + + + + {props.children} ); diff --git a/apps/web/app/error.tsx b/apps/web/app/error.tsx index ac3c2fb40..bbaff0842 100644 --- a/apps/web/app/error.tsx +++ b/apps/web/app/error.tsx @@ -24,7 +24,7 @@ const ErrorPage = ({
diff --git a/apps/web/app/(dashboard)/home/(user)/_components/home-sidebar-account-selector.tsx b/apps/web/app/home/(user)/_components/home-account-selector.tsx similarity index 94% rename from apps/web/app/(dashboard)/home/(user)/_components/home-sidebar-account-selector.tsx rename to apps/web/app/home/(user)/_components/home-account-selector.tsx index 79fb71eaa..2cd241d66 100644 --- a/apps/web/app/(dashboard)/home/(user)/_components/home-sidebar-account-selector.tsx +++ b/apps/web/app/home/(user)/_components/home-account-selector.tsx @@ -11,7 +11,7 @@ const features = { enableTeamCreation: featureFlagsConfig.enableTeamCreation, }; -export function HomeSidebarAccountSelector(props: { +export function HomeAccountSelector(props: { accounts: Array<{ label: string | null; value: string | null; diff --git a/apps/web/app/home/(user)/_components/home-menu-navigation.tsx b/apps/web/app/home/(user)/_components/home-menu-navigation.tsx new file mode 100644 index 000000000..1ef536ade --- /dev/null +++ b/apps/web/app/home/(user)/_components/home-menu-navigation.tsx @@ -0,0 +1,62 @@ +import { + BorderedNavigationMenu, + BorderedNavigationMenuItem, +} from '@kit/ui/bordered-navigation-menu'; + +import { AppLogo } from '~/components/app-logo'; +import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container'; +import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config'; + +// home imports +import { HomeAccountSelector } from '../_components/home-account-selector'; +import { UserNotifications } from '../_components/user-notifications'; +import { type UserWorkspace } from '../_lib/server/load-user-workspace'; + +export function HomeMenuNavigation(props: { workspace: UserWorkspace }) { + const { workspace, user, accounts } = props.workspace; + + const routes = personalAccountNavigationConfig.routes.reduce< + Array<{ + path: string; + label: string; + Icon?: React.ReactNode; + end?: boolean | undefined; + }> + >((acc, item) => { + if ('children' in item) { + return [...acc, ...item.children]; + } + + if ('divider' in item) { + return acc; + } + + return [...acc, item]; + }, []); + + return ( +
+
+ + + + {routes.map((route) => ( + + ))} + +
+ +
+ + + + + +
+
+ ); +} diff --git a/apps/web/app/(dashboard)/home/(user)/_components/user-layout-mobile-navigation.tsx b/apps/web/app/home/(user)/_components/home-mobile-navigation.tsx similarity index 67% rename from apps/web/app/(dashboard)/home/(user)/_components/user-layout-mobile-navigation.tsx rename to apps/web/app/home/(user)/_components/home-mobile-navigation.tsx index d54e6a84b..cd0236d9f 100644 --- a/apps/web/app/(dashboard)/home/(user)/_components/user-layout-mobile-navigation.tsx +++ b/apps/web/app/home/(user)/_components/home-mobile-navigation.tsx @@ -8,18 +8,26 @@ import { useSignOut } from '@kit/supabase/hooks/use-sign-out'; import { DropdownMenu, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuItem, + DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@kit/ui/dropdown-menu'; +import { If } from '@kit/ui/if'; import { Trans } from '@kit/ui/trans'; -import { personalAccountSidebarConfig } from '~/config/personal-account-sidebar.config'; +import featuresFlagConfig from '~/config/feature-flags.config'; +import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config'; -export function UserLayoutMobileNavigation() { +// home imports +import { HomeAccountSelector } from '../_components/home-account-selector'; +import type { UserWorkspace } from '../_lib/server/load-user-workspace'; + +export function HomeMobileNavigation(props: { workspace: UserWorkspace }) { const signOut = useSignOut(); - const Links = personalAccountSidebarConfig.routes.map((item, index) => { + const Links = personalAccountNavigationConfig.routes.map((item, index) => { if ('children' in item) { return item.children.map((child) => { return ( @@ -54,7 +62,22 @@ export function UserLayoutMobileNavigation() { - {Links} + + + + + + + + + + + + + {Links} diff --git a/apps/web/app/home/(user)/_components/home-page-header.tsx b/apps/web/app/home/(user)/_components/home-page-header.tsx new file mode 100644 index 000000000..c43d87af5 --- /dev/null +++ b/apps/web/app/home/(user)/_components/home-page-header.tsx @@ -0,0 +1,14 @@ +import { PageHeader } from '@kit/ui/page'; + +export function HomeLayoutPageHeader( + props: React.PropsWithChildren<{ + title: string | React.ReactNode; + description: string | React.ReactNode; + }>, +) { + return ( + + {props.children} + + ); +} diff --git a/apps/web/app/home/(user)/_components/home-sidebar.tsx b/apps/web/app/home/(user)/_components/home-sidebar.tsx new file mode 100644 index 000000000..e84dadcb7 --- /dev/null +++ b/apps/web/app/home/(user)/_components/home-sidebar.tsx @@ -0,0 +1,47 @@ +import { If } from '@kit/ui/if'; +import { Sidebar, SidebarContent, SidebarNavigation } from '@kit/ui/sidebar'; + +import { AppLogo } from '~/components/app-logo'; +import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container'; +import featuresFlagConfig from '~/config/feature-flags.config'; +import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config'; +import { UserNotifications } from '~/home/(user)/_components/user-notifications'; + +// home imports +import type { UserWorkspace } from '../_lib/server/load-user-workspace'; +import { HomeAccountSelector } from './home-account-selector'; + +export function HomeSidebar(props: { workspace: UserWorkspace }) { + const { workspace, user, accounts } = props.workspace; + + return ( + + +
+ } + > + + + + +
+
+ + + + + +
+ + + +
+
+ ); +} diff --git a/apps/web/app/(dashboard)/home/(user)/_components/user-notifications.tsx b/apps/web/app/home/(user)/_components/user-notifications.tsx similarity index 59% rename from apps/web/app/(dashboard)/home/(user)/_components/user-notifications.tsx rename to apps/web/app/home/(user)/_components/user-notifications.tsx index 7b16a358a..f0dd41428 100644 --- a/apps/web/app/(dashboard)/home/(user)/_components/user-notifications.tsx +++ b/apps/web/app/home/(user)/_components/user-notifications.tsx @@ -1,21 +1,15 @@ -import { use } from 'react'; - import { NotificationsPopover } from '@kit/notifications/components'; import featuresFlagConfig from '~/config/feature-flags.config'; -import { loadUserWorkspace } from '../_lib/server/load-user-workspace'; - -export function UserNotifications() { - const { user } = use(loadUserWorkspace()); - +export function UserNotifications(props: { userId: string }) { if (!featuresFlagConfig.enableNotifications) { return null; } return ( ); diff --git a/apps/web/app/(dashboard)/home/(user)/_lib/server/load-user-workspace.ts b/apps/web/app/home/(user)/_lib/server/load-user-workspace.ts similarity index 94% rename from apps/web/app/(dashboard)/home/(user)/_lib/server/load-user-workspace.ts rename to apps/web/app/home/(user)/_lib/server/load-user-workspace.ts index 00c13f912..a4cff39b1 100644 --- a/apps/web/app/(dashboard)/home/(user)/_lib/server/load-user-workspace.ts +++ b/apps/web/app/home/(user)/_lib/server/load-user-workspace.ts @@ -7,6 +7,8 @@ import featureFlagsConfig from '~/config/feature-flags.config'; const shouldLoadAccounts = featureFlagsConfig.enableTeamAccounts; +export type UserWorkspace = Awaited>; + /** * @name loadUserWorkspace * @description diff --git a/apps/web/app/(dashboard)/home/(user)/billing/_components/personal-account-checkout-form.tsx b/apps/web/app/home/(user)/billing/_components/personal-account-checkout-form.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/(user)/billing/_components/personal-account-checkout-form.tsx rename to apps/web/app/home/(user)/billing/_components/personal-account-checkout-form.tsx diff --git a/apps/web/app/(dashboard)/home/(user)/billing/_lib/schema/personal-account-checkout.schema.ts b/apps/web/app/home/(user)/billing/_lib/schema/personal-account-checkout.schema.ts similarity index 100% rename from apps/web/app/(dashboard)/home/(user)/billing/_lib/schema/personal-account-checkout.schema.ts rename to apps/web/app/home/(user)/billing/_lib/schema/personal-account-checkout.schema.ts diff --git a/apps/web/app/(dashboard)/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts b/apps/web/app/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts similarity index 100% rename from apps/web/app/(dashboard)/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts rename to apps/web/app/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts diff --git a/apps/web/app/(dashboard)/home/(user)/billing/_lib/server/server-actions.ts b/apps/web/app/home/(user)/billing/_lib/server/server-actions.ts similarity index 100% rename from apps/web/app/(dashboard)/home/(user)/billing/_lib/server/server-actions.ts rename to apps/web/app/home/(user)/billing/_lib/server/server-actions.ts diff --git a/apps/web/app/(dashboard)/home/(user)/billing/_lib/server/user-billing.service.ts b/apps/web/app/home/(user)/billing/_lib/server/user-billing.service.ts similarity index 100% rename from apps/web/app/(dashboard)/home/(user)/billing/_lib/server/user-billing.service.ts rename to apps/web/app/home/(user)/billing/_lib/server/user-billing.service.ts diff --git a/apps/web/app/(dashboard)/home/(user)/billing/error.tsx b/apps/web/app/home/(user)/billing/error.tsx similarity index 64% rename from apps/web/app/(dashboard)/home/(user)/billing/error.tsx rename to apps/web/app/home/(user)/billing/error.tsx index e4a931d1b..61bb21f12 100644 --- a/apps/web/app/(dashboard)/home/(user)/billing/error.tsx +++ b/apps/web/app/home/(user)/billing/error.tsx @@ -2,6 +2,6 @@ // We reuse the page from the billing module // as there is no need to create a new one. -import BillingErrorPage from '~/(dashboard)/home/[account]/billing/error'; +import BillingErrorPage from '~/home/[account]/billing/error'; export default BillingErrorPage; diff --git a/apps/web/app/(dashboard)/home/(user)/billing/layout.tsx b/apps/web/app/home/(user)/billing/layout.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/(user)/billing/layout.tsx rename to apps/web/app/home/(user)/billing/layout.tsx diff --git a/apps/web/app/(dashboard)/home/(user)/billing/page.tsx b/apps/web/app/home/(user)/billing/page.tsx similarity index 96% rename from apps/web/app/(dashboard)/home/(user)/billing/page.tsx rename to apps/web/app/home/(user)/billing/page.tsx index cc861c306..90c5e2bb0 100644 --- a/apps/web/app/(dashboard)/home/(user)/billing/page.tsx +++ b/apps/web/app/home/(user)/billing/page.tsx @@ -15,10 +15,10 @@ import billingConfig from '~/config/billing.config'; import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; import { withI18n } from '~/lib/i18n/with-i18n'; -import { UserAccountHeader } from '../_components/user-account-header'; +// local imports +import { HomeLayoutPageHeader } from '../_components/home-page-header'; import { createPersonalAccountBillingPortalSession } from '../billing/_lib/server/server-actions'; import { PersonalAccountCheckoutForm } from './_components/personal-account-checkout-form'; -// user billing imports import { loadPersonalAccountBillingPageData } from './_lib/server/personal-account-billing-page.loader'; export const generateMetadata = async () => { @@ -44,7 +44,7 @@ async function PersonalAccountBillingPage() { return ( <> - } description={} /> diff --git a/apps/web/app/(dashboard)/home/(user)/billing/return/page.tsx b/apps/web/app/home/(user)/billing/return/page.tsx similarity index 59% rename from apps/web/app/(dashboard)/home/(user)/billing/return/page.tsx rename to apps/web/app/home/(user)/billing/return/page.tsx index 221e880fa..bc819a3f4 100644 --- a/apps/web/app/(dashboard)/home/(user)/billing/return/page.tsx +++ b/apps/web/app/home/(user)/billing/return/page.tsx @@ -1,5 +1,5 @@ // We reuse the page from the billing module // as there is no need to create a new one. -import ReturnCheckoutSessionPage from '~/(dashboard)/home/[account]/billing/return/page'; +import ReturnCheckoutSessionPage from '~/home/[account]/billing/return/page'; export default ReturnCheckoutSessionPage; diff --git a/apps/web/app/home/(user)/layout.tsx b/apps/web/app/home/(user)/layout.tsx new file mode 100644 index 000000000..c681865f9 --- /dev/null +++ b/apps/web/app/home/(user)/layout.tsx @@ -0,0 +1,43 @@ +import { use } from 'react'; + +import { If } from '@kit/ui/if'; +import { Page, PageMobileNavigation, PageNavigation } from '@kit/ui/page'; + +import { AppLogo } from '~/components/app-logo'; +import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config'; +import { withI18n } from '~/lib/i18n/with-i18n'; + +// home imports +import { HomeMenuNavigation } from './_components/home-menu-navigation'; +import { HomeMobileNavigation } from './_components/home-mobile-navigation'; +import { HomeSidebar } from './_components/home-sidebar'; +import { loadUserWorkspace } from './_lib/server/load-user-workspace'; + +const style = personalAccountNavigationConfig.style; + +function UserHomeLayout({ children }: React.PropsWithChildren) { + const workspace = use(loadUserWorkspace()); + + return ( + + + + + + + + + + + + + + + + + {children} + + ); +} + +export default withI18n(UserHomeLayout); diff --git a/apps/web/app/(dashboard)/home/(user)/loading.tsx b/apps/web/app/home/(user)/loading.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/(user)/loading.tsx rename to apps/web/app/home/(user)/loading.tsx diff --git a/apps/web/app/(dashboard)/home/(user)/page.tsx b/apps/web/app/home/(user)/page.tsx similarity index 84% rename from apps/web/app/(dashboard)/home/(user)/page.tsx rename to apps/web/app/home/(user)/page.tsx index d8a24da12..843362c21 100644 --- a/apps/web/app/(dashboard)/home/(user)/page.tsx +++ b/apps/web/app/home/(user)/page.tsx @@ -1,10 +1,12 @@ import { PageBody } from '@kit/ui/page'; import { Trans } from '@kit/ui/trans'; -import { UserAccountHeader } from '~/(dashboard)/home/(user)/_components/user-account-header'; import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; import { withI18n } from '~/lib/i18n/with-i18n'; +// local imports +import { HomeLayoutPageHeader } from './_components/home-page-header'; + export const generateMetadata = async () => { const i18n = await createI18nServerInstance(); const title = i18n.t('account:homePage'); @@ -17,7 +19,7 @@ export const generateMetadata = async () => { function UserHomePage() { return ( <> - } description={} /> diff --git a/apps/web/app/(dashboard)/home/(user)/settings/layout.tsx b/apps/web/app/home/(user)/settings/layout.tsx similarity index 76% rename from apps/web/app/(dashboard)/home/(user)/settings/layout.tsx rename to apps/web/app/home/(user)/settings/layout.tsx index 8abb26b56..476a62d28 100644 --- a/apps/web/app/(dashboard)/home/(user)/settings/layout.tsx +++ b/apps/web/app/home/(user)/settings/layout.tsx @@ -1,12 +1,14 @@ import { Trans } from '@kit/ui/trans'; -import { UserAccountHeader } from '~/(dashboard)/home/(user)/_components/user-account-header'; import { withI18n } from '~/lib/i18n/with-i18n'; +// local imports +import { HomeLayoutPageHeader } from '../_components/home-page-header'; + function UserSettingsLayout(props: React.PropsWithChildren) { return ( <> - } description={} /> diff --git a/apps/web/app/(dashboard)/home/(user)/settings/page.tsx b/apps/web/app/home/(user)/settings/page.tsx similarity index 92% rename from apps/web/app/(dashboard)/home/(user)/settings/page.tsx rename to apps/web/app/home/(user)/settings/page.tsx index 1b3ce89eb..396242625 100644 --- a/apps/web/app/(dashboard)/home/(user)/settings/page.tsx +++ b/apps/web/app/home/(user)/settings/page.tsx @@ -26,7 +26,7 @@ export const generateMetadata = async () => { function PersonalAccountSettingsPage() { return ( -
+
diff --git a/apps/web/app/(dashboard)/home/[account]/_components/dashboard-demo.tsx b/apps/web/app/home/[account]/_components/dashboard-demo.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/_components/dashboard-demo.tsx rename to apps/web/app/home/[account]/_components/dashboard-demo.tsx diff --git a/apps/web/app/home/[account]/_components/team-account-accounts-selector.tsx b/apps/web/app/home/[account]/_components/team-account-accounts-selector.tsx new file mode 100644 index 000000000..ec520ba4a --- /dev/null +++ b/apps/web/app/home/[account]/_components/team-account-accounts-selector.tsx @@ -0,0 +1,39 @@ +'use client'; + +import { useRouter } from 'next/navigation'; + +import { AccountSelector } from '@kit/accounts/account-selector'; + +import featureFlagsConfig from '~/config/feature-flags.config'; +import pathsConfig from '~/config/paths.config'; + +const features = { + enableTeamCreation: featureFlagsConfig.enableTeamCreation, +}; + +export function TeamAccountAccountsSelector(params: { + selectedAccount: string; + accounts: Array<{ + label: string | null; + value: string | null; + image: string | null; + }>; +}) { + const router = useRouter(); + + return ( + { + const path = value + ? pathsConfig.app.accountHome.replace('[account]', value) + : pathsConfig.app.home; + + router.replace(path); + }} + /> + ); +} diff --git a/apps/web/app/(dashboard)/home/[account]/_components/account-layout-mobile-navigation.tsx b/apps/web/app/home/[account]/_components/team-account-layout-mobile-navigation.tsx similarity index 98% rename from apps/web/app/(dashboard)/home/[account]/_components/account-layout-mobile-navigation.tsx rename to apps/web/app/home/[account]/_components/team-account-layout-mobile-navigation.tsx index 697d69564..15f9eb0bc 100644 --- a/apps/web/app/(dashboard)/home/[account]/_components/account-layout-mobile-navigation.tsx +++ b/apps/web/app/home/[account]/_components/team-account-layout-mobile-navigation.tsx @@ -25,14 +25,14 @@ import { Trans } from '@kit/ui/trans'; import featureFlagsConfig from '~/config/feature-flags.config'; import pathsConfig from '~/config/paths.config'; -import { getTeamAccountSidebarConfig } from '~/config/team-account-sidebar.config'; +import { getTeamAccountSidebarConfig } from '~/config/team-account-navigation.config'; const features = { enableTeamAccounts: featureFlagsConfig.enableTeamAccounts, enableTeamCreation: featureFlagsConfig.enableTeamCreation, }; -export const AccountLayoutMobileNavigation = ( +export const TeamAccountLayoutMobileNavigation = ( props: React.PropsWithChildren<{ account: string; }>, diff --git a/apps/web/app/home/[account]/_components/team-account-layout-page-header.tsx b/apps/web/app/home/[account]/_components/team-account-layout-page-header.tsx new file mode 100644 index 000000000..80491ead9 --- /dev/null +++ b/apps/web/app/home/[account]/_components/team-account-layout-page-header.tsx @@ -0,0 +1,15 @@ +import { PageHeader } from '@kit/ui/page'; + +export function TeamAccountLayoutPageHeader( + props: React.PropsWithChildren<{ + title: string | React.ReactNode; + description: string | React.ReactNode; + account: string; + }>, +) { + return ( + + {props.children} + + ); +} diff --git a/apps/web/app/(dashboard)/home/[account]/_components/account-layout-sidebar-navigation.tsx b/apps/web/app/home/[account]/_components/team-account-layout-sidebar-navigation.tsx similarity index 95% rename from apps/web/app/(dashboard)/home/[account]/_components/account-layout-sidebar-navigation.tsx rename to apps/web/app/home/[account]/_components/team-account-layout-sidebar-navigation.tsx index 32791cf9d..e484f2f78 100644 --- a/apps/web/app/(dashboard)/home/[account]/_components/account-layout-sidebar-navigation.tsx +++ b/apps/web/app/home/[account]/_components/team-account-layout-sidebar-navigation.tsx @@ -1,9 +1,9 @@ import { SidebarDivider, SidebarGroup, SidebarItem } from '@kit/ui/sidebar'; import { Trans } from '@kit/ui/trans'; -import { getTeamAccountSidebarConfig } from '~/config/team-account-sidebar.config'; +import { getTeamAccountSidebarConfig } from '~/config/team-account-navigation.config'; -export function AccountLayoutSidebarNavigation({ +export function TeamAccountLayoutSidebarNavigation({ account, }: React.PropsWithChildren<{ account: string; diff --git a/apps/web/app/(dashboard)/home/[account]/_components/account-layout-sidebar.tsx b/apps/web/app/home/[account]/_components/team-account-layout-sidebar.tsx similarity index 74% rename from apps/web/app/(dashboard)/home/[account]/_components/account-layout-sidebar.tsx rename to apps/web/app/home/[account]/_components/team-account-layout-sidebar.tsx index 52f3fe51c..e8ba8d57e 100644 --- a/apps/web/app/(dashboard)/home/[account]/_components/account-layout-sidebar.tsx +++ b/apps/web/app/home/[account]/_components/team-account-layout-sidebar.tsx @@ -1,12 +1,9 @@ 'use client'; -import { useRouter } from 'next/navigation'; - import { User } from '@supabase/supabase-js'; import { ArrowLeftCircle, ArrowRightCircle } from 'lucide-react'; -import { AccountSelector } from '@kit/accounts/account-selector'; import { If } from '@kit/ui/if'; import { Sidebar, SidebarContent } from '@kit/ui/sidebar'; import { @@ -19,10 +16,10 @@ import { Trans } from '@kit/ui/trans'; import { cn } from '@kit/ui/utils'; import { ProfileAccountDropdownContainer } from '~/components//personal-account-dropdown-container'; -import featureFlagsConfig from '~/config/feature-flags.config'; -import pathsConfig from '~/config/paths.config'; +import { TeamAccountNotifications } from '~/home/[account]/_components/team-account-notifications'; -import { AccountLayoutSidebarNavigation } from './account-layout-sidebar-navigation'; +import { TeamAccountAccountsSelector } from '../_components/team-account-accounts-selector'; +import { TeamAccountLayoutSidebarNavigation } from './team-account-layout-sidebar-navigation'; type AccountModel = { label: string | null; @@ -30,16 +27,11 @@ type AccountModel = { image: string | null; }; -const features = { - enableTeamAccounts: featureFlagsConfig.enableTeamAccounts, - enableTeamCreation: featureFlagsConfig.enableTeamCreation, -}; - -export function AccountLayoutSidebar(props: { +export function TeamAccountLayoutSidebar(props: { account: string; accounts: AccountModel[]; collapsed: boolean; - user: User | null; + user: User; }) { return ( @@ -62,31 +54,28 @@ function SidebarContainer(props: { collapsed: boolean; setCollapsed: (collapsed: boolean) => void; collapsible?: boolean; - user: User | null; + user: User; }) { const { account, accounts } = props; - const router = useRouter(); return ( <> - - { - const path = value - ? pathsConfig.app.accountHome.replace('[account]', value) - : pathsConfig.app.home; + +
+ - router.replace(path); - }} - /> + +
- +
diff --git a/apps/web/app/home/[account]/_components/team-account-navigation-menu.tsx b/apps/web/app/home/[account]/_components/team-account-navigation-menu.tsx new file mode 100644 index 000000000..3c53df1a0 --- /dev/null +++ b/apps/web/app/home/[account]/_components/team-account-navigation-menu.tsx @@ -0,0 +1,71 @@ +import { + BorderedNavigationMenu, + BorderedNavigationMenuItem, +} from '@kit/ui/bordered-navigation-menu'; + +import { AppLogo } from '~/components/app-logo'; +import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container'; +import { getTeamAccountSidebarConfig } from '~/config/team-account-navigation.config'; +import { TeamAccountAccountsSelector } from '~/home/[account]/_components/team-account-accounts-selector'; + +// local imports +import { TeamAccountWorkspace } from '../_lib/server/team-account-workspace.loader'; +import { TeamAccountNotifications } from './team-account-notifications'; + +export function TeamAccountNavigationMenu(props: { + workspace: TeamAccountWorkspace; +}) { + const { account, user, accounts } = props.workspace; + + const routes = getTeamAccountSidebarConfig(account.slug).routes.reduce< + Array<{ + path: string; + label: string; + Icon?: React.ReactNode; + end?: boolean | undefined; + }> + >((acc, item) => { + if ('children' in item) { + return [...acc, ...item.children]; + } + + if ('divider' in item) { + return acc; + } + + return [...acc, item]; + }, []); + + return ( +
+
+ + + + {routes.map((route) => ( + + ))} + +
+ +
+ ({ + label: account.name, + value: account.id, + image: account.picture_url, + }))} + /> + + + + +
+
+ ); +} diff --git a/apps/web/app/(dashboard)/home/[account]/_components/account-notifications.tsx b/apps/web/app/home/[account]/_components/team-account-notifications.tsx similarity index 51% rename from apps/web/app/(dashboard)/home/[account]/_components/account-notifications.tsx rename to apps/web/app/home/[account]/_components/team-account-notifications.tsx index c62c87ac0..5655ccf2b 100644 --- a/apps/web/app/(dashboard)/home/[account]/_components/account-notifications.tsx +++ b/apps/web/app/home/[account]/_components/team-account-notifications.tsx @@ -1,21 +1,18 @@ -import { use } from 'react'; - import { NotificationsPopover } from '@kit/notifications/components'; import featuresFlagConfig from '~/config/feature-flags.config'; -import { loadTeamWorkspace } from '../_lib/server/team-account-workspace.loader'; - -export function AccountNotifications(params: { accountId: string }) { - const { user, account } = use(loadTeamWorkspace(params.accountId)); - +export function TeamAccountNotifications(params: { + userId: string; + accountId: string; +}) { if (!featuresFlagConfig.enableNotifications) { return null; } return ( ); diff --git a/apps/web/app/(dashboard)/home/[account]/_lib/server/team-account-billing-page.loader.ts b/apps/web/app/home/[account]/_lib/server/team-account-billing-page.loader.ts similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/_lib/server/team-account-billing-page.loader.ts rename to apps/web/app/home/[account]/_lib/server/team-account-billing-page.loader.ts diff --git a/apps/web/app/(dashboard)/home/[account]/_lib/server/team-account-workspace.loader.ts b/apps/web/app/home/[account]/_lib/server/team-account-workspace.loader.ts similarity index 93% rename from apps/web/app/(dashboard)/home/[account]/_lib/server/team-account-workspace.loader.ts rename to apps/web/app/home/[account]/_lib/server/team-account-workspace.loader.ts index 6a0dd71cd..d273d04de 100644 --- a/apps/web/app/(dashboard)/home/[account]/_lib/server/team-account-workspace.loader.ts +++ b/apps/web/app/home/[account]/_lib/server/team-account-workspace.loader.ts @@ -9,6 +9,10 @@ import { createTeamAccountsApi } from '@kit/team-accounts/api'; import pathsConfig from '~/config/paths.config'; +export type TeamAccountWorkspace = Awaited< + ReturnType +>; + /** * Load the account workspace data. * We place this function into a separate file so it can be reused in multiple places across the server components. diff --git a/apps/web/app/(dashboard)/home/[account]/billing/_components/team-account-checkout-form.tsx b/apps/web/app/home/[account]/billing/_components/team-account-checkout-form.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/billing/_components/team-account-checkout-form.tsx rename to apps/web/app/home/[account]/billing/_components/team-account-checkout-form.tsx diff --git a/apps/web/app/(dashboard)/home/[account]/billing/_lib/schema/team-billing.schema.ts b/apps/web/app/home/[account]/billing/_lib/schema/team-billing.schema.ts similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/billing/_lib/schema/team-billing.schema.ts rename to apps/web/app/home/[account]/billing/_lib/schema/team-billing.schema.ts diff --git a/apps/web/app/(dashboard)/home/[account]/billing/_lib/server/server-actions.ts b/apps/web/app/home/[account]/billing/_lib/server/server-actions.ts similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/billing/_lib/server/server-actions.ts rename to apps/web/app/home/[account]/billing/_lib/server/server-actions.ts diff --git a/apps/web/app/(dashboard)/home/[account]/billing/_lib/server/team-billing.service.ts b/apps/web/app/home/[account]/billing/_lib/server/team-billing.service.ts similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/billing/_lib/server/team-billing.service.ts rename to apps/web/app/home/[account]/billing/_lib/server/team-billing.service.ts diff --git a/apps/web/app/(dashboard)/home/[account]/billing/error.tsx b/apps/web/app/home/[account]/billing/error.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/billing/error.tsx rename to apps/web/app/home/[account]/billing/error.tsx diff --git a/apps/web/app/(dashboard)/home/[account]/billing/layout.tsx b/apps/web/app/home/[account]/billing/layout.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/billing/layout.tsx rename to apps/web/app/home/[account]/billing/layout.tsx diff --git a/apps/web/app/(dashboard)/home/[account]/billing/page.tsx b/apps/web/app/home/[account]/billing/page.tsx similarity index 96% rename from apps/web/app/(dashboard)/home/[account]/billing/page.tsx rename to apps/web/app/home/[account]/billing/page.tsx index 1ab199bf8..d2a1e87c9 100644 --- a/apps/web/app/(dashboard)/home/[account]/billing/page.tsx +++ b/apps/web/app/home/[account]/billing/page.tsx @@ -15,7 +15,8 @@ import billingConfig from '~/config/billing.config'; import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; import { withI18n } from '~/lib/i18n/with-i18n'; -import { AccountLayoutHeader } from '../_components/account-layout-header'; +// local imports +import { TeamAccountLayoutPageHeader } from '../_components/team-account-layout-page-header'; import { loadTeamAccountBillingPage } from '../_lib/server/team-account-billing-page.loader'; import { loadTeamWorkspace } from '../_lib/server/team-account-workspace.loader'; import { TeamAccountCheckoutForm } from './_components/team-account-checkout-form'; @@ -72,10 +73,10 @@ async function TeamAccountBillingPage({ params }: Params) { return ( <> - } description={} - account={params.account} /> diff --git a/apps/web/app/(dashboard)/home/[account]/billing/return/page.tsx b/apps/web/app/home/[account]/billing/return/page.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/billing/return/page.tsx rename to apps/web/app/home/[account]/billing/return/page.tsx diff --git a/apps/web/app/home/[account]/layout.tsx b/apps/web/app/home/[account]/layout.tsx new file mode 100644 index 000000000..e520746d1 --- /dev/null +++ b/apps/web/app/home/[account]/layout.tsx @@ -0,0 +1,65 @@ +import { use } from 'react'; + +import { If } from '@kit/ui/if'; +import { Page, PageMobileNavigation, PageNavigation } from '@kit/ui/page'; + +import { AppLogo } from '~/components/app-logo'; +import { getTeamAccountSidebarConfig } from '~/config/team-account-navigation.config'; +import { withI18n } from '~/lib/i18n/with-i18n'; + +// local imports +import { TeamAccountLayoutMobileNavigation } from './_components/team-account-layout-mobile-navigation'; +import { TeamAccountLayoutSidebar } from './_components/team-account-layout-sidebar'; +import { TeamAccountNavigationMenu } from './_components/team-account-navigation-menu'; +import { loadTeamWorkspace } from './_lib/server/team-account-workspace.loader'; + +interface Params { + account: string; +} + +function TeamWorkspaceLayout({ + children, + params, +}: React.PropsWithChildren<{ + params: Params; +}>) { + const data = use(loadTeamWorkspace(params.account)); + const style = getTeamAccountSidebarConfig(params.account).style; + + const accounts = data.accounts.map(({ name, slug, picture_url }) => ({ + label: name, + value: slug, + image: picture_url, + })); + + return ( + + + + + + + + + + + + + + +
+ +
+
+ + {children} +
+ ); +} + +export default withI18n(TeamWorkspaceLayout); diff --git a/apps/web/app/(dashboard)/home/[account]/loading.tsx b/apps/web/app/home/[account]/loading.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/loading.tsx rename to apps/web/app/home/[account]/loading.tsx diff --git a/apps/web/app/(dashboard)/home/[account]/members/_lib/server/members-page.loader.ts b/apps/web/app/home/[account]/members/_lib/server/members-page.loader.ts similarity index 100% rename from apps/web/app/(dashboard)/home/[account]/members/_lib/server/members-page.loader.ts rename to apps/web/app/home/[account]/members/_lib/server/members-page.loader.ts diff --git a/apps/web/app/(dashboard)/home/[account]/members/page.tsx b/apps/web/app/home/[account]/members/page.tsx similarity index 94% rename from apps/web/app/(dashboard)/home/[account]/members/page.tsx rename to apps/web/app/home/[account]/members/page.tsx index 9256e6efd..4a51b92b3 100644 --- a/apps/web/app/(dashboard)/home/[account]/members/page.tsx +++ b/apps/web/app/home/[account]/members/page.tsx @@ -21,7 +21,8 @@ import { Trans } from '@kit/ui/trans'; import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; import { withI18n } from '~/lib/i18n/with-i18n'; -import { AccountLayoutHeader } from '../_components/account-layout-header'; +// local imports +import { TeamAccountLayoutPageHeader } from '../_components/team-account-layout-page-header'; import { loadMembersPageData } from './_lib/server/members-page.loader'; interface Params { @@ -53,16 +54,14 @@ async function TeamAccountMembersPage({ params }: Params) { return ( <> - } description={} - account={params.account} + account={account.slug} /> -
+
diff --git a/apps/web/app/(dashboard)/home/[account]/page.tsx b/apps/web/app/home/[account]/page.tsx similarity index 79% rename from apps/web/app/(dashboard)/home/[account]/page.tsx rename to apps/web/app/home/[account]/page.tsx index e61fd86bb..943efb768 100644 --- a/apps/web/app/(dashboard)/home/[account]/page.tsx +++ b/apps/web/app/home/[account]/page.tsx @@ -4,13 +4,18 @@ import { PlusCircle } from 'lucide-react'; import { Button } from '@kit/ui/button'; import { PageBody } from '@kit/ui/page'; -import Spinner from '@kit/ui/spinner'; +import { Spinner } from '@kit/ui/spinner'; import { Trans } from '@kit/ui/trans'; -import { AccountLayoutHeader } from '~/(dashboard)/home/[account]/_components/account-layout-header'; import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; import { withI18n } from '~/lib/i18n/with-i18n'; +import { TeamAccountLayoutPageHeader } from './_components/team-account-layout-page-header'; + +interface Params { + account: string; +} + const DashboardDemo = loadDynamic( () => import('./_components/dashboard-demo'), { @@ -41,25 +46,19 @@ export const generateMetadata = async () => { }; }; -function TeamAccountHomePage({ - params, -}: { - params: { - account: string; - }; -}) { +function TeamAccountHomePage({ params }: { params: Params }) { return ( <> - } description={} - account={params.account} > - - + diff --git a/apps/web/app/(dashboard)/home/[account]/settings/page.tsx b/apps/web/app/home/[account]/settings/page.tsx similarity index 82% rename from apps/web/app/(dashboard)/home/[account]/settings/page.tsx rename to apps/web/app/home/[account]/settings/page.tsx index 77cba73d6..b7ccdbac5 100644 --- a/apps/web/app/(dashboard)/home/[account]/settings/page.tsx +++ b/apps/web/app/home/[account]/settings/page.tsx @@ -5,7 +5,8 @@ import { Trans } from '@kit/ui/trans'; import pathsConfig from '~/config/paths.config'; import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; -import { AccountLayoutHeader } from '../_components/account-layout-header'; +// local imports +import { TeamAccountLayoutPageHeader } from '../_components/team-account-layout-page-header'; import { loadTeamWorkspace } from '../_lib/server/team-account-workspace.loader'; export const generateMetadata = async () => { @@ -40,18 +41,14 @@ async function TeamAccountSettingsPage(props: Props) { return ( <> - } description={} - account={props.params.account} /> -
+
diff --git a/apps/web/app/(dashboard)/home/loading.tsx b/apps/web/app/home/loading.tsx similarity index 100% rename from apps/web/app/(dashboard)/home/loading.tsx rename to apps/web/app/home/loading.tsx diff --git a/apps/web/app/not-found.tsx b/apps/web/app/not-found.tsx index 4414cb26b..f70ee9c31 100644 --- a/apps/web/app/not-found.tsx +++ b/apps/web/app/not-found.tsx @@ -33,12 +33,12 @@ const NotFoundPage = async () => {
-

+

diff --git a/apps/web/components/app-logo.tsx b/apps/web/components/app-logo.tsx index 2afbabc8e..612f746ff 100644 --- a/apps/web/components/app-logo.tsx +++ b/apps/web/components/app-logo.tsx @@ -15,37 +15,10 @@ const LogoImage: React.FC<{ xmlns="http://www.w3.org/2000/svg" > - - - - - - - - - ); }; diff --git a/apps/web/config/feature-flags.config.ts b/apps/web/config/feature-flags.config.ts index 62ec5f2db..31c6807e0 100644 --- a/apps/web/config/feature-flags.config.ts +++ b/apps/web/config/feature-flags.config.ts @@ -1,5 +1,7 @@ import { z } from 'zod'; +type LanguagePriority = 'user' | 'application'; + const FeatureFlagsSchema = z.object({ enableThemeToggle: z.boolean({ description: 'Enable theme toggle in the user interface.', @@ -83,9 +85,8 @@ const featuresFlagConfig = FeatureFlagsSchema.parse({ process.env.NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING, false, ), - languagePriority: process.env.NEXT_PUBLIC_LANGUAGE_PRIORITY as - | 'user' - | 'application', + languagePriority: process.env + .NEXT_PUBLIC_LANGUAGE_PRIORITY as LanguagePriority, enableNotifications: getBoolean( process.env.NEXT_PUBLIC_ENABLE_NOTIFICATIONS, true, diff --git a/apps/web/config/personal-account-sidebar.config.tsx b/apps/web/config/personal-account-navigation.config.tsx similarity index 78% rename from apps/web/config/personal-account-sidebar.config.tsx rename to apps/web/config/personal-account-navigation.config.tsx index 738685247..f9a253429 100644 --- a/apps/web/config/personal-account-sidebar.config.tsx +++ b/apps/web/config/personal-account-navigation.config.tsx @@ -1,6 +1,6 @@ import { CreditCard, Home, User } from 'lucide-react'; -import { SidebarConfigSchema } from '@kit/ui/sidebar-schema'; +import { NavigationConfigSchema } from '@kit/ui/navigation-schema'; import featureFlagsConfig from '~/config/feature-flags.config'; import pathsConfig from '~/config/paths.config'; @@ -29,6 +29,7 @@ if (featureFlagsConfig.enablePersonalAccountBilling) { }); } -export const personalAccountSidebarConfig = SidebarConfigSchema.parse({ +export const personalAccountNavigationConfig = NavigationConfigSchema.parse({ routes, + style: process.env.NEXT_PUBLIC_USER_NAVIGATION_STYLE, }); diff --git a/apps/web/config/team-account-sidebar.config.tsx b/apps/web/config/team-account-navigation.config.tsx similarity index 89% rename from apps/web/config/team-account-sidebar.config.tsx rename to apps/web/config/team-account-navigation.config.tsx index 28b7016fa..139cd08f2 100644 --- a/apps/web/config/team-account-sidebar.config.tsx +++ b/apps/web/config/team-account-navigation.config.tsx @@ -1,6 +1,6 @@ import { CreditCard, LayoutDashboard, Settings, Users } from 'lucide-react'; -import { SidebarConfigSchema } from '@kit/ui/sidebar-schema'; +import { NavigationConfigSchema } from '@kit/ui/navigation-schema'; import featureFlagsConfig from '~/config/feature-flags.config'; import pathsConfig from '~/config/paths.config'; @@ -40,8 +40,9 @@ const getRoutes = (account: string) => [ ]; export function getTeamAccountSidebarConfig(account: string) { - return SidebarConfigSchema.parse({ + return NavigationConfigSchema.parse({ routes: getRoutes(account), + style: process.env.NEXT_PUBLIC_TEAM_NAVIGATION_STYLE, }); } diff --git a/apps/web/lib/database.types.ts b/apps/web/lib/database.types.ts index 320274e2c..26ae42f21 100644 --- a/apps/web/lib/database.types.ts +++ b/apps/web/lib/database.types.ts @@ -4,1353 +4,1352 @@ export type Json = | boolean | null | { [key: string]: Json | undefined } - | Json[] + | Json[]; export type Database = { graphql_public: { Tables: { - [_ in never]: never - } + [_ in never]: never; + }; Views: { - [_ in never]: never - } + [_ in never]: never; + }; Functions: { graphql: { Args: { - operationName?: string - query?: string - variables?: Json - extensions?: Json - } - Returns: Json - } - } + operationName?: string; + query?: string; + variables?: Json; + extensions?: Json; + }; + Returns: Json; + }; + }; Enums: { - [_ in never]: never - } + [_ in never]: never; + }; CompositeTypes: { - [_ in never]: never - } - } + [_ in never]: never; + }; + }; public: { Tables: { accounts: { Row: { - created_at: string | null - created_by: string | null - email: string | null - id: string - is_personal_account: boolean - name: string - picture_url: string | null - primary_owner_user_id: string - public_data: Json - slug: string | null - updated_at: string | null - updated_by: string | null - } + created_at: string | null; + created_by: string | null; + email: string | null; + id: string; + is_personal_account: boolean; + name: string; + picture_url: string | null; + primary_owner_user_id: string; + public_data: Json; + slug: string | null; + updated_at: string | null; + updated_by: string | null; + }; Insert: { - created_at?: string | null - created_by?: string | null - email?: string | null - id?: string - is_personal_account?: boolean - name: string - picture_url?: string | null - primary_owner_user_id?: string - public_data?: Json - slug?: string | null - updated_at?: string | null - updated_by?: string | null - } + created_at?: string | null; + created_by?: string | null; + email?: string | null; + id?: string; + is_personal_account?: boolean; + name: string; + picture_url?: string | null; + primary_owner_user_id?: string; + public_data?: Json; + slug?: string | null; + updated_at?: string | null; + updated_by?: string | null; + }; Update: { - created_at?: string | null - created_by?: string | null - email?: string | null - id?: string - is_personal_account?: boolean - name?: string - picture_url?: string | null - primary_owner_user_id?: string - public_data?: Json - slug?: string | null - updated_at?: string | null - updated_by?: string | null - } + created_at?: string | null; + created_by?: string | null; + email?: string | null; + id?: string; + is_personal_account?: boolean; + name?: string; + picture_url?: string | null; + primary_owner_user_id?: string; + public_data?: Json; + slug?: string | null; + updated_at?: string | null; + updated_by?: string | null; + }; Relationships: [ { - foreignKeyName: "accounts_created_by_fkey" - columns: ["created_by"] - isOneToOne: false - referencedRelation: "users" - referencedColumns: ["id"] + foreignKeyName: 'accounts_created_by_fkey'; + columns: ['created_by']; + isOneToOne: false; + referencedRelation: 'users'; + referencedColumns: ['id']; }, { - foreignKeyName: "accounts_primary_owner_user_id_fkey" - columns: ["primary_owner_user_id"] - isOneToOne: false - referencedRelation: "users" - referencedColumns: ["id"] + foreignKeyName: 'accounts_primary_owner_user_id_fkey'; + columns: ['primary_owner_user_id']; + isOneToOne: false; + referencedRelation: 'users'; + referencedColumns: ['id']; }, { - foreignKeyName: "accounts_updated_by_fkey" - columns: ["updated_by"] - isOneToOne: false - referencedRelation: "users" - referencedColumns: ["id"] + foreignKeyName: 'accounts_updated_by_fkey'; + columns: ['updated_by']; + isOneToOne: false; + referencedRelation: 'users'; + referencedColumns: ['id']; }, - ] - } + ]; + }; accounts_memberships: { Row: { - account_id: string - account_role: string - created_at: string - created_by: string | null - updated_at: string - updated_by: string | null - user_id: string - } + account_id: string; + account_role: string; + created_at: string; + created_by: string | null; + updated_at: string; + updated_by: string | null; + user_id: string; + }; Insert: { - account_id: string - account_role: string - created_at?: string - created_by?: string | null - updated_at?: string - updated_by?: string | null - user_id: string - } + account_id: string; + account_role: string; + created_at?: string; + created_by?: string | null; + updated_at?: string; + updated_by?: string | null; + user_id: string; + }; Update: { - account_id?: string - account_role?: string - created_at?: string - created_by?: string | null - updated_at?: string - updated_by?: string | null - user_id?: string - } + account_id?: string; + account_role?: string; + created_at?: string; + created_by?: string | null; + updated_at?: string; + updated_by?: string | null; + user_id?: string; + }; Relationships: [ { - foreignKeyName: "accounts_memberships_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: 'accounts_memberships_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "accounts_memberships_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_account_workspace" - referencedColumns: ["id"] + foreignKeyName: 'accounts_memberships_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_account_workspace'; + referencedColumns: ['id']; }, { - foreignKeyName: "accounts_memberships_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_accounts" - referencedColumns: ["id"] + foreignKeyName: 'accounts_memberships_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "accounts_memberships_account_role_fkey" - columns: ["account_role"] - isOneToOne: false - referencedRelation: "roles" - referencedColumns: ["name"] + foreignKeyName: 'accounts_memberships_account_role_fkey'; + columns: ['account_role']; + isOneToOne: false; + referencedRelation: 'roles'; + referencedColumns: ['name']; }, { - foreignKeyName: "accounts_memberships_created_by_fkey" - columns: ["created_by"] - isOneToOne: false - referencedRelation: "users" - referencedColumns: ["id"] + foreignKeyName: 'accounts_memberships_created_by_fkey'; + columns: ['created_by']; + isOneToOne: false; + referencedRelation: 'users'; + referencedColumns: ['id']; }, { - foreignKeyName: "accounts_memberships_updated_by_fkey" - columns: ["updated_by"] - isOneToOne: false - referencedRelation: "users" - referencedColumns: ["id"] + foreignKeyName: 'accounts_memberships_updated_by_fkey'; + columns: ['updated_by']; + isOneToOne: false; + referencedRelation: 'users'; + referencedColumns: ['id']; }, { - foreignKeyName: "accounts_memberships_user_id_fkey" - columns: ["user_id"] - isOneToOne: false - referencedRelation: "users" - referencedColumns: ["id"] + foreignKeyName: 'accounts_memberships_user_id_fkey'; + columns: ['user_id']; + isOneToOne: false; + referencedRelation: 'users'; + referencedColumns: ['id']; }, - ] - } + ]; + }; billing_customers: { Row: { - account_id: string - customer_id: string - email: string | null - id: number - provider: Database["public"]["Enums"]["billing_provider"] - } + account_id: string; + customer_id: string; + email: string | null; + id: number; + provider: Database['public']['Enums']['billing_provider']; + }; Insert: { - account_id: string - customer_id: string - email?: string | null - id?: number - provider: Database["public"]["Enums"]["billing_provider"] - } + account_id: string; + customer_id: string; + email?: string | null; + id?: number; + provider: Database['public']['Enums']['billing_provider']; + }; Update: { - account_id?: string - customer_id?: string - email?: string | null - id?: number - provider?: Database["public"]["Enums"]["billing_provider"] - } + account_id?: string; + customer_id?: string; + email?: string | null; + id?: number; + provider?: Database['public']['Enums']['billing_provider']; + }; Relationships: [ { - foreignKeyName: "billing_customers_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: 'billing_customers_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "billing_customers_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_account_workspace" - referencedColumns: ["id"] + foreignKeyName: 'billing_customers_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_account_workspace'; + referencedColumns: ['id']; }, { - foreignKeyName: "billing_customers_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_accounts" - referencedColumns: ["id"] + foreignKeyName: 'billing_customers_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_accounts'; + referencedColumns: ['id']; }, - ] - } + ]; + }; config: { Row: { - billing_provider: Database["public"]["Enums"]["billing_provider"] - enable_account_billing: boolean - enable_team_account_billing: boolean - enable_team_accounts: boolean - } + billing_provider: Database['public']['Enums']['billing_provider']; + enable_account_billing: boolean; + enable_team_account_billing: boolean; + enable_team_accounts: boolean; + }; Insert: { - billing_provider?: Database["public"]["Enums"]["billing_provider"] - enable_account_billing?: boolean - enable_team_account_billing?: boolean - enable_team_accounts?: boolean - } + billing_provider?: Database['public']['Enums']['billing_provider']; + enable_account_billing?: boolean; + enable_team_account_billing?: boolean; + enable_team_accounts?: boolean; + }; Update: { - billing_provider?: Database["public"]["Enums"]["billing_provider"] - enable_account_billing?: boolean - enable_team_account_billing?: boolean - enable_team_accounts?: boolean - } - Relationships: [] - } + billing_provider?: Database['public']['Enums']['billing_provider']; + enable_account_billing?: boolean; + enable_team_account_billing?: boolean; + enable_team_accounts?: boolean; + }; + Relationships: []; + }; invitations: { Row: { - account_id: string - created_at: string - email: string - expires_at: string - id: number - invite_token: string - invited_by: string - role: string - updated_at: string - } + account_id: string; + created_at: string; + email: string; + expires_at: string; + id: number; + invite_token: string; + invited_by: string; + role: string; + updated_at: string; + }; Insert: { - account_id: string - created_at?: string - email: string - expires_at?: string - id?: number - invite_token: string - invited_by: string - role: string - updated_at?: string - } + account_id: string; + created_at?: string; + email: string; + expires_at?: string; + id?: number; + invite_token: string; + invited_by: string; + role: string; + updated_at?: string; + }; Update: { - account_id?: string - created_at?: string - email?: string - expires_at?: string - id?: number - invite_token?: string - invited_by?: string - role?: string - updated_at?: string - } + account_id?: string; + created_at?: string; + email?: string; + expires_at?: string; + id?: number; + invite_token?: string; + invited_by?: string; + role?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "invitations_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: 'invitations_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "invitations_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_account_workspace" - referencedColumns: ["id"] + foreignKeyName: 'invitations_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_account_workspace'; + referencedColumns: ['id']; }, { - foreignKeyName: "invitations_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_accounts" - referencedColumns: ["id"] + foreignKeyName: 'invitations_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "invitations_invited_by_fkey" - columns: ["invited_by"] - isOneToOne: false - referencedRelation: "users" - referencedColumns: ["id"] + foreignKeyName: 'invitations_invited_by_fkey'; + columns: ['invited_by']; + isOneToOne: false; + referencedRelation: 'users'; + referencedColumns: ['id']; }, { - foreignKeyName: "invitations_role_fkey" - columns: ["role"] - isOneToOne: false - referencedRelation: "roles" - referencedColumns: ["name"] + foreignKeyName: 'invitations_role_fkey'; + columns: ['role']; + isOneToOne: false; + referencedRelation: 'roles'; + referencedColumns: ['name']; }, - ] - } + ]; + }; notifications: { Row: { - account_id: string - body: string - channel: Database["public"]["Enums"]["notification_channel"] - created_at: string - dismissed: boolean - expires_at: string | null - id: number - link: string | null - type: Database["public"]["Enums"]["notification_type"] - } + account_id: string; + body: string; + channel: Database['public']['Enums']['notification_channel']; + created_at: string; + dismissed: boolean; + expires_at: string | null; + id: number; + link: string | null; + type: Database['public']['Enums']['notification_type']; + }; Insert: { - account_id: string - body: string - channel?: Database["public"]["Enums"]["notification_channel"] - created_at?: string - dismissed?: boolean - expires_at?: string | null - id?: never - link?: string | null - type?: Database["public"]["Enums"]["notification_type"] - } + account_id: string; + body: string; + channel?: Database['public']['Enums']['notification_channel']; + created_at?: string; + dismissed?: boolean; + expires_at?: string | null; + id?: never; + link?: string | null; + type?: Database['public']['Enums']['notification_type']; + }; Update: { - account_id?: string - body?: string - channel?: Database["public"]["Enums"]["notification_channel"] - created_at?: string - dismissed?: boolean - expires_at?: string | null - id?: never - link?: string | null - type?: Database["public"]["Enums"]["notification_type"] - } + account_id?: string; + body?: string; + channel?: Database['public']['Enums']['notification_channel']; + created_at?: string; + dismissed?: boolean; + expires_at?: string | null; + id?: never; + link?: string | null; + type?: Database['public']['Enums']['notification_type']; + }; Relationships: [ { - foreignKeyName: "notifications_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: 'notifications_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "notifications_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_account_workspace" - referencedColumns: ["id"] + foreignKeyName: 'notifications_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_account_workspace'; + referencedColumns: ['id']; }, { - foreignKeyName: "notifications_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_accounts" - referencedColumns: ["id"] + foreignKeyName: 'notifications_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_accounts'; + referencedColumns: ['id']; }, - ] - } + ]; + }; order_items: { Row: { - created_at: string - id: string - order_id: string - price_amount: number | null - product_id: string - quantity: number - updated_at: string - variant_id: string - } + created_at: string; + id: string; + order_id: string; + price_amount: number | null; + product_id: string; + quantity: number; + updated_at: string; + variant_id: string; + }; Insert: { - created_at?: string - id: string - order_id: string - price_amount?: number | null - product_id: string - quantity?: number - updated_at?: string - variant_id: string - } + created_at?: string; + id: string; + order_id: string; + price_amount?: number | null; + product_id: string; + quantity?: number; + updated_at?: string; + variant_id: string; + }; Update: { - created_at?: string - id?: string - order_id?: string - price_amount?: number | null - product_id?: string - quantity?: number - updated_at?: string - variant_id?: string - } + created_at?: string; + id?: string; + order_id?: string; + price_amount?: number | null; + product_id?: string; + quantity?: number; + updated_at?: string; + variant_id?: string; + }; Relationships: [ { - foreignKeyName: "order_items_order_id_fkey" - columns: ["order_id"] - isOneToOne: false - referencedRelation: "orders" - referencedColumns: ["id"] + foreignKeyName: 'order_items_order_id_fkey'; + columns: ['order_id']; + isOneToOne: false; + referencedRelation: 'orders'; + referencedColumns: ['id']; }, - ] - } + ]; + }; orders: { Row: { - account_id: string - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - created_at: string - currency: string - id: string - status: Database["public"]["Enums"]["payment_status"] - total_amount: number - updated_at: string - } + account_id: string; + billing_customer_id: number; + billing_provider: Database['public']['Enums']['billing_provider']; + created_at: string; + currency: string; + id: string; + status: Database['public']['Enums']['payment_status']; + total_amount: number; + updated_at: string; + }; Insert: { - account_id: string - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - created_at?: string - currency: string - id: string - status: Database["public"]["Enums"]["payment_status"] - total_amount: number - updated_at?: string - } + account_id: string; + billing_customer_id: number; + billing_provider: Database['public']['Enums']['billing_provider']; + created_at?: string; + currency: string; + id: string; + status: Database['public']['Enums']['payment_status']; + total_amount: number; + updated_at?: string; + }; Update: { - account_id?: string - billing_customer_id?: number - billing_provider?: Database["public"]["Enums"]["billing_provider"] - created_at?: string - currency?: string - id?: string - status?: Database["public"]["Enums"]["payment_status"] - total_amount?: number - updated_at?: string - } + account_id?: string; + billing_customer_id?: number; + billing_provider?: Database['public']['Enums']['billing_provider']; + created_at?: string; + currency?: string; + id?: string; + status?: Database['public']['Enums']['payment_status']; + total_amount?: number; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "orders_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: 'orders_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "orders_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_account_workspace" - referencedColumns: ["id"] + foreignKeyName: 'orders_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_account_workspace'; + referencedColumns: ['id']; }, { - foreignKeyName: "orders_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_accounts" - referencedColumns: ["id"] + foreignKeyName: 'orders_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "orders_billing_customer_id_fkey" - columns: ["billing_customer_id"] - isOneToOne: false - referencedRelation: "billing_customers" - referencedColumns: ["id"] + foreignKeyName: 'orders_billing_customer_id_fkey'; + columns: ['billing_customer_id']; + isOneToOne: false; + referencedRelation: 'billing_customers'; + referencedColumns: ['id']; }, - ] - } + ]; + }; role_permissions: { Row: { - id: number - permission: Database["public"]["Enums"]["app_permissions"] - role: string - } + id: number; + permission: Database['public']['Enums']['app_permissions']; + role: string; + }; Insert: { - id?: number - permission: Database["public"]["Enums"]["app_permissions"] - role: string - } + id?: number; + permission: Database['public']['Enums']['app_permissions']; + role: string; + }; Update: { - id?: number - permission?: Database["public"]["Enums"]["app_permissions"] - role?: string - } + id?: number; + permission?: Database['public']['Enums']['app_permissions']; + role?: string; + }; Relationships: [ { - foreignKeyName: "role_permissions_role_fkey" - columns: ["role"] - isOneToOne: false - referencedRelation: "roles" - referencedColumns: ["name"] + foreignKeyName: 'role_permissions_role_fkey'; + columns: ['role']; + isOneToOne: false; + referencedRelation: 'roles'; + referencedColumns: ['name']; }, - ] - } + ]; + }; roles: { Row: { - hierarchy_level: number - name: string - } + hierarchy_level: number; + name: string; + }; Insert: { - hierarchy_level: number - name: string - } + hierarchy_level: number; + name: string; + }; Update: { - hierarchy_level?: number - name?: string - } - Relationships: [] - } + hierarchy_level?: number; + name?: string; + }; + Relationships: []; + }; subscription_items: { Row: { - created_at: string - id: string - interval: string - interval_count: number - price_amount: number | null - product_id: string - quantity: number - subscription_id: string - type: Database["public"]["Enums"]["subscription_item_type"] - updated_at: string - variant_id: string - } + created_at: string; + id: string; + interval: string; + interval_count: number; + price_amount: number | null; + product_id: string; + quantity: number; + subscription_id: string; + type: Database['public']['Enums']['subscription_item_type']; + updated_at: string; + variant_id: string; + }; Insert: { - created_at?: string - id: string - interval: string - interval_count: number - price_amount?: number | null - product_id: string - quantity?: number - subscription_id: string - type: Database["public"]["Enums"]["subscription_item_type"] - updated_at?: string - variant_id: string - } + created_at?: string; + id: string; + interval: string; + interval_count: number; + price_amount?: number | null; + product_id: string; + quantity?: number; + subscription_id: string; + type: Database['public']['Enums']['subscription_item_type']; + updated_at?: string; + variant_id: string; + }; Update: { - created_at?: string - id?: string - interval?: string - interval_count?: number - price_amount?: number | null - product_id?: string - quantity?: number - subscription_id?: string - type?: Database["public"]["Enums"]["subscription_item_type"] - updated_at?: string - variant_id?: string - } + created_at?: string; + id?: string; + interval?: string; + interval_count?: number; + price_amount?: number | null; + product_id?: string; + quantity?: number; + subscription_id?: string; + type?: Database['public']['Enums']['subscription_item_type']; + updated_at?: string; + variant_id?: string; + }; Relationships: [ { - foreignKeyName: "subscription_items_subscription_id_fkey" - columns: ["subscription_id"] - isOneToOne: false - referencedRelation: "subscriptions" - referencedColumns: ["id"] + foreignKeyName: 'subscription_items_subscription_id_fkey'; + columns: ['subscription_id']; + isOneToOne: false; + referencedRelation: 'subscriptions'; + referencedColumns: ['id']; }, - ] - } + ]; + }; subscriptions: { Row: { - account_id: string - active: boolean - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end: boolean - created_at: string - currency: string - id: string - period_ends_at: string - period_starts_at: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at: string | null - trial_starts_at: string | null - updated_at: string - } + account_id: string; + active: boolean; + billing_customer_id: number; + billing_provider: Database['public']['Enums']['billing_provider']; + cancel_at_period_end: boolean; + created_at: string; + currency: string; + id: string; + period_ends_at: string; + period_starts_at: string; + status: Database['public']['Enums']['subscription_status']; + trial_ends_at: string | null; + trial_starts_at: string | null; + updated_at: string; + }; Insert: { - account_id: string - active: boolean - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end: boolean - created_at?: string - currency: string - id: string - period_ends_at: string - period_starts_at: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at?: string | null - trial_starts_at?: string | null - updated_at?: string - } + account_id: string; + active: boolean; + billing_customer_id: number; + billing_provider: Database['public']['Enums']['billing_provider']; + cancel_at_period_end: boolean; + created_at?: string; + currency: string; + id: string; + period_ends_at: string; + period_starts_at: string; + status: Database['public']['Enums']['subscription_status']; + trial_ends_at?: string | null; + trial_starts_at?: string | null; + updated_at?: string; + }; Update: { - account_id?: string - active?: boolean - billing_customer_id?: number - billing_provider?: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end?: boolean - created_at?: string - currency?: string - id?: string - period_ends_at?: string - period_starts_at?: string - status?: Database["public"]["Enums"]["subscription_status"] - trial_ends_at?: string | null - trial_starts_at?: string | null - updated_at?: string - } + account_id?: string; + active?: boolean; + billing_customer_id?: number; + billing_provider?: Database['public']['Enums']['billing_provider']; + cancel_at_period_end?: boolean; + created_at?: string; + currency?: string; + id?: string; + period_ends_at?: string; + period_starts_at?: string; + status?: Database['public']['Enums']['subscription_status']; + trial_ends_at?: string | null; + trial_starts_at?: string | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "subscriptions_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: 'subscriptions_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "subscriptions_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_account_workspace" - referencedColumns: ["id"] + foreignKeyName: 'subscriptions_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_account_workspace'; + referencedColumns: ['id']; }, { - foreignKeyName: "subscriptions_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_accounts" - referencedColumns: ["id"] + foreignKeyName: 'subscriptions_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "subscriptions_billing_customer_id_fkey" - columns: ["billing_customer_id"] - isOneToOne: false - referencedRelation: "billing_customers" - referencedColumns: ["id"] + foreignKeyName: 'subscriptions_billing_customer_id_fkey'; + columns: ['billing_customer_id']; + isOneToOne: false; + referencedRelation: 'billing_customers'; + referencedColumns: ['id']; }, - ] - } - } + ]; + }; + }; Views: { user_account_workspace: { Row: { - id: string | null - name: string | null - picture_url: string | null - public_data: Json | null + id: string | null; + name: string | null; + picture_url: string | null; + public_data: Json | null; subscription_status: - | Database["public"]["Enums"]["subscription_status"] - | null - } - Relationships: [] - } + | Database['public']['Enums']['subscription_status'] + | null; + }; + Relationships: []; + }; user_accounts: { Row: { - id: string | null - name: string | null - picture_url: string | null - role: string | null - slug: string | null - } + id: string | null; + name: string | null; + picture_url: string | null; + role: string | null; + slug: string | null; + }; Relationships: [ { - foreignKeyName: "accounts_memberships_account_role_fkey" - columns: ["role"] - isOneToOne: false - referencedRelation: "roles" - referencedColumns: ["name"] + foreignKeyName: 'accounts_memberships_account_role_fkey'; + columns: ['role']; + isOneToOne: false; + referencedRelation: 'roles'; + referencedColumns: ['name']; }, - ] - } - } + ]; + }; + }; Functions: { accept_invitation: { Args: { - token: string - user_id: string - } - Returns: string - } + token: string; + user_id: string; + }; + Returns: string; + }; add_invitations_to_account: { Args: { - account_slug: string - invitations: Database["public"]["CompositeTypes"]["invitation"][] - } - Returns: Database["public"]["Tables"]["invitations"]["Row"][] - } + account_slug: string; + invitations: Database['public']['CompositeTypes']['invitation'][]; + }; + Returns: Database['public']['Tables']['invitations']['Row'][]; + }; can_action_account_member: { Args: { - target_team_account_id: string - target_user_id: string - } - Returns: boolean - } + target_team_account_id: string; + target_user_id: string; + }; + Returns: boolean; + }; create_invitation: { Args: { - account_id: string - email: string - role: string - } + account_id: string; + email: string; + role: string; + }; Returns: { - account_id: string - created_at: string - email: string - expires_at: string - id: number - invite_token: string - invited_by: string - role: string - updated_at: string - } - } + account_id: string; + created_at: string; + email: string; + expires_at: string; + id: number; + invite_token: string; + invited_by: string; + role: string; + updated_at: string; + }; + }; create_team_account: { Args: { - account_name: string - } + account_name: string; + }; Returns: { - created_at: string | null - created_by: string | null - email: string | null - id: string - is_personal_account: boolean - name: string - picture_url: string | null - primary_owner_user_id: string - public_data: Json - slug: string | null - updated_at: string | null - updated_by: string | null - } - } + created_at: string | null; + created_by: string | null; + email: string | null; + id: string; + is_personal_account: boolean; + name: string; + picture_url: string | null; + primary_owner_user_id: string; + public_data: Json; + slug: string | null; + updated_at: string | null; + updated_by: string | null; + }; + }; get_account_invitations: { Args: { - account_slug: string - } + account_slug: string; + }; Returns: { - id: number - email: string - account_id: string - invited_by: string - role: string - created_at: string - updated_at: string - expires_at: string - inviter_name: string - inviter_email: string - }[] - } + id: number; + email: string; + account_id: string; + invited_by: string; + role: string; + created_at: string; + updated_at: string; + expires_at: string; + inviter_name: string; + inviter_email: string; + }[]; + }; get_account_members: { Args: { - account_slug: string - } + account_slug: string; + }; Returns: { - id: string - user_id: string - account_id: string - role: string - role_hierarchy_level: number - primary_owner_user_id: string - name: string - email: string - picture_url: string - created_at: string - updated_at: string - }[] - } + id: string; + user_id: string; + account_id: string; + role: string; + role_hierarchy_level: number; + primary_owner_user_id: string; + name: string; + email: string; + picture_url: string; + created_at: string; + updated_at: string; + }[]; + }; get_config: { - Args: Record - Returns: Json - } + Args: Record; + Returns: Json; + }; get_upper_system_role: { - Args: Record - Returns: string - } + Args: Record; + Returns: string; + }; has_active_subscription: { Args: { - target_account_id: string - } - Returns: boolean - } + target_account_id: string; + }; + Returns: boolean; + }; has_more_elevated_role: { Args: { - target_user_id: string - target_account_id: string - role_name: string - } - Returns: boolean - } + target_user_id: string; + target_account_id: string; + role_name: string; + }; + Returns: boolean; + }; has_permission: { Args: { - user_id: string - account_id: string - permission_name: Database["public"]["Enums"]["app_permissions"] - } - Returns: boolean - } + user_id: string; + account_id: string; + permission_name: Database['public']['Enums']['app_permissions']; + }; + Returns: boolean; + }; has_role_on_account: { Args: { - account_id: string - account_role?: string - } - Returns: boolean - } + account_id: string; + account_role?: string; + }; + Returns: boolean; + }; has_same_role_hierarchy_level: { Args: { - target_user_id: string - target_account_id: string - role_name: string - } - Returns: boolean - } + target_user_id: string; + target_account_id: string; + role_name: string; + }; + Returns: boolean; + }; install_extensions: { - Args: Record - Returns: undefined - } + Args: Record; + Returns: undefined; + }; is_account_owner: { Args: { - account_id: string - } - Returns: boolean - } + account_id: string; + }; + Returns: boolean; + }; is_account_team_member: { Args: { - target_account_id: string - } - Returns: boolean - } + target_account_id: string; + }; + Returns: boolean; + }; is_set: { Args: { - field_name: string - } - Returns: boolean - } + field_name: string; + }; + Returns: boolean; + }; is_team_member: { Args: { - account_id: string - user_id: string - } - Returns: boolean - } + account_id: string; + user_id: string; + }; + Returns: boolean; + }; team_account_workspace: { Args: { - account_slug: string - } + account_slug: string; + }; Returns: { - id: string - name: string - picture_url: string - slug: string - role: string - role_hierarchy_level: number - primary_owner_user_id: string - subscription_status: Database["public"]["Enums"]["subscription_status"] - permissions: Database["public"]["Enums"]["app_permissions"][] - }[] - } + id: string; + name: string; + picture_url: string; + slug: string; + role: string; + role_hierarchy_level: number; + primary_owner_user_id: string; + subscription_status: Database['public']['Enums']['subscription_status']; + permissions: Database['public']['Enums']['app_permissions'][]; + }[]; + }; transfer_team_account_ownership: { Args: { - target_account_id: string - new_owner_id: string - } - Returns: undefined - } + target_account_id: string; + new_owner_id: string; + }; + Returns: undefined; + }; upsert_order: { Args: { - target_account_id: string - target_customer_id: string - target_order_id: string - status: Database["public"]["Enums"]["payment_status"] - billing_provider: Database["public"]["Enums"]["billing_provider"] - total_amount: number - currency: string - line_items: Json - } + target_account_id: string; + target_customer_id: string; + target_order_id: string; + status: Database['public']['Enums']['payment_status']; + billing_provider: Database['public']['Enums']['billing_provider']; + total_amount: number; + currency: string; + line_items: Json; + }; Returns: { - account_id: string - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - created_at: string - currency: string - id: string - status: Database["public"]["Enums"]["payment_status"] - total_amount: number - updated_at: string - } - } + account_id: string; + billing_customer_id: number; + billing_provider: Database['public']['Enums']['billing_provider']; + created_at: string; + currency: string; + id: string; + status: Database['public']['Enums']['payment_status']; + total_amount: number; + updated_at: string; + }; + }; upsert_subscription: { Args: { - target_account_id: string - target_customer_id: string - target_subscription_id: string - active: boolean - status: Database["public"]["Enums"]["subscription_status"] - billing_provider: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end: boolean - currency: string - period_starts_at: string - period_ends_at: string - line_items: Json - trial_starts_at?: string - trial_ends_at?: string - } + target_account_id: string; + target_customer_id: string; + target_subscription_id: string; + active: boolean; + status: Database['public']['Enums']['subscription_status']; + billing_provider: Database['public']['Enums']['billing_provider']; + cancel_at_period_end: boolean; + currency: string; + period_starts_at: string; + period_ends_at: string; + line_items: Json; + trial_starts_at?: string; + trial_ends_at?: string; + }; Returns: { - account_id: string - active: boolean - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end: boolean - created_at: string - currency: string - id: string - period_ends_at: string - period_starts_at: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at: string | null - trial_starts_at: string | null - updated_at: string - } - } - } + account_id: string; + active: boolean; + billing_customer_id: number; + billing_provider: Database['public']['Enums']['billing_provider']; + cancel_at_period_end: boolean; + created_at: string; + currency: string; + id: string; + period_ends_at: string; + period_starts_at: string; + status: Database['public']['Enums']['subscription_status']; + trial_ends_at: string | null; + trial_starts_at: string | null; + updated_at: string; + }; + }; + }; Enums: { app_permissions: - | "roles.manage" - | "billing.manage" - | "settings.manage" - | "members.manage" - | "invites.manage" - billing_provider: "stripe" | "lemon-squeezy" | "paddle" - notification_channel: "in_app" | "email" - notification_type: "info" | "warning" | "error" - payment_status: "pending" | "succeeded" | "failed" - subscription_item_type: "flat" | "per_seat" | "metered" + | 'roles.manage' + | 'billing.manage' + | 'settings.manage' + | 'members.manage' + | 'invites.manage'; + billing_provider: 'stripe' | 'lemon-squeezy' | 'paddle'; + notification_channel: 'in_app' | 'email'; + notification_type: 'info' | 'warning' | 'error'; + payment_status: 'pending' | 'succeeded' | 'failed'; + subscription_item_type: 'flat' | 'per_seat' | 'metered'; subscription_status: - | "active" - | "trialing" - | "past_due" - | "canceled" - | "unpaid" - | "incomplete" - | "incomplete_expired" - | "paused" - } + | 'active' + | 'trialing' + | 'past_due' + | 'canceled' + | 'unpaid' + | 'incomplete' + | 'incomplete_expired' + | 'paused'; + }; CompositeTypes: { invitation: { - email: string | null - role: string | null - } - } - } + email: string | null; + role: string | null; + }; + }; + }; storage: { Tables: { buckets: { Row: { - allowed_mime_types: string[] | null - avif_autodetection: boolean | null - created_at: string | null - file_size_limit: number | null - id: string - name: string - owner: string | null - owner_id: string | null - public: boolean | null - updated_at: string | null - } + allowed_mime_types: string[] | null; + avif_autodetection: boolean | null; + created_at: string | null; + file_size_limit: number | null; + id: string; + name: string; + owner: string | null; + owner_id: string | null; + public: boolean | null; + updated_at: string | null; + }; Insert: { - allowed_mime_types?: string[] | null - avif_autodetection?: boolean | null - created_at?: string | null - file_size_limit?: number | null - id: string - name: string - owner?: string | null - owner_id?: string | null - public?: boolean | null - updated_at?: string | null - } + allowed_mime_types?: string[] | null; + avif_autodetection?: boolean | null; + created_at?: string | null; + file_size_limit?: number | null; + id: string; + name: string; + owner?: string | null; + owner_id?: string | null; + public?: boolean | null; + updated_at?: string | null; + }; Update: { - allowed_mime_types?: string[] | null - avif_autodetection?: boolean | null - created_at?: string | null - file_size_limit?: number | null - id?: string - name?: string - owner?: string | null - owner_id?: string | null - public?: boolean | null - updated_at?: string | null - } - Relationships: [] - } + allowed_mime_types?: string[] | null; + avif_autodetection?: boolean | null; + created_at?: string | null; + file_size_limit?: number | null; + id?: string; + name?: string; + owner?: string | null; + owner_id?: string | null; + public?: boolean | null; + updated_at?: string | null; + }; + Relationships: []; + }; migrations: { Row: { - executed_at: string | null - hash: string - id: number - name: string - } + executed_at: string | null; + hash: string; + id: number; + name: string; + }; Insert: { - executed_at?: string | null - hash: string - id: number - name: string - } + executed_at?: string | null; + hash: string; + id: number; + name: string; + }; Update: { - executed_at?: string | null - hash?: string - id?: number - name?: string - } - Relationships: [] - } + executed_at?: string | null; + hash?: string; + id?: number; + name?: string; + }; + Relationships: []; + }; objects: { Row: { - bucket_id: string | null - created_at: string | null - id: string - last_accessed_at: string | null - metadata: Json | null - name: string | null - owner: string | null - owner_id: string | null - path_tokens: string[] | null - updated_at: string | null - version: string | null - } + bucket_id: string | null; + created_at: string | null; + id: string; + last_accessed_at: string | null; + metadata: Json | null; + name: string | null; + owner: string | null; + owner_id: string | null; + path_tokens: string[] | null; + updated_at: string | null; + version: string | null; + }; Insert: { - bucket_id?: string | null - created_at?: string | null - id?: string - last_accessed_at?: string | null - metadata?: Json | null - name?: string | null - owner?: string | null - owner_id?: string | null - path_tokens?: string[] | null - updated_at?: string | null - version?: string | null - } + bucket_id?: string | null; + created_at?: string | null; + id?: string; + last_accessed_at?: string | null; + metadata?: Json | null; + name?: string | null; + owner?: string | null; + owner_id?: string | null; + path_tokens?: string[] | null; + updated_at?: string | null; + version?: string | null; + }; Update: { - bucket_id?: string | null - created_at?: string | null - id?: string - last_accessed_at?: string | null - metadata?: Json | null - name?: string | null - owner?: string | null - owner_id?: string | null - path_tokens?: string[] | null - updated_at?: string | null - version?: string | null - } + bucket_id?: string | null; + created_at?: string | null; + id?: string; + last_accessed_at?: string | null; + metadata?: Json | null; + name?: string | null; + owner?: string | null; + owner_id?: string | null; + path_tokens?: string[] | null; + updated_at?: string | null; + version?: string | null; + }; Relationships: [ { - foreignKeyName: "objects_bucketId_fkey" - columns: ["bucket_id"] - isOneToOne: false - referencedRelation: "buckets" - referencedColumns: ["id"] + foreignKeyName: 'objects_bucketId_fkey'; + columns: ['bucket_id']; + isOneToOne: false; + referencedRelation: 'buckets'; + referencedColumns: ['id']; }, - ] - } + ]; + }; s3_multipart_uploads: { Row: { - bucket_id: string - created_at: string - id: string - in_progress_size: number - key: string - owner_id: string | null - upload_signature: string - version: string - } + bucket_id: string; + created_at: string; + id: string; + in_progress_size: number; + key: string; + owner_id: string | null; + upload_signature: string; + version: string; + }; Insert: { - bucket_id: string - created_at?: string - id: string - in_progress_size?: number - key: string - owner_id?: string | null - upload_signature: string - version: string - } + bucket_id: string; + created_at?: string; + id: string; + in_progress_size?: number; + key: string; + owner_id?: string | null; + upload_signature: string; + version: string; + }; Update: { - bucket_id?: string - created_at?: string - id?: string - in_progress_size?: number - key?: string - owner_id?: string | null - upload_signature?: string - version?: string - } + bucket_id?: string; + created_at?: string; + id?: string; + in_progress_size?: number; + key?: string; + owner_id?: string | null; + upload_signature?: string; + version?: string; + }; Relationships: [ { - foreignKeyName: "s3_multipart_uploads_bucket_id_fkey" - columns: ["bucket_id"] - isOneToOne: false - referencedRelation: "buckets" - referencedColumns: ["id"] + foreignKeyName: 's3_multipart_uploads_bucket_id_fkey'; + columns: ['bucket_id']; + isOneToOne: false; + referencedRelation: 'buckets'; + referencedColumns: ['id']; }, - ] - } + ]; + }; s3_multipart_uploads_parts: { Row: { - bucket_id: string - created_at: string - etag: string - id: string - key: string - owner_id: string | null - part_number: number - size: number - upload_id: string - version: string - } + bucket_id: string; + created_at: string; + etag: string; + id: string; + key: string; + owner_id: string | null; + part_number: number; + size: number; + upload_id: string; + version: string; + }; Insert: { - bucket_id: string - created_at?: string - etag: string - id?: string - key: string - owner_id?: string | null - part_number: number - size?: number - upload_id: string - version: string - } + bucket_id: string; + created_at?: string; + etag: string; + id?: string; + key: string; + owner_id?: string | null; + part_number: number; + size?: number; + upload_id: string; + version: string; + }; Update: { - bucket_id?: string - created_at?: string - etag?: string - id?: string - key?: string - owner_id?: string | null - part_number?: number - size?: number - upload_id?: string - version?: string - } + bucket_id?: string; + created_at?: string; + etag?: string; + id?: string; + key?: string; + owner_id?: string | null; + part_number?: number; + size?: number; + upload_id?: string; + version?: string; + }; Relationships: [ { - foreignKeyName: "s3_multipart_uploads_parts_bucket_id_fkey" - columns: ["bucket_id"] - isOneToOne: false - referencedRelation: "buckets" - referencedColumns: ["id"] + foreignKeyName: 's3_multipart_uploads_parts_bucket_id_fkey'; + columns: ['bucket_id']; + isOneToOne: false; + referencedRelation: 'buckets'; + referencedColumns: ['id']; }, { - foreignKeyName: "s3_multipart_uploads_parts_upload_id_fkey" - columns: ["upload_id"] - isOneToOne: false - referencedRelation: "s3_multipart_uploads" - referencedColumns: ["id"] + foreignKeyName: 's3_multipart_uploads_parts_upload_id_fkey'; + columns: ['upload_id']; + isOneToOne: false; + referencedRelation: 's3_multipart_uploads'; + referencedColumns: ['id']; }, - ] - } - } + ]; + }; + }; Views: { - [_ in never]: never - } + [_ in never]: never; + }; Functions: { can_insert_object: { Args: { - bucketid: string - name: string - owner: string - metadata: Json - } - Returns: undefined - } + bucketid: string; + name: string; + owner: string; + metadata: Json; + }; + Returns: undefined; + }; extension: { Args: { - name: string - } - Returns: string - } + name: string; + }; + Returns: string; + }; filename: { Args: { - name: string - } - Returns: string - } + name: string; + }; + Returns: string; + }; foldername: { Args: { - name: string - } - Returns: string[] - } + name: string; + }; + Returns: string[]; + }; get_size_by_bucket: { - Args: Record + Args: Record; Returns: { - size: number - bucket_id: string - }[] - } + size: number; + bucket_id: string; + }[]; + }; list_multipart_uploads_with_delimiter: { Args: { - bucket_id: string - prefix_param: string - delimiter_param: string - max_keys?: number - next_key_token?: string - next_upload_token?: string - } + bucket_id: string; + prefix_param: string; + delimiter_param: string; + max_keys?: number; + next_key_token?: string; + next_upload_token?: string; + }; Returns: { - key: string - id: string - created_at: string - }[] - } + key: string; + id: string; + created_at: string; + }[]; + }; list_objects_with_delimiter: { Args: { - bucket_id: string - prefix_param: string - delimiter_param: string - max_keys?: number - start_after?: string - next_token?: string - } + bucket_id: string; + prefix_param: string; + delimiter_param: string; + max_keys?: number; + start_after?: string; + next_token?: string; + }; Returns: { - name: string - id: string - metadata: Json - updated_at: string - }[] - } + name: string; + id: string; + metadata: Json; + updated_at: string; + }[]; + }; search: { Args: { - prefix: string - bucketname: string - limits?: number - levels?: number - offsets?: number - search?: string - sortcolumn?: string - sortorder?: string - } + prefix: string; + bucketname: string; + limits?: number; + levels?: number; + offsets?: number; + search?: string; + sortcolumn?: string; + sortorder?: string; + }; Returns: { - name: string - id: string - updated_at: string - created_at: string - last_accessed_at: string - metadata: Json - }[] - } - } + name: string; + id: string; + updated_at: string; + created_at: string; + last_accessed_at: string; + metadata: Json; + }[]; + }; + }; Enums: { - [_ in never]: never - } + [_ in never]: never; + }; CompositeTypes: { - [_ in never]: never - } - } -} + [_ in never]: never; + }; + }; +}; -type PublicSchema = Database[Extract] +type PublicSchema = Database[Extract]; export type Tables< PublicTableNameOrOptions extends - | keyof (PublicSchema["Tables"] & PublicSchema["Views"]) + | keyof (PublicSchema['Tables'] & PublicSchema['Views']) | { schema: keyof Database }, TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] & - Database[PublicTableNameOrOptions["schema"]]["Views"]) + ? keyof (Database[PublicTableNameOrOptions['schema']]['Tables'] & + Database[PublicTableNameOrOptions['schema']]['Views']) : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? (Database[PublicTableNameOrOptions["schema"]]["Tables"] & - Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends { - Row: infer R + ? (Database[PublicTableNameOrOptions['schema']]['Tables'] & + Database[PublicTableNameOrOptions['schema']]['Views'])[TableName] extends { + Row: infer R; } ? R : never - : PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] & - PublicSchema["Views"]) - ? (PublicSchema["Tables"] & - PublicSchema["Views"])[PublicTableNameOrOptions] extends { - Row: infer R + : PublicTableNameOrOptions extends keyof (PublicSchema['Tables'] & + PublicSchema['Views']) + ? (PublicSchema['Tables'] & + PublicSchema['Views'])[PublicTableNameOrOptions] extends { + Row: infer R; } ? R : never - : never + : never; export type TablesInsert< PublicTableNameOrOptions extends - | keyof PublicSchema["Tables"] + | keyof PublicSchema['Tables'] | { schema: keyof Database }, TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + ? keyof Database[PublicTableNameOrOptions['schema']]['Tables'] : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Insert: infer I + ? Database[PublicTableNameOrOptions['schema']]['Tables'][TableName] extends { + Insert: infer I; } ? I : never - : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] - ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { - Insert: infer I + : PublicTableNameOrOptions extends keyof PublicSchema['Tables'] + ? PublicSchema['Tables'][PublicTableNameOrOptions] extends { + Insert: infer I; } ? I : never - : never + : never; export type TablesUpdate< PublicTableNameOrOptions extends - | keyof PublicSchema["Tables"] + | keyof PublicSchema['Tables'] | { schema: keyof Database }, TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + ? keyof Database[PublicTableNameOrOptions['schema']]['Tables'] : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Update: infer U + ? Database[PublicTableNameOrOptions['schema']]['Tables'][TableName] extends { + Update: infer U; } ? U : never - : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] - ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { - Update: infer U + : PublicTableNameOrOptions extends keyof PublicSchema['Tables'] + ? PublicSchema['Tables'][PublicTableNameOrOptions] extends { + Update: infer U; } ? U : never - : never + : never; export type Enums< PublicEnumNameOrOptions extends - | keyof PublicSchema["Enums"] + | keyof PublicSchema['Enums'] | { schema: keyof Database }, EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"] + ? keyof Database[PublicEnumNameOrOptions['schema']]['Enums'] : never = never, > = PublicEnumNameOrOptions extends { schema: keyof Database } - ? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName] - : PublicEnumNameOrOptions extends keyof PublicSchema["Enums"] - ? PublicSchema["Enums"][PublicEnumNameOrOptions] - : never - + ? Database[PublicEnumNameOrOptions['schema']]['Enums'][EnumName] + : PublicEnumNameOrOptions extends keyof PublicSchema['Enums'] + ? PublicSchema['Enums'][PublicEnumNameOrOptions] + : never; diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs index 6e4adec5e..763ea14b8 100644 --- a/apps/web/next.config.mjs +++ b/apps/web/next.config.mjs @@ -19,7 +19,7 @@ const INTERNAL_PACKAGES = [ '@kit/cms', '@kit/monitoring', '@kit/next', - '@kit/notifications' + '@kit/notifications', ]; /** @type {import('next').NextConfig} */ diff --git a/packages/features/accounts/src/components/account-selector.tsx b/packages/features/accounts/src/components/account-selector.tsx index 3954850ae..d02a60a70 100644 --- a/packages/features/accounts/src/components/account-selector.tsx +++ b/packages/features/accounts/src/components/account-selector.tsx @@ -98,7 +98,7 @@ export function AccountSelector({ variant="ghost" role="combobox" aria-expanded={open} - className={cn('dark:shadow-primary/10 group w-full border px-4', { + className={cn('dark:shadow-primary/10 group px-2', { 'justify-between': !collapsed, 'justify-center': collapsed, })} @@ -144,11 +144,11 @@ export function AccountSelector({ )} - + - + diff --git a/packages/features/accounts/src/components/personal-account-dropdown.tsx b/packages/features/accounts/src/components/personal-account-dropdown.tsx index 212ea07bb..38f1a1b42 100644 --- a/packages/features/accounts/src/components/personal-account-dropdown.tsx +++ b/packages/features/accounts/src/components/personal-account-dropdown.tsx @@ -115,15 +115,15 @@ export function PersonalAccountDropdown({