diff --git a/src/actions/get-users.ts b/src/actions/get-users.ts
index afd68c7..67d3005 100644
--- a/src/actions/get-users.ts
+++ b/src/actions/get-users.ts
@@ -2,6 +2,7 @@
import { getDb } from '@/db';
import { user } from '@/db/schema';
+import { isDemoWebsite } from '@/lib/demo';
import { asc, desc, ilike, or, sql } from 'drizzle-orm';
import { createSafeActionClient } from 'next-safe-action';
import { z } from 'zod';
@@ -75,7 +76,8 @@ export const getUsersAction = actionClient
]);
// hide user data in demo website
- if (process.env.NEXT_PUBLIC_DEMO_WEBSITE === 'true') {
+ const isDemo = isDemoWebsite();
+ if (isDemo) {
items = items.map((item) => ({
...item,
name: 'Demo User',
diff --git a/src/app/[locale]/(protected)/admin/users/layout.tsx b/src/app/[locale]/(protected)/admin/users/layout.tsx
index 1bd220c..f3cffb8 100644
--- a/src/app/[locale]/(protected)/admin/users/layout.tsx
+++ b/src/app/[locale]/(protected)/admin/users/layout.tsx
@@ -1,4 +1,5 @@
import { DashboardHeader } from '@/components/dashboard/dashboard-header';
+import { isDemoWebsite } from '@/lib/demo';
import { getSession } from '@/lib/server';
import { getTranslations } from 'next-intl/server';
import { notFound } from 'next/navigation';
@@ -9,7 +10,7 @@ interface UsersLayoutProps {
export default async function UsersLayout({ children }: UsersLayoutProps) {
// if is demo website, allow user to access admin and user pages, but data is fake
- const isDemo = process.env.NEXT_PUBLIC_DEMO_WEBSITE === 'true';
+ const isDemo = isDemoWebsite();
// Check if user is admin
const session = await getSession();
if (!session || (session.user.role !== 'admin' && !isDemo)) {
diff --git a/src/app/[locale]/(protected)/settings/profile/page.tsx b/src/app/[locale]/(protected)/settings/profile/page.tsx
index 3b14e97..6776077 100644
--- a/src/app/[locale]/(protected)/settings/profile/page.tsx
+++ b/src/app/[locale]/(protected)/settings/profile/page.tsx
@@ -1,20 +1,15 @@
import { UpdateAvatarCard } from '@/components/settings/profile/update-avatar-card';
import { UpdateNameCard } from '@/components/settings/profile/update-name-card';
-import { websiteConfig } from '@/config/website';
export default function ProfilePage() {
- const enableUpdateAvatar = websiteConfig.features.enableUpdateAvatar;
-
return (
- {enableUpdateAvatar && (
-
-
-
- )}
+
+
+
);
}
diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts
index 8e98301..4b17e75 100644
--- a/src/app/sitemap.ts
+++ b/src/app/sitemap.ts
@@ -14,8 +14,6 @@ type Href = Parameters[0]['href'];
const staticRoutes = [
'/',
'/pricing',
- '/blog',
- '/docs',
'/about',
'/contact',
'/waitlist',
@@ -25,6 +23,8 @@ const staticRoutes = [
'/cookie',
'/auth/login',
'/auth/register',
+ ...(websiteConfig.blog.enable ? ['/blog'] : []),
+ ...(websiteConfig.docs.enable ? ['/docs'] : []),
];
/**
@@ -48,101 +48,106 @@ export default async function sitemap(): Promise {
})
);
- // add categories
- sitemapList.push(
- ...categorySource.getPages().flatMap((category) =>
- routing.locales.map((locale) => ({
- url: getUrl(`/blog/category/${category.slugs[0]}`, locale),
- lastModified: new Date(),
- priority: 0.8,
- changeFrequency: 'weekly' as const,
- }))
- )
- );
-
- // add paginated blog list pages
- routing.locales.forEach((locale) => {
- const posts = blogSource
- .getPages(locale)
- .filter((post) => post.data.published);
- const totalPages = Math.max(
- 1,
- Math.ceil(posts.length / websiteConfig.blog.paginationSize)
+ // add blog related routes if enabled
+ if (websiteConfig.blog.enable) {
+ // add categories
+ sitemapList.push(
+ ...categorySource.getPages().flatMap((category) =>
+ routing.locales.map((locale) => ({
+ url: getUrl(`/blog/category/${category.slugs[0]}`, locale),
+ lastModified: new Date(),
+ priority: 0.8,
+ changeFrequency: 'weekly' as const,
+ }))
+ )
);
- // /blog/page/[page] (from 2)
- for (let page = 2; page <= totalPages; page++) {
- sitemapList.push({
- url: getUrl(`/blog/page/${page}`, locale),
- lastModified: new Date(),
- priority: 0.8,
- changeFrequency: 'weekly' as const,
- });
- }
- });
- // add paginated category pages
- routing.locales.forEach((locale) => {
- const localeCategories = categorySource.getPages(locale);
- localeCategories.forEach((category) => {
- // posts in this category and locale
- const postsInCategory = blogSource
+ // add paginated blog list pages
+ routing.locales.forEach((locale) => {
+ const posts = blogSource
.getPages(locale)
- .filter((post) => post.data.published)
- .filter((post) =>
- post.data.categories.some((cat) => cat === category.slugs[0])
- );
+ .filter((post) => post.data.published);
const totalPages = Math.max(
1,
- Math.ceil(postsInCategory.length / websiteConfig.blog.paginationSize)
+ Math.ceil(posts.length / websiteConfig.blog.paginationSize)
);
- // /blog/category/[slug] (first page)
- sitemapList.push({
- url: getUrl(`/blog/category/${category.slugs[0]}`, locale),
- lastModified: new Date(),
- priority: 0.8,
- changeFrequency: 'weekly' as const,
- });
- // /blog/category/[slug]/page/[page] (from 2)
+ // /blog/page/[page] (from 2)
for (let page = 2; page <= totalPages; page++) {
sitemapList.push({
- url: getUrl(
- `/blog/category/${category.slugs[0]}/page/${page}`,
- locale
- ),
+ url: getUrl(`/blog/page/${page}`, locale),
lastModified: new Date(),
priority: 0.8,
changeFrequency: 'weekly' as const,
});
}
});
- });
- // add posts (single post pages)
- sitemapList.push(
- ...blogSource.getPages().flatMap((post) =>
- routing.locales
- .filter((locale) => post.locale === locale)
- .map((locale) => ({
- url: getUrl(`/blog/${post.slugs.join('/')}`, locale),
+ // add paginated category pages
+ routing.locales.forEach((locale) => {
+ const localeCategories = categorySource.getPages(locale);
+ localeCategories.forEach((category) => {
+ // posts in this category and locale
+ const postsInCategory = blogSource
+ .getPages(locale)
+ .filter((post) => post.data.published)
+ .filter((post) =>
+ post.data.categories.some((cat) => cat === category.slugs[0])
+ );
+ const totalPages = Math.max(
+ 1,
+ Math.ceil(postsInCategory.length / websiteConfig.blog.paginationSize)
+ );
+ // /blog/category/[slug] (first page)
+ sitemapList.push({
+ url: getUrl(`/blog/category/${category.slugs[0]}`, locale),
+ lastModified: new Date(),
+ priority: 0.8,
+ changeFrequency: 'weekly' as const,
+ });
+ // /blog/category/[slug]/page/[page] (from 2)
+ for (let page = 2; page <= totalPages; page++) {
+ sitemapList.push({
+ url: getUrl(
+ `/blog/category/${category.slugs[0]}/page/${page}`,
+ locale
+ ),
+ lastModified: new Date(),
+ priority: 0.8,
+ changeFrequency: 'weekly' as const,
+ });
+ }
+ });
+ });
+
+ // add posts (single post pages)
+ sitemapList.push(
+ ...blogSource.getPages().flatMap((post) =>
+ routing.locales
+ .filter((locale) => post.locale === locale)
+ .map((locale) => ({
+ url: getUrl(`/blog/${post.slugs.join('/')}`, locale),
+ lastModified: new Date(),
+ priority: 0.8,
+ changeFrequency: 'weekly' as const,
+ }))
+ )
+ );
+ }
+
+ // add docs related routes if enabled
+ if (websiteConfig.docs.enable) {
+ const docsParams = source.generateParams();
+ sitemapList.push(
+ ...docsParams.flatMap((param) =>
+ routing.locales.map((locale) => ({
+ url: getUrl(`/docs/${param.slug.join('/')}`, locale),
lastModified: new Date(),
priority: 0.8,
changeFrequency: 'weekly' as const,
}))
- )
- );
-
- // add docs
- const docsParams = source.generateParams();
- sitemapList.push(
- ...docsParams.flatMap((param) =>
- routing.locales.map((locale) => ({
- url: getUrl(`/docs/${param.slug.join('/')}`, locale),
- lastModified: new Date(),
- priority: 0.8,
- changeFrequency: 'weekly' as const,
- }))
- )
- );
+ )
+ );
+ }
return sitemapList;
}
diff --git a/src/components/admin/user-detail-viewer.tsx b/src/components/admin/user-detail-viewer.tsx
index 392ccf9..3936f58 100644
--- a/src/components/admin/user-detail-viewer.tsx
+++ b/src/components/admin/user-detail-viewer.tsx
@@ -23,6 +23,7 @@ import { Textarea } from '@/components/ui/textarea';
import { useIsMobile } from '@/hooks/use-mobile';
import { authClient } from '@/lib/auth-client';
import type { User } from '@/lib/auth-types';
+import { isDemoWebsite } from '@/lib/demo';
import { formatDate } from '@/lib/formatter';
import { getStripeDashboardCustomerUrl } from '@/lib/urls/urls';
import { cn } from '@/lib/utils';
@@ -53,7 +54,7 @@ export function UserDetailViewer({ user }: UserDetailViewerProps) {
const triggerRefresh = useUsersStore((state) => state.triggerRefresh);
// show fake data in demo website
- const isDemo = process.env.NEXT_PUBLIC_DEMO_WEBSITE === 'true';
+ const isDemo = isDemoWebsite();
const handleBan = async () => {
if (!banReason) {
diff --git a/src/components/admin/users-table.tsx b/src/components/admin/users-table.tsx
index 7fd0bc3..f9f54f6 100644
--- a/src/components/admin/users-table.tsx
+++ b/src/components/admin/users-table.tsx
@@ -27,6 +27,7 @@ import {
TableRow,
} from '@/components/ui/table';
import type { User } from '@/lib/auth-types';
+import { isDemoWebsite } from '@/lib/demo';
import { formatDate } from '@/lib/formatter';
import { getStripeDashboardCustomerUrl } from '@/lib/urls/urls';
import { IconCaretDownFilled, IconCaretUpFilled } from '@tabler/icons-react';
@@ -152,7 +153,7 @@ export function UsersTable({
const [columnVisibility, setColumnVisibility] = useState({});
// show fake data in demo website
- const isDemo = process.env.NEXT_PUBLIC_DEMO_WEBSITE === 'true';
+ const isDemo = isDemoWebsite();
// Map column IDs to translation keys
const columnIdToTranslationKey = {
diff --git a/src/components/dashboard/dashboard-header.tsx b/src/components/dashboard/dashboard-header.tsx
index cb7d855..5a07451 100644
--- a/src/components/dashboard/dashboard-header.tsx
+++ b/src/components/dashboard/dashboard-header.tsx
@@ -7,6 +7,7 @@ import {
} from '@/components/ui/breadcrumb';
import { Separator } from '@/components/ui/separator';
import { SidebarTrigger } from '@/components/ui/sidebar';
+import { isDemoWebsite } from '@/lib/demo';
import React, { type ReactNode } from 'react';
import { CreditsBalanceButton } from '../layout/credits-balance-button';
import LocaleSwitcher from '../layout/locale-switcher';
@@ -30,8 +31,7 @@ export function DashboardHeader({
breadcrumbs,
actions,
}: DashboardHeaderProps) {
- // if is demo website, allow user to access admin and user pages, but data is fake
- const isDemo = process.env.NEXT_PUBLIC_DEMO_WEBSITE === 'true';
+ const isDemo = isDemoWebsite();
return (