fix: wire referral deep link to citizenship form via startParam

- Detect SS58 address in Telegram startParam and auto-route to CitizenPage
- Pass startParam as initialReferrer to CitizenForm
- Show read-only referrer badge when pre-filled from referral link
This commit is contained in:
2026-02-28 01:59:10 +03:00
parent b800b36b9f
commit 5065e0f70c
5 changed files with 37 additions and 18 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "pezkuwi-telegram-miniapp",
"version": "1.0.225",
"version": "1.0.226",
"type": "module",
"description": "Pezkuwichain Telegram Mini App - Forum, Announcements, Rewards",
"author": "Pezkuwichain Team",
+6 -1
View File
@@ -52,7 +52,12 @@ const NAV_ITEMS: NavItem[] = [
// Check for standalone pages via URL query params or path (evaluated once at module level)
const PAGE_PARAM = new URLSearchParams(window.location.search).get('page');
const IS_CITIZEN_PAGE = PAGE_PARAM === 'citizen' || window.location.pathname === '/citizens';
const TELEGRAM_START_PARAM = window.Telegram?.WebApp?.initDataUnsafe?.start_param;
// SS58 address for prefix 42 starts with "5" and is 48 chars of base58
const IS_CITIZENSHIP_REFERRAL =
!!TELEGRAM_START_PARAM && /^5[1-9A-HJ-NP-Za-km-z]{46,47}$/.test(TELEGRAM_START_PARAM);
const IS_CITIZEN_PAGE =
PAGE_PARAM === 'citizen' || window.location.pathname === '/citizens' || IS_CITIZENSHIP_REFERRAL;
const IS_EXPLORER_PAGE = window.location.pathname.replace(/\/$/, '') === '/explorer';
export default function App() {
+22 -12
View File
@@ -12,6 +12,7 @@ import type { CitizenshipData, Region, MaritalStatus, ChildInfo } from '@/lib/ci
interface Props {
onSubmit: (data: CitizenshipData) => void;
initialReferrer?: string;
}
const REGIONS: { value: Region; labelKey: string }[] = [
@@ -23,7 +24,7 @@ const REGIONS: { value: Region; labelKey: string }[] = [
{ value: 'diaspora', labelKey: 'citizen.regionDiaspora' },
];
export function CitizenForm({ onSubmit }: Props) {
export function CitizenForm({ onSubmit, initialReferrer }: Props) {
const { t } = useTranslation();
const { hapticImpact, hapticNotification } = useTelegram();
@@ -38,7 +39,7 @@ export function CitizenForm({ onSubmit }: Props) {
const [region, setRegion] = useState<Region | ''>('');
const [email, setEmail] = useState('');
const [profession, setProfession] = useState('');
const [referrerAddress, setReferrerAddress] = useState('');
const [referrerAddress, setReferrerAddress] = useState(initialReferrer || '');
const [seedPhrase, setSeedPhrase] = useState('');
const [consent, setConsent] = useState(false);
const [error, setError] = useState('');
@@ -377,16 +378,25 @@ export function CitizenForm({ onSubmit }: Props) {
</div>
{/* Referrer Address */}
<div>
<label className={labelClass}>{t('citizen.referrerAddress')}</label>
<input
type="text"
value={referrerAddress}
onChange={(e) => setReferrerAddress(e.target.value)}
className={inputClass}
placeholder={t('citizen.referrerPlaceholder')}
/>
</div>
{initialReferrer ? (
<div className="p-3 bg-green-500/10 border border-green-500/30 rounded-xl">
<label className="text-xs text-green-400 mb-1 block">
{t('citizen.referrerAddress')}
</label>
<p className="text-sm font-mono text-green-300 break-all">{initialReferrer}</p>
</div>
) : (
<div>
<label className={labelClass}>{t('citizen.referrerAddress')}</label>
<input
type="text"
value={referrerAddress}
onChange={(e) => setReferrerAddress(e.target.value)}
className={inputClass}
placeholder={t('citizen.referrerPlaceholder')}
/>
</div>
)}
{/* Consent */}
<label className="flex items-start gap-3 p-3 bg-muted/50 rounded-xl cursor-pointer">
+5 -1
View File
@@ -10,6 +10,7 @@ import { Globe, Loader2 } from 'lucide-react';
import { useTranslation, LANGUAGE_NAMES, VALID_LANGS } from '@/i18n';
import type { LanguageCode } from '@/i18n';
import type { CitizenshipData } from '@/lib/citizenship';
import { useTelegram } from '@/hooks/useTelegram';
// Lazy load sub-components
const CitizenForm = lazy(() =>
@@ -34,6 +35,7 @@ function SectionLoader() {
export function CitizenPage() {
const { t, lang, setLang } = useTranslation();
const { startParam } = useTelegram();
const [showLangMenu, setShowLangMenu] = useState(false);
const [citizenshipData, setCitizenshipData] = useState<CitizenshipData | null>(null);
const [identityHash, setIdentityHash] = useState<string>('');
@@ -118,7 +120,9 @@ export function CitizenPage() {
{/* Content */}
<main className="flex-1 overflow-y-auto">
<Suspense fallback={<SectionLoader />}>
{step === 'form' && <CitizenForm onSubmit={handleFormSubmit} />}
{step === 'form' && (
<CitizenForm onSubmit={handleFormSubmit} initialReferrer={startParam} />
)}
{step === 'processing' && citizenshipData && (
<CitizenProcessing
+3 -3
View File
@@ -1,5 +1,5 @@
{
"version": "1.0.225",
"buildTime": "2026-02-26T22:51:27.298Z",
"buildNumber": 1772146287300
"version": "1.0.226",
"buildTime": "2026-02-27T22:59:11.026Z",
"buildNumber": 1772233151029
}