mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-10-28 21:39:49 +00:00
feat: add i18n support (6 langs) to governance and finance pages
- Add assembly/justice/polls/bank/taxZekat translation keys to all 6 locale files: en, kmr (Kurmanji), ckb (Sorani), tr, ar, fa - Wire useTranslation() into AssemblyPage, JusticePage, PollsPage, BankPage, TaxZekatPage — all hardcoded bilingual strings replaced - TaxZekat success message now uses i18n key with amount interpolation
This commit is contained in:
1 parent
f22ad439e4
commit
b965b4a507
11 files changed
+738
-154
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface SavingsAccount {
|
||||
id: string;
|
||||
@@ -23,35 +24,36 @@ interface LendingPool {
|
||||
}
|
||||
|
||||
const SAVINGS: SavingsAccount[] = [
|
||||
{ id: 's1', emoji: '🌱', nameKu: 'Teserûfa Destpêk', name: 'Starter Savings', apy: '4.5%', minDeposit: '100 HEZ', lockPeriod: 'Tune / None', totalDeposited: '125,430 HEZ' },
|
||||
{ id: 's2', emoji: '🌿', nameKu: 'Teserûfa Navîn', name: 'Growth Savings', apy: '8.2%', minDeposit: '1,000 HEZ', lockPeriod: '90 roj / days', totalDeposited: '892,100 HEZ' },
|
||||
{ id: 's3', emoji: '🌳', nameKu: 'Teserûfa Zêrîn', name: 'Gold Savings', apy: '12.0%', minDeposit: '10,000 HEZ', lockPeriod: '365 roj / days', totalDeposited: '2,340,000 HEZ' },
|
||||
{ id: 's1', emoji: '🌱', nameKu: 'Teserûfa Destpêk', name: 'Starter Savings', apy: '4.5%', minDeposit: '100 HEZ', lockPeriod: 'None', totalDeposited: '125,430 HEZ' },
|
||||
{ id: 's2', emoji: '🌿', nameKu: 'Teserûfa Navîn', name: 'Growth Savings', apy: '8.2%', minDeposit: '1,000 HEZ', lockPeriod: '90 days', totalDeposited: '892,100 HEZ' },
|
||||
{ id: 's3', emoji: '🌳', nameKu: 'Teserûfa Zêrîn', name: 'Gold Savings', apy: '12.0%', minDeposit: '10,000 HEZ', lockPeriod: '365 days', totalDeposited: '2,340,000 HEZ' },
|
||||
];
|
||||
|
||||
const LENDING: LendingPool[] = [
|
||||
{ id: 'l1', emoji: '💳', nameKu: 'Deyna Bilez', name: 'Flash Loan', borrowRate: '0.1%', collateralRatio: 'Tune / None', available: '50,000 HEZ' },
|
||||
{ id: 'l2', emoji: '🏠', nameKu: 'Deyna Kesane', name: 'Personal Loan', borrowRate: '5.5%', collateralRatio: '150%', available: '200,000 HEZ' },
|
||||
{ id: 'l3', emoji: '🏢', nameKu: 'Deyna Karsaziyê', name: 'Business Loan', borrowRate: '3.8%', collateralRatio: '200%', available: '500,000 HEZ' },
|
||||
{ id: 'l1', emoji: '💳', nameKu: 'Deyna Bilez', name: 'Flash Loan', borrowRate: '0.1%', collateralRatio: 'None', available: '50,000 HEZ' },
|
||||
{ id: 'l2', emoji: '🏠', nameKu: 'Deyna Kesane', name: 'Personal Loan', borrowRate: '5.5%', collateralRatio: '150%', available: '200,000 HEZ' },
|
||||
{ id: 'l3', emoji: '🏢', nameKu: 'Deyna Karsaziyê', name: 'Business Loan', borrowRate: '3.8%', collateralRatio: '200%', available: '500,000 HEZ' },
|
||||
];
|
||||
|
||||
const TREASURY_ALLOCATIONS = [
|
||||
{ label: 'Perwerde / Education', pct: '25%', color: '#00A94F' },
|
||||
{ label: 'Teknolojî / Technology', pct: '30%', color: '#2196F3' },
|
||||
{ label: 'Ewlehî / Security', pct: '15%', color: '#EE2A35' },
|
||||
{ label: 'Civak / Community', pct: '20%', color: '#9C27B0' },
|
||||
{ label: 'Pareztî / Reserve', pct: '10%', color: '#FFD700' },
|
||||
{ labelKu: 'Perwerde', labelEn: 'Education', pct: '25%', color: '#00A94F' },
|
||||
{ labelKu: 'Teknolojî', labelEn: 'Technology', pct: '30%', color: '#2196F3' },
|
||||
{ labelKu: 'Ewlehî', labelEn: 'Security', pct: '15%', color: '#EE2A35' },
|
||||
{ labelKu: 'Civak', labelEn: 'Community', pct: '20%', color: '#9C27B0' },
|
||||
{ labelKu: 'Pareztî', labelEn: 'Reserve', pct: '10%', color: '#FFD700' },
|
||||
];
|
||||
|
||||
type Tab = 'savings' | 'lending' | 'treasury';
|
||||
|
||||
export default function BankPage() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const [activeTab, setActiveTab] = useState<Tab>('savings');
|
||||
|
||||
const tabs: { key: Tab; label: string }[] = [
|
||||
{ key: 'savings', label: 'Teserûf' },
|
||||
{ key: 'lending', label: 'Deyn' },
|
||||
{ key: 'treasury', label: 'Xezîne' },
|
||||
{ key: 'savings', label: t('bank.tab.savings', 'Savings') },
|
||||
{ key: 'lending', label: t('bank.tab.lending', 'Lending') },
|
||||
{ key: 'treasury', label: t('bank.tab.treasury', 'Treasury') },
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -60,15 +62,15 @@ export default function BankPage() {
|
||||
<div className="bg-green-700 px-4 pt-4 pb-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<button onClick={() => navigate(-1)} className="text-white/80 hover:text-white text-xl leading-none">←</button>
|
||||
<span className="text-sm text-white/70">Finance</span>
|
||||
<span className="text-sm text-white/70">{t('bank.breadcrumb', 'Finance')}</span>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<span className="text-5xl block mb-2">🏦</span>
|
||||
<h1 className="text-2xl font-bold text-white">Banka Dijîtal</h1>
|
||||
<p className="text-white/70 text-sm mt-0.5">Digital Bank of Kurdistan</p>
|
||||
<h1 className="text-2xl font-bold text-white">{t('bank.title', 'Digital Bank')}</h1>
|
||||
<p className="text-white/70 text-sm mt-0.5">{t('bank.subtitle', 'Digital Bank of Kurdistan')}</p>
|
||||
</div>
|
||||
<div className="mt-4 bg-white/10 rounded-2xl p-4 text-center">
|
||||
<p className="text-white/60 text-xs">Bihaya Giştî / Total Value</p>
|
||||
<p className="text-white/60 text-xs">{t('bank.totalValue', 'Total Value')}</p>
|
||||
<p className="text-3xl font-bold text-white mt-1">24,580.00 HEZ</p>
|
||||
<p className="text-yellow-400 text-sm mt-0.5">~ $1,229.00</p>
|
||||
</div>
|
||||
@@ -82,9 +84,7 @@ export default function BankPage() {
|
||||
key={tab.key}
|
||||
onClick={() => setActiveTab(tab.key)}
|
||||
className={`flex-1 py-2.5 rounded-lg text-sm font-semibold transition-all ${
|
||||
activeTab === tab.key
|
||||
? 'bg-green-600 text-white'
|
||||
: 'text-gray-400 hover:text-gray-300'
|
||||
activeTab === tab.key ? 'bg-green-600 text-white' : 'text-gray-400 hover:text-gray-300'
|
||||
}`}
|
||||
>
|
||||
{tab.label}
|
||||
@@ -100,10 +100,8 @@ export default function BankPage() {
|
||||
{activeTab === 'savings' && (
|
||||
<>
|
||||
<div className="mb-1">
|
||||
<h2 className="font-bold text-white text-base">Hesabên Teserûfê / Savings Accounts</h2>
|
||||
<p className="text-xs text-gray-400 mt-0.5">
|
||||
Tokenên xwe stake bikin û xelatên salane bistînin. · Stake your tokens and earn annual rewards.
|
||||
</p>
|
||||
<h2 className="font-bold text-white text-base">{t('bank.savings.title', 'Savings Accounts')}</h2>
|
||||
<p className="text-xs text-gray-400 mt-0.5">{t('bank.savings.desc', 'Stake your tokens and earn annual rewards.')}</p>
|
||||
</div>
|
||||
{SAVINGS.map(account => (
|
||||
<div key={account.id} className="bg-gray-900 rounded-xl p-4">
|
||||
@@ -119,20 +117,20 @@ export default function BankPage() {
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2 bg-gray-800 rounded-xl p-3 mb-3">
|
||||
<div className="text-center">
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">Kêmtirîn / Min</p>
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">{t('bank.savings.min', 'Min')}</p>
|
||||
<p className="text-xs font-semibold text-gray-300">{account.minDeposit}</p>
|
||||
</div>
|
||||
<div className="text-center border-x border-gray-700">
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">Kilîtkirin / Lock</p>
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">{t('bank.savings.lock', 'Lock')}</p>
|
||||
<p className="text-xs font-semibold text-gray-300">{account.lockPeriod}</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">Giştî / Total</p>
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">{t('bank.savings.total', 'Total')}</p>
|
||||
<p className="text-xs font-semibold text-gray-300">{account.totalDeposited}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button className="w-full py-2.5 bg-green-600 hover:bg-green-500 rounded-xl text-white font-semibold text-sm transition-colors">
|
||||
Depo bike / Deposit
|
||||
{t('bank.savings.deposit', 'Deposit')}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
@@ -143,10 +141,8 @@ export default function BankPage() {
|
||||
{activeTab === 'lending' && (
|
||||
<>
|
||||
<div className="mb-1">
|
||||
<h2 className="font-bold text-white text-base">Hovzên Deyndanê / Lending Pools</h2>
|
||||
<p className="text-xs text-gray-400 mt-0.5">
|
||||
Bi rêya peymana zîrek deyn bistînin. · Borrow through smart contracts with collateral.
|
||||
</p>
|
||||
<h2 className="font-bold text-white text-base">{t('bank.lending.title', 'Lending Pools')}</h2>
|
||||
<p className="text-xs text-gray-400 mt-0.5">{t('bank.lending.desc', 'Borrow through smart contracts with collateral.')}</p>
|
||||
</div>
|
||||
{LENDING.map(pool => (
|
||||
<div key={pool.id} className="bg-gray-900 rounded-xl p-4">
|
||||
@@ -162,20 +158,20 @@ export default function BankPage() {
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2 bg-gray-800 rounded-xl p-3 mb-3">
|
||||
<div className="text-center">
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">Rêje / Rate</p>
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">{t('bank.lending.rate', 'Rate')}</p>
|
||||
<p className="text-xs font-semibold text-gray-300">{pool.borrowRate}</p>
|
||||
</div>
|
||||
<div className="text-center border-x border-gray-700">
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">Garantî / Collateral</p>
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">{t('bank.lending.collateral', 'Collateral')}</p>
|
||||
<p className="text-xs font-semibold text-gray-300">{pool.collateralRatio}</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">Peyda / Available</p>
|
||||
<p className="text-[10px] text-gray-500 mb-0.5">{t('bank.lending.available', 'Available')}</p>
|
||||
<p className="text-xs font-semibold text-gray-300">{pool.available}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button className="w-full py-2.5 bg-blue-600 hover:bg-blue-500 rounded-xl text-white font-semibold text-sm transition-colors">
|
||||
Deyn bistîne / Borrow
|
||||
{t('bank.lending.borrow', 'Borrow')}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
@@ -186,23 +182,21 @@ export default function BankPage() {
|
||||
{activeTab === 'treasury' && (
|
||||
<>
|
||||
<div className="mb-1">
|
||||
<h2 className="font-bold text-white text-base">Xezîneya Civakê / Community Treasury</h2>
|
||||
<p className="text-xs text-gray-400 mt-0.5">
|
||||
Xezîneya giştî ya Komara Dijîtal a Kurdistanê. · The public treasury of the Digital Kurdistan Republic.
|
||||
</p>
|
||||
<h2 className="font-bold text-white text-base">{t('bank.treasury.title', 'Community Treasury')}</h2>
|
||||
<p className="text-xs text-gray-400 mt-0.5">{t('bank.treasury.desc', 'The public treasury of the Digital Kurdistan Republic.')}</p>
|
||||
</div>
|
||||
<div className="bg-gray-900 rounded-xl p-6 text-center">
|
||||
<p className="text-xs text-gray-400">Bihaya Xezîneyê / Treasury Balance</p>
|
||||
<p className="text-xs text-gray-400">{t('bank.treasury.balance', 'Treasury Balance')}</p>
|
||||
<p className="text-3xl font-bold text-green-400 mt-2">12,450,000 HEZ</p>
|
||||
<p className="text-gray-400 text-sm mt-1">~ $622,500</p>
|
||||
</div>
|
||||
<div className="bg-gray-900 rounded-xl p-4">
|
||||
<p className="font-bold text-white mb-3">Dabeşkirin / Allocation</p>
|
||||
<p className="font-bold text-white mb-3">{t('bank.treasury.allocation', 'Allocation')}</p>
|
||||
<div className="space-y-3">
|
||||
{TREASURY_ALLOCATIONS.map((item, i) => (
|
||||
<div key={i} className="flex items-center gap-3">
|
||||
<div className="w-3 h-3 rounded-full flex-shrink-0" style={{ backgroundColor: item.color }} />
|
||||
<span className="flex-1 text-sm text-gray-300">{item.label}</span>
|
||||
<span className="flex-1 text-sm text-gray-300">{item.labelKu} / {item.labelEn}</span>
|
||||
<span className="font-bold text-white text-sm">{item.pct}</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useState, useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { usePezkuwi } from '@/contexts/PezkuwiContext';
|
||||
|
||||
type ContributionType = 'zekat' | 'tax';
|
||||
@@ -25,6 +26,7 @@ const DEFAULT_ALLOCATIONS: AllocationItem[] = [
|
||||
|
||||
export default function TaxZekatPage() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const { api, selectedAccount, getKeyPair } = usePezkuwi();
|
||||
|
||||
const [contributionType, setContributionType] = useState<ContributionType>('zekat');
|
||||
@@ -96,7 +98,7 @@ export default function TaxZekatPage() {
|
||||
.catch(reject);
|
||||
});
|
||||
|
||||
setResult({ ok: true, msg: `${amount} HEZ başarıyla gönderildi. Spas!` });
|
||||
setResult({ ok: true, msg: t('taxZekat.success', '{{amount}} HEZ sent successfully. Thank you!', { amount }) });
|
||||
setAmount('');
|
||||
setAllocations(DEFAULT_ALLOCATIONS);
|
||||
setTermsAccepted(false);
|
||||
@@ -117,9 +119,9 @@ export default function TaxZekatPage() {
|
||||
<button onClick={() => navigate(-1)} className="text-white/80 hover:text-white text-xl leading-none">←</button>
|
||||
<div>
|
||||
<h1 className="font-bold text-lg">
|
||||
{isZekat ? '🤲 Zekat' : '📜 Bac / Tax'}
|
||||
{isZekat ? '🤲 Zekat' : `📜 ${t('taxZekat.title', 'Tax & Zekat')}`}
|
||||
</h1>
|
||||
<p className="text-white/70 text-xs">Komara Dijîtal a Kurdistanê</p>
|
||||
<p className="text-white/70 text-xs">{t('taxZekat.subtitle', 'Digital Kurdistan Republic')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -135,31 +137,28 @@ export default function TaxZekatPage() {
|
||||
{/* Description */}
|
||||
<div className="bg-gray-900 rounded-xl p-4 border-l-4" style={{ borderColor: accentColor }}>
|
||||
<p className="text-sm text-gray-200 leading-relaxed">
|
||||
Beşdariya xwe ya bi dilxwazî ji Komara Dijîtaliya Kurdistanê re bişînin.
|
||||
</p>
|
||||
<p className="text-xs text-gray-400 mt-1 italic">
|
||||
Send your voluntary contribution to the Digital Kurdistan Republic.
|
||||
{t('taxZekat.desc', 'Send your voluntary contribution to the Digital Kurdistan Republic.')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Type selector */}
|
||||
<div className="bg-gray-900 rounded-xl p-4">
|
||||
<p className="text-sm font-bold text-gray-300 mb-3">Cureyê Beşdariyê / Contribution Type</p>
|
||||
<p className="text-sm font-bold text-gray-300 mb-3">{t('taxZekat.type.label', 'Contribution Type')}</p>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{(['zekat', 'tax'] as ContributionType[]).map(type => (
|
||||
<button
|
||||
key={type}
|
||||
onClick={() => setContributionType(type)}
|
||||
className={`rounded-xl p-4 text-center border-2 transition-all ${
|
||||
contributionType === type
|
||||
? 'border-current bg-white/5'
|
||||
: 'border-gray-700 bg-gray-800/50'
|
||||
contributionType === type ? 'border-current bg-white/5' : 'border-gray-700 bg-gray-800/50'
|
||||
}`}
|
||||
style={{ borderColor: contributionType === type ? accentColor : undefined }}
|
||||
>
|
||||
<div className="text-3xl mb-1">{type === 'zekat' ? '🤲' : '📜'}</div>
|
||||
<p className="font-bold text-white">{type === 'zekat' ? 'Zekat' : 'Bac'}</p>
|
||||
<p className="text-xs text-gray-400">{type === 'zekat' ? 'Islamic Zekat' : 'Vergi / Tax'}</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
{type === 'zekat' ? t('taxZekat.type.zekatSub', 'Islamic Zekat') : t('taxZekat.type.taxSub', 'Tax')}
|
||||
</p>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -167,7 +166,7 @@ export default function TaxZekatPage() {
|
||||
|
||||
{/* Amount */}
|
||||
<div className="bg-gray-900 rounded-xl p-4">
|
||||
<p className="text-sm font-bold text-gray-300 mb-3">Miqdar / Amount</p>
|
||||
<p className="text-sm font-bold text-gray-300 mb-3">{t('taxZekat.amount.label', 'Amount')}</p>
|
||||
<div className="flex items-center bg-gray-800 rounded-xl border border-gray-700 overflow-hidden">
|
||||
<input
|
||||
type="number"
|
||||
@@ -179,14 +178,14 @@ export default function TaxZekatPage() {
|
||||
<span className="pr-4 text-lg font-bold" style={{ color: accentColor }}>HEZ</span>
|
||||
</div>
|
||||
{!selectedAccount && (
|
||||
<p className="text-xs text-amber-400 mt-2">⚠️ Cüzdan bağlı değil / Wallet not connected</p>
|
||||
<p className="text-xs text-amber-400 mt-2">{t('taxZekat.walletNotConnected', '⚠️ Wallet not connected')}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Allocation */}
|
||||
<div className="bg-gray-900 rounded-xl p-4">
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<p className="text-sm font-bold text-gray-300">Dabeşkirina Fonê / Fund Allocation</p>
|
||||
<p className="text-sm font-bold text-gray-300">{t('taxZekat.allocation.title', 'Fund Allocation')}</p>
|
||||
<span className={`px-2 py-0.5 rounded-full text-xs font-bold ${
|
||||
totalPercentage === 100 ? 'bg-green-900 text-green-400' :
|
||||
totalPercentage > 100 ? 'bg-red-900 text-red-400' : 'bg-gray-800 text-gray-400'
|
||||
@@ -194,7 +193,7 @@ export default function TaxZekatPage() {
|
||||
{totalPercentage}%
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 mb-3">Divê bêkêmasî %100 be / Must equal exactly 100%</p>
|
||||
<p className="text-xs text-gray-500 mb-3">{t('taxZekat.allocation.desc', 'Must equal exactly 100%')}</p>
|
||||
|
||||
<div className="space-y-2">
|
||||
{allocations.map(item => (
|
||||
@@ -231,31 +230,23 @@ export default function TaxZekatPage() {
|
||||
style={{ borderColor: isZekat ? '#00A94F30' : '#D4A01730' }}>
|
||||
<div className="text-center mb-3">
|
||||
<span className="text-4xl">{isZekat ? '🤲' : '📜'}</span>
|
||||
<p className="font-bold text-white mt-2">SOZNAME / COMMITMENT</p>
|
||||
<p className="font-bold text-white mt-2">{t('taxZekat.commitment.title', 'COMMITMENT')}</p>
|
||||
</div>
|
||||
{isZekat ? (
|
||||
<p className="text-xs text-gray-400 leading-relaxed">
|
||||
Komara Dîjîtal a Kurdistanê SOZ DIDE ku zekata we BI TEMAMÎ li gorî rêjeyên ku we destnîşan kirine dê bê xerckirin, li gorî rêgez û qaîdeyên Îslamî.
|
||||
<br /><br />
|
||||
<span className="text-gray-500">The Digital Republic of Kurdistan COMMITS to spending your zekat EXACTLY according to the ratios you specify, in accordance with Islamic principles.</span>
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-xs text-gray-400 leading-relaxed">
|
||||
Komara Dîjîtal a Kurdistanê SOZ DIDE ku beşdariyên baca we BI QASÎ KU MIMKUN BE li gorî rêjeyên ku we destnîşan kirine dê bê xerckirin. Hemû lêçûn dê bi şefafî li ser blockchain werin tomar kirin.
|
||||
<br /><br />
|
||||
<span className="text-gray-500">The Digital Republic of Kurdistan COMMITS to using your tax contributions AS CLOSELY AS POSSIBLE according to the ratios you specify. All expenses will be transparently recorded on the blockchain.</span>
|
||||
</p>
|
||||
)}
|
||||
<p className="text-xs text-gray-400 leading-relaxed">
|
||||
{isZekat
|
||||
? t('taxZekat.commitment.zekat', 'The Digital Republic of Kurdistan COMMITS to spending your zekat EXACTLY according to the ratios you specify, in accordance with Islamic principles.')
|
||||
: t('taxZekat.commitment.tax', 'The Digital Republic of Kurdistan COMMITS to using your tax contributions AS CLOSELY AS POSSIBLE according to the ratios you specify. All expenses will be transparently recorded on the blockchain.')}
|
||||
</p>
|
||||
|
||||
<button
|
||||
onClick={() => setTermsAccepted(!termsAccepted)}
|
||||
className="flex items-center gap-3 mt-4 w-full bg-gray-800 rounded-xl p-3"
|
||||
>
|
||||
<div className={`w-6 h-6 rounded-md border-2 flex items-center justify-center flex-shrink-0 transition-colors`}
|
||||
<div className="w-6 h-6 rounded-md border-2 flex items-center justify-center flex-shrink-0 transition-colors"
|
||||
style={{ borderColor: accentColor, backgroundColor: termsAccepted ? accentColor : 'transparent' }}>
|
||||
{termsAccepted && <span className="text-white text-xs font-bold">✓</span>}
|
||||
</div>
|
||||
<span className="text-sm text-gray-300 text-left">Min xwend û qebûl dikim / I have read and accept</span>
|
||||
<span className="text-sm text-gray-300 text-left">{t('taxZekat.accept', 'I have read and accept')}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -267,8 +258,10 @@ export default function TaxZekatPage() {
|
||||
style={{ backgroundColor: accentColor }}
|
||||
>
|
||||
{isSubmitting
|
||||
? '⏳ Tê şandin...'
|
||||
: isZekat ? '🤲 ZEKAT BIŞÎNE' : '📤 BAC BIŞÎNE'}
|
||||
? t('taxZekat.submitting', '⏳ Sending...')
|
||||
: isZekat
|
||||
? t('taxZekat.submit.zekat', '🤲 SEND ZEKAT')
|
||||
: t('taxZekat.submit.tax', '📤 SEND TAX')}
|
||||
</button>
|
||||
|
||||
<div className="h-6" />
|
||||
@@ -278,19 +271,19 @@ export default function TaxZekatPage() {
|
||||
{showConfirm && (
|
||||
<div className="fixed inset-0 z-50 bg-black/70 flex items-center justify-center p-4">
|
||||
<div className="bg-gray-900 rounded-2xl p-6 w-full max-w-sm border border-gray-700">
|
||||
<h3 className="text-lg font-bold text-white text-center mb-4">Piştrast bike / Confirm</h3>
|
||||
<h3 className="text-lg font-bold text-white text-center mb-4">{t('taxZekat.confirm.title', 'Confirm')}</h3>
|
||||
|
||||
<div className="bg-gray-800 rounded-xl p-4 space-y-2 mb-4 text-sm">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-400">Cure / Type:</span>
|
||||
<span className="text-gray-400">{t('taxZekat.confirm.type', 'Type')}:</span>
|
||||
<span className="text-white font-semibold">{isZekat ? 'Zekat' : 'Bac / Tax'}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-400">Miqdar / Amount:</span>
|
||||
<span className="text-gray-400">{t('taxZekat.confirm.amount', 'Amount')}:</span>
|
||||
<span className="font-bold" style={{ color: accentColor }}>{amount} HEZ</span>
|
||||
</div>
|
||||
<div className="border-t border-gray-700 pt-2 mt-2">
|
||||
<p className="text-gray-400 text-xs mb-2">Dabeşkirin / Allocation:</p>
|
||||
<p className="text-gray-400 text-xs mb-2">{t('taxZekat.confirm.allocation', 'Allocation')}:</p>
|
||||
{allocations.filter(a => a.percentage > 0).map(a => (
|
||||
<div key={a.id} className="flex justify-between text-xs py-0.5">
|
||||
<span className="text-gray-300">{a.icon} {a.nameKu}</span>
|
||||
@@ -305,14 +298,14 @@ export default function TaxZekatPage() {
|
||||
onClick={() => setShowConfirm(false)}
|
||||
className="py-3 rounded-xl bg-gray-800 text-gray-300 font-semibold"
|
||||
>
|
||||
Betal / Cancel
|
||||
{t('taxZekat.confirm.cancel', 'Cancel')}
|
||||
</button>
|
||||
<button
|
||||
onClick={confirmAndSend}
|
||||
className="py-3 rounded-xl text-white font-bold"
|
||||
style={{ backgroundColor: accentColor }}
|
||||
>
|
||||
✓ Piştrast
|
||||
✓ {t('taxZekat.confirm.confirm', 'Confirm')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface Member {
|
||||
id: string;
|
||||
@@ -37,36 +38,43 @@ const SESSIONS: Session[] = [
|
||||
{ id: 's4', titleKu: 'Civîna Yasadanînê #11', title: 'Legislative Session #11', date: '2026-03-15', status: 'completed', agenda: 'Citizenship criteria, NFT standards, community grants.' },
|
||||
];
|
||||
|
||||
const STATUS_CONFIG = {
|
||||
upcoming: { label: 'Tê / Upcoming', cls: 'bg-blue-900/50 text-blue-400' },
|
||||
'in-session': { label: 'Niha / In Session', cls: 'bg-green-900/50 text-green-400' },
|
||||
completed: { label: 'Qediya / Completed', cls: 'bg-gray-800 text-gray-400' },
|
||||
};
|
||||
|
||||
type Tab = 'members' | 'sessions';
|
||||
|
||||
export default function AssemblyPage() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const [activeTab, setActiveTab] = useState<Tab>('members');
|
||||
|
||||
const sessionStatusLabel = (status: Session['status']) => {
|
||||
if (status === 'upcoming') return t('assembly.session.upcoming', 'Upcoming');
|
||||
if (status === 'in-session') return t('assembly.session.inSession', 'In Session');
|
||||
return t('assembly.session.completed', 'Completed');
|
||||
};
|
||||
|
||||
const sessionStatusCls = (status: Session['status']) => {
|
||||
if (status === 'upcoming') return 'bg-blue-900/50 text-blue-400';
|
||||
if (status === 'in-session') return 'bg-green-900/50 text-green-400';
|
||||
return 'bg-gray-800 text-gray-400';
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-950 text-white">
|
||||
{/* Header */}
|
||||
<div className="bg-green-700 px-4 pt-4 pb-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<button onClick={() => navigate(-1)} className="text-white/80 hover:text-white text-xl">←</button>
|
||||
<span className="text-sm text-white/70">Governance</span>
|
||||
<span className="text-sm text-white/70">{t('assembly.breadcrumb', 'Governance')}</span>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<span className="text-5xl block mb-2">🏛️</span>
|
||||
<h1 className="text-2xl font-bold">Meclîsa Kurdistanê</h1>
|
||||
<p className="text-white/70 text-sm mt-0.5">Kurdistan Digital Assembly</p>
|
||||
<h1 className="text-2xl font-bold">{t('assembly.title', 'Kurdistan Digital Assembly')}</h1>
|
||||
<p className="text-white/70 text-sm mt-0.5">{t('assembly.subtitle', 'Kurdistan Digital Assembly')}</p>
|
||||
</div>
|
||||
<div className="mt-4 flex bg-white/10 rounded-2xl overflow-hidden">
|
||||
{[
|
||||
{ val: MEMBERS.length, label: 'Endam / Members' },
|
||||
{ val: 4, label: 'Komîte / Committees' },
|
||||
{ val: 12, label: 'Civîn / Sessions' },
|
||||
{ val: MEMBERS.length, label: t('assembly.stats.members', 'Members') },
|
||||
{ val: 4, label: t('assembly.stats.committees', 'Committees') },
|
||||
{ val: 12, label: t('assembly.stats.sessions', 'Sessions') },
|
||||
].map((stat, i) => (
|
||||
<div key={i} className={`flex-1 py-3 text-center ${i > 0 ? 'border-l border-white/20' : ''}`}>
|
||||
<p className="text-xl font-bold text-white">{stat.val}</p>
|
||||
@@ -87,7 +95,7 @@ export default function AssemblyPage() {
|
||||
activeTab === tab ? 'bg-green-600 text-white' : 'text-gray-400'
|
||||
}`}
|
||||
>
|
||||
{tab === 'members' ? 'Endam / Members' : 'Civîn / Sessions'}
|
||||
{tab === 'members' ? t('assembly.tab.members', 'Members') : t('assembly.tab.sessions', 'Sessions')}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -103,28 +111,25 @@ export default function AssemblyPage() {
|
||||
<p className="text-gray-500 text-xs">{m.role}</p>
|
||||
<div className="flex gap-3 mt-1.5 text-xs text-gray-500">
|
||||
<span>📍 {m.region}</span>
|
||||
<span>Ji {m.since}</span>
|
||||
<span>{t('assembly.member.since', 'Since')} {m.since}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{activeTab === 'sessions' && SESSIONS.map(s => {
|
||||
const cfg = STATUS_CONFIG[s.status];
|
||||
return (
|
||||
<div key={s.id} className="bg-gray-900 rounded-xl p-4">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${cfg.cls}`}>
|
||||
{cfg.label}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">{s.date}</span>
|
||||
</div>
|
||||
<p className="font-bold text-white">{s.titleKu}</p>
|
||||
<p className="text-gray-400 text-sm mb-2">{s.title}</p>
|
||||
<p className="text-gray-500 text-xs leading-relaxed">{s.agenda}</p>
|
||||
{activeTab === 'sessions' && SESSIONS.map(s => (
|
||||
<div key={s.id} className="bg-gray-900 rounded-xl p-4">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${sessionStatusCls(s.status)}`}>
|
||||
{sessionStatusLabel(s.status)}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">{s.date}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<p className="font-bold text-white">{s.titleKu}</p>
|
||||
<p className="text-gray-400 text-sm mb-2">{s.title}</p>
|
||||
<p className="text-gray-500 text-xs leading-relaxed">{s.agenda}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="h-10" />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface DisputeCase {
|
||||
id: string;
|
||||
@@ -45,14 +46,9 @@ const CASES: DisputeCase[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const STATUS_CONFIG = {
|
||||
'open': { label: 'Vekirî / Open', cls: 'bg-red-900/50 text-red-400', dot: 'bg-red-400' },
|
||||
'in-review': { label: 'Di lêkolînê de / In Review', cls: 'bg-yellow-900/50 text-yellow-400', dot: 'bg-yellow-400' },
|
||||
'resolved': { label: 'Çareserkirî / Resolved', cls: 'bg-green-900/50 text-green-400', dot: 'bg-green-400' },
|
||||
};
|
||||
|
||||
export default function JusticePage() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const [expanded, setExpanded] = useState<string | null>(null);
|
||||
|
||||
const counts = {
|
||||
@@ -61,18 +57,30 @@ export default function JusticePage() {
|
||||
resolved: CASES.filter(c => c.status === 'resolved').length,
|
||||
};
|
||||
|
||||
const statusLabel = (status: DisputeCase['status']) => {
|
||||
if (status === 'open') return t('justice.status.open', 'Open');
|
||||
if (status === 'in-review') return t('justice.status.inReview', 'In Review');
|
||||
return t('justice.status.resolved', 'Resolved');
|
||||
};
|
||||
|
||||
const statusCls = (status: DisputeCase['status']) => {
|
||||
if (status === 'open') return 'bg-red-900/50 text-red-400';
|
||||
if (status === 'in-review') return 'bg-yellow-900/50 text-yellow-400';
|
||||
return 'bg-green-900/50 text-green-400';
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-950 text-white">
|
||||
{/* Header */}
|
||||
<div className="bg-green-700 px-4 pt-4 pb-5">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<button onClick={() => navigate(-1)} className="text-white/80 hover:text-white text-xl">←</button>
|
||||
<span className="text-sm text-white/70">Governance</span>
|
||||
<span className="text-sm text-white/70">{t('justice.breadcrumb', 'Governance')}</span>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<span className="text-5xl block mb-2">⚖️</span>
|
||||
<h1 className="text-2xl font-bold">Dadwerî</h1>
|
||||
<p className="text-white/70 text-sm mt-0.5">Justice & Dispute Resolution</p>
|
||||
<h1 className="text-2xl font-bold">{t('justice.title', 'Justice & Dispute Resolution')}</h1>
|
||||
<p className="text-white/70 text-sm mt-0.5">{t('justice.subtitle', 'Justice & Dispute Resolution')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -80,39 +88,35 @@ export default function JusticePage() {
|
||||
{/* Stats */}
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
{[
|
||||
{ label: 'Vekirî\nOpen', val: counts['open'], color: 'border-l-red-500' },
|
||||
{ label: 'Lêkolîn\nIn Review', val: counts['in-review'], color: 'border-l-yellow-500' },
|
||||
{ label: 'Çareser\nResolved', val: counts['resolved'], color: 'border-l-green-500' },
|
||||
{ label: t('justice.stats.open', 'Open'), val: counts['open'], color: 'border-l-red-500' },
|
||||
{ label: t('justice.stats.inReview', 'In Review'), val: counts['in-review'], color: 'border-l-yellow-500' },
|
||||
{ label: t('justice.stats.resolved', 'Resolved'), val: counts['resolved'], color: 'border-l-green-500' },
|
||||
].map((s, i) => (
|
||||
<div key={i} className={`bg-gray-900 rounded-xl p-4 text-center border-l-4 ${s.color}`}>
|
||||
<p className="text-2xl font-bold text-white">{s.val}</p>
|
||||
<p className="text-[10px] text-gray-400 mt-1 whitespace-pre-line leading-tight">{s.label}</p>
|
||||
<p className="text-[10px] text-gray-400 mt-1 leading-tight">{s.label}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Info */}
|
||||
<div className="bg-gray-900 rounded-xl p-4 border-l-4 border-l-green-600">
|
||||
<p className="font-bold text-white text-sm mb-2">Çareserkirina Nakokiyan / Dispute Resolution</p>
|
||||
<p className="font-bold text-white text-sm mb-2">{t('justice.info.title', 'Dispute Resolution')}</p>
|
||||
<p className="text-xs text-gray-400 leading-relaxed">
|
||||
Sîstema dadweriya dijîtal a Kurdistanê nakokiyên di navbera welatiyên dijîtal de bi awayekî adil û zelal çareser dike. Hemû biryar li ser blockchain tên tomarkirin.
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mt-2 leading-relaxed italic">
|
||||
Kurdistan's digital justice system resolves disputes between digital citizens fairly and transparently. All decisions are recorded on the blockchain.
|
||||
{t('justice.info.body', "Kurdistan's digital justice system resolves disputes between digital citizens fairly and transparently. All decisions are recorded on the blockchain.")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Cases */}
|
||||
<h2 className="font-bold text-white text-base pt-1">Dozên Dawî / Recent Cases</h2>
|
||||
<h2 className="font-bold text-white text-base pt-1">{t('justice.cases.title', 'Recent Cases')}</h2>
|
||||
{CASES.map(c => {
|
||||
const cfg = STATUS_CONFIG[c.status];
|
||||
const isOpen = expanded === c.id;
|
||||
return (
|
||||
<div key={c.id} className="bg-gray-900 rounded-xl p-4">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-blue-400 text-xs font-semibold">{c.caseNumber}</span>
|
||||
<span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${cfg.cls}`}>
|
||||
{cfg.label}
|
||||
<span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${statusCls(c.status)}`}>
|
||||
{statusLabel(c.status)}
|
||||
</span>
|
||||
</div>
|
||||
<p className="font-bold text-white">{c.titleKu}</p>
|
||||
@@ -127,9 +131,9 @@ export default function JusticePage() {
|
||||
<p className="text-sm text-gray-300 leading-relaxed">{c.description}</p>
|
||||
{c.resolution && (
|
||||
<div className="bg-green-900/20 border border-green-800/50 rounded-xl p-3">
|
||||
<p className="text-green-400 text-xs font-bold mb-1">Biryar / Resolution:</p>
|
||||
<p className="text-green-400 text-xs font-bold mb-1">{t('justice.case.resolution', 'Resolution')}:</p>
|
||||
<p className="text-gray-300 text-xs leading-relaxed">{c.resolution}</p>
|
||||
<p className="text-gray-500 text-xs mt-2">Dîroka çareseriyê: {c.resolvedDate}</p>
|
||||
<p className="text-gray-500 text-xs mt-2">{t('justice.case.resolvedDate', 'Resolution date')}: {c.resolvedDate}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -139,7 +143,7 @@ export default function JusticePage() {
|
||||
onClick={() => setExpanded(isOpen ? null : c.id)}
|
||||
className="mt-2 text-green-400 text-xs font-medium w-full text-center"
|
||||
>
|
||||
{isOpen ? '▲ Kêmtir' : '▼ Bêtir'}
|
||||
{isOpen ? t('justice.case.less', '▲ Less') : t('justice.case.more', '▼ More')}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface PollOption {
|
||||
id: string;
|
||||
@@ -41,9 +42,9 @@ const INITIAL_POLLS: Poll[] = [
|
||||
description: 'Proposal to reduce transaction fees by 50% for the next quarter.',
|
||||
status: 'active', totalVotes: 521, endsAt: '2026-04-15',
|
||||
options: [
|
||||
{ id: '2a', text: 'Ere / Yes', votes: 389 },
|
||||
{ id: '2b', text: 'Na / No', votes: 87 },
|
||||
{ id: '2c', text: 'Bêalî / Abstain', votes: 45 },
|
||||
{ id: '2a', text: 'Yes', votes: 389 },
|
||||
{ id: '2b', text: 'No', votes: 87 },
|
||||
{ id: '2c', text: 'Abstain', votes: 45 },
|
||||
],
|
||||
userVoted: null,
|
||||
},
|
||||
@@ -54,10 +55,10 @@ const INITIAL_POLLS: Poll[] = [
|
||||
description: 'Allocate 5% of treasury funds for a community education scholarship.',
|
||||
status: 'active', totalVotes: 198, endsAt: '2026-04-25',
|
||||
options: [
|
||||
{ id: '3a', text: 'Ere, 5% / Yes, 5%', votes: 112 },
|
||||
{ id: '3b', text: 'Ere, 3% / Yes, 3%', votes: 48 },
|
||||
{ id: '3c', text: 'Na / No', votes: 23 },
|
||||
{ id: '3d', text: 'Bêalî / Abstain', votes: 15 },
|
||||
{ id: '3a', text: 'Yes, 5%', votes: 112 },
|
||||
{ id: '3b', text: 'Yes, 3%', votes: 48 },
|
||||
{ id: '3c', text: 'No', votes: 23 },
|
||||
{ id: '3d', text: 'Abstain', votes: 15 },
|
||||
],
|
||||
userVoted: null,
|
||||
},
|
||||
@@ -78,6 +79,7 @@ const INITIAL_POLLS: Poll[] = [
|
||||
|
||||
export default function PollsPage() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const [polls, setPolls] = useState<Poll[]>(INITIAL_POLLS);
|
||||
|
||||
const handleVote = (pollId: string, optionId: string) => {
|
||||
@@ -112,9 +114,9 @@ export default function PollsPage() {
|
||||
<span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${
|
||||
poll.status === 'active' ? 'bg-green-900/50 text-green-400' : 'bg-gray-800 text-gray-400'
|
||||
}`}>
|
||||
{poll.status === 'active' ? 'Çalak / Active' : 'Qediya / Ended'}
|
||||
{poll.status === 'active' ? t('polls.status.active', 'Active') : t('polls.status.ended', 'Ended')}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">{poll.totalVotes} deng</span>
|
||||
<span className="text-xs text-gray-500">{poll.totalVotes} {t('polls.votes', 'votes')}</span>
|
||||
</div>
|
||||
|
||||
<p className="font-bold text-white mb-0.5">{poll.titleKu}</p>
|
||||
@@ -164,7 +166,9 @@ export default function PollsPage() {
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-gray-600 mt-3 text-right">
|
||||
{poll.status === 'active' ? `Dawî: ${poll.endsAt}` : `Qediya: ${poll.endsAt}`}
|
||||
{poll.status === 'active'
|
||||
? `${t('polls.ends', 'Ends')}: ${poll.endsAt}`
|
||||
: `${t('polls.ended', 'Ended')}: ${poll.endsAt}`}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
@@ -176,26 +180,28 @@ export default function PollsPage() {
|
||||
<div className="bg-green-700 px-4 pt-4 pb-5">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<button onClick={() => navigate(-1)} className="text-white/80 hover:text-white text-xl">←</button>
|
||||
<span className="text-sm text-white/70">Governance</span>
|
||||
<span className="text-sm text-white/70">{t('polls.breadcrumb', 'Governance')}</span>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<span className="text-5xl block mb-2">📊</span>
|
||||
<h1 className="text-2xl font-bold">Rapirsî</h1>
|
||||
<p className="text-white/70 text-sm mt-0.5">Community Polls</p>
|
||||
<p className="text-yellow-400 text-sm font-semibold mt-2">{activePolls.length} çalak / active</p>
|
||||
<h1 className="text-2xl font-bold">{t('polls.title', 'Community Polls')}</h1>
|
||||
<p className="text-white/70 text-sm mt-0.5">{t('polls.subtitle', 'Community Polls')}</p>
|
||||
<p className="text-yellow-400 text-sm font-semibold mt-2">
|
||||
{t('polls.active.count', '{{count}} active', { count: activePolls.length })}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="px-4 py-4 space-y-4 max-w-lg mx-auto">
|
||||
{activePolls.length > 0 && (
|
||||
<div className="space-y-3">
|
||||
<h2 className="font-bold text-white text-base">Rapirsiyên Çalak / Active Polls</h2>
|
||||
<h2 className="font-bold text-white text-base">{t('polls.section.active', 'Active Polls')}</h2>
|
||||
{activePolls.map(renderPoll)}
|
||||
</div>
|
||||
)}
|
||||
{endedPolls.length > 0 && (
|
||||
<div className="space-y-3">
|
||||
<h2 className="font-bold text-white text-base">Rapirsiyên Qediyayî / Ended Polls</h2>
|
||||
<h2 className="font-bold text-white text-base">{t('polls.section.ended', 'Ended Polls')}</h2>
|
||||
{endedPolls.map(renderPoll)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user