diff --git a/apps/web/app/(dashboard)/home/(user)/page.tsx b/apps/web/app/(dashboard)/home/(user)/page.tsx
index 73cd8c7e9..d8a24da12 100644
--- a/apps/web/app/(dashboard)/home/(user)/page.tsx
+++ b/apps/web/app/(dashboard)/home/(user)/page.tsx
@@ -18,13 +18,8 @@ function UserHomePage() {
return (
<>
}
- description={
-
- }
+ title={}
+ description={}
/>
diff --git a/apps/web/app/(dashboard)/home/(user)/settings/layout.tsx b/apps/web/app/(dashboard)/home/(user)/settings/layout.tsx
index ccdce4cd4..8abb26b56 100644
--- a/apps/web/app/(dashboard)/home/(user)/settings/layout.tsx
+++ b/apps/web/app/(dashboard)/home/(user)/settings/layout.tsx
@@ -7,8 +7,8 @@ function UserSettingsLayout(props: React.PropsWithChildren) {
return (
<>
}
- description={'Manage your account settings'}
+ title={}
+ description={}
/>
{props.children}
diff --git a/apps/web/app/(marketing)/(legal)/cookie-policy/page.tsx b/apps/web/app/(marketing)/(legal)/cookie-policy/page.tsx
index a59d6bfcd..6638a51f1 100644
--- a/apps/web/app/(marketing)/(legal)/cookie-policy/page.tsx
+++ b/apps/web/app/(marketing)/(legal)/cookie-policy/page.tsx
@@ -18,7 +18,7 @@ async function CookiePolicyPage() {
diff --git a/apps/web/app/(marketing)/(legal)/privacy-policy/page.tsx b/apps/web/app/(marketing)/(legal)/privacy-policy/page.tsx
index b580aa5fa..5bdab2ac4 100644
--- a/apps/web/app/(marketing)/(legal)/privacy-policy/page.tsx
+++ b/apps/web/app/(marketing)/(legal)/privacy-policy/page.tsx
@@ -16,7 +16,10 @@ async function PrivacyPolicyPage() {
return (
);
diff --git a/apps/web/app/(marketing)/(legal)/terms-of-service/page.tsx b/apps/web/app/(marketing)/(legal)/terms-of-service/page.tsx
index 1c1607bb8..fa5d4c4d0 100644
--- a/apps/web/app/(marketing)/(legal)/terms-of-service/page.tsx
+++ b/apps/web/app/(marketing)/(legal)/terms-of-service/page.tsx
@@ -16,7 +16,10 @@ async function TermsOfServicePage() {
return (
);
diff --git a/apps/web/app/(marketing)/blog/[slug]/page.tsx b/apps/web/app/(marketing)/blog/[slug]/page.tsx
index 215f9e3e6..6b4553207 100644
--- a/apps/web/app/(marketing)/blog/[slug]/page.tsx
+++ b/apps/web/app/(marketing)/blog/[slug]/page.tsx
@@ -62,7 +62,11 @@ async function BlogPost({ params }: { params: { slug: string } }) {
notFound();
}
- return ;
+ return (
+
+ );
}
export default withI18n(BlogPost);
diff --git a/apps/web/config/personal-account-sidebar.config.tsx b/apps/web/config/personal-account-sidebar.config.tsx
index f7df14c21..738685247 100644
--- a/apps/web/config/personal-account-sidebar.config.tsx
+++ b/apps/web/config/personal-account-sidebar.config.tsx
@@ -15,7 +15,7 @@ const routes = [
end: true,
},
{
- label: 'common:yourAccountTabLabel',
+ label: 'account:accountTabLabel',
path: pathsConfig.app.personalAccountSettings,
Icon: ,
},
diff --git a/apps/web/public/locales/en/account.json b/apps/web/public/locales/en/account.json
index fe1809d28..0ae4babbe 100644
--- a/apps/web/public/locales/en/account.json
+++ b/apps/web/public/locales/en/account.json
@@ -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",
diff --git a/apps/web/public/locales/en/common.json b/apps/web/public/locales/en/common.json
index 139ef16fb..ccf56423d 100644
--- a/apps/web/public/locales/en/common.json
+++ b/apps/web/public/locales/en/common.json
@@ -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",
diff --git a/apps/web/public/locales/en/marketing.json b/apps/web/public/locales/en/marketing.json
index fd64e4418..bf580b210 100644
--- a/apps/web/public/locales/en/marketing.json
+++ b/apps/web/public/locales/en/marketing.json
@@ -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"
}
+
+
diff --git a/packages/features/admin/package.json b/packages/features/admin/package.json
index 17b86060c..3b05447ec 100644
--- a/packages/features/admin/package.json
+++ b/packages/features/admin/package.json
@@ -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"
},
diff --git a/packages/features/admin/src/components/admin-guard.tsx b/packages/features/admin/src/components/admin-guard.tsx
index 1a26c8cdd..0bb8091e1 100644
--- a/packages/features/admin/src/components/admin-guard.tsx
+++ b/packages/features/admin/src/components/admin-guard.tsx
@@ -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 = React.ComponentType;
diff --git a/packages/features/admin/src/index.ts b/packages/features/admin/src/index.ts
index a944278f0..b6bada708 100644
--- a/packages/features/admin/src/index.ts
+++ b/packages/features/admin/src/index.ts
@@ -1 +1 @@
-export * from './lib/server/is-super-admin';
+export * from './lib/server/utils/is-super-admin';
diff --git a/packages/features/admin/src/lib/server/admin-server-actions.ts b/packages/features/admin/src/lib/server/admin-server-actions.ts
index ec5dab20f..79683d9e8 100644
--- a/packages/features/admin/src/lib/server/admin-server-actions.ts
+++ b/packages/features/admin/src/lib/server/admin-server-actions.ts
@@ -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
diff --git a/packages/features/admin/src/lib/server/loaders/admin-dashboard.loader.ts b/packages/features/admin/src/lib/server/loaders/admin-dashboard.loader.ts
index 5bb7fa277..55d2b0510 100644
--- a/packages/features/admin/src/lib/server/loaders/admin-dashboard.loader.ts
+++ b/packages/features/admin/src/lib/server/loaders/admin-dashboard.loader.ts
@@ -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();
+});
diff --git a/packages/features/admin/src/lib/server/services/admin-dashboard.service.ts b/packages/features/admin/src/lib/server/services/admin-dashboard.service.ts
new file mode 100644
index 000000000..0ceaf7987
--- /dev/null
+++ b/packages/features/admin/src/lib/server/services/admin-dashboard.service.ts
@@ -0,0 +1,80 @@
+import { SupabaseClient } from '@supabase/supabase-js';
+
+import { Database } from '@kit/supabase/database';
+
+export class AdminDashboardService {
+ constructor(private readonly client: SupabaseClient) {}
+
+ 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,
+ };
+ }
+}
diff --git a/packages/features/admin/src/lib/server/admin-action.ts b/packages/features/admin/src/lib/server/utils/admin-action.ts
similarity index 100%
rename from packages/features/admin/src/lib/server/admin-action.ts
rename to packages/features/admin/src/lib/server/utils/admin-action.ts
diff --git a/packages/features/admin/src/lib/server/is-super-admin.ts b/packages/features/admin/src/lib/server/utils/is-super-admin.ts
similarity index 100%
rename from packages/features/admin/src/lib/server/is-super-admin.ts
rename to packages/features/admin/src/lib/server/utils/is-super-admin.ts