Skip to content

Commit 4442b8b

Browse files
author
CloudLobster
committed
Add fallback basename claim input to PendingActionBanner
When ?claim= fails (e.g. name already taken by someone else), show an input field so the user can try claiming with their actual basename — same UX as Settings page.
1 parent b5855ec commit 4442b8b

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

web/src/pages/Dashboard.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2815,6 +2815,37 @@ function PendingActionBanner({
28152815
);
28162816
}
28172817

2818+
// Fallback: claim failed but user may own a different basename — show input
2819+
const [fallbackName, setFallbackName] = useState('');
2820+
const [fallbackError, setFallbackError] = useState('');
2821+
const [fallbackUpgrading, setFallbackUpgrading] = useState(false);
2822+
2823+
async function handleFallbackClaim() {
2824+
if (!fallbackName.trim()) { setFallbackError('Please enter your Basename'); return; }
2825+
setFallbackUpgrading(true);
2826+
setFallbackError('');
2827+
try {
2828+
const fullName = `${fallbackName.trim().replace(/\.base\.eth$/i, '')}.base.eth`;
2829+
const res = await apiFetch('/api/register/upgrade', auth.token, {
2830+
method: 'PUT',
2831+
body: JSON.stringify({ basename: fullName }),
2832+
});
2833+
if (res.ok) {
2834+
window.location.href = '/dashboard';
2835+
return;
2836+
}
2837+
const errData = await res.json().catch(() => ({}));
2838+
if (errData.error?.includes('already has')) {
2839+
window.location.href = '/dashboard';
2840+
return;
2841+
}
2842+
setFallbackError(errData.error || 'Verification failed');
2843+
} catch (e: any) {
2844+
setFallbackError(e.message || 'Failed');
2845+
}
2846+
setFallbackUpgrading(false);
2847+
}
2848+
28182849
// Buy flow → direct on-chain purchase
28192850
return (
28202851
<div className="bg-gradient-to-r from-blue-900/30 to-purple-900/30 border border-blue-700/50 rounded-xl p-6 mb-6">
@@ -2832,6 +2863,39 @@ function PendingActionBanner({
28322863

28332864
{error && <p className="text-red-400 text-sm mb-3">{error}</p>}
28342865

2866+
{/* Fallback: if claim failed, let user try a different basename */}
2867+
{error && !available && (
2868+
<div className="bg-gray-900/50 border border-gray-700 rounded-lg p-4 mb-4">
2869+
<div className="flex items-center gap-2 mb-2">
2870+
<span></span>
2871+
<span className="text-blue-300 text-sm font-bold">Own a different Basename?</span>
2872+
</div>
2873+
<p className="text-gray-400 text-xs mb-3">
2874+
Enter your actual Basename to claim your email address.
2875+
</p>
2876+
<div className="flex gap-2">
2877+
<div className="flex-1 flex items-center bg-base-dark rounded-lg border border-gray-700 px-2">
2878+
<input
2879+
type="text"
2880+
value={fallbackName}
2881+
onChange={(e) => { setFallbackName(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, '')); setFallbackError(''); }}
2882+
placeholder="yourname"
2883+
className="flex-1 bg-transparent py-2 text-white font-mono text-sm focus:outline-none"
2884+
/>
2885+
<span className="text-gray-500 font-mono text-xs">.base.eth</span>
2886+
</div>
2887+
<button
2888+
onClick={handleFallbackClaim}
2889+
disabled={fallbackUpgrading || !fallbackName.trim()}
2890+
className="bg-base-blue text-white px-5 py-2 rounded-lg text-sm font-medium hover:bg-blue-500 transition disabled:opacity-50"
2891+
>
2892+
{fallbackUpgrading ? 'Verifying...' : '✨ Claim'}
2893+
</button>
2894+
</div>
2895+
{fallbackError && <p className="text-red-400 text-xs mt-2">{fallbackError}</p>}
2896+
</div>
2897+
)}
2898+
28352899
{available && priceEth && buyData && (
28362900
<>
28372901
{action.type === 'claim' && (

0 commit comments

Comments
 (0)