Refactor admin dashboard loader and update translations

The admin-dashboard.loader file was refactored to use a newly created AdminDashboardService. This service encapsulates the logic for fetching dashboard data. Translations related to account settings, privacy policy, terms of service, and cookie policy were updated for better readability. Changes also include minor reorganizing of code files for clearer structure.
This commit is contained in:
giancarlo
2024-04-22 20:30:21 +08:00
parent 8c5b0496da
commit 8e1d7ad1f5
18 changed files with 120 additions and 68 deletions

View File

@@ -18,13 +18,8 @@ function UserHomePage() {
return (
<>
<UserAccountHeader
title={<Trans i18nKey={'common:homeTabLabel'} defaults={'Home'} />}
description={
<Trans
i18nKey={'common:homeTabDescription'}
defaults={'Welcome to your Home Page'}
/>
}
title={<Trans i18nKey={'common:homeTabLabel'} />}
description={<Trans i18nKey={'common:homeTabDescription'} />}
/>
<PageBody></PageBody>

View File

@@ -7,8 +7,8 @@ function UserSettingsLayout(props: React.PropsWithChildren) {
return (
<>
<UserAccountHeader
title={<Trans i18nKey={'common:yourAccountTabLabel'} />}
description={'Manage your account settings'}
title={<Trans i18nKey={'account:accountTabLabel'} />}
description={<Trans i18nKey={'account:accountTabDescription'} />}
/>
{props.children}

View File

@@ -18,7 +18,7 @@ async function CookiePolicyPage() {
<div className={'container mx-auto'}>
<SitePageHeader
title={t(`marketing:cookiePolicy`)}
subtitle={`This is the cookie policy page. It's a great place to put information about the cookies your site uses.`}
subtitle={t(`marketing:cookiePolicyDescription`)}
/>
</div>
</div>

View File

@@ -16,7 +16,10 @@ async function PrivacyPolicyPage() {
return (
<div className={'mt-8'}>
<div className={'container mx-auto'}>
<SitePageHeader title={t('marketing.privacyPolicy')} subtitle={``} />
<SitePageHeader
title={t('marketing:privacyPolicy')}
subtitle={t('marketing:privacyPolicyDescription')}
/>
</div>
</div>
);

View File

@@ -16,7 +16,10 @@ async function TermsOfServicePage() {
return (
<div className={'mt-8'}>
<div className={'container mx-auto'}>
<SitePageHeader title={t(`marketing:termsOfService`)} subtitle={``} />
<SitePageHeader
title={t(`marketing:termsOfService`)}
subtitle={t(`marketing:termsOfServiceDescription`)}
/>
</div>
</div>
);

View File

@@ -62,7 +62,11 @@ async function BlogPost({ params }: { params: { slug: string } }) {
notFound();
}
return <Post post={post} content={post.content} />;
return (
<div className={'container'}>
<Post post={post} content={post.content} />;
</div>
);
}
export default withI18n(BlogPost);

View File

@@ -15,7 +15,7 @@ const routes = [
end: true,
},
{
label: 'common:yourAccountTabLabel',
label: 'account:accountTabLabel',
path: pathsConfig.app.personalAccountSettings,
Icon: <User className={iconClasses} />,
},

View File

@@ -1,6 +1,6 @@
{
"generalTab": "My Details",
"generalTabSubheading": "Manage your profile details",
"accountTabLabel": "Account Settings",
"accountTabDescription": "Manage your account settings",
"emailTab": "Email",
"emailTabTabSubheading": "Update your email address",
"passwordTab": "Password",

View File

@@ -5,7 +5,6 @@
"membersTabDescription": "Here you can manage the members of your team.",
"billingTabLabel": "Billing",
"billingTabDescription": "Manage your billing and subscription",
"yourAccountTabLabel": "Account Settings",
"dashboardTabLabel": "Dashboard",
"settingsTabLabel": "Settings",
"profileSettingsTabLabel": "Profile",

View File

@@ -18,6 +18,11 @@
"product": "Product",
"legal": "Legal",
"termsOfService": "Terms of Service",
"termsOfServiceDescription": "Our terms and conditions",
"cookiePolicy": "Cookie Policy",
"privacyPolicy": "Privacy Policy"
"cookiePolicyDescription": "Our cookie policy and how we use them",
"privacyPolicy": "Privacy Policy",
"privacyPolicyDescription": "Our privacy policy and how we use your data"
}

View File

@@ -21,6 +21,7 @@
"lucide-react": "^0.368.0",
"next": "^14.1.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.2",
"zod": "^3.22.4"
},
@@ -42,6 +43,7 @@
"lucide-react": "^0.372.0",
"next": "14.3.0-canary.7",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.51.3",
"zod": "^3.23.0"
},

View File

@@ -2,7 +2,7 @@ import { notFound } from 'next/navigation';
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
import { isSuperAdmin } from '../lib/server/is-super-admin';
import { isSuperAdmin } from '../lib/server/utils/is-super-admin';
type LayoutOrPageComponent<Params> = React.ComponentType<Params>;

View File

@@ -1 +1 @@
export * from './lib/server/is-super-admin';
export * from './lib/server/utils/is-super-admin';

View File

@@ -6,7 +6,6 @@ import { redirect } from 'next/navigation';
import { enhanceAction } from '@kit/next/actions';
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
import { adminAction } from './admin-action';
import {
BanUserSchema,
DeleteAccountSchema,
@@ -16,6 +15,7 @@ import {
} from './schema/admin-actions.schema';
import { AdminAccountsService } from './services/admin-accounts.service';
import { AdminAuthUserService } from './services/admin-auth-user.service';
import { adminAction } from './utils/admin-action';
/**
* @name banUserAction

View File

@@ -1,58 +1,19 @@
import 'server-only';
import { cache } from 'react';
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
import { AdminDashboardService } from '../services/admin-dashboard.service';
/**
* @name loadAdminDashboard
* @description Load the admin dashboard data.
* @param params
*/
export async function loadAdminDashboard(params?: {
count: 'exact' | 'estimated' | 'planned';
}) {
const count = params?.count ?? 'estimated';
export const loadAdminDashboard = cache(() => {
const client = getSupabaseServerComponentClient({ admin: true });
const service = new AdminDashboardService(client);
const selectParams = {
count,
head: true,
};
const subscriptionsPromise = client
.from('subscriptions')
.select('*', selectParams)
.eq('status', 'active')
.then((response) => response.count);
const trialsPromise = client
.from('subscriptions')
.select('*', selectParams)
.eq('status', 'trialing')
.then((response) => response.count);
const accountsPromise = client
.from('accounts')
.select('*', selectParams)
.eq('is_personal_account', true)
.then((response) => response.count);
const teamAccountsPromise = client
.from('accounts')
.select('*', selectParams)
.eq('is_personal_account', false)
.then((response) => response.count);
const [subscriptions, trials, accounts, teamAccounts] = await Promise.all([
subscriptionsPromise,
trialsPromise,
accountsPromise,
teamAccountsPromise,
]);
return {
subscriptions,
trials,
accounts,
teamAccounts,
};
}
return service.getDashboardData();
});

View File

@@ -0,0 +1,80 @@
import { SupabaseClient } from '@supabase/supabase-js';
import { Database } from '@kit/supabase/database';
export class AdminDashboardService {
constructor(private readonly client: SupabaseClient<Database>) {}
async getDashboardData(
{ count }: { count: 'exact' | 'estimated' | 'planned' } = {
count: 'estimated',
},
) {
const selectParams = {
count,
head: true,
};
const subscriptionsPromise = this.client
.from('subscriptions')
.select('*', selectParams)
.eq('status', 'active')
.then((response) => {
if (response.error) {
throw new Error(response.error.message);
}
return response.count;
});
const trialsPromise = this.client
.from('subscriptions')
.select('*', selectParams)
.eq('status', 'trialing')
.then((response) => {
if (response.error) {
throw new Error(response.error.message);
}
return response.count;
});
const accountsPromise = this.client
.from('accounts')
.select('*', selectParams)
.eq('is_personal_account', true)
.then((response) => {
if (response.error) {
throw new Error(response.error.message);
}
return response.count;
});
const teamAccountsPromise = this.client
.from('accounts')
.select('*', selectParams)
.eq('is_personal_account', false)
.then((response) => {
if (response.error) {
throw new Error(response.error.message);
}
return response.count;
});
const [subscriptions, trials, accounts, teamAccounts] = await Promise.all([
subscriptionsPromise,
trialsPromise,
accountsPromise,
teamAccountsPromise,
]);
return {
subscriptions,
trials,
accounts,
teamAccounts,
};
}
}