From 2db79a871a5c74bc5c82599020b7810cb17d9097 Mon Sep 17 00:00:00 2001 From: javayhu Date: Sun, 18 May 2025 16:55:37 +0800 Subject: [PATCH 01/25] chore: show discord widget in homepage only --- src/app/[locale]/(marketing)/(home)/page.tsx | 3 +++ src/app/[locale]/layout.tsx | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/[locale]/(marketing)/(home)/page.tsx b/src/app/[locale]/(marketing)/(home)/page.tsx index b33001a..88d79fd 100644 --- a/src/app/[locale]/(marketing)/(home)/page.tsx +++ b/src/app/[locale]/(marketing)/(home)/page.tsx @@ -11,6 +11,7 @@ import PricingSection from '@/components/blocks/pricing/pricing'; import StatsSection from '@/components/blocks/stats/stats'; import TestimonialsSection from '@/components/blocks/testimonials/testimonials'; import { NewsletterCard } from '@/components/newsletter/newsletter-card'; +import DiscordWidget from '@/components/shared/discord-widget'; import { constructMetadata } from '@/lib/metadata'; import { getUrlWithLocale } from '@/lib/urls/urls'; import type { Metadata } from 'next'; @@ -72,6 +73,8 @@ export default async function HomePage(props: HomePageProps) { + + ); diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index c13a808..0952441 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -15,7 +15,7 @@ import { Providers } from './providers'; import '@/styles/globals.css'; import { Analytics } from '@/analytics/analytics'; import { TailwindIndicator } from '@/components/layout/tailwind-indicator'; -import DiscordWidget from '@/components/shared/discord-widget'; + interface LocaleLayoutProps { children: ReactNode; params: Promise<{ locale: Locale }>; @@ -56,7 +56,6 @@ export default async function LocaleLayout({ {children} - From 044af8bf7496952bc609c134dcddff01f2eb72fa Mon Sep 17 00:00:00 2001 From: javayhu Date: Sun, 18 May 2025 17:36:30 +0800 Subject: [PATCH 02/25] chore: add mcp tool of context7 --- .cursor/mcp.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.cursor/mcp.json b/.cursor/mcp.json index c138370..cfd47ae 100644 --- a/.cursor/mcp.json +++ b/.cursor/mcp.json @@ -5,6 +5,10 @@ "args": [ "~/.console-ninja/mcp/" ] + }, + "context7": { + "command": "npx", + "args": ["-y", "@upstash/context7-mcp@latest"] } } } \ No newline at end of file From 28ad92e101ccc765700d05e71db4bd6eace25dcc Mon Sep 17 00:00:00 2001 From: javayhu Date: Thu, 22 May 2025 22:30:35 +0800 Subject: [PATCH 03/25] fix: fix canonicalUrl --- src/app/[locale]/(marketing)/(home)/page.tsx | 2 +- .../[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/[locale]/(marketing)/(home)/page.tsx b/src/app/[locale]/(marketing)/(home)/page.tsx index 88d79fd..6433930 100644 --- a/src/app/[locale]/(marketing)/(home)/page.tsx +++ b/src/app/[locale]/(marketing)/(home)/page.tsx @@ -32,7 +32,7 @@ export async function generateMetadata({ return constructMetadata({ title: t('title'), description: t('description'), - canonicalUrl: getUrlWithLocale('/', locale), + canonicalUrl: getUrlWithLocale('', locale), }); } diff --git a/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx b/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx index 5e69f4e..7eb00a4 100644 --- a/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx +++ b/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx @@ -34,7 +34,7 @@ export async function generateMetadata({ return constructMetadata({ title: `${category.name} | ${t('title')}`, description: category.description, - canonicalUrl: getUrlWithLocale('/blog/category/${slug}', locale), + canonicalUrl: getUrlWithLocale(`/blog/category/${slug}`, locale), }); } From 82f40d7dc6648fb8dc9fffa4d2e6fa51380647e9 Mon Sep 17 00:00:00 2001 From: javayhu Date: Thu, 22 May 2025 22:53:29 +0800 Subject: [PATCH 04/25] fix: fix canonicalUrl in block pages --- src/app/[locale]/(marketing)/blocks/[category]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/[locale]/(marketing)/blocks/[category]/page.tsx b/src/app/[locale]/(marketing)/blocks/[category]/page.tsx index 8f93db4..cd893d1 100644 --- a/src/app/[locale]/(marketing)/blocks/[category]/page.tsx +++ b/src/app/[locale]/(marketing)/blocks/[category]/page.tsx @@ -26,7 +26,7 @@ export async function generateMetadata({ return constructMetadata({ title: category + ' | ' + t('title'), description: t('description'), - canonicalUrl: getUrlWithLocale('/blocks/${category}', locale), + canonicalUrl: getUrlWithLocale(`/blocks/${category}`, locale), }); } From 02df9d134f18d3335f15324dfee22a4e7e43f4fd Mon Sep 17 00:00:00 2001 From: javayhu Date: Sun, 25 May 2025 22:19:06 +0800 Subject: [PATCH 05/25] fix: change og:site_name to metadata name instead of title --- src/lib/metadata.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/metadata.ts b/src/lib/metadata.ts index ab4ad72..4c82804 100644 --- a/src/lib/metadata.ts +++ b/src/lib/metadata.ts @@ -37,7 +37,7 @@ export function constructMetadata({ url: canonicalUrl, title, description, - siteName: title, + siteName: defaultMessages.Metadata.name, images: [ogImageUrl.toString()], }, twitter: { From 5824e7489cb80e097df5efe1e16eaa1e78394738 Mon Sep 17 00:00:00 2001 From: javayhu Date: Sun, 25 May 2025 22:26:14 +0800 Subject: [PATCH 06/25] fix: show post image as og image --- src/app/[locale]/(marketing)/blog/[...slug]/page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx b/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx index c90fabb..15b8d24 100644 --- a/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx +++ b/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx @@ -100,6 +100,7 @@ export async function generateMetadata({ title: `${post.title} | ${t('title')}`, description: post.description, canonicalUrl: getUrlWithLocale(post.slug, locale), + image: post.image, }); } From 1e203f4e87134a247b9ace7340369dcb5706a72a Mon Sep 17 00:00:00 2001 From: javayhu Date: Tue, 27 May 2025 23:09:47 +0800 Subject: [PATCH 07/25] fix: do not show upgrade card when sidebar collapses --- src/components/dashboard/dashboard-sidebar.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/dashboard/dashboard-sidebar.tsx b/src/components/dashboard/dashboard-sidebar.tsx index be80da6..f010307 100644 --- a/src/components/dashboard/dashboard-sidebar.tsx +++ b/src/components/dashboard/dashboard-sidebar.tsx @@ -10,6 +10,7 @@ import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, + useSidebar, } from '@/components/ui/sidebar'; import { getSidebarLinks } from '@/config/sidebar-config'; import { LocaleLink } from '@/i18n/navigation'; @@ -31,6 +32,7 @@ export function DashboardSidebar({ const [mounted, setMounted] = useState(false); const { data: session, isPending } = authClient.useSession(); const currentUser = session?.user; + const { state } = useSidebar(); // console.log('sidebar currentUser:', currentUser); const sidebarLinks = getSidebarLinks(); @@ -73,8 +75,8 @@ export function DashboardSidebar({ {/* Only show UI components when not in loading state */} {!isPending && mounted && ( <> - {/* show upgrade card if user is not a member */} - {currentUser && } + {/* show upgrade card if user is not a member, and sidebar is not collapsed */} + {currentUser && state !== 'collapsed' && } {/* show user profile if user is logged in */} {currentUser && } From 38bb93fa4f66fd45186802f41744ec86c624ce86 Mon Sep 17 00:00:00 2001 From: javayhu Date: Tue, 27 May 2025 23:17:49 +0800 Subject: [PATCH 08/25] chore: support config for discord widget feature --- src/app/[locale]/(marketing)/(home)/page.tsx | 3 ++- src/config/website.tsx | 3 +++ src/types/index.d.ts | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/app/[locale]/(marketing)/(home)/page.tsx b/src/app/[locale]/(marketing)/(home)/page.tsx index 6433930..f83e6c7 100644 --- a/src/app/[locale]/(marketing)/(home)/page.tsx +++ b/src/app/[locale]/(marketing)/(home)/page.tsx @@ -12,6 +12,7 @@ import StatsSection from '@/components/blocks/stats/stats'; import TestimonialsSection from '@/components/blocks/testimonials/testimonials'; import { NewsletterCard } from '@/components/newsletter/newsletter-card'; import DiscordWidget from '@/components/shared/discord-widget'; +import { websiteConfig } from '@/config/website'; import { constructMetadata } from '@/lib/metadata'; import { getUrlWithLocale } from '@/lib/urls/urls'; import type { Metadata } from 'next'; @@ -74,7 +75,7 @@ export default async function HomePage(props: HomePageProps) { - + {websiteConfig.features.enableDiscordWidget && } ); diff --git a/src/config/website.tsx b/src/config/website.tsx index 62d2476..4624bf7 100644 --- a/src/config/website.tsx +++ b/src/config/website.tsx @@ -32,6 +32,9 @@ export const websiteConfig: WebsiteConfig = { youtube: 'https://mksaas.link/youtube', }, }, + features: { + enableDiscordWidget: true, + }, routes: { defaultLoginRedirect: '/dashboard', }, diff --git a/src/types/index.d.ts b/src/types/index.d.ts index c0d131e..2f7d725 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -5,6 +5,7 @@ import type { ReactNode } from 'react'; */ export type WebsiteConfig = { metadata: MetadataConfig; + features: FeaturesConfig; routes: RoutesConfig; analytics: AnalyticsConfig; auth: AuthConfig; @@ -60,6 +61,13 @@ export interface SocialConfig { telegram?: string; } +/** + * Website features + */ +export interface FeaturesConfig { + enableDiscordWidget?: boolean; // Whether to enable the discord widget +} + /** * Routes configuration */ From 3ea18fcade560142fdcd9a693b420dfcf0865785 Mon Sep 17 00:00:00 2001 From: javayhu Date: Tue, 27 May 2025 23:47:05 +0800 Subject: [PATCH 09/25] chore: support config for enable upgrade card --- src/components/dashboard/dashboard-sidebar.tsx | 5 ++++- src/config/website.tsx | 1 + src/types/index.d.ts | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/dashboard/dashboard-sidebar.tsx b/src/components/dashboard/dashboard-sidebar.tsx index f010307..fff7379 100644 --- a/src/components/dashboard/dashboard-sidebar.tsx +++ b/src/components/dashboard/dashboard-sidebar.tsx @@ -13,6 +13,7 @@ import { useSidebar, } from '@/components/ui/sidebar'; import { getSidebarLinks } from '@/config/sidebar-config'; +import { websiteConfig } from '@/config/website'; import { LocaleLink } from '@/i18n/navigation'; import { authClient } from '@/lib/auth-client'; import { Routes } from '@/routes'; @@ -76,7 +77,9 @@ export function DashboardSidebar({ {!isPending && mounted && ( <> {/* show upgrade card if user is not a member, and sidebar is not collapsed */} - {currentUser && state !== 'collapsed' && } + {currentUser && + state !== 'collapsed' && + websiteConfig.features.enableUpgradeCard && } {/* show user profile if user is logged in */} {currentUser && } diff --git a/src/config/website.tsx b/src/config/website.tsx index 4624bf7..0f7cf25 100644 --- a/src/config/website.tsx +++ b/src/config/website.tsx @@ -34,6 +34,7 @@ export const websiteConfig: WebsiteConfig = { }, features: { enableDiscordWidget: true, + enableUpgradeCard: true, }, routes: { defaultLoginRedirect: '/dashboard', diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 2f7d725..c195cd3 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -66,6 +66,7 @@ export interface SocialConfig { */ export interface FeaturesConfig { enableDiscordWidget?: boolean; // Whether to enable the discord widget + enableUpgradeCard?: boolean; // Whether to enable the upgrade card in the sidebar } /** From e27a7a081cd9d496e34a394c74309fdffc4e6a15 Mon Sep 17 00:00:00 2001 From: javayhu Date: Fri, 30 May 2025 13:26:42 +0800 Subject: [PATCH 10/25] chore: optimize discord widget config --- src/app/[locale]/(marketing)/(home)/page.tsx | 2 +- src/components/shared/discord-widget.tsx | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/[locale]/(marketing)/(home)/page.tsx b/src/app/[locale]/(marketing)/(home)/page.tsx index f83e6c7..19e68fd 100644 --- a/src/app/[locale]/(marketing)/(home)/page.tsx +++ b/src/app/[locale]/(marketing)/(home)/page.tsx @@ -75,7 +75,7 @@ export default async function HomePage(props: HomePageProps) { - {websiteConfig.features.enableDiscordWidget && } + ); diff --git a/src/components/shared/discord-widget.tsx b/src/components/shared/discord-widget.tsx index 2468910..4c8fd91 100644 --- a/src/components/shared/discord-widget.tsx +++ b/src/components/shared/discord-widget.tsx @@ -1,6 +1,7 @@ 'use client'; import { DiscordIcon } from '@/components/icons/discord'; +import { websiteConfig } from '@/config/website'; import { useMediaQuery } from '@/hooks/use-media-query'; import WidgetBot from '@widgetbot/react-embed'; import { useEffect, useRef, useState } from 'react'; @@ -11,6 +12,10 @@ import { useEffect, useRef, useState } from 'react'; * https://docs.widgetbot.io/embed/react-embed/ */ export default function DiscordWidget() { + if (!websiteConfig.features.enableDiscordWidget) { + return null; + } + const serverId = process.env.NEXT_PUBLIC_DISCORD_WIDGET_SERVER_ID as string; const channelId = process.env.NEXT_PUBLIC_DISCORD_WIDGET_CHANNEL_ID as string; if (!serverId || !channelId) { From 1a4917c874fe2a0e175c8605d31b2e6991460ce2 Mon Sep 17 00:00:00 2001 From: javayhu Date: Fri, 30 May 2025 13:28:03 +0800 Subject: [PATCH 11/25] chore: optimize upgrade card config --- src/components/dashboard/dashboard-sidebar.tsx | 4 +--- src/components/dashboard/upgrade-card.tsx | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/dashboard/dashboard-sidebar.tsx b/src/components/dashboard/dashboard-sidebar.tsx index fff7379..247b8f2 100644 --- a/src/components/dashboard/dashboard-sidebar.tsx +++ b/src/components/dashboard/dashboard-sidebar.tsx @@ -77,9 +77,7 @@ export function DashboardSidebar({ {!isPending && mounted && ( <> {/* show upgrade card if user is not a member, and sidebar is not collapsed */} - {currentUser && - state !== 'collapsed' && - websiteConfig.features.enableUpgradeCard && } + {currentUser && state !== 'collapsed' && } {/* show user profile if user is logged in */} {currentUser && } diff --git a/src/components/dashboard/upgrade-card.tsx b/src/components/dashboard/upgrade-card.tsx index fdd35ed..e22d001 100644 --- a/src/components/dashboard/upgrade-card.tsx +++ b/src/components/dashboard/upgrade-card.tsx @@ -8,6 +8,7 @@ import { CardHeader, CardTitle, } from '@/components/ui/card'; +import { websiteConfig } from '@/config/website'; import { usePayment } from '@/hooks/use-payment'; import { LocaleLink } from '@/i18n/navigation'; import { Routes } from '@/routes'; @@ -16,6 +17,10 @@ import { useTranslations } from 'next-intl'; import { useEffect, useState } from 'react'; export function UpgradeCard() { + if (!websiteConfig.features.enableUpgradeCard) { + return null; + } + const t = useTranslations('Dashboard.upgrade'); const [mounted, setMounted] = useState(false); const { isLoading, currentPlan, subscription } = usePayment(); From 8dd3e12824a2ad34df257fa564b2ba1e3368ffeb Mon Sep 17 00:00:00 2001 From: javayhu Date: Fri, 30 May 2025 14:05:45 +0800 Subject: [PATCH 12/25] feat: support affonso affiliate --- env.example | 6 ++++ src/app/[locale]/(marketing)/(home)/page.tsx | 1 - src/components/affiliate/affonso.tsx | 33 +++++++++++++++++++ src/components/auth/register-form.tsx | 8 +++++ .../dashboard/dashboard-sidebar.tsx | 1 - .../pricing/create-checkout-button.tsx | 26 ++++++++++++++- src/config/website.tsx | 1 + src/types/index.d.ts | 1 + 8 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 src/components/affiliate/affonso.tsx diff --git a/env.example b/env.example index 1380cb6..abd45c2 100644 --- a/env.example +++ b/env.example @@ -129,3 +129,9 @@ NEXT_PUBLIC_DATAFAST_ANALYTICS_DOMAIN="" # ----------------------------------------------------------------------------- NEXT_PUBLIC_DISCORD_WIDGET_SERVER_ID="" NEXT_PUBLIC_DISCORD_WIDGET_CHANNEL_ID="" + +# ----------------------------------------------------------------------------- +# Affiliate (Affonso) +# https://mksaas.com/docs/affiliate +# ----------------------------------------------------------------------------- +NEXT_PUBLIC_AFFILIATE_AFFONSO_ID="" diff --git a/src/app/[locale]/(marketing)/(home)/page.tsx b/src/app/[locale]/(marketing)/(home)/page.tsx index 19e68fd..6433930 100644 --- a/src/app/[locale]/(marketing)/(home)/page.tsx +++ b/src/app/[locale]/(marketing)/(home)/page.tsx @@ -12,7 +12,6 @@ import StatsSection from '@/components/blocks/stats/stats'; import TestimonialsSection from '@/components/blocks/testimonials/testimonials'; import { NewsletterCard } from '@/components/newsletter/newsletter-card'; import DiscordWidget from '@/components/shared/discord-widget'; -import { websiteConfig } from '@/config/website'; import { constructMetadata } from '@/lib/metadata'; import { getUrlWithLocale } from '@/lib/urls/urls'; import type { Metadata } from 'next'; diff --git a/src/components/affiliate/affonso.tsx b/src/components/affiliate/affonso.tsx new file mode 100644 index 0000000..73df2f5 --- /dev/null +++ b/src/components/affiliate/affonso.tsx @@ -0,0 +1,33 @@ +'use client'; + +import { websiteConfig } from '@/config/website'; +import Script from 'next/script'; + +/** + * Affonso Affiliate + * + * https://affonso.com + */ +export function AffonsoAffiliate() { + if (process.env.NODE_ENV !== 'production') { + return null; + } + + if (!websiteConfig.features.enableAffonsoAffiliate) { + return null; + } + + const affiliateId = process.env.NEXT_PUBLIC_AFFILIATE_AFFONSO_ID as string; + if (!affiliateId) { + return null; + } + + return ( +