mirror of
https://github.com/Such-Software/smirk-website.git
synced 2026-10-17 05:51:28 +02:00
fix(auth): sign in against the v0.3 backend
v0.3 wallets register with the v0.3 backend, so a site built against the legacy backend answered every v0.3 sign-in with "User not found". The v0.3 backend resolves website sign-in by each coin's own key and adopts a legacy identity on first proof, so it serves both generations. The v0.3 backend has no social linking. Settings now loads linked accounts separately and hides that section when they are unavailable, instead of failing the whole page and taking username editing with it. The public user count and stats may come from a separate backend via NEXT_PUBLIC_STATS_API_URL; unset keeps today's behavior.
This commit is contained in:
@@ -2,3 +2,7 @@
|
|||||||
# For local development: http://localhost:8080
|
# For local development: http://localhost:8080
|
||||||
# For production: https://api.smirk.cash (or your backend URL)
|
# For production: https://api.smirk.cash (or your backend URL)
|
||||||
NEXT_PUBLIC_API_URL=http://localhost:8080
|
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
|
||||||
|
|||||||
+143
-124
@@ -21,6 +21,7 @@ type LinkStep = 'idle' | 'linking' | 'waiting';
|
|||||||
export default function SettingsPage() {
|
export default function SettingsPage() {
|
||||||
const [user, setUser] = useState<MeResponse | null>(null);
|
const [user, setUser] = useState<MeResponse | null>(null);
|
||||||
const [socials, setSocials] = useState<LinkedSocial[]>([]);
|
const [socials, setSocials] = useState<LinkedSocial[]>([]);
|
||||||
|
const [socialsAvailable, setSocialsAvailable] = useState(true);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
@@ -81,10 +82,16 @@ export default function SettingsPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.all([getMe(token), getLinkedSocials(token), getMyUsername(token)])
|
// Linked accounts are a legacy-backend feature; the v0.3 backend has no
|
||||||
.then(([userData, socialsData, username]) => {
|
// 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);
|
setUser(userData);
|
||||||
setSocials(socialsData.socials);
|
|
||||||
setSmirkUsername(username || '');
|
setSmirkUsername(username || '');
|
||||||
setUsernameInput(username || '');
|
setUsernameInput(username || '');
|
||||||
})
|
})
|
||||||
@@ -320,139 +327,151 @@ export default function SettingsPage() {
|
|||||||
<section>
|
<section>
|
||||||
<h2 className="text-lg font-semibold mb-4 text-zinc-400">Linked Accounts</h2>
|
<h2 className="text-lg font-semibold mb-4 text-zinc-400">Linked Accounts</h2>
|
||||||
|
|
||||||
{/* Telegram */}
|
{socialsAvailable ? (
|
||||||
<div className="bg-zinc-900 rounded-xl p-4 mb-4">
|
<>
|
||||||
<div className="flex items-center justify-between">
|
{/* Telegram */}
|
||||||
<div className="flex items-center gap-3">
|
<div className="bg-zinc-900 rounded-xl p-4 mb-4">
|
||||||
<div className="w-10 h-10 bg-[#0088cc] rounded-full flex items-center justify-center">
|
<div className="flex items-center justify-between">
|
||||||
<svg className="w-6 h-6 text-white" viewBox="0 0 24 24" fill="currentColor">
|
<div className="flex items-center gap-3">
|
||||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.64 6.8c-.15 1.58-.8 5.42-1.13 7.19-.14.75-.42 1-.68 1.03-.58.05-1.02-.38-1.58-.75-.88-.58-1.38-.94-2.23-1.5-.99-.65-.35-1.01.22-1.59.15-.15 2.71-2.48 2.76-2.69a.2.2 0 00-.05-.18c-.06-.05-.14-.03-.21-.02-.09.02-1.49.95-4.22 2.79-.4.27-.76.41-1.08.4-.36-.01-1.04-.2-1.55-.37-.63-.2-1.12-.31-1.08-.66.02-.18.27-.36.74-.55 2.92-1.27 4.86-2.11 5.83-2.51 2.78-1.16 3.35-1.36 3.73-1.36.08 0 .27.02.39.12.1.08.13.19.14.27-.01.06.01.24 0 .38z" />
|
<div className="w-10 h-10 bg-[#0088cc] rounded-full flex items-center justify-center">
|
||||||
</svg>
|
<svg className="w-6 h-6 text-white" viewBox="0 0 24 24" fill="currentColor">
|
||||||
</div>
|
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.64 6.8c-.15 1.58-.8 5.42-1.13 7.19-.14.75-.42 1-.68 1.03-.58.05-1.02-.38-1.58-.75-.88-.58-1.38-.94-2.23-1.5-.99-.65-.35-1.01.22-1.59.15-.15 2.71-2.48 2.76-2.69a.2.2 0 00-.05-.18c-.06-.05-.14-.03-.21-.02-.09.02-1.49.95-4.22 2.79-.4.27-.76.41-1.08.4-.36-.01-1.04-.2-1.55-.37-.63-.2-1.12-.31-1.08-.66.02-.18.27-.36.74-.55 2.92-1.27 4.86-2.11 5.83-2.51 2.78-1.16 3.35-1.36 3.73-1.36.08 0 .27.02.39.12.1.08.13.19.14.27-.01.06.01.24 0 .38z" />
|
||||||
<div>
|
</svg>
|
||||||
<p className="font-medium">Telegram</p>
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="font-medium">Telegram</p>
|
||||||
|
{telegramSocial?.verified ? (
|
||||||
|
<p className="text-sm text-green-400">
|
||||||
|
{telegramSocial.username ? `@${telegramSocial.username}` : telegramSocial.display_name || 'Linked'}
|
||||||
|
</p>
|
||||||
|
) : telegramSocial?.pending_verification ? (
|
||||||
|
<p className="text-sm text-yellow-400">Verification pending</p>
|
||||||
|
) : (
|
||||||
|
<p className="text-sm text-zinc-500">Not linked</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{telegramSocial?.verified ? (
|
{telegramSocial?.verified ? (
|
||||||
<p className="text-sm text-green-400">
|
<button
|
||||||
{telegramSocial.username ? `@${telegramSocial.username}` : telegramSocial.display_name || 'Linked'}
|
onClick={() => handleUnlink('telegram')}
|
||||||
|
className="px-3 py-1 text-sm text-red-400 border border-red-400/50 rounded hover:bg-red-400/10"
|
||||||
|
>
|
||||||
|
Unlink
|
||||||
|
</button>
|
||||||
|
) : linkStep === 'idle' ? (
|
||||||
|
<button
|
||||||
|
onClick={handleStartLink}
|
||||||
|
className="px-4 py-2 bg-[#fbeb0a] text-black font-medium rounded-lg hover:bg-[#d4c708]"
|
||||||
|
>
|
||||||
|
Link
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Link flow UI */}
|
||||||
|
{linkStep === 'linking' && (
|
||||||
|
<div className="mt-4 pt-4 border-t border-zinc-800">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<div className="animate-spin w-5 h-5 border-2 border-[#fbeb0a] border-t-transparent rounded-full" />
|
||||||
|
<span className="text-zinc-400">Setting up link...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{linkStep === 'waiting' && deepLink && (
|
||||||
|
<div className="mt-4 pt-4 border-t border-zinc-800">
|
||||||
|
<p className="text-sm text-zinc-400 mb-4">
|
||||||
|
Click the button below to open Telegram and link your account automatically:
|
||||||
</p>
|
</p>
|
||||||
) : telegramSocial?.pending_verification ? (
|
|
||||||
<p className="text-sm text-yellow-400">Verification pending</p>
|
<div className="flex gap-2 mb-4">
|
||||||
) : (
|
<a
|
||||||
<p className="text-sm text-zinc-500">Not linked</p>
|
href={deepLink}
|
||||||
)}
|
target="_blank"
|
||||||
</div>
|
rel="noopener noreferrer"
|
||||||
|
className="flex items-center gap-2 px-4 py-2 bg-[#0088cc] text-white font-medium rounded-lg hover:bg-[#0077b3]"
|
||||||
|
>
|
||||||
|
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.64 6.8c-.15 1.58-.8 5.42-1.13 7.19-.14.75-.42 1-.68 1.03-.58.05-1.02-.38-1.58-.75-.88-.58-1.38-.94-2.23-1.5-.99-.65-.35-1.01.22-1.59.15-.15 2.71-2.48 2.76-2.69a.2.2 0 00-.05-.18c-.06-.05-.14-.03-.21-.02-.09.02-1.49.95-4.22 2.79-.4.27-.76.41-1.08.4-.36-.01-1.04-.2-1.55-.37-.63-.2-1.12-.31-1.08-.66.02-.18.27-.36.74-.55 2.92-1.27 4.86-2.11 5.83-2.51 2.78-1.16 3.35-1.36 3.73-1.36.08 0 .27.02.39.12.1.08.13.19.14.27-.01.06.01.24 0 .38z" />
|
||||||
|
</svg>
|
||||||
|
Open Telegram
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
onClick={handleCancelLink}
|
||||||
|
className="px-4 py-2 border border-zinc-700 rounded-lg hover:border-zinc-500"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-2 text-sm text-zinc-500">
|
||||||
|
<div className="animate-spin w-4 h-4 border-2 border-zinc-500 border-t-transparent rounded-full" />
|
||||||
|
<span>Waiting for verification...</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{linkError && <p className="mt-2 text-sm text-red-400">{linkError}</p>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{telegramSocial?.verified ? (
|
{/* Discord */}
|
||||||
<button
|
<div className="bg-zinc-900 rounded-xl p-4 mb-4">
|
||||||
onClick={() => handleUnlink('telegram')}
|
<div className="flex items-center justify-between">
|
||||||
className="px-3 py-1 text-sm text-red-400 border border-red-400/50 rounded hover:bg-red-400/10"
|
<div className="flex items-center gap-3">
|
||||||
>
|
<div className="w-10 h-10 bg-[#5865F2] rounded-full flex items-center justify-center">
|
||||||
Unlink
|
<svg className="w-6 h-6 text-white" viewBox="0 0 24 24" fill="currentColor">
|
||||||
</button>
|
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189z" />
|
||||||
) : linkStep === 'idle' ? (
|
</svg>
|
||||||
<button
|
</div>
|
||||||
onClick={handleStartLink}
|
<div>
|
||||||
className="px-4 py-2 bg-[#fbeb0a] text-black font-medium rounded-lg hover:bg-[#d4c708]"
|
<p className="font-medium">Discord</p>
|
||||||
>
|
{discordSocial?.verified ? (
|
||||||
Link
|
<p className="text-sm text-green-400">
|
||||||
</button>
|
{discordSocial.display_name || discordSocial.username || 'Linked'}
|
||||||
) : null}
|
</p>
|
||||||
</div>
|
) : discordLinking ? (
|
||||||
|
<p className="text-sm text-yellow-400">Linking...</p>
|
||||||
|
) : (
|
||||||
|
<p className="text-sm text-zinc-500">Not linked</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Link flow UI */}
|
|
||||||
{linkStep === 'linking' && (
|
|
||||||
<div className="mt-4 pt-4 border-t border-zinc-800">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<div className="animate-spin w-5 h-5 border-2 border-[#fbeb0a] border-t-transparent rounded-full" />
|
|
||||||
<span className="text-zinc-400">Setting up link...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{linkStep === 'waiting' && deepLink && (
|
|
||||||
<div className="mt-4 pt-4 border-t border-zinc-800">
|
|
||||||
<p className="text-sm text-zinc-400 mb-4">
|
|
||||||
Click the button below to open Telegram and link your account automatically:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div className="flex gap-2 mb-4">
|
|
||||||
<a
|
|
||||||
href={deepLink}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="flex items-center gap-2 px-4 py-2 bg-[#0088cc] text-white font-medium rounded-lg hover:bg-[#0077b3]"
|
|
||||||
>
|
|
||||||
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.64 6.8c-.15 1.58-.8 5.42-1.13 7.19-.14.75-.42 1-.68 1.03-.58.05-1.02-.38-1.58-.75-.88-.58-1.38-.94-2.23-1.5-.99-.65-.35-1.01.22-1.59.15-.15 2.71-2.48 2.76-2.69a.2.2 0 00-.05-.18c-.06-.05-.14-.03-.21-.02-.09.02-1.49.95-4.22 2.79-.4.27-.76.41-1.08.4-.36-.01-1.04-.2-1.55-.37-.63-.2-1.12-.31-1.08-.66.02-.18.27-.36.74-.55 2.92-1.27 4.86-2.11 5.83-2.51 2.78-1.16 3.35-1.36 3.73-1.36.08 0 .27.02.39.12.1.08.13.19.14.27-.01.06.01.24 0 .38z" />
|
|
||||||
</svg>
|
|
||||||
Open Telegram
|
|
||||||
</a>
|
|
||||||
<button
|
|
||||||
onClick={handleCancelLink}
|
|
||||||
className="px-4 py-2 border border-zinc-700 rounded-lg hover:border-zinc-500"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex items-center gap-2 text-sm text-zinc-500">
|
|
||||||
<div className="animate-spin w-4 h-4 border-2 border-zinc-500 border-t-transparent rounded-full" />
|
|
||||||
<span>Waiting for verification...</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{linkError && <p className="mt-2 text-sm text-red-400">{linkError}</p>}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Discord */}
|
|
||||||
<div className="bg-zinc-900 rounded-xl p-4 mb-4">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<div className="w-10 h-10 bg-[#5865F2] rounded-full flex items-center justify-center">
|
|
||||||
<svg className="w-6 h-6 text-white" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p className="font-medium">Discord</p>
|
|
||||||
{discordSocial?.verified ? (
|
{discordSocial?.verified ? (
|
||||||
<p className="text-sm text-green-400">
|
<button
|
||||||
{discordSocial.display_name || discordSocial.username || 'Linked'}
|
onClick={() => handleUnlink('discord')}
|
||||||
</p>
|
className="px-3 py-1 text-sm text-red-400 border border-red-400/50 rounded hover:bg-red-400/10"
|
||||||
) : discordLinking ? (
|
>
|
||||||
<p className="text-sm text-yellow-400">Linking...</p>
|
Unlink
|
||||||
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm text-zinc-500">Not linked</p>
|
<button
|
||||||
|
onClick={handleLinkDiscord}
|
||||||
|
disabled={discordLinking}
|
||||||
|
className="px-4 py-2 bg-[#fbeb0a] text-black font-medium rounded-lg hover:bg-[#d4c708] disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{discordLinking ? 'Linking...' : 'Link'}
|
||||||
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{discordError && (
|
||||||
|
<div className="mt-4 pt-4 border-t border-zinc-800">
|
||||||
|
<p className="text-sm text-red-400">{discordError}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{discordSocial?.verified ? (
|
</>
|
||||||
<button
|
) : (
|
||||||
onClick={() => handleUnlink('discord')}
|
<div className="bg-zinc-900 rounded-xl p-4 mb-4">
|
||||||
className="px-3 py-1 text-sm text-red-400 border border-red-400/50 rounded hover:bg-red-400/10"
|
<p className="text-sm text-zinc-500">
|
||||||
>
|
Linking Telegram and Discord isn't available for this wallet. Your Smirk
|
||||||
Unlink
|
username above is how others find and tip you.
|
||||||
</button>
|
</p>
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
onClick={handleLinkDiscord}
|
|
||||||
disabled={discordLinking}
|
|
||||||
className="px-4 py-2 bg-[#fbeb0a] text-black font-medium rounded-lg hover:bg-[#d4c708] disabled:opacity-50"
|
|
||||||
>
|
|
||||||
{discordLinking ? 'Linking...' : 'Link'}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
{discordError && (
|
|
||||||
<div className="mt-4 pt-4 border-t border-zinc-800">
|
|
||||||
<p className="text-sm text-red-400">{discordError}</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Future platforms */}
|
{/* Future platforms */}
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
|
|||||||
+5
-2
@@ -1,6 +1,9 @@
|
|||||||
// API client for Smirk backend
|
// API client for Smirk backend
|
||||||
|
|
||||||
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000';
|
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 {
|
export interface ChallengeResponse {
|
||||||
challenge: string;
|
challenge: string;
|
||||||
@@ -398,7 +401,7 @@ export interface UserCountResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getUserCount(): Promise<UserCountResponse> {
|
export async function getUserCount(): Promise<UserCountResponse> {
|
||||||
const res = await fetch(`${API_URL}/api/v1/users/count`);
|
const res = await fetch(`${STATS_API_URL}/api/v1/users/count`);
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw new Error('Failed to get user count');
|
throw new Error('Failed to get user count');
|
||||||
@@ -419,7 +422,7 @@ export interface PublicStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getPublicStats(): Promise<PublicStats> {
|
export async function getPublicStats(): Promise<PublicStats> {
|
||||||
const res = await fetch(`${API_URL}/api/v1/stats/public`);
|
const res = await fetch(`${STATS_API_URL}/api/v1/stats/public`);
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw new Error('Failed to get stats');
|
throw new Error('Failed to get stats');
|
||||||
|
|||||||
Reference in New Issue
Block a user