From 4032aed827b82a36c4938d0f8c1d93c29ed32d56 Mon Sep 17 00:00:00 2001 From: giancarlo Date: Tue, 26 Mar 2024 16:49:11 +0800 Subject: [PATCH] Perf improvements and billing updates --- .../app/(dashboard)/home/(user)/loading.tsx | 4 +- .../team-account-checkout-form.tsx | 1 + .../home/[account]/billing/return/page.tsx | 15 +- .../(dashboard)/home/[account]/loading.tsx | 4 +- apps/web/app/(dashboard)/home/loading.tsx | 4 +- .../_components/site-navigation.tsx | 2 +- apps/web/app/(marketing)/blog/[slug]/page.tsx | 4 +- .../app/(marketing)/blog/_components/post.tsx | 8 +- apps/web/app/(marketing)/loading.tsx | 4 +- apps/web/app/loading.tsx | 5 + apps/web/app/not-found.tsx | 11 +- apps/web/middleware.ts | 8 +- apps/web/next.config.mjs | 48 +- apps/web/package.json | 9 +- .../src/components/billing-portal-card.tsx | 18 +- .../src/components/current-plan-alert.tsx | 63 + .../src/components/current-plan-badge.tsx | 48 + .../src/components/current-plan-card.tsx | 123 +- .../src/components/embedded-checkout.tsx | 16 +- packages/billing/src/create-billing-schema.ts | 2 +- .../components/sign-in-methods-container.tsx | 10 +- packages/i18n/src/i18n.client.ts | 2 +- .../stripe-webhook-handler.service.ts | 2 +- .../src/components/auth-change-listener.tsx | 1 + packages/supabase/src/database.types.ts | 1475 ++++++++--------- packages/ui/package.json | 5 +- .../src/makerkit/mobile-navigation-menu.tsx | 2 + .../navigation/navigation-container.tsx | 15 - .../makerkit/navigation/navigation-item.tsx | 124 -- .../navigation/navigation-menu-context.tsx | 5 - .../makerkit/navigation/navigation-menu.tsx | 49 - packages/ui/src/makerkit/spinner.tsx | 1 - packages/ui/src/shadcn/accordion.tsx | 58 + packages/ui/src/shadcn/badge.tsx | 2 +- pnpm-lock.yaml | 153 +- tooling/prettier/index.mjs | 1 - tooling/tailwind/index.ts | 2 +- tsconfig.json | 3 +- turbo.json | 44 +- 39 files changed, 1261 insertions(+), 1090 deletions(-) create mode 100644 apps/web/app/loading.tsx create mode 100644 packages/billing-gateway/src/components/current-plan-alert.tsx create mode 100644 packages/billing-gateway/src/components/current-plan-badge.tsx delete mode 100644 packages/ui/src/makerkit/navigation/navigation-container.tsx delete mode 100644 packages/ui/src/makerkit/navigation/navigation-item.tsx delete mode 100644 packages/ui/src/makerkit/navigation/navigation-menu-context.tsx delete mode 100644 packages/ui/src/makerkit/navigation/navigation-menu.tsx create mode 100644 packages/ui/src/shadcn/accordion.tsx diff --git a/apps/web/app/(dashboard)/home/(user)/loading.tsx b/apps/web/app/(dashboard)/home/(user)/loading.tsx index 4ea53181d..bbf9ff827 100644 --- a/apps/web/app/(dashboard)/home/(user)/loading.tsx +++ b/apps/web/app/(dashboard)/home/(user)/loading.tsx @@ -1,3 +1,5 @@ import { GlobalLoader } from '@kit/ui/global-loader'; -export default GlobalLoader; +import { withI18n } from '~/lib/i18n/with-i18n'; + +export default withI18n(GlobalLoader); diff --git a/apps/web/app/(dashboard)/home/[account]/billing/_components/team-account-checkout-form.tsx b/apps/web/app/(dashboard)/home/[account]/billing/_components/team-account-checkout-form.tsx index dc39b3cce..c1495949c 100644 --- a/apps/web/app/(dashboard)/home/[account]/billing/_components/team-account-checkout-form.tsx +++ b/apps/web/app/(dashboard)/home/[account]/billing/_components/team-account-checkout-form.tsx @@ -26,6 +26,7 @@ export function TeamAccountCheckoutForm(params: { accountId: string }) { if (checkoutToken) { return ( diff --git a/apps/web/app/(dashboard)/home/[account]/billing/return/page.tsx b/apps/web/app/(dashboard)/home/[account]/billing/return/page.tsx index a0443bdb2..6c8fe24b0 100644 --- a/apps/web/app/(dashboard)/home/[account]/billing/return/page.tsx +++ b/apps/web/app/(dashboard)/home/[account]/billing/return/page.tsx @@ -16,11 +16,18 @@ interface SessionPageProps { }; } -const LazyEmbeddedCheckout = dynamic(async () => { - const { EmbeddedCheckout } = await import('@kit/billing-gateway/components'); +const LazyEmbeddedCheckout = dynamic( + async () => { + const { EmbeddedCheckout } = await import( + '@kit/billing-gateway/components' + ); - return EmbeddedCheckout; -}); + return EmbeddedCheckout; + }, + { + ssr: false, + }, +); async function ReturnStripeSessionPage({ searchParams }: SessionPageProps) { const { customerEmail, checkoutToken } = await loadCheckoutSession( diff --git a/apps/web/app/(dashboard)/home/[account]/loading.tsx b/apps/web/app/(dashboard)/home/[account]/loading.tsx index 4ea53181d..bbf9ff827 100644 --- a/apps/web/app/(dashboard)/home/[account]/loading.tsx +++ b/apps/web/app/(dashboard)/home/[account]/loading.tsx @@ -1,3 +1,5 @@ import { GlobalLoader } from '@kit/ui/global-loader'; -export default GlobalLoader; +import { withI18n } from '~/lib/i18n/with-i18n'; + +export default withI18n(GlobalLoader); diff --git a/apps/web/app/(dashboard)/home/loading.tsx b/apps/web/app/(dashboard)/home/loading.tsx index 4ea53181d..bbf9ff827 100644 --- a/apps/web/app/(dashboard)/home/loading.tsx +++ b/apps/web/app/(dashboard)/home/loading.tsx @@ -1,3 +1,5 @@ import { GlobalLoader } from '@kit/ui/global-loader'; -export default GlobalLoader; +import { withI18n } from '~/lib/i18n/with-i18n'; + +export default withI18n(GlobalLoader); diff --git a/apps/web/app/(marketing)/_components/site-navigation.tsx b/apps/web/app/(marketing)/_components/site-navigation.tsx index 8dd505e9c..20c6d5608 100644 --- a/apps/web/app/(marketing)/_components/site-navigation.tsx +++ b/apps/web/app/(marketing)/_components/site-navigation.tsx @@ -44,7 +44,7 @@ export function SiteNavigation() { <>
- + {links.Blog.label} diff --git a/apps/web/app/(marketing)/blog/[slug]/page.tsx b/apps/web/app/(marketing)/blog/[slug]/page.tsx index 581e77720..1bc901833 100644 --- a/apps/web/app/(marketing)/blog/[slug]/page.tsx +++ b/apps/web/app/(marketing)/blog/[slug]/page.tsx @@ -9,7 +9,7 @@ import Post from '~/(marketing)/blog/_components/post'; import appConfig from '~/config/app.config'; import { withI18n } from '~/lib/i18n/with-i18n'; -export async function generateMetadata({ +export function generateMetadata({ params, }: { params: { slug: string }; @@ -49,7 +49,7 @@ export async function generateMetadata({ }; } -async function BlogPost({ params }: { params: { slug: string } }) { +function BlogPost({ params }: { params: { slug: string } }) { const post = allPosts.find((post) => post.slug === params.slug); if (!post) { diff --git a/apps/web/app/(marketing)/blog/_components/post.tsx b/apps/web/app/(marketing)/blog/_components/post.tsx index 72449b758..97ea7b4d9 100644 --- a/apps/web/app/(marketing)/blog/_components/post.tsx +++ b/apps/web/app/(marketing)/blog/_components/post.tsx @@ -1,11 +1,13 @@ -import React from 'react'; +import dynamic from 'next/dynamic'; import type { Post as PostType } from 'contentlayer/generated'; -import { Mdx } from '@kit/ui/mdx'; - import { PostHeader } from './post-header'; +const Mdx = dynamic(() => + import('@kit/ui/mdx').then((mod) => ({ default: mod.Mdx })), +); + export const Post: React.FC<{ post: PostType; content: string; diff --git a/apps/web/app/(marketing)/loading.tsx b/apps/web/app/(marketing)/loading.tsx index 4ea53181d..bbf9ff827 100644 --- a/apps/web/app/(marketing)/loading.tsx +++ b/apps/web/app/(marketing)/loading.tsx @@ -1,3 +1,5 @@ import { GlobalLoader } from '@kit/ui/global-loader'; -export default GlobalLoader; +import { withI18n } from '~/lib/i18n/with-i18n'; + +export default withI18n(GlobalLoader); diff --git a/apps/web/app/loading.tsx b/apps/web/app/loading.tsx new file mode 100644 index 000000000..bbf9ff827 --- /dev/null +++ b/apps/web/app/loading.tsx @@ -0,0 +1,5 @@ +import { GlobalLoader } from '@kit/ui/global-loader'; + +import { withI18n } from '~/lib/i18n/with-i18n'; + +export default withI18n(GlobalLoader); diff --git a/apps/web/app/not-found.tsx b/apps/web/app/not-found.tsx index d41d92e3b..5e98a7dcb 100644 --- a/apps/web/app/not-found.tsx +++ b/apps/web/app/not-found.tsx @@ -2,6 +2,7 @@ import Link from 'next/link'; import { ArrowLeft } from 'lucide-react'; +import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client'; import { Button } from '@kit/ui/button'; import { Heading } from '@kit/ui/heading'; import { Trans } from '@kit/ui/trans'; @@ -14,10 +15,16 @@ export const metadata = { title: `Page not found - ${appConfig.name}`, }; -const NotFoundPage = () => { +const NotFoundPage = async () => { + const client = getSupabaseServerComponentClient(); + + const { + data: { session }, + } = await client.auth.getSession(); + return (
- +
- Manage your Subscription + Manage your Billing Details You can change your plan or cancel your subscription at any time. @@ -23,15 +23,13 @@ export function BillingPortalCard() { - +
+ +
); diff --git a/packages/billing-gateway/src/components/current-plan-alert.tsx b/packages/billing-gateway/src/components/current-plan-alert.tsx new file mode 100644 index 000000000..41dc44692 --- /dev/null +++ b/packages/billing-gateway/src/components/current-plan-alert.tsx @@ -0,0 +1,63 @@ +import { Database } from '@kit/supabase/database'; +import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert'; + +export function CurrentPlanAlert( + props: React.PropsWithoutRef<{ + status: Database['public']['Enums']['subscription_status']; + }>, +) { + let variant: 'success' | 'warning' | 'destructive'; + let text: string; + let title: string; + + switch (props.status) { + case 'active': + variant = 'success'; + title = 'Active'; + text = 'Your subscription is active'; + break; + case 'trialing': + variant = 'success'; + title = 'Trial'; + text = 'You are currently on a trial'; + break; + case 'past_due': + variant = 'destructive'; + title = 'Past Due'; + text = 'Your subscription payment is past due'; + break; + case 'canceled': + variant = 'destructive'; + title = 'Canceled'; + text = 'You have canceled your subscription'; + break; + case 'unpaid': + variant = 'destructive'; + title = 'Unpaid'; + text = 'Your subscription payment is unpaid'; + break; + case 'incomplete': + variant = 'warning'; + title = 'Incomplete'; + text = 'We are processing your subscription payment'; + break; + case 'incomplete_expired': + variant = 'destructive'; + title = 'Incomplete Expired'; + text = 'Your subscription payment has expired'; + break; + case 'paused': + variant = 'warning'; + title = 'Paused'; + text = 'Your subscription is paused'; + break; + } + + return ( + + {title} + + {text} + + ); +} diff --git a/packages/billing-gateway/src/components/current-plan-badge.tsx b/packages/billing-gateway/src/components/current-plan-badge.tsx new file mode 100644 index 000000000..74d48f559 --- /dev/null +++ b/packages/billing-gateway/src/components/current-plan-badge.tsx @@ -0,0 +1,48 @@ +import { Database } from '@kit/supabase/database'; +import { Badge } from '@kit/ui/badge'; + +export function CurrentPlanBadge( + props: React.PropsWithoutRef<{ + status: Database['public']['Enums']['subscription_status']; + }>, +) { + let variant: 'success' | 'warning' | 'destructive'; + let text: string; + + switch (props.status) { + case 'active': + variant = 'success'; + text = 'Active'; + break; + case 'trialing': + variant = 'success'; + text = 'Trialing'; + break; + case 'past_due': + variant = 'destructive'; + text = 'Past due'; + break; + case 'canceled': + variant = 'destructive'; + text = 'Canceled'; + break; + case 'unpaid': + variant = 'destructive'; + text = 'Unpaid'; + break; + case 'incomplete': + variant = 'warning'; + text = 'Incomplete'; + break; + case 'incomplete_expired': + variant = 'destructive'; + text = 'Incomplete expired'; + break; + case 'paused': + variant = 'warning'; + text = 'Paused'; + break; + } + + return {text}; +} diff --git a/packages/billing-gateway/src/components/current-plan-card.tsx b/packages/billing-gateway/src/components/current-plan-card.tsx index 4cfb05e9a..a0f3b8e62 100644 --- a/packages/billing-gateway/src/components/current-plan-card.tsx +++ b/packages/billing-gateway/src/components/current-plan-card.tsx @@ -1,8 +1,15 @@ import { formatDate } from 'date-fns'; +import { BadgeCheck, CheckCircle2 } from 'lucide-react'; import { z } from 'zod'; import { BillingSchema, getProductPlanPairFromId } from '@kit/billing'; import { Database } from '@kit/supabase/database'; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from '@kit/ui/accordion'; import { Card, CardContent, @@ -11,6 +18,10 @@ import { CardTitle, } from '@kit/ui/card'; import { If } from '@kit/ui/if'; +import { Trans } from '@kit/ui/trans'; + +import { CurrentPlanAlert } from './current-plan-alert'; +import { CurrentPlanBadge } from './current-plan-badge'; export function CurrentPlanCard({ subscription, @@ -27,41 +38,103 @@ export function CurrentPlanCard({ return ( - {product.name} + Your Plan - {product.description} + + You can change your plan or cancel your subscription at any time. + - -
-
- Your Current Plan: {plan.name} + +
+
+ + {product.name} + +
+ +
+ Renews every {subscription.interval} at{' '} + {product.currency} {plan.price}
-
- Your Subscription is currently {subscription.status} -
+
- -
-
- Cancellation Date:{' '} - {formatDate(subscription.period_ends_at, 'P')} -
-
-
+
+ + + Plan details - -
-
- Next Billing Date:{' '} - {formatDate(subscription.period_ends_at, 'P')}{' '} -
-
-
+ + +
+ Your trial ends on + +
+ + {subscription.trial_ends_at + ? formatDate(subscription.trial_ends_at, 'P') + : ''} + +
+
+
+ + +
+ + Your subscription will be cancelled at the end of the + period + + +
+ + {formatDate(subscription.period_ends_at ?? '', 'P')} + +
+
+
+ + +
+ Your next bill + +
+ Your next bill is for {product.currency} {plan.price} on{' '} + + {formatDate(subscription.period_ends_at ?? '', 'P')} + {' '} +
+
+
+ +
+ Features + +
    + {product.features.map((item) => { + return ( +
  • + + + + +
  • + ); + })} +
+
+
+
+
+
); diff --git a/packages/billing-gateway/src/components/embedded-checkout.tsx b/packages/billing-gateway/src/components/embedded-checkout.tsx index 6b0a0c7ae..f892c2779 100644 --- a/packages/billing-gateway/src/components/embedded-checkout.tsx +++ b/packages/billing-gateway/src/components/embedded-checkout.tsx @@ -15,10 +15,22 @@ export function EmbeddedCheckout( provider: BillingProvider; onClose?: () => void; }>, +) { + return ( + + ); +} + +function LazyCheckout( + props: React.PropsWithChildren<{ + checkoutToken: string; + provider: BillingProvider; + onClose?: () => void; + }>, ) { const CheckoutComponent = useMemo( () => memo(loadCheckoutComponent(props.provider)), - [], + [props.provider], ); return ( @@ -69,7 +81,7 @@ function buildLazyComponent< ) { let LoadedComponent: ReturnType | null = null; - const LazyComponent = forwardRef((props, ref) => { + const LazyComponent = forwardRef(function LazyDynamicComponent(props, ref) { if (!LoadedComponent) { LoadedComponent = lazy(load); } diff --git a/packages/billing/src/create-billing-schema.ts b/packages/billing/src/create-billing-schema.ts index 79a9c09be..f5b1d72a1 100644 --- a/packages/billing/src/create-billing-schema.ts +++ b/packages/billing/src/create-billing-schema.ts @@ -105,5 +105,5 @@ export function getProductPlanPairFromId( } } - return undefined; + throw new Error(`Plan with ID ${planId} not found`); } diff --git a/packages/features/auth/src/components/sign-in-methods-container.tsx b/packages/features/auth/src/components/sign-in-methods-container.tsx index 1651c900d..ea7b951df 100644 --- a/packages/features/auth/src/components/sign-in-methods-container.tsx +++ b/packages/features/auth/src/components/sign-in-methods-container.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useRouter } from 'next/navigation'; +import { useRouter, useSearchParams } from 'next/navigation'; import type { Provider } from '@supabase/supabase-js'; @@ -27,13 +27,17 @@ export function SignInMethodsContainer(props: { oAuth: Provider[]; }; }) { + const router = useRouter(); + const nextPath = useSearchParams().get('next') ?? props.paths.home; + const redirectUrl = new URL( props.paths.callback, isBrowser() ? window?.location.origin : '', ).toString(); - const router = useRouter(); - const onSignIn = () => router.replace(props.paths.home); + const onSignIn = () => { + router.replace(nextPath); + }; return ( <> diff --git a/packages/i18n/src/i18n.client.ts b/packages/i18n/src/i18n.client.ts index 8ef7b7b92..7cb505382 100644 --- a/packages/i18n/src/i18n.client.ts +++ b/packages/i18n/src/i18n.client.ts @@ -23,7 +23,7 @@ export function initializeI18nClient( .use( resourcesToBackend(async (language, namespace, callback) => { const data = await i18nResolver(language, namespace); - console.log(data); + return callback(null, data); }), ) diff --git a/packages/stripe/src/services/stripe-webhook-handler.service.ts b/packages/stripe/src/services/stripe-webhook-handler.service.ts index d3989f2f1..397aa2ffa 100644 --- a/packages/stripe/src/services/stripe-webhook-handler.service.ts +++ b/packages/stripe/src/services/stripe-webhook-handler.service.ts @@ -30,7 +30,7 @@ export class StripeWebhookHandlerService async verifyWebhookSignature(request: Request) { const body = await request.clone().text(); const signatureKey = `stripe-signature`; - const signature = request.headers.get(signatureKey) as string; + const signature = request.headers.get(signatureKey)!; const { STRIPE_WEBHOOK_SECRET } = StripeServerEnvSchema.parse({ STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY, diff --git a/packages/supabase/src/components/auth-change-listener.tsx b/packages/supabase/src/components/auth-change-listener.tsx index 925ecd922..62a1851e8 100644 --- a/packages/supabase/src/components/auth-change-listener.tsx +++ b/packages/supabase/src/components/auth-change-listener.tsx @@ -28,6 +28,7 @@ function AuthRedirectListener({ useEffect(() => { // keep this running for the whole session unless the component was unmounted const listener = client.auth.onAuthStateChange((_, user) => { + console.log(_, user); // log user out if user is falsy // and if the current path is a private route const shouldRedirectUser = !user && isPrivateRoute(pathName); diff --git a/packages/supabase/src/database.types.ts b/packages/supabase/src/database.types.ts index a4110945e..fb0a9b170 100644 --- a/packages/supabase/src/database.types.ts +++ b/packages/supabase/src/database.types.ts @@ -4,966 +4,965 @@ 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: { account_roles: { Row: { - account_id: string - id: number - role: Database["public"]["Enums"]["account_role"] - } + account_id: string; + id: number; + role: Database['public']['Enums']['account_role']; + }; Insert: { - account_id: string - id?: number - role: Database["public"]["Enums"]["account_role"] - } + account_id: string; + id?: number; + role: Database['public']['Enums']['account_role']; + }; Update: { - account_id?: string - id?: number - role?: Database["public"]["Enums"]["account_role"] - } + account_id?: string; + id?: number; + role?: Database['public']['Enums']['account_role']; + }; Relationships: [ { - foreignKeyName: "account_roles_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: 'account_roles_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'accounts'; + referencedColumns: ['id']; }, { - foreignKeyName: "account_roles_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_account_workspace" - referencedColumns: ["id"] + foreignKeyName: 'account_roles_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_account_workspace'; + referencedColumns: ['id']; }, { - foreignKeyName: "account_roles_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "user_accounts" - referencedColumns: ["id"] + foreignKeyName: 'account_roles_account_id_fkey'; + columns: ['account_id']; + isOneToOne: false; + referencedRelation: 'user_accounts'; + referencedColumns: ['id']; }, - ] - } + ]; + }; 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 - 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; + 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 - 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; + 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 - 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; + 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: Database["public"]["Enums"]["account_role"] - created_at: string - created_by: string | null - updated_at: string - updated_by: string | null - user_id: string - } + account_id: string; + account_role: Database['public']['Enums']['account_role']; + created_at: string; + created_by: string | null; + updated_at: string; + updated_by: string | null; + user_id: string; + }; Insert: { - account_id: string - account_role: Database["public"]["Enums"]["account_role"] - created_at?: string - created_by?: string | null - updated_at?: string - updated_by?: string | null - user_id: string - } + account_id: string; + account_role: Database['public']['Enums']['account_role']; + created_at?: string; + created_by?: string | null; + updated_at?: string; + updated_by?: string | null; + user_id: string; + }; Update: { - account_id?: string - account_role?: Database["public"]["Enums"]["account_role"] - created_at?: string - created_by?: string | null - updated_at?: string - updated_by?: string | null - user_id?: string - } + account_id?: string; + account_role?: Database['public']['Enums']['account_role']; + 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_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_organization_accounts: boolean - enable_organization_billing: boolean - } + billing_provider: Database['public']['Enums']['billing_provider']; + enable_account_billing: boolean; + enable_organization_accounts: boolean; + enable_organization_billing: boolean; + }; Insert: { - billing_provider?: Database["public"]["Enums"]["billing_provider"] - enable_account_billing?: boolean - enable_organization_accounts?: boolean - enable_organization_billing?: boolean - } + billing_provider?: Database['public']['Enums']['billing_provider']; + enable_account_billing?: boolean; + enable_organization_accounts?: boolean; + enable_organization_billing?: boolean; + }; Update: { - billing_provider?: Database["public"]["Enums"]["billing_provider"] - enable_account_billing?: boolean - enable_organization_accounts?: boolean - enable_organization_billing?: boolean - } - Relationships: [] - } + billing_provider?: Database['public']['Enums']['billing_provider']; + enable_account_billing?: boolean; + enable_organization_accounts?: boolean; + enable_organization_billing?: boolean; + }; + Relationships: []; + }; invitations: { Row: { - account_id: string - created_at: string - email: string - expires_at: string - id: number - invite_token: string - invited_by: string - role: Database["public"]["Enums"]["account_role"] - updated_at: string - } + account_id: string; + created_at: string; + email: string; + expires_at: string; + id: number; + invite_token: string; + invited_by: string; + role: Database['public']['Enums']['account_role']; + updated_at: string; + }; Insert: { - account_id: string - created_at?: string - email: string - expires_at?: string - id?: number - invite_token: string - invited_by: string - role: Database["public"]["Enums"]["account_role"] - updated_at?: string - } + account_id: string; + created_at?: string; + email: string; + expires_at?: string; + id?: number; + invite_token: string; + invited_by: string; + role: Database['public']['Enums']['account_role']; + updated_at?: string; + }; Update: { - account_id?: string - created_at?: string - email?: string - expires_at?: string - id?: number - invite_token?: string - invited_by?: string - role?: Database["public"]["Enums"]["account_role"] - updated_at?: string - } + account_id?: string; + created_at?: string; + email?: string; + expires_at?: string; + id?: number; + invite_token?: string; + invited_by?: string; + role?: Database['public']['Enums']['account_role']; + 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']; }, - ] - } + ]; + }; role_permissions: { Row: { - id: number - permission: Database["public"]["Enums"]["app_permissions"] - role: Database["public"]["Enums"]["account_role"] - } + id: number; + permission: Database['public']['Enums']['app_permissions']; + role: Database['public']['Enums']['account_role']; + }; Insert: { - id?: number - permission: Database["public"]["Enums"]["app_permissions"] - role: Database["public"]["Enums"]["account_role"] - } + id?: number; + permission: Database['public']['Enums']['app_permissions']; + role: Database['public']['Enums']['account_role']; + }; Update: { - id?: number - permission?: Database["public"]["Enums"]["app_permissions"] - role?: Database["public"]["Enums"]["account_role"] - } - Relationships: [] - } + id?: number; + permission?: Database['public']['Enums']['app_permissions']; + role?: Database['public']['Enums']['account_role']; + }; + Relationships: []; + }; 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 - interval: string - interval_count: number - period_ends_at: string | null - period_starts_at: string | null - price_amount: number | null - product_id: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at: string | null - trial_starts_at: string | null - updated_at: string - variant_id: 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; + interval: string; + interval_count: number; + period_ends_at: string | null; + period_starts_at: string | null; + price_amount: number | null; + product_id: string; + status: Database['public']['Enums']['subscription_status']; + trial_ends_at: string | null; + trial_starts_at: string | null; + updated_at: string; + variant_id: 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 - interval: string - interval_count: number - period_ends_at?: string | null - period_starts_at?: string | null - price_amount?: number | null - product_id: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at?: string | null - trial_starts_at?: string | null - updated_at?: string - variant_id: 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; + interval: string; + interval_count: number; + period_ends_at?: string | null; + period_starts_at?: string | null; + price_amount?: number | null; + product_id: string; + status: Database['public']['Enums']['subscription_status']; + trial_ends_at?: string | null; + trial_starts_at?: string | null; + updated_at?: string; + variant_id: 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 - interval?: string - interval_count?: number - period_ends_at?: string | null - period_starts_at?: string | null - price_amount?: number | null - product_id?: string - status?: Database["public"]["Enums"]["subscription_status"] - trial_ends_at?: string | null - trial_starts_at?: string | null - updated_at?: string - variant_id?: 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; + interval?: string; + interval_count?: number; + period_ends_at?: string | null; + period_starts_at?: string | null; + price_amount?: number | null; + product_id?: string; + status?: Database['public']['Enums']['subscription_status']; + trial_ends_at?: string | null; + trial_starts_at?: string | null; + updated_at?: string; + variant_id?: 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 + id: string | null; + name: string | null; + picture_url: string | 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: Database["public"]["Enums"]["account_role"] | null - slug: string | null - } - Relationships: [] - } - } + id: string | null; + name: string | null; + picture_url: string | null; + role: Database['public']['Enums']['account_role'] | null; + slug: string | null; + }; + Relationships: []; + }; + }; Functions: { add_invitations_to_account: { Args: { - account_slug: string - invitations: unknown[] - } - Returns: Database["public"]["Tables"]["invitations"]["Row"][] - } + account_slug: string; + invitations: unknown[]; + }; + Returns: Database['public']['Tables']['invitations']['Row'][]; + }; add_subscription: { Args: { - account_id: string - subscription_id: string - active: boolean - status: Database["public"]["Enums"]["subscription_status"] - billing_provider: Database["public"]["Enums"]["billing_provider"] - product_id: string - variant_id: string - price_amount: number - cancel_at_period_end: boolean - currency: string - interval: string - interval_count: number - period_starts_at: string - period_ends_at: string - trial_starts_at: string - trial_ends_at: string - customer_id: string - } + account_id: string; + subscription_id: string; + active: boolean; + status: Database['public']['Enums']['subscription_status']; + billing_provider: Database['public']['Enums']['billing_provider']; + product_id: string; + variant_id: string; + price_amount: number; + cancel_at_period_end: boolean; + currency: string; + interval: string; + interval_count: number; + period_starts_at: string; + period_ends_at: string; + trial_starts_at: string; + trial_ends_at: string; + customer_id: 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 - interval: string - interval_count: number - period_ends_at: string | null - period_starts_at: string | null - price_amount: number | null - product_id: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at: string | null - trial_starts_at: string | null - updated_at: string - variant_id: 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; + interval: string; + interval_count: number; + period_ends_at: string | null; + period_starts_at: string | null; + price_amount: number | null; + product_id: string; + status: Database['public']['Enums']['subscription_status']; + trial_ends_at: string | null; + trial_starts_at: string | null; + updated_at: string; + variant_id: string; + }; + }; create_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 - 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; + slug: string | null; + updated_at: string | null; + updated_by: string | null; + }; + }; create_invitation: { Args: { - account_id: string - email: string - role: Database["public"]["Enums"]["account_role"] - } + account_id: string; + email: string; + role: Database['public']['Enums']['account_role']; + }; Returns: { - account_id: string - created_at: string - email: string - expires_at: string - id: number - invite_token: string - invited_by: string - role: Database["public"]["Enums"]["account_role"] - updated_at: string - } - } + account_id: string; + created_at: string; + email: string; + expires_at: string; + id: number; + invite_token: string; + invited_by: string; + role: Database['public']['Enums']['account_role']; + updated_at: string; + }; + }; get_account_invitations: { Args: { - account_slug: string - } + account_slug: string; + }; Returns: { - id: number - email: string - account_id: string - invited_by: string - role: Database["public"]["Enums"]["account_role"] - created_at: string - updated_at: string - inviter_name: string - inviter_email: string - }[] - } + id: number; + email: string; + account_id: string; + invited_by: string; + role: Database['public']['Enums']['account_role']; + created_at: string; + updated_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: Database["public"]["Enums"]["account_role"] - 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: Database['public']['Enums']['account_role']; + 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_user_accounts: { - Args: Record + Args: Record; 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 - 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; + slug: string | null; + updated_at: string | null; + updated_by: string | null; + }[]; + }; 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?: Database["public"]["Enums"]["account_role"] - } - Returns: boolean - } + account_id: string; + account_role?: Database['public']['Enums']['account_role']; + }; + Returns: boolean; + }; is_account_owner: { Args: { - account_id: string - } - Returns: boolean - } + 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; + }; organization_account_workspace: { Args: { - account_slug: string - } + account_slug: string; + }; Returns: { - id: string - name: string - picture_url: string - slug: string - role: Database["public"]["Enums"]["account_role"] - 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: Database['public']['Enums']['account_role']; + primary_owner_user_id: string; + subscription_status: Database['public']['Enums']['subscription_status']; + permissions: Database['public']['Enums']['app_permissions'][]; + }[]; + }; unaccent: { Args: { - "": string - } - Returns: string - } + '': string; + }; + Returns: string; + }; unaccent_init: { Args: { - "": unknown - } - Returns: unknown - } - } + '': unknown; + }; + Returns: unknown; + }; + }; Enums: { - account_role: "owner" | "member" + account_role: 'owner' | 'member'; app_permissions: - | "roles.manage" - | "billing.manage" - | "settings.manage" - | "members.manage" - | "invites.manage" - billing_provider: "stripe" | "lemon-squeezy" | "paddle" + | 'roles.manage' + | 'billing.manage' + | 'settings.manage' + | 'members.manage' + | 'invites.manage'; + billing_provider: 'stripe' | 'lemon-squeezy' | 'paddle'; subscription_status: - | "active" - | "trialing" - | "past_due" - | "canceled" - | "unpaid" - | "incomplete" - | "incomplete_expired" - | "paused" - } + | 'active' + | 'trialing' + | 'past_due' + | 'canceled' + | 'unpaid' + | 'incomplete' + | 'incomplete_expired' + | 'paused'; + }; CompositeTypes: { - [_ in never]: never - } - } + [_ in never]: never; + }; + }; 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']; }, - ] - } - } + ]; + }; + }; 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; + }[]; + }; 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/packages/ui/package.json b/packages/ui/package.json index af04b24b8..0d72b5e25 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -9,6 +9,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@radix-ui/react-accordion": "1.1.2", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", @@ -44,7 +45,6 @@ "@kit/prettier-config": "0.1.0", "@kit/tailwind-config": "0.1.0", "@kit/tsconfig": "0.1.0", - "@tanstack/react-table": "^8.11.3", "@types/react": "^18.2.48", "@types/react-dom": "^18.2.18", "date-fns": "^3.2.0", @@ -67,6 +67,7 @@ }, "prettier": "@kit/prettier-config", "exports": { + "./accordion": "./src/shadcn/accordion.tsx", "./avatar": "./src/shadcn/avatar.tsx", "./button": "./src/shadcn/button.tsx", "./calendar": "./src/shadcn/calendar.tsx", @@ -117,4 +118,4 @@ ] } } -} +} \ No newline at end of file diff --git a/packages/ui/src/makerkit/mobile-navigation-menu.tsx b/packages/ui/src/makerkit/mobile-navigation-menu.tsx index 56570d700..76ee84503 100644 --- a/packages/ui/src/makerkit/mobile-navigation-menu.tsx +++ b/packages/ui/src/makerkit/mobile-navigation-menu.tsx @@ -1,3 +1,5 @@ +'use client'; + import { useMemo } from 'react'; import Link from 'next/link'; diff --git a/packages/ui/src/makerkit/navigation/navigation-container.tsx b/packages/ui/src/makerkit/navigation/navigation-container.tsx deleted file mode 100644 index 627545545..000000000 --- a/packages/ui/src/makerkit/navigation/navigation-container.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { cn } from './utils'; - -const NavigationContainer: React.FC<{ - className?: string; -}> = ({ children, className }) => { - return ( -
- {children} -
- ); -}; - -export default NavigationContainer; diff --git a/packages/ui/src/makerkit/navigation/navigation-item.tsx b/packages/ui/src/makerkit/navigation/navigation-item.tsx deleted file mode 100644 index d827c6a72..000000000 --- a/packages/ui/src/makerkit/navigation/navigation-item.tsx +++ /dev/null @@ -1,124 +0,0 @@ -'use client'; - -import { useContext } from 'react'; - -import Link from 'next/link'; -import { usePathname } from 'next/navigation'; - -import Trans from '@/components/app/Trans'; -import { cva } from 'class-variance-authority'; - -import isRouteActive from '@kit/generic/is-route-active'; - -import { NavigationMenuContext } from './navigation-menu-context'; -import { cn } from './utils'; - -interface Link { - path: string; - label?: string; -} - -const NavigationMenuItem: React.FC<{ - link: Link; - depth?: number; - disabled?: boolean; - shallow?: boolean; - className?: string; -}> = ({ link, disabled, shallow, depth, ...props }) => { - const pathName = usePathname() ?? ''; - const active = isRouteActive(link.path, pathName, depth ?? 3); - const menuProps = useContext(NavigationMenuContext); - const label = link.label; - - const itemClassName = getNavigationMenuItemClassBuilder()({ - active, - ...menuProps, - }); - - const className = cn(itemClassName, props.className ?? ``); - - return ( -
  • - - - -
  • - ); -}; - -export default NavigationMenuItem; - -function getNavigationMenuItemClassBuilder() { - return cva( - [ - `flex items-center justify-center font-medium lg:justify-start rounded-md text-sm transition colors transform *:active:translate-y-[2px]`, - '*:p-1 *:lg:px-2.5 *:s-full *:flex *:items-center', - 'aria-disabled:cursor-not-allowed aria-disabled:opacity-50', - ], - { - compoundVariants: [ - // not active - shared - { - active: false, - className: `font-medium hover:underline`, - }, - // active - shared - { - active: true, - className: `font-semibold`, - }, - // active - pill - { - active: true, - pill: true, - className: `bg-gray-50 text-gray-800 dark:bg-primary-300/10`, - }, - // not active - pill - { - active: false, - pill: true, - className: `hover:bg-gray-50 active:bg-gray-100 text-gray-500 dark:text-gray-300 dark:hover:bg-background dark:active:bg-dark-900/90`, - }, - // not active - bordered - { - active: false, - bordered: true, - className: `hover:bg-gray-50 active:bg-gray-100 dark:active:bg-dark-800 dark:hover:bg-dark/90 transition-colors rounded-lg border-transparent`, - }, - // active - bordered - { - active: true, - bordered: true, - className: `top-[0.4rem] border-b-[0.25rem] rounded-none border-primary bg-transparent pb-[0.55rem] text-primary-700 dark:text-white`, - }, - // active - secondary - { - active: true, - secondary: true, - className: `bg-transparent font-semibold`, - }, - ], - variants: { - active: { - true: ``, - }, - pill: { - true: `[&>*]:py-2`, - }, - bordered: { - true: `relative h-10`, - }, - secondary: { - true: ``, - }, - }, - }, - ); -} diff --git a/packages/ui/src/makerkit/navigation/navigation-menu-context.tsx b/packages/ui/src/makerkit/navigation/navigation-menu-context.tsx deleted file mode 100644 index 5409f4a1e..000000000 --- a/packages/ui/src/makerkit/navigation/navigation-menu-context.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { createContext } from 'react'; - -import type { NavigationMenuProps } from './navigation-menu'; - -export const NavigationMenuContext = createContext({}); diff --git a/packages/ui/src/makerkit/navigation/navigation-menu.tsx b/packages/ui/src/makerkit/navigation/navigation-menu.tsx deleted file mode 100644 index 2f7d0022c..000000000 --- a/packages/ui/src/makerkit/navigation/navigation-menu.tsx +++ /dev/null @@ -1,49 +0,0 @@ -'use client'; - -import type { PropsWithChildren } from 'react'; - -import { cva } from 'class-variance-authority'; - -import { NavigationMenuContext } from './navigation-menu-context'; - -type Vertical = { - vertical?: boolean; -}; - -type Bordered = { - bordered?: boolean; -}; - -type Pill = { - pill?: boolean; -}; - -export type NavigationMenuProps = Vertical & (Bordered | Pill); - -function NavigationMenu(props: PropsWithChildren) { - const className = getNavigationMenuClassBuilder()(props); - - return ( -
      - - {props.children} - -
    - ); -} - -export default NavigationMenu; - -function getNavigationMenuClassBuilder() { - return cva(['w-full dark:text-gray-300 items-center flex-wrap flex'], { - variants: { - vertical: { - true: `flex items-start justify-between space-x-2 - lg:flex-col lg:justify-start lg:space-x-0 lg:space-y-1.5 [&>li>a]:w-full`, - }, - bordered: { - true: `lg:space-x-3 border-b border-gray-100 dark:border-dark-800 pb-1.5`, - }, - }, - }); -} diff --git a/packages/ui/src/makerkit/spinner.tsx b/packages/ui/src/makerkit/spinner.tsx index b5b5ee422..34668bdac 100644 --- a/packages/ui/src/makerkit/spinner.tsx +++ b/packages/ui/src/makerkit/spinner.tsx @@ -21,7 +21,6 @@ function Spinner( d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor" /> - , + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AccordionItem.displayName = 'AccordionItem'; + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180', + className, + )} + {...props} + > + {children} + + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
    {children}
    +
    +)); +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/packages/ui/src/shadcn/badge.tsx b/packages/ui/src/shadcn/badge.tsx index 1706fe49b..12411df06 100644 --- a/packages/ui/src/shadcn/badge.tsx +++ b/packages/ui/src/shadcn/badge.tsx @@ -17,7 +17,7 @@ const badgeVariants = cva( 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80', outline: 'text-foreground', success: - 'border-transparent bg-green-50 text-green-500 dark:bg-transparent', + 'border-transparent bg-green-50 text-green-500 dark:bg-green-500/20', warning: 'border-transparent bg-orange-50 text-orange-500 dark:bg-transparent', info: 'border-transparent bg-blue-50 text-blue-500 dark:bg-transparent', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eaeb3540d..67ca6d1f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,7 +88,7 @@ importers: version: 5.28.6(react@18.2.0) '@tanstack/react-query-next-experimental': specifier: ^5.28.6 - version: 5.28.6(@tanstack/react-query@5.28.6)(next@14.2.0-canary.41)(react@18.2.0) + version: 5.28.6(@tanstack/react-query@5.28.6)(next@14.2.0-canary.43)(react@18.2.0) '@tanstack/react-table': specifier: ^8.11.3 version: 8.14.0(react-dom@18.2.0)(react@18.2.0) @@ -100,7 +100,7 @@ importers: version: 3.6.0 edge-csrf: specifier: ^1.0.9 - version: 1.0.9(next@14.2.0-canary.41) + version: 1.0.9(next@14.2.0-canary.43) i18next: specifier: ^23.10.1 version: 23.10.1 @@ -108,17 +108,17 @@ importers: specifier: ^1.2.0 version: 1.2.0 next: - specifier: ^14.2.0-canary.41 - version: 14.2.0-canary.41(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) + specifier: canary + version: 14.2.0-canary.43(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) next-contentlayer: specifier: 0.3.4 - version: 0.3.4(contentlayer@0.3.4)(esbuild@0.19.11)(next@14.2.0-canary.41)(react-dom@18.2.0)(react@18.2.0) + version: 0.3.4(contentlayer@0.3.4)(esbuild@0.19.11)(next@14.2.0-canary.43)(react-dom@18.2.0)(react@18.2.0) next-sitemap: specifier: ^4.2.3 - version: 4.2.3(next@14.2.0-canary.41) + version: 4.2.3(next@14.2.0-canary.43) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.2.0-canary.41)(react-dom@18.2.0)(react@18.2.0) + version: 0.2.1(next@14.2.0-canary.43)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -163,8 +163,8 @@ importers: specifier: ^0.1.0 version: link:../../tooling/typescript '@next/bundle-analyzer': - specifier: ^14.2.0-canary.41 - version: 14.2.0-canary.41 + specifier: canary + version: 14.2.0-canary.43 '@types/mdx': specifier: ^2.0.10 version: 2.0.11 @@ -333,6 +333,10 @@ importers: version: link:../../../tooling/typescript packages/features/admin: + dependencies: + '@kit/ui': + specifier: 0.1.0 + version: link:../../ui devDependencies: '@kit/eslint-config': specifier: 0.2.0 @@ -568,6 +572,9 @@ importers: packages/ui: dependencies: + '@radix-ui/react-accordion': + specifier: 1.1.2 + version: 1.1.2(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-alert-dialog': specifier: ^1.0.5 version: 1.0.5(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0) @@ -619,6 +626,9 @@ importers: '@radix-ui/react-tooltip': specifier: 1.0.7 version: 1.0.7(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0) + '@tanstack/react-table': + specifier: ^8.10.7 + version: 8.14.0(react-dom@18.2.0)(react@18.2.0) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -659,9 +669,6 @@ importers: '@kit/tsconfig': specifier: 0.1.0 version: link:../../tooling/typescript - '@tanstack/react-table': - specifier: ^8.11.3 - version: 8.14.0(react-dom@18.2.0)(react@18.2.0) '@types/react': specifier: ^18.2.48 version: 18.2.67 @@ -1770,8 +1777,8 @@ packages: - supports-color dev: false - /@next/bundle-analyzer@14.2.0-canary.41: - resolution: {integrity: sha512-1+PP3XaC3lz0oE49D0jxGsiEJZOmwlDgqV3yantl64vXRNX8Ae3Gsk1KcDhp7JHKKPvFx4AF13/LF48sbH0zkw==} + /@next/bundle-analyzer@14.2.0-canary.43: + resolution: {integrity: sha512-5GYBb99OLnmg5xZDrUUD0ILB/gJDN4MxJTG5fU5JQXIDc6Ew+jJgMzjdqptJduvlExorAWNNpQnjdnRlnZCQfg==} dependencies: webpack-bundle-analyzer: 4.10.1 transitivePeerDependencies: @@ -1791,8 +1798,8 @@ packages: resolution: {integrity: sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ==} dev: false - /@next/env@14.2.0-canary.41: - resolution: {integrity: sha512-6bd8zNDEferyJ9qkJrCB0pTgGFaJ9XttMI+uj5jrSeQ88kxsgPcoOFqBEMDtDOEzWqi+17B29alThei0Cmw0dA==} + /@next/env@14.2.0-canary.43: + resolution: {integrity: sha512-jBjfC5J053shwv+g4kplFG+iH1TqWwMtLCIpDSplOmRDLdGeai6s3oKmWIxd+MbG5ETSZOl1vCN5A3nMgGkXfg==} dev: false /@next/eslint-plugin-next@14.1.4: @@ -1833,8 +1840,8 @@ packages: dev: false optional: true - /@next/swc-darwin-arm64@14.2.0-canary.41: - resolution: {integrity: sha512-cplMeo/uQcfSHwZH2naB87IWzJouOSPXFQqRk1/nwuQNPxLFT2xO2v7zP4L4W98qukvLylFxWQhqpIQqZnohIA==} + /@next/swc-darwin-arm64@14.2.0-canary.43: + resolution: {integrity: sha512-M9Asj8J6GMVNdMRnDnR+hELiyjgaHSUYAZz4M7ro5Vd1X8wpg3jygd/RnkTv+hhHn3rqwV9jWyZ4xdyG3SORrg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -1860,8 +1867,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@14.2.0-canary.41: - resolution: {integrity: sha512-mnqPeUMFUg73DXEsNOxrKXy09ikcErLeFEzYVqn5XwaewVyqny9xwf8f02BYBcLEBrmk565xkocnTs7su45qqA==} + /@next/swc-darwin-x64@14.2.0-canary.43: + resolution: {integrity: sha512-3BQ5FirbYZgXAFOCUynDr/Sl0fcFfEiLiDVdGMaJO7754fuWJShcj5tODiFC2B7MgLsVkri/84prBzsjkg76jA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -1887,8 +1894,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@14.2.0-canary.41: - resolution: {integrity: sha512-ns0/YS9yqqS71h4xZNGn+IDZC7q3fLrF9mIaZ3aXhkHpXfeyjACOAEC6/0l0E49w4VkPv0XK64aRvsxsZfFr9g==} + /@next/swc-linux-arm64-gnu@14.2.0-canary.43: + resolution: {integrity: sha512-VoCLYDTD2bkLsUkT0bACplrdpTw+IBKdFr5ih85atePrujCz6dMPUxeNMwH9aYL7r3PgzH6dR30r0Y5TFwUUSg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1914,8 +1921,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@14.2.0-canary.41: - resolution: {integrity: sha512-22nsQMLgJH3ZbxbgQmiwGbFtW8KtDRQJU8OSyWcO8MFTgPdL3IcRd/lTsR5r9qliosoGgHzFSYDAq/7M5I/w0Q==} + /@next/swc-linux-arm64-musl@14.2.0-canary.43: + resolution: {integrity: sha512-8c35oylAS4Ggu155txTpOv7VG4BzG8BTluVbUZuaneZwsZi6VTbjVKMVnLYmmdcdRkkvRgPc83oUr2HGxwxFBw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1941,8 +1948,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@14.2.0-canary.41: - resolution: {integrity: sha512-ZkcPQk+SV+i06i0k/UVmXKk+k70yKIwtTPrWl7JpeJ/Wc7sWoRqNCdpFqP227oOsy6dM0NKqJTEOATBYAefQLg==} + /@next/swc-linux-x64-gnu@14.2.0-canary.43: + resolution: {integrity: sha512-PHy7clJ+ChZzNJ3c9A2IrWJN4aNa+FZ+v39XNdcjdkdhPvwu1QSvtirWSbxqKpAqgA/3sMhAGCvwOx6yeBs4Ug==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1968,8 +1975,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@14.2.0-canary.41: - resolution: {integrity: sha512-1Uofz0Bkec63oN7Xj9lHGevCqxZJrr6pruPx5JUb613CYqUVCVj6JA8H2JutYYwgcbwstjdA+9He37HlW1FGTw==} + /@next/swc-linux-x64-musl@14.2.0-canary.43: + resolution: {integrity: sha512-pvma+GKwkDEzhQRrwl9P4oGu9A9NGJH/Za+SG/XwWph2i78+4OMDCKrmKEJ1T5BE6Bgo+Emfhdy8TmfqHPQQCg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1995,8 +2002,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@14.2.0-canary.41: - resolution: {integrity: sha512-gMzwgq1ZnKwxYx2I4qhuRtaGZ/6WZD8XV0cObnaWXiu8O7NCK1kEKa6+IWy+Manax5qwamHKzWND5uKbeddToQ==} + /@next/swc-win32-arm64-msvc@14.2.0-canary.43: + resolution: {integrity: sha512-b1npBheIu7/BgMZTCFkuNYv0Q/N9u6+7MYY5xjZDVIutW8ut2V93JZqeC2SYWFm03I+LNdYjplRhn3TVerz9Xg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -2022,8 +2029,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc@14.2.0-canary.41: - resolution: {integrity: sha512-U72bjcHUUoRToFTAouUqK9y/PaiKVo4rDX5/RwzIZThPghfHf5ALG6DYiw64sKWSRXSfFOv9DzhofjK1+CIgSA==} + /@next/swc-win32-ia32-msvc@14.2.0-canary.43: + resolution: {integrity: sha512-1bZDCGyQzvdRNxVUUhsjBZOzBEEoQlh1r91ifjUz9nhcFYOlmP6IplPMjaLmG+GJMUiI36j5svdPYO3LP08b8g==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -2049,8 +2056,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@14.2.0-canary.41: - resolution: {integrity: sha512-cBgEDwdxfyv9bBoo5dKBtfxd7S7Dv3dTRKYx7agprJ3BdGc8gXs2zdi08lR/fBU0kjpsC4gw/tg5p+IDkuZUaw==} + /@next/swc-win32-x64-msvc@14.2.0-canary.43: + resolution: {integrity: sha512-pU9gjLmp4yjYzBqCGa5bQ0iyJ5D73IRITEUFKrjZPi0XHUbFLrhcaaCsnVgMO4xfOQJgS7ODuQB7N0iPk7/EMw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2386,6 +2393,35 @@ packages: '@babel/runtime': 7.24.1 dev: false + /@radix-ui/react-accordion@1.1.2(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collapsible': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.67)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.67)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.67)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.67)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.67)(react@18.2.0) + '@types/react': 18.2.67 + '@types/react-dom': 18.2.22 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-alert-dialog@1.0.5(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OrVIOcZL0tl6xibeuGt5/+UxoT2N27KCFOPjFyfXMnchxSHZ/OW7cCX2nGlIYJrbHK/fczPcFzAwvNBB6XBNMA==} peerDependencies: @@ -4187,7 +4223,7 @@ packages: /@tanstack/query-core@5.28.6: resolution: {integrity: sha512-hnhotV+DnQtvtR3jPvbQMPNMW4KEK0J4k7c609zJ8muiNknm+yoDyMHmxTWM5ZnlZpsz0zOxYFr+mzRJNHWJsA==} - /@tanstack/react-query-next-experimental@5.28.6(@tanstack/react-query@5.28.6)(next@14.2.0-canary.41)(react@18.2.0): + /@tanstack/react-query-next-experimental@5.28.6(@tanstack/react-query@5.28.6)(next@14.2.0-canary.43)(react@18.2.0): resolution: {integrity: sha512-KHTR1nGChTXk/kELit2gaqF3cQuN68F5UJv0377Gz5DnllPnBegja6if2W9KtKxm3Z1xP0j8LQXplqlqny2SYw==} peerDependencies: '@tanstack/react-query': ^5.28.6 @@ -4195,7 +4231,7 @@ packages: react: ^18.0.0 dependencies: '@tanstack/react-query': 5.28.6(react@18.2.0) - next: 14.2.0-canary.41(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) + next: 14.2.0-canary.43(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 dev: false @@ -4217,10 +4253,12 @@ packages: '@tanstack/table-core': 8.14.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + dev: false /@tanstack/table-core@8.14.0: resolution: {integrity: sha512-wDhpKJahGHWhmRt4RxtV3pES63CoeadljGWS/xeS9OJr1HBl2NB+OO44ht3sxDH5j5TRDAbQzC0NvSlsUfn7lQ==} engines: {node: '>=12'} + dev: false /@tootallnate/quickjs-emscripten@0.23.0: resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} @@ -6033,12 +6071,12 @@ packages: /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - /edge-csrf@1.0.9(next@14.2.0-canary.41): + /edge-csrf@1.0.9(next@14.2.0-canary.43): resolution: {integrity: sha512-3F89YTh42UDdISr3s9AEcgJDLi4ysgjGfnybzF0LuZGaG2W31h1ZwgWwEQBLMj04lAklcP4XHZYi7vk9o8zcbg==} peerDependencies: next: ^13.0.0 || ^14.0.0 dependencies: - next: 14.2.0-canary.41(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) + next: 14.2.0-canary.43(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) dev: false /editorconfig@1.0.4: @@ -8784,7 +8822,7 @@ packages: engines: {node: '>= 0.4.0'} dev: true - /next-contentlayer@0.3.4(contentlayer@0.3.4)(esbuild@0.19.11)(next@14.2.0-canary.41)(react-dom@18.2.0)(react@18.2.0): + /next-contentlayer@0.3.4(contentlayer@0.3.4)(esbuild@0.19.11)(next@14.2.0-canary.43)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-UtUCwgAl159KwfhNaOwyiI7Lg6sdioyKMeh+E7jxx0CJ29JuXGxBEYmCI6+72NxFGIFZKx8lvttbbQhbnYWYSw==} peerDependencies: contentlayer: 0.3.4 @@ -8795,7 +8833,7 @@ packages: '@contentlayer/core': 0.3.4(esbuild@0.19.11) '@contentlayer/utils': 0.3.4 contentlayer: 0.3.4(esbuild@0.19.11) - next: 14.2.0-canary.41(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) + next: 14.2.0-canary.43(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -8805,7 +8843,7 @@ packages: - supports-color dev: false - /next-sitemap@4.2.3(next@14.2.0-canary.41): + /next-sitemap@4.2.3(next@14.2.0-canary.43): resolution: {integrity: sha512-vjdCxeDuWDzldhCnyFCQipw5bfpl4HmZA7uoo3GAaYGjGgfL4Cxb1CiztPuWGmS+auYs7/8OekRS8C2cjdAsjQ==} engines: {node: '>=14.18'} hasBin: true @@ -8816,17 +8854,17 @@ packages: '@next/env': 13.5.6 fast-glob: 3.3.2 minimist: 1.2.8 - next: 14.2.0-canary.41(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) + next: 14.2.0-canary.43(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) dev: false - /next-themes@0.2.1(next@14.2.0-canary.41)(react-dom@18.2.0)(react@18.2.0): + /next-themes@0.2.1(next@14.2.0-canary.43)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==} peerDependencies: next: '*' react: '*' react-dom: '*' dependencies: - next: 14.2.0-canary.41(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) + next: 14.2.0-canary.43(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -8909,22 +8947,25 @@ packages: - babel-plugin-macros dev: false - /next@14.2.0-canary.41(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-jqNSTq1COP04WXpj88Bzt8kkCLXFNpCU4tHzQrICAMVWeNtHTZpK2WPR8560SWBw614bW2qHYY85k0tez3YLiA==} + /next@14.2.0-canary.43(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-tL5fxsleOuRS7Momx5wRwkCOPLybQKwgJnpzgMGVReQs+kA9lkQiBANvlYdAsrvZ3vjzx2H+9mSqKDcKaC8UXQ==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 react: ^18.2.0 react-dom: ^18.2.0 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': optional: true + '@playwright/test': + optional: true sass: optional: true dependencies: - '@next/env': 14.2.0-canary.41 + '@next/env': 14.2.0-canary.43 '@opentelemetry/api': 1.8.0 '@swc/helpers': 0.5.5 busboy: 1.6.0 @@ -8935,15 +8976,15 @@ packages: react-dom: 18.2.0(react@18.2.0) styled-jsx: 5.1.1(react@18.2.0) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.0-canary.41 - '@next/swc-darwin-x64': 14.2.0-canary.41 - '@next/swc-linux-arm64-gnu': 14.2.0-canary.41 - '@next/swc-linux-arm64-musl': 14.2.0-canary.41 - '@next/swc-linux-x64-gnu': 14.2.0-canary.41 - '@next/swc-linux-x64-musl': 14.2.0-canary.41 - '@next/swc-win32-arm64-msvc': 14.2.0-canary.41 - '@next/swc-win32-ia32-msvc': 14.2.0-canary.41 - '@next/swc-win32-x64-msvc': 14.2.0-canary.41 + '@next/swc-darwin-arm64': 14.2.0-canary.43 + '@next/swc-darwin-x64': 14.2.0-canary.43 + '@next/swc-linux-arm64-gnu': 14.2.0-canary.43 + '@next/swc-linux-arm64-musl': 14.2.0-canary.43 + '@next/swc-linux-x64-gnu': 14.2.0-canary.43 + '@next/swc-linux-x64-musl': 14.2.0-canary.43 + '@next/swc-win32-arm64-msvc': 14.2.0-canary.43 + '@next/swc-win32-ia32-msvc': 14.2.0-canary.43 + '@next/swc-win32-x64-msvc': 14.2.0-canary.43 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros diff --git a/tooling/prettier/index.mjs b/tooling/prettier/index.mjs index d6579416d..a876f89da 100644 --- a/tooling/prettier/index.mjs +++ b/tooling/prettier/index.mjs @@ -19,7 +19,6 @@ const config = { '^@supabase/supabase-js$', '^@supabase/gotrue-js$', '', - '^@packages/(.*)$', '^@kit/(.*)$', '^~/(.*)$', // app-specific imports '^[./]', // relative imports diff --git a/tooling/tailwind/index.ts b/tooling/tailwind/index.ts index ea511c04b..ecae70641 100644 --- a/tooling/tailwind/index.ts +++ b/tooling/tailwind/index.ts @@ -3,7 +3,7 @@ import { fontFamily } from 'tailwindcss/defaultTheme'; export default { darkMode: ['class'], - content: ['../../packages/**/*.{ts,tsx}', '../../apps/**/*.{ts,tsx}'], + content: ['../../packages/**/*.tsx', '../../apps/**/*.tsx'], theme: { container: { center: true, diff --git a/tsconfig.json b/tsconfig.json index d7e31233e..31e1fe5f0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,5 +16,6 @@ "jsx": "preserve", "incremental": true, "noUncheckedIndexedAccess": true - } + }, + "exclude": ["node_modules"] } diff --git a/turbo.json b/turbo.json index fa4f8f526..9ac375933 100644 --- a/turbo.json +++ b/turbo.json @@ -1,31 +1,49 @@ { "$schema": "https://turborepo.org/schema.json", - "globalDependencies": ["**/.env"], + "globalDependencies": [ + "**/.env" + ], "pipeline": { "topo": { - "dependsOn": ["^topo"] + "dependsOn": [ + "^topo" + ] }, "build": { - "dependsOn": ["^build"], - "outputs": [".next/**", "!.next/cache/**", "next-env.d.ts"], - "dotEnv": [".env.production.local", ".env.local", ".env.production", ".env"] + "dependsOn": [ + "^build" + ], + "outputs": [ + ".next/**", + "!.next/cache/**", + "next-env.d.ts" + ] }, "dev": { "persistent": true, - "cache": false, - "dotEnv": [".env.development.local", ".env.local", ".env.development", ".env"] + "cache": false }, "format": { - "outputs": ["node_modules/.cache/.prettiercache"], + "outputs": [ + "node_modules/.cache/.prettiercache" + ], "outputMode": "new-only" }, "lint": { - "dependsOn": ["^topo"], - "outputs": ["node_modules/.cache/.eslintcache"] + "dependsOn": [ + "^topo" + ], + "outputs": [ + "node_modules/.cache/.eslintcache" + ] }, "typecheck": { - "dependsOn": ["^topo"], - "outputs": ["node_modules/.cache/tsbuildinfo.json"] + "dependsOn": [ + "^topo" + ], + "outputs": [ + "node_modules/.cache/tsbuildinfo.json" + ] }, "clean": { "cache": false @@ -39,4 +57,4 @@ "STRIPE_SECRET_KEY", "STRIPE_WEBHOOK_SECRET" ] -} +} \ No newline at end of file