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