Refactored classes according to new convention
This commit is contained in:
@@ -6,7 +6,7 @@ import { enhanceAction } from '@kit/next/actions';
|
||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||
|
||||
import { PersonalAccountCheckoutSchema } from '../schema/personal-account-checkout.schema';
|
||||
import { UserBillingService } from './user-billing.service';
|
||||
import { createUserBillingService } from './user-billing.service';
|
||||
|
||||
/**
|
||||
* @name createPersonalAccountCheckoutSession
|
||||
@@ -14,7 +14,8 @@ import { UserBillingService } from './user-billing.service';
|
||||
*/
|
||||
export const createPersonalAccountCheckoutSession = enhanceAction(
|
||||
async function (data) {
|
||||
const service = new UserBillingService(getSupabaseServerActionClient());
|
||||
const client = getSupabaseServerActionClient();
|
||||
const service = createUserBillingService(client);
|
||||
|
||||
return await service.createCheckoutSession(data);
|
||||
},
|
||||
@@ -24,10 +25,14 @@ export const createPersonalAccountCheckoutSession = enhanceAction(
|
||||
);
|
||||
|
||||
/**
|
||||
* @name createPersonalAccountBillingPortalSession
|
||||
* @description Creates a billing Portal session for a personal account
|
||||
*/
|
||||
export async function createPersonalAccountBillingPortalSession() {
|
||||
const service = new UserBillingService(getSupabaseServerActionClient());
|
||||
const client = getSupabaseServerActionClient();
|
||||
const service = createUserBillingService(client);
|
||||
|
||||
// get url to billing portal
|
||||
const url = await service.createBillingPortalSession();
|
||||
|
||||
return redirect(url);
|
||||
|
||||
@@ -17,7 +17,15 @@ import { Database } from '~/lib/database.types';
|
||||
|
||||
import { PersonalAccountCheckoutSchema } from '../schema/personal-account-checkout.schema';
|
||||
|
||||
export class UserBillingService {
|
||||
export function createUserBillingService(client: SupabaseClient<Database>) {
|
||||
return new UserBillingService(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name UserBillingService
|
||||
* @description Service for managing billing for personal accounts.
|
||||
*/
|
||||
class UserBillingService {
|
||||
private readonly namespace = 'billing.personal-account';
|
||||
|
||||
constructor(private readonly client: SupabaseClient<Database>) {}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
TeamBillingPortalSchema,
|
||||
TeamCheckoutSchema,
|
||||
} from '../schema/team-billing.schema';
|
||||
import { TeamBillingService } from './team-billing.service';
|
||||
import { createTeamBillingService } from './team-billing.service';
|
||||
|
||||
/**
|
||||
* @name createTeamAccountCheckoutSession
|
||||
@@ -21,7 +21,9 @@ export async function createTeamAccountCheckoutSession(
|
||||
params: z.infer<typeof TeamCheckoutSchema>,
|
||||
) {
|
||||
const data = TeamCheckoutSchema.parse(params);
|
||||
const service = new TeamBillingService(getSupabaseServerActionClient());
|
||||
|
||||
const client = getSupabaseServerActionClient();
|
||||
const service = createTeamBillingService(client);
|
||||
|
||||
return service.createCheckout(data);
|
||||
}
|
||||
@@ -33,7 +35,9 @@ export async function createTeamAccountCheckoutSession(
|
||||
*/
|
||||
export async function createBillingPortalSession(formData: FormData) {
|
||||
const params = TeamBillingPortalSchema.parse(Object.fromEntries(formData));
|
||||
const service = new TeamBillingService(getSupabaseServerActionClient());
|
||||
|
||||
const client = getSupabaseServerActionClient();
|
||||
const service = createTeamBillingService(client);
|
||||
|
||||
// get url to billing portal
|
||||
const url = await service.createBillingPortalSession(params);
|
||||
|
||||
@@ -18,7 +18,15 @@ import { Database } from '~/lib/database.types';
|
||||
|
||||
import { TeamCheckoutSchema } from '../schema/team-billing.schema';
|
||||
|
||||
export class TeamBillingService {
|
||||
export function createTeamBillingService(client: SupabaseClient<Database>) {
|
||||
return new TeamBillingService(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name TeamBillingService
|
||||
* @description Service for managing billing for team accounts.
|
||||
*/
|
||||
class TeamBillingService {
|
||||
private readonly namespace = 'billing.team-account';
|
||||
|
||||
constructor(private readonly client: SupabaseClient<Database>) {}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import 'server-only';
|
||||
|
||||
import { SupabaseClient } from '@supabase/supabase-js';
|
||||
|
||||
import { Database } from '~/lib/database.types';
|
||||
|
||||
import { loadTeamWorkspace } from '../../../_lib/server/team-account-workspace.loader';
|
||||
|
||||
/**
|
||||
* Load data for the members page
|
||||
* @param client
|
||||
* @param slug
|
||||
*/
|
||||
export async function loadMembersPageData(
|
||||
client: SupabaseClient<Database>,
|
||||
slug: string,
|
||||
) {
|
||||
return Promise.all([
|
||||
loadTeamWorkspace(slug),
|
||||
loadAccountMembers(client, slug),
|
||||
loadInvitations(client, slug),
|
||||
loadUser(client),
|
||||
canAddMember,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name canAddMember
|
||||
* @description Check if the current user can add a member to the account
|
||||
*
|
||||
* This needs additional logic to determine if the user can add a member to the account
|
||||
* Please implement the logic and return a boolean value
|
||||
*
|
||||
* The same check needs to be added when creating an invitation
|
||||
*
|
||||
*/
|
||||
async function canAddMember() {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
async function loadUser(client: SupabaseClient<Database>) {
|
||||
const { data, error } = await client.auth.getUser();
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data.user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load account members
|
||||
* @param client
|
||||
* @param account
|
||||
*/
|
||||
async function loadAccountMembers(
|
||||
client: SupabaseClient<Database>,
|
||||
account: string,
|
||||
) {
|
||||
const { data, error } = await client.rpc('get_account_members', {
|
||||
account_slug: account,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load account invitations
|
||||
* @param client
|
||||
* @param account
|
||||
*/
|
||||
async function loadInvitations(
|
||||
client: SupabaseClient<Database>,
|
||||
account: string,
|
||||
) {
|
||||
const { data, error } = await client.rpc('get_account_invitations', {
|
||||
account_slug: account,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data ?? [];
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import { SupabaseClient } from '@supabase/supabase-js';
|
||||
|
||||
import { PlusCircle } from 'lucide-react';
|
||||
|
||||
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
|
||||
@@ -20,12 +18,11 @@ import { If } from '@kit/ui/if';
|
||||
import { PageBody } from '@kit/ui/page';
|
||||
import { Trans } from '@kit/ui/trans';
|
||||
|
||||
import { Database } from '~/lib/database.types';
|
||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||
|
||||
import { AccountLayoutHeader } from '../_components/account-layout-header';
|
||||
import { loadTeamWorkspace } from '../_lib/server/team-account-workspace.loader';
|
||||
import { loadMembersPageData } from './_lib/server/members-page.loader';
|
||||
|
||||
interface Params {
|
||||
params: {
|
||||
@@ -33,57 +30,6 @@ interface Params {
|
||||
};
|
||||
}
|
||||
|
||||
async function loadUser(client: SupabaseClient<Database>) {
|
||||
const { data, error } = await client.auth.getUser();
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data.user;
|
||||
}
|
||||
|
||||
async function loadAccountMembers(
|
||||
client: SupabaseClient<Database>,
|
||||
account: string,
|
||||
) {
|
||||
const { data, error } = await client.rpc('get_account_members', {
|
||||
account_slug: account,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data ?? [];
|
||||
}
|
||||
|
||||
async function loadInvitations(
|
||||
client: SupabaseClient<Database>,
|
||||
account: string,
|
||||
) {
|
||||
const { data, error } = await client.rpc('get_account_invitations', {
|
||||
account_slug: account,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data ?? [];
|
||||
}
|
||||
|
||||
async function loadData(client: SupabaseClient<Database>, slug: string) {
|
||||
return Promise.all([
|
||||
loadTeamWorkspace(slug),
|
||||
loadAccountMembers(client, slug),
|
||||
loadInvitations(client, slug),
|
||||
loadUser(client),
|
||||
]);
|
||||
}
|
||||
|
||||
export const generateMetadata = async () => {
|
||||
const i18n = await createI18nServerInstance();
|
||||
const title = i18n.t('teams:members.pageTitle');
|
||||
@@ -96,10 +42,8 @@ export const generateMetadata = async () => {
|
||||
async function TeamAccountMembersPage({ params }: Params) {
|
||||
const client = getSupabaseServerComponentClient();
|
||||
|
||||
const [{ account }, members, invitations, user] = await loadData(
|
||||
client,
|
||||
params.account,
|
||||
);
|
||||
const [{ account }, members, invitations, user, canAddMember] =
|
||||
await loadMembersPageData(client, params.account);
|
||||
|
||||
const canManageRoles = account.permissions.includes('roles.manage');
|
||||
const canManageInvitations = account.permissions.includes('invites.manage');
|
||||
@@ -131,7 +75,7 @@ async function TeamAccountMembersPage({ params }: Params) {
|
||||
</CardDescription>
|
||||
</div>
|
||||
|
||||
<If condition={canManageInvitations}>
|
||||
<If condition={canManageInvitations && canAddMember}>
|
||||
<InviteMembersDialogContainer
|
||||
userRoleHierarchy={currentUserRoleHierarchy}
|
||||
accountId={account.id}
|
||||
|
||||
Reference in New Issue
Block a user