+
+
+
+ Mentor Portal
+
+
+ Manage your vouch requests, active vouches, and track your mentoring impact.
+
+
+ {!walletConnected && (
+
+
+ Connect Wallet
+
+ )}
+
+
+
+
+
+ {tabs.map((tab) => (
+ setActiveTab(tab.key)}
+ role="tab"
+ aria-selected={activeTab === tab.key}
+ aria-controls={`tabpanel-${tab.key}`}
+ id={`tab-${tab.key}`}
+ className={`
+ flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all
+ ${
+ activeTab === tab.key
+ ? 'bg-elevated text-text-primary shadow-sm'
+ : 'text-text-muted hover:text-text-secondary'
+ }
+ `}
+ >
+
+ {tab.label}
+ {tab.count !== undefined && (
+
+ {tab.count}
+
+ )}
+
+ ))}
+
+
+
+ <>
+ {isLoadingRequests ? (
+
+
+
Loading vouch requests...
+
+ ) : isErrorRequests ? (
+
+
+
+ Failed to load requests
+
+
+ Could not fetch vouch requests. Please try again later.
+
+
refetchRequests()}>
+
+ Retry
+
+
+ ) : !requests.length ? (
+
+
+
+
+
+ No pending requests
+
+
+ There are no learners requesting vouches right now. Check back later.
+
+
+ ) : (
+
+ {requests.map((request) => (
+
+ navigate(`/learner/${request.learnerAddress}`)
+ }
+ onVouch={setPreviewRequest}
+ onDecline={handleDecline}
+ declining={decliningId === request.id}
+ />
+ ))}
+
+ )}
+ >
+
+
+
+ <>
+ {isLoadingActiveVouches ? (
+
+
+
Loading active vouches...
+
+ ) : isErrorActiveVouches ? (
+
+
+
+ Failed to load vouches
+
+
+ Could not fetch your active vouches. Please try again later.
+
+
refetchActiveVouches()}>
+
+ Retry
+
+
+ ) : !activeVouches.length ? (
+
+
+
+
+
+ No active vouches
+
+
+ You haven't vouched for anyone yet. Go to the Pending Requests tab to find learners.
+
+
+ ) : (
+
+ {activeVouches.map((vouch) => (
+
+
+
+
+
+
+
+
+ {formatWallet(vouch.learnerWallet)}
+
+
+
+
+
+
+
+
Rep Boost
+
+
+
+{vouch.reputationBoost}
+
+
+
+
Interest
+
+
+
{vouch.interestRateBefore}% → {vouch.interestRateAfter}%
+
+
+
+
Expiry
+
+
+
+ {new Date(vouch.expiryDate).toLocaleDateString()}
+
+
+
+
+
Repayment
+
+
+
+ ${vouch.paidAmount.toLocaleString()} / ${vouch.loanAmount.toLocaleString()}
+
+
+
+
+
+ {vouch.installments > 0 && (
+
+
+
+ {vouch.paidInstallments}/{vouch.installments}
+
+
+ )}
+
+
+
+ navigate(`/learner/${vouch.learnerAddress}`)}
+ >
+
+ Profile
+
+ setRevokeTarget(vouch.id)}
+ className="border-red-500/40 text-red-400 hover:bg-red-500/10"
+ >
+
+ Revoke
+
+
+
+
+ ))}
+
+ )}
+ >
+
+
+ {previewRequest && (
+
setPreviewRequest(null)}
+ confirming={submitMutation.isPending}
+ />
+ )}
+
+ {
+ if (revokeTarget) {
+ revokeMutation.mutate(revokeTarget, {
+ onSuccess: () => {
+ setRevokeTarget(null)
+ toast.success('Vouch revoked successfully.')
+ },
+ onError: (error) => {
+ const message = error instanceof Error ? error.message : 'Failed to revoke vouch.'
+ toast.error(message)
+ },
+ })
+ }
+ }}
+ onCancel={() => setRevokeTarget(null)}
+ revoking={revokeMutation.isPending}
+ />
+
+ )
+}
diff --git a/src/router/index.tsx b/src/router/index.tsx
index 21c24fb..e3f34e9 100644
--- a/src/router/index.tsx
+++ b/src/router/index.tsx
@@ -11,6 +11,7 @@ import { VendorDashboard } from '../pages/VendorDashboard'
import { Sponsors } from '../pages/Sponsors'
import { SponsorOnboarding } from '../pages/SponsorOnboarding'
import { Vouch } from '../pages/Vouch'
+import { MentorDashboard } from '../pages/MentorDashboard'
import { LearnerProfile } from '../pages/LearnerProfile'
import { NotFound } from '../pages/NotFound'
import { History } from '../pages/History'
@@ -87,6 +88,10 @@ const router = createBrowserRouter([
path: '/sponsors/onboarding',
element: