diff --git a/.env.local.example b/.env.local.example index b21bb54..8dde6a9 100644 --- a/.env.local.example +++ b/.env.local.example @@ -2,3 +2,7 @@ # For local development: http://localhost:8080 # For production: https://api.smirk.cash (or your backend URL) NEXT_PUBLIC_API_URL=http://localhost:8080 + +# Optional: backend serving the public user count and stats, when it differs +# from the sign-in backend above. Unset means the same backend. +# NEXT_PUBLIC_STATS_API_URL=https://backend.smirk.cash diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index eb008ec..b4e8ab5 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -21,6 +21,7 @@ type LinkStep = 'idle' | 'linking' | 'waiting'; export default function SettingsPage() { const [user, setUser] = useState(null); const [socials, setSocials] = useState([]); + const [socialsAvailable, setSocialsAvailable] = useState(true); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -81,10 +82,16 @@ export default function SettingsPage() { return; } - Promise.all([getMe(token), getLinkedSocials(token), getMyUsername(token)]) - .then(([userData, socialsData, username]) => { + // Linked accounts are a legacy-backend feature; the v0.3 backend has no + // social linking. Load them separately so their absence hides that section + // instead of failing the whole page. + getLinkedSocials(token) + .then((socialsData) => setSocials(socialsData.socials)) + .catch(() => setSocialsAvailable(false)); + + Promise.all([getMe(token), getMyUsername(token)]) + .then(([userData, username]) => { setUser(userData); - setSocials(socialsData.socials); setSmirkUsername(username || ''); setUsernameInput(username || ''); }) @@ -320,139 +327,151 @@ export default function SettingsPage() {

Linked Accounts

- {/* Telegram */} -
-
-
-
- - - -
-
-

Telegram

+ {socialsAvailable ? ( + <> + {/* Telegram */} +
+
+
+
+ + + +
+
+

Telegram

+ {telegramSocial?.verified ? ( +

+ {telegramSocial.username ? `@${telegramSocial.username}` : telegramSocial.display_name || 'Linked'} +

+ ) : telegramSocial?.pending_verification ? ( +

Verification pending

+ ) : ( +

Not linked

+ )} +
+
+ {telegramSocial?.verified ? ( -

- {telegramSocial.username ? `@${telegramSocial.username}` : telegramSocial.display_name || 'Linked'} + + ) : linkStep === 'idle' ? ( + + ) : null} +

+ + {/* Link flow UI */} + {linkStep === 'linking' && ( +
+
+
+ Setting up link... +
+
+ )} + + {linkStep === 'waiting' && deepLink && ( +
+

+ Click the button below to open Telegram and link your account automatically:

- ) : telegramSocial?.pending_verification ? ( -

Verification pending

- ) : ( -

Not linked

- )} -
+ +
+ + + + + Open Telegram + + +
+ +
+
+ Waiting for verification... +
+ + {linkError &&

{linkError}

} +
+ )}
- {telegramSocial?.verified ? ( - - ) : linkStep === 'idle' ? ( - - ) : null} -
+ {/* Discord */} +
+
+
+
+ + + +
+
+

Discord

+ {discordSocial?.verified ? ( +

+ {discordSocial.display_name || discordSocial.username || 'Linked'} +

+ ) : discordLinking ? ( +

Linking...

+ ) : ( +

Not linked

+ )} +
+
- {/* Link flow UI */} - {linkStep === 'linking' && ( -
-
-
- Setting up link... -
-
- )} - - {linkStep === 'waiting' && deepLink && ( -
-

- Click the button below to open Telegram and link your account automatically: -

- -
- - - - - Open Telegram - - -
- -
-
- Waiting for verification... -
- - {linkError &&

{linkError}

} -
- )} -
- - {/* Discord */} -
-
-
-
- - - -
-
-

Discord

{discordSocial?.verified ? ( -

- {discordSocial.display_name || discordSocial.username || 'Linked'} -

- ) : discordLinking ? ( -

Linking...

+ ) : ( -

Not linked

+ )}
+ + {discordError && ( +
+

{discordError}

+
+ )}
- {discordSocial?.verified ? ( - - ) : ( - - )} + + ) : ( +
+

+ Linking Telegram and Discord isn't available for this wallet. Your Smirk + username above is how others find and tip you. +

- - {discordError && ( -
-

{discordError}

-
- )} -
+ )} {/* Future platforms */}
diff --git a/src/lib/api.ts b/src/lib/api.ts index afaeaac..f13f4b5 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,6 +1,9 @@ // API client for Smirk backend const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'; +// Public counters (user count, stats) may live on a different backend than +// sign-in. Unset means the same backend. +const STATS_API_URL = process.env.NEXT_PUBLIC_STATS_API_URL || API_URL; export interface ChallengeResponse { challenge: string; @@ -398,7 +401,7 @@ export interface UserCountResponse { } export async function getUserCount(): Promise { - const res = await fetch(`${API_URL}/api/v1/users/count`); + const res = await fetch(`${STATS_API_URL}/api/v1/users/count`); if (!res.ok) { throw new Error('Failed to get user count'); @@ -419,7 +422,7 @@ export interface PublicStats { } export async function getPublicStats(): Promise { - const res = await fetch(`${API_URL}/api/v1/stats/public`); + const res = await fetch(`${STATS_API_URL}/api/v1/stats/public`); if (!res.ok) { throw new Error('Failed to get stats');