diff --git a/apps/web/README.md b/apps/web/README.md index 909831182..cbf5045dc 100644 --- a/apps/web/README.md +++ b/apps/web/README.md @@ -30,4 +30,4 @@ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY= ### Supabase -Please follow the instructions in the [Supabase README](../supabase/README.md) to setup your Supabase project. \ No newline at end of file +Please follow the instructions in the [Supabase README](../supabase/README.md) to setup your Supabase project. diff --git a/apps/web/app/(dashboard)/home/(user)/billing/server-actions.ts b/apps/web/app/(dashboard)/home/(user)/billing/server-actions.ts index ee203ddd5..3d552fb0d 100644 --- a/apps/web/app/(dashboard)/home/(user)/billing/server-actions.ts +++ b/apps/web/app/(dashboard)/home/(user)/billing/server-actions.ts @@ -7,7 +7,7 @@ import { z } from 'zod'; import { getLineItemsFromPlanId } from '@kit/billing'; import { getBillingGatewayProvider } from '@kit/billing-gateway'; import { Logger } from '@kit/shared/logger'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client'; import appConfig from '~/config/app.config'; @@ -25,9 +25,9 @@ export async function createPersonalAccountCheckoutSession(params: { productId: string; }) { const client = getSupabaseServerActionClient(); - const { data, error } = await requireAuth(client); + const { data: user, error } = await requireUser(client); - if (error ?? !data.user) { + if (error ?? !user) { throw new Error('Authentication required'); } @@ -50,7 +50,7 @@ export async function createPersonalAccountCheckoutSession(params: { // in the case of personal accounts // the account ID is the same as the user ID - const accountId = data.user.id; + const accountId = user.id; // the return URL for the checkout session const returnUrl = getCheckoutSessionReturnUrl(); @@ -74,13 +74,13 @@ export async function createPersonalAccountCheckoutSession(params: { accountId, trialDays, paymentType: product.paymentType, - customerEmail: data.user.email, + customerEmail: user.email, customerId, }); Logger.info( { - userId: data.user.id, + userId: user.id, }, `Checkout session created. Returning checkout token to client...`, ); diff --git a/apps/web/app/(dashboard)/home/[account]/_lib/load-team-account-workspace.ts b/apps/web/app/(dashboard)/home/[account]/_lib/load-team-account-workspace.ts index a1b09baab..44f0d203b 100644 --- a/apps/web/app/(dashboard)/home/[account]/_lib/load-team-account-workspace.ts +++ b/apps/web/app/(dashboard)/home/[account]/_lib/load-team-account-workspace.ts @@ -43,6 +43,8 @@ export const loadTeamWorkspace = cache(async (accountSlug: string) => { const accountData = accountResult.data[0]; + // we cannot find any record for the selected organization + // so we redirect the user to the home page if (!accountData) { return redirect(pathsConfig.app.home); } 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 6c8fe24b0..328cced96 100644 --- a/apps/web/app/(dashboard)/home/[account]/billing/return/page.tsx +++ b/apps/web/app/(dashboard)/home/[account]/billing/return/page.tsx @@ -3,7 +3,7 @@ import { notFound } from 'next/navigation'; import { getBillingGatewayProvider } from '@kit/billing-gateway'; import { BillingSessionStatus } from '@kit/billing-gateway/components'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client'; import billingConfig from '~/config/billing.config'; @@ -66,8 +66,11 @@ export default withI18n(ReturnStripeSessionPage); export async function loadCheckoutSession(sessionId: string) { const client = getSupabaseServerComponentClient(); + const { error } = await requireUser(client); - await requireAuth(client); + if (error) { + throw new Error('Authentication required'); + } const gateway = await getBillingGatewayProvider(client); diff --git a/apps/web/app/(dashboard)/home/[account]/billing/server-actions.ts b/apps/web/app/(dashboard)/home/[account]/billing/server-actions.ts index 238d9af88..a359de9d0 100644 --- a/apps/web/app/(dashboard)/home/[account]/billing/server-actions.ts +++ b/apps/web/app/(dashboard)/home/[account]/billing/server-actions.ts @@ -6,7 +6,7 @@ import { z } from 'zod'; import { getLineItemsFromPlanId } from '@kit/billing'; import { getBillingGatewayProvider } from '@kit/billing-gateway'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client'; import appConfig from '~/config/app.config'; @@ -33,13 +33,13 @@ export async function createTeamAccountCheckoutSession(params: { const productId = z.string().min(1).parse(params.productId); // we require the user to be authenticated - const { data: session } = await requireAuth(client); + const { data: user } = await requireUser(client); - if (!session) { + if (!user) { throw new Error('Authentication required'); } - const userId = session.user.id; + const userId = user.id; const accountId = params.accountId; const hasPermission = await getPermissionsForAccountId(userId, accountId); @@ -67,7 +67,7 @@ export async function createTeamAccountCheckoutSession(params: { // find the customer ID for the account if it exists // (eg. if the account has been billed before) const customerId = await getCustomerIdFromAccountId(client, accountId); - const customerEmail = session.user.email; + const customerEmail = user.email; // the return URL for the checkout session const returnUrl = getCheckoutSessionReturnUrl(params.slug); @@ -100,13 +100,13 @@ export async function createBillingPortalSession(formData: FormData) { }) .parse(Object.fromEntries(formData)); - const { data: session, error } = await requireAuth(client); + const { data: user, error } = await requireUser(client); - if (error ?? !session) { + if (error ?? !user) { throw new Error('Authentication required'); } - const userId = session.user.id; + const userId = user.id; // we require the user to have permissions to manage billing for the account const hasPermission = await getPermissionsForAccountId(userId, accountId); diff --git a/apps/web/app/join/page.tsx b/apps/web/app/join/page.tsx index cd0c6920b..a16aca495 100644 --- a/apps/web/app/join/page.tsx +++ b/apps/web/app/join/page.tsx @@ -4,7 +4,7 @@ import { notFound, redirect } from 'next/navigation'; import { ArrowLeft } from 'lucide-react'; import { Logger } from '@kit/shared/logger'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client'; import { AcceptInvitationContainer } from '@kit/team-accounts/components'; import { Button } from '@kit/ui/button'; @@ -12,6 +12,7 @@ import { Heading } from '@kit/ui/heading'; import { Trans } from '@kit/ui/trans'; import pathsConfig from '~/config/paths.config'; +import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; import { withI18n } from '~/lib/i18n/with-i18n'; interface Context { @@ -20,9 +21,11 @@ interface Context { }; } -export const generateMetadata = () => { +export const generateMetadata = async () => { + const i18n = await createI18nServerInstance(); + return { - title: 'Join Team Account', + title: i18n.t('teams:joinTeamAccount'), }; }; @@ -35,12 +38,12 @@ async function JoinTeamAccountPage({ searchParams }: Context) { } const client = getSupabaseServerComponentClient(); - const session = await requireAuth(client); + const auth = await requireUser(client); // if the user is not logged in or there is an error // redirect to the sign up page with the invite token // so that they will get back to this page after signing up - if (session.error ?? !session.data) { + if (auth.error ?? !auth.data) { redirect(pathsConfig.auth.signUp + '?invite_token=' + token); } @@ -61,7 +64,7 @@ async function JoinTeamAccountPage({ searchParams }: Context) { { name: 'join-team-account', accountId: invitation.account.id, - userId: session.data.user.id, + userId: auth.data.id, }, 'User is already in the account. Redirecting to account page.', ); @@ -137,8 +140,6 @@ async function getInviteDataFromInviteToken(token: string) { .gte('expires_at', new Date().toISOString()) .single(); - console.log(invitation, error); - if (!invitation ?? error) { return null; } diff --git a/apps/web/app/update-password/page.tsx b/apps/web/app/update-password/page.tsx index 27a852f61..59f99188d 100644 --- a/apps/web/app/update-password/page.tsx +++ b/apps/web/app/update-password/page.tsx @@ -2,7 +2,7 @@ import { redirect } from 'next/navigation'; import { PasswordResetForm } from '@kit/auth/password-reset'; import { AuthLayoutShell } from '@kit/auth/shared'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client'; import { AppLogo } from '~/components/app-logo'; @@ -11,7 +11,7 @@ import { withI18n } from '~/lib/i18n/with-i18n'; async function PasswordResetPage() { const client = getSupabaseServerComponentClient(); - const auth = await requireAuth(client); + const auth = await requireUser(client); // we require the user to be logged in to access this page if (auth.error) { diff --git a/apps/web/public/locales/en/teams.json b/apps/web/public/locales/en/teams.json index 7286a9302..5b845c475 100644 --- a/apps/web/public/locales/en/teams.json +++ b/apps/web/public/locales/en/teams.json @@ -152,5 +152,6 @@ "acceptInvitationHeading": "Accept Invitation to join {{accountName}}", "acceptInvitationDescription": "You have been invited to join the team {{accountName}}. If you wish to accept the invitation, please click the button below.", "joinTeam": "Join {{accountName}}", + "joinTeamAccount": "Join Team", "joiningTeam": "Joining team..." } diff --git a/package.json b/package.json index 8765ea0e3..a8f47beb6 100644 --- a/package.json +++ b/package.json @@ -8,9 +8,6 @@ "build": "turbo build", "clean": "git clean -xdf node_modules dist .next", "clean:workspaces": "turbo clean", - "db:generate": "turbo db:generate", - "db:push": "turbo db:push db:generate", - "db:studio": "pnpm -F db studio", "dev": "cross-env FORCE_COLOR=1 turbo dev --parallel", "dev:web": "turbo dev --parallel", "format": "turbo format --continue -- --cache --cache-location='node_modules/.cache/.prettiercache' --ignore-path='../../.gitignore'", diff --git a/packages/features/accounts/src/server/personal-accounts-server-actions.ts b/packages/features/accounts/src/server/personal-accounts-server-actions.ts index e04830781..f63a62b27 100644 --- a/packages/features/accounts/src/server/personal-accounts-server-actions.ts +++ b/packages/features/accounts/src/server/personal-accounts-server-actions.ts @@ -5,7 +5,7 @@ import { RedirectType, redirect } from 'next/navigation'; import { z } from 'zod'; import { Logger } from '@kit/shared/logger'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client'; import { DeletePersonalAccountService } from './services/delete-personal-account.service'; @@ -28,17 +28,17 @@ export async function deletePersonalAccountAction(formData: FormData) { } const client = getSupabaseServerActionClient(); - const session = await requireAuth(client); + const auth = await requireUser(client); - if (session.error) { + if (auth.error) { Logger.error(`User is not authenticated. Redirecting to login page`); - redirect(session.redirectTo); + redirect(auth.redirectTo); } // retrieve user ID and email - const userId = session.data.user.id; - const userEmail = session.data.user.email ?? null; + const userId = auth.data.id; + const userEmail = auth.data.email ?? null; // create a new instance of the personal accounts service const service = new DeletePersonalAccountService(); diff --git a/packages/features/team-accounts/src/schema/leave-team-account.schema.ts b/packages/features/team-accounts/src/schema/leave-team-account.schema.ts index ca068e423..99204bd63 100644 --- a/packages/features/team-accounts/src/schema/leave-team-account.schema.ts +++ b/packages/features/team-accounts/src/schema/leave-team-account.schema.ts @@ -2,5 +2,4 @@ import { z } from 'zod'; export const LeaveTeamAccountSchema = z.object({ accountId: z.string(), - userId: z.string(), }); diff --git a/packages/features/team-accounts/src/server/actions/create-team-account-server-actions.ts b/packages/features/team-accounts/src/server/actions/create-team-account-server-actions.ts index b17938f7a..bd7e5307e 100644 --- a/packages/features/team-accounts/src/server/actions/create-team-account-server-actions.ts +++ b/packages/features/team-accounts/src/server/actions/create-team-account-server-actions.ts @@ -5,7 +5,7 @@ import { redirect } from 'next/navigation'; import { z } from 'zod'; import { Logger } from '@kit/shared/logger'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client'; import { CreateTeamSchema } from '../../schema/create-team.schema'; @@ -25,13 +25,13 @@ export async function createOrganizationAccountAction( const client = getSupabaseServerActionClient(); const service = new CreateTeamAccountService(client); - const session = await requireAuth(client); + const auth = await requireUser(client); - if (session.error) { - redirect(session.redirectTo); + if (auth.error) { + redirect(auth.redirectTo); } - const userId = session.data.user.id; + const userId = auth.data.id; const createAccountResponse = await service.createNewOrganizationAccount({ name: accountName, diff --git a/packages/features/team-accounts/src/server/actions/delete-team-account-server-actions.ts b/packages/features/team-accounts/src/server/actions/delete-team-account-server-actions.ts index 0e8af1895..9436d3973 100644 --- a/packages/features/team-accounts/src/server/actions/delete-team-account-server-actions.ts +++ b/packages/features/team-accounts/src/server/actions/delete-team-account-server-actions.ts @@ -5,7 +5,7 @@ import { redirect } from 'next/navigation'; import { SupabaseClient } from '@supabase/supabase-js'; import { Database } from '@kit/supabase/database'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client'; import { DeleteTeamAccountSchema } from '../../schema/delete-team-account.schema'; @@ -17,7 +17,7 @@ export async function deleteTeamAccountAction(formData: FormData) { ); const client = getSupabaseServerActionClient(); - const auth = await requireAuth(client); + const auth = await requireUser(client); if (auth.error) { throw new Error('Authentication required'); @@ -36,7 +36,7 @@ export async function deleteTeamAccountAction(formData: FormData) { }), { accountId: params.accountId, - userId: auth.data.user.id, + userId: auth.data.id, }, ); @@ -47,13 +47,13 @@ async function assertUserPermissionsToDeleteTeamAccount( client: SupabaseClient, accountId: string, ) { - const auth = await requireAuth(client); + const auth = await requireUser(client); - if (auth.error ?? !auth.data.user.id) { + if (auth.error ?? !auth.data.id) { throw new Error('Authentication required'); } - const userId = auth.data.user.id; + const userId = auth.data.id; const { data, error } = await client .from('accounts') diff --git a/packages/features/team-accounts/src/server/actions/leave-team-account-server-actions.ts b/packages/features/team-accounts/src/server/actions/leave-team-account-server-actions.ts index 06f53859a..23548471f 100644 --- a/packages/features/team-accounts/src/server/actions/leave-team-account-server-actions.ts +++ b/packages/features/team-accounts/src/server/actions/leave-team-account-server-actions.ts @@ -1,16 +1,35 @@ 'use server'; +import { revalidatePath } from 'next/cache'; +import { redirect } from 'next/navigation'; + +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client'; import { LeaveTeamAccountSchema } from '../../schema/leave-team-account.schema'; -import { LeaveAccountService } from '../services/leave-account.service'; +import { LeaveTeamAccountService } from '../services/leave-team-account.service'; export async function leaveTeamAccountAction(formData: FormData) { const body = Object.fromEntries(formData.entries()); const params = LeaveTeamAccountSchema.parse(body); - const service = new LeaveAccountService(getSupabaseServerActionClient()); + const client = getSupabaseServerActionClient(); - await service.leaveTeamAccount(params); + const auth = await requireUser(client); - return { success: true }; + if (auth.error) { + throw new Error('Authentication required'); + } + + const service = new LeaveTeamAccountService( + getSupabaseServerActionClient({ admin: true }), + ); + + await service.leaveTeamAccount({ + accountId: params.accountId, + userId: auth.data.id, + }); + + revalidatePath('/home/[account]', 'layout'); + + return redirect('/home'); } diff --git a/packages/features/team-accounts/src/server/actions/team-invitations-server-actions.ts b/packages/features/team-accounts/src/server/actions/team-invitations-server-actions.ts index d06c4edbe..ba71e55f0 100644 --- a/packages/features/team-accounts/src/server/actions/team-invitations-server-actions.ts +++ b/packages/features/team-accounts/src/server/actions/team-invitations-server-actions.ts @@ -8,7 +8,7 @@ import { SupabaseClient } from '@supabase/supabase-js'; import { z } from 'zod'; import { Database } from '@kit/supabase/database'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client'; import { AcceptInvitationSchema } from '../../schema/accept-invitation.schema'; @@ -94,7 +94,7 @@ export async function acceptInvitationAction(data: FormData) { Object.fromEntries(data), ); - const { user } = await assertSession(client); + const user = await assertSession(client); const service = new AccountInvitationsService(client); @@ -123,7 +123,7 @@ export async function renewInvitationAction(params: { invitationId: number }) { } async function assertSession(client: SupabaseClient) { - const { error, data } = await requireAuth(client); + const { error, data } = await requireUser(client); if (error) { throw new Error(`Authentication required`); diff --git a/packages/features/team-accounts/src/server/services/account-invitations.service.ts b/packages/features/team-accounts/src/server/services/account-invitations.service.ts index 765dd8a78..128179218 100644 --- a/packages/features/team-accounts/src/server/services/account-invitations.service.ts +++ b/packages/features/team-accounts/src/server/services/account-invitations.service.ts @@ -7,7 +7,7 @@ import { z } from 'zod'; import { Mailer } from '@kit/mailers'; import { Logger } from '@kit/shared/logger'; import { Database } from '@kit/supabase/database'; -import { requireAuth } from '@kit/supabase/require-auth'; +import { requireUser } from '@kit/supabase/require-user'; import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema'; import { InviteMembersSchema } from '../../schema/invite-members.schema'; @@ -102,8 +102,7 @@ export class AccountInvitationsService { ); const mailer = new Mailer(); - - const { user } = await this.getUser(); + const user = await this.getUser(); const accountResponse = await this.client .from('accounts') @@ -258,7 +257,7 @@ export class AccountInvitationsService { } private async getUser() { - const { data, error } = await requireAuth(this.client); + const { data, error } = await requireUser(this.client); if (error ?? !data) { throw new Error('Authentication required'); diff --git a/packages/features/team-accounts/src/server/services/leave-account.service.ts b/packages/features/team-accounts/src/server/services/leave-account.service.ts deleted file mode 100644 index 0ce694485..000000000 --- a/packages/features/team-accounts/src/server/services/leave-account.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { SupabaseClient } from '@supabase/supabase-js'; - -import 'server-only'; -import { z } from 'zod'; - -import { Database } from '@kit/supabase/database'; - -import { LeaveTeamAccountSchema } from '../../schema/leave-team-account.schema'; - -export class LeaveAccountService { - constructor(private readonly client: SupabaseClient) {} - - async leaveTeamAccount(params: z.infer) { - await Promise.resolve(); - - console.log(params); - // TODO - // implement this method - } -} diff --git a/packages/features/team-accounts/src/server/services/leave-team-account.service.ts b/packages/features/team-accounts/src/server/services/leave-team-account.service.ts new file mode 100644 index 000000000..eaa34d3e5 --- /dev/null +++ b/packages/features/team-accounts/src/server/services/leave-team-account.service.ts @@ -0,0 +1,31 @@ +import { SupabaseClient } from '@supabase/supabase-js'; + +import 'server-only'; +import { z } from 'zod'; + +import { Database } from '@kit/supabase/database'; + +const Schema = z.object({ + accountId: z.string(), + userId: z.string(), +}); + +export class LeaveTeamAccountService { + constructor(private readonly adminClient: SupabaseClient) {} + + async leaveTeamAccount(params: z.infer) { + const { accountId, userId } = Schema.parse(params); + + const { error } = await this.adminClient + .from('accounts_memberships') + .delete() + .match({ + account_id: accountId, + user_id: userId, + }); + + if (error) { + throw error; + } + } +} diff --git a/packages/stripe/src/services/stripe-webhook-handler.service.ts b/packages/stripe/src/services/stripe-webhook-handler.service.ts index 22b3aa8b1..19d867986 100644 --- a/packages/stripe/src/services/stripe-webhook-handler.service.ts +++ b/packages/stripe/src/services/stripe-webhook-handler.service.ts @@ -195,7 +195,7 @@ export class StripeWebhookHandlerService cancel_at_period_end: subscription.cancel_at_period_end ?? false, interval: interval as string, currency: (price as Stripe.Price).currency, - product_id: (price as Stripe.Price).product, + product_id: (price as Stripe.Price).product as string, variant_id: priceId, interval_count: price?.recurring?.interval_count ?? 1, period_starts_at: getISOString(subscription.current_period_start), diff --git a/packages/supabase/package.json b/packages/supabase/package.json index 7fac9a8be..93a3ac7cc 100644 --- a/packages/supabase/package.json +++ b/packages/supabase/package.json @@ -17,7 +17,7 @@ "./server-component-client": "./src/clients/server-component.client.ts", "./browser-client": "./src/clients/browser.client.ts", "./check-requires-mfa": "./src/check-requires-mfa.ts", - "./require-auth": "./src/require-auth.ts", + "./require-user": "./src/require-user.ts", "./hooks/*": "./src/hooks/*.ts", "./components/*": "./src/components/*.tsx", "./database": "./src/database.types.ts" diff --git a/packages/supabase/src/require-auth.ts b/packages/supabase/src/require-user.ts similarity index 70% rename from packages/supabase/src/require-auth.ts rename to packages/supabase/src/require-user.ts index 152f6fa41..8a2ced264 100644 --- a/packages/supabase/src/require-auth.ts +++ b/packages/supabase/src/require-user.ts @@ -1,4 +1,4 @@ -import type { Session, SupabaseClient } from '@supabase/supabase-js'; +import type { SupabaseClient, User } from '@supabase/supabase-js'; import { z } from 'zod'; @@ -15,18 +15,14 @@ const SIGN_IN_PATH = z .parse(process.env.SIGN_IN_PATH); /** - * @name requireAuth + * @name requireUser * @description Require a session to be present in the request * @param client - * @param verifyFromServer */ -export async function requireAuth( - client: SupabaseClient, - verifyFromServer = true, -): Promise< +export async function requireUser(client: SupabaseClient): Promise< | { error: null; - data: Session; + data: User; } | ( | { @@ -41,9 +37,9 @@ export async function requireAuth( } ) > { - const { data, error } = await client.auth.getSession(); + const { data, error } = await client.auth.getUser(); - if (!data.session || error) { + if (!data.user || error) { return { data: null, error: new AuthenticationError(), @@ -63,21 +59,9 @@ export async function requireAuth( }; } - if (verifyFromServer) { - const { data: user, error } = await client.auth.getUser(); - - if (!user || error) { - return { - data: null, - error: new AuthenticationError(), - redirectTo: SIGN_IN_PATH, - }; - } - } - return { error: null, - data: data.session, + data: data.user, }; } diff --git a/packages/ui/src/makerkit/mdx/mdx-renderer.tsx b/packages/ui/src/makerkit/mdx/mdx-renderer.tsx index 9375555d8..9540fb302 100644 --- a/packages/ui/src/makerkit/mdx/mdx-renderer.tsx +++ b/packages/ui/src/makerkit/mdx/mdx-renderer.tsx @@ -2,7 +2,7 @@ import type { MDXComponents } from 'mdx/types'; import { getMDXComponent } from 'next-contentlayer/hooks'; import Components from './mdx-components'; -// @ts-expect-error: weird typescript error with css modules +// @ts-ignore: ignore weird error import styles from './mdx-renderer.module.css'; export function Mdx({