Clarify cross-site signup messaging and pass domain on login.

Also strengthen the businesses three-dot menu glass background.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-10 01:02:49 +03:30
co-authored by Cursor
parent debca2cf99
commit 855f337006
5 changed files with 38 additions and 16 deletions
+2 -2
View File
@@ -121,13 +121,13 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}, [logout]) }, [logout])
const login = useCallback(async (cellNumber: string, password: string) => { const login = useCallback(async (cellNumber: string, password: string) => {
const data = await loginRequest(cellNumber, password) const data = await loginRequest(cellNumber, password, getTenantDomain())
await assertCustomerAccess(data.user) await assertCustomerAccess(data.user)
setUser(data.user) setUser(data.user)
}, []) }, [])
const loginWithOtp = useCallback(async (cellNumber: string, code: string) => { const loginWithOtp = useCallback(async (cellNumber: string, code: string) => {
const data = await loginWithOtpRequest(cellNumber, code) const data = await loginWithOtpRequest(cellNumber, code, getTenantDomain())
await assertCustomerAccess(data.user) await assertCustomerAccess(data.user)
setUser(data.user) setUser(data.user)
}, []) }, [])
+6 -2
View File
@@ -328,7 +328,9 @@ const en = {
'signup.error.length': 'Password must be at least 8 characters.', 'signup.error.length': 'Password must be at least 8 characters.',
'signup.error.create': 'Unable to create account.', 'signup.error.create': 'Unable to create account.',
'signup.error.cellExists': 'signup.error.cellExists':
'This mobile number is already registered. Please sign in or reset your password.', 'This mobile number already has a Meshkee account on {sites}. For a better experience we use that accounts name and password. Sign in with that password, reset it, or use one-time login — then you can access this website too.',
'signup.error.cellExistsGeneric':
'This mobile number already has a Meshkee account on another website. For a better experience we use that accounts name and password. Sign in with that password, reset it, or use one-time login — then you can access this website too.',
'signup.info.verify': 'Account created. Enter the SMS code to verify your number and sign in.', 'signup.info.verify': 'Account created. Enter the SMS code to verify your number and sign in.',
'forgot.back': 'Back to sign in', 'forgot.back': 'Back to sign in',
@@ -707,7 +709,9 @@ const fa: Record<MessageKey, string> = {
'signup.error.length': 'رمز عبور باید حداقل ۸ کاراکتر باشد.', 'signup.error.length': 'رمز عبور باید حداقل ۸ کاراکتر باشد.',
'signup.error.create': 'ایجاد حساب ممکن نشد.', 'signup.error.create': 'ایجاد حساب ممکن نشد.',
'signup.error.cellExists': 'signup.error.cellExists':
'این شماره موبایل قبلاً ثبت شده است. لطفاً وارد شوید یا رمز عبور را بازیابی کنید.', 'این شماره موبایل قبلاً در مشکی حساب دارد ({sites}). برای تجربه بهتر از همان نام و رمز استفاده می‌کنیم. با همان رمز وارد شوید، رمز را بازیابی کنید، یا ورود یک‌بارمصرف را امتحان کنید — بعد می‌توانید وارد این وب‌سایت هم شوید.',
'signup.error.cellExistsGeneric':
'این شماره موبایل قبلاً در مشکی (وب‌سایت دیگری) حساب دارد. برای تجربه بهتر از همان نام و رمز استفاده می‌کنیم. با همان رمز وارد شوید، رمز را بازیابی کنید، یا ورود یک‌بارمصرف را امتحان کنید — بعد می‌توانید وارد این وب‌سایت هم شوید.',
'signup.info.verify': 'حساب ایجاد شد. کد پیامکی را وارد کنید تا شماره تأیید شود و وارد شوید.', 'signup.info.verify': 'حساب ایجاد شد. کد پیامکی را وارد کنید تا شماره تأیید شود و وارد شوید.',
'forgot.back': 'بازگشت به ورود', 'forgot.back': 'بازگشت به ورود',
+12 -2
View File
@@ -108,8 +108,18 @@ export function LoginPage() {
err.message.includes('Unable to send SMS') err.message.includes('Unable to send SMS')
) { ) {
setError(t('login.error.smsProvider')) setError(t('login.error.smsProvider'))
} else if (err.message.includes('Cell number exists on another account')) { } else if (
setError(t('signup.error.cellExists')) err.message.includes('CELL_EXISTS_OTHER_SITE:') ||
err.message.includes('Cell number exists on another account')
) {
const sites = err.message.startsWith('CELL_EXISTS_OTHER_SITE:')
? err.message.slice('CELL_EXISTS_OTHER_SITE:'.length).trim()
: ''
setError(
sites
? t('signup.error.cellExists', { sites })
: t('signup.error.cellExistsGeneric'),
)
} else { } else {
setError(err.message) setError(err.message)
} }
+12 -4
View File
@@ -10,10 +10,14 @@ import type {
UserProfile, UserProfile,
} from '../types/auth' } from '../types/auth'
export async function login(cellNumber: string, password: string) { export async function login(
cellNumber: string,
password: string,
domain?: string,
) {
const data = await apiRequest<LoginResponse>('/auth/login', { const data = await apiRequest<LoginResponse>('/auth/login', {
method: 'POST', method: 'POST',
body: { cellNumber, password }, body: domain ? { cellNumber, password, domain } : { cellNumber, password },
}) })
setTokens(data.accessToken, data.refreshToken) setTokens(data.accessToken, data.refreshToken)
@@ -79,10 +83,14 @@ export async function verifyOtp(cellNumber: string, code: string) {
}) })
} }
export async function loginWithOtp(cellNumber: string, code: string) { export async function loginWithOtp(
cellNumber: string,
code: string,
domain?: string,
) {
const data = await apiRequest<LoginResponse>('/auth/login-otp', { const data = await apiRequest<LoginResponse>('/auth/login-otp', {
method: 'POST', method: 'POST',
body: { cellNumber, code }, body: domain ? { cellNumber, code, domain } : { cellNumber, code },
}) })
setTokens(data.accessToken, data.refreshToken) setTokens(data.accessToken, data.refreshToken)
@@ -31,13 +31,13 @@
min-width: 220px; min-width: 220px;
padding: 6px; padding: 6px;
border-radius: 10px; border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.92); border: 1px solid rgba(255, 255, 255, 0.95);
background: rgba(255, 255, 255, 0.58); background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(160px) saturate(1.85); backdrop-filter: blur(80px) saturate(1.7);
-webkit-backdrop-filter: blur(160px) saturate(1.85); -webkit-backdrop-filter: blur(80px) saturate(1.7);
box-shadow: box-shadow:
0 12px 40px rgba(15, 23, 42, 0.16), 0 12px 40px rgba(15, 23, 42, 0.18),
inset 0 1px 0 rgba(255, 255, 255, 0.65); inset 0 1px 0 rgba(255, 255, 255, 0.8);
isolation: isolate; isolation: isolate;
animation: menuIn 0.14s ease; animation: menuIn 0.14s ease;
} }