feat: Add AI Assistance Portal components and enhance layout; update notification service and processing pipeline for improved request handling
This commit is contained in:
42
src/App.tsx
42
src/App.tsx
@@ -2894,7 +2894,7 @@ function PortalsPage() {
|
||||
return (
|
||||
<PageShell title="Staff & Partner Portals" icon={Building2} eyebrow="Secure access for team members">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div className="grid gap-8 md:grid-cols-3">
|
||||
<div className="grid gap-8 md:grid-cols-2 xl:grid-cols-4">
|
||||
{/* Admin Portal */}
|
||||
<motion.div
|
||||
className="card bg-gradient-to-br from-red-50 to-rose-50 dark:from-red-900/20 dark:to-rose-900/20 border-red-200 dark:border-red-800"
|
||||
@@ -3014,6 +3014,46 @@ function PortalsPage() {
|
||||
Access Resource Portal
|
||||
</a>
|
||||
</motion.div>
|
||||
|
||||
{/* AI Assistance Portal - Phase 3 */}
|
||||
<motion.div
|
||||
className="card bg-gradient-to-br from-purple-50 to-violet-50 dark:from-purple-900/20 dark:to-violet-900/20 border-purple-200 dark:border-purple-800"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.4 }}
|
||||
>
|
||||
<div className="text-center mb-6">
|
||||
<div className="mx-auto w-16 h-16 bg-purple-600 text-white rounded-xl flex items-center justify-center mb-4">
|
||||
<Brain className="h-8 w-8" />
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold text-purple-900 dark:text-purple-100">AI Assistance Portal</h3>
|
||||
<p className="text-sm text-purple-700 dark:text-purple-300 mt-2">
|
||||
AI-powered request matching and insights
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2 text-sm text-purple-800 dark:text-purple-200 mb-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<Cpu className="h-4 w-4" />
|
||||
<span>Real-time AI request processing</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Target className="h-4 w-4" />
|
||||
<span>Smart resource matching & allocation</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Activity className="h-4 w-4" />
|
||||
<span>Predictive analytics & insights</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="#/ai-portal"
|
||||
className="block w-full text-center bg-purple-600 text-white py-3 px-4 rounded-lg hover:bg-purple-700 transition-colors font-medium focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
|
||||
>
|
||||
Access AI Portal
|
||||
</a>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Access Information */}
|
||||
|
||||
@@ -29,7 +29,7 @@ class MockQueue<T> {
|
||||
return job
|
||||
}
|
||||
|
||||
process(jobType: string, concurrency: number, processor: (job: { id: string; data: T }) => Promise<void>): void {
|
||||
process(jobType: string, _concurrency: number, processor: (job: { id: string; data: T }) => Promise<void>): void {
|
||||
this.processors.set(jobType, processor)
|
||||
}
|
||||
|
||||
@@ -66,17 +66,17 @@ class NotificationService {
|
||||
})
|
||||
}
|
||||
|
||||
async notifyStudent(studentId: string, assignment: any): Promise<void> {
|
||||
async notifyStudent(studentId: string, _assignment: any): Promise<void> {
|
||||
console.log(`📧 Notifying student ${studentId} about assignment`)
|
||||
// In production: send email, SMS, or push notification
|
||||
}
|
||||
|
||||
async notifyVolunteer(volunteerId: string, assignment: any): Promise<void> {
|
||||
async notifyVolunteer(volunteerId: string, _assignment: any): Promise<void> {
|
||||
console.log(`📧 Notifying volunteer ${volunteerId} about new assignment`)
|
||||
// In production: send volunteer notification
|
||||
}
|
||||
|
||||
async notifyCoordinators(assignment: any): Promise<void> {
|
||||
async notifyCoordinators(_assignment: any): Promise<void> {
|
||||
console.log(`📧 Notifying coordinators about new assignment`)
|
||||
// In production: alert coordination team
|
||||
}
|
||||
@@ -86,7 +86,7 @@ class NotificationService {
|
||||
// In production: trigger donor engagement campaign
|
||||
}
|
||||
|
||||
async notifyReviewer(reviewer: any, reviewTask: any, aiInsights: any): Promise<void> {
|
||||
async notifyReviewer(reviewer: any, _reviewTask: any, aiInsights: any): Promise<void> {
|
||||
console.log(`👥 Notifying reviewer ${reviewer.id} about review task with AI confidence: ${aiInsights.aiConfidence}`)
|
||||
// In production: send detailed review notification with AI recommendations
|
||||
}
|
||||
@@ -303,7 +303,7 @@ export class RealTimeProcessingPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
private async selectOptimalReviewer(request: StudentRequest, matches: MatchResult[]) {
|
||||
private async selectOptimalReviewer(request: StudentRequest, _matches: MatchResult[]) {
|
||||
// Mock reviewer selection - in production, this would use actual staff data
|
||||
const reviewers = [
|
||||
{ id: 'rev1', name: 'Sarah Martinez', specialties: ['clothing', 'emergency-housing'], workload: 5 },
|
||||
@@ -366,7 +366,7 @@ export class RealTimeProcessingPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
private async updateDashboard(requestId: string, matches: MatchResult[]): Promise<void> {
|
||||
private async updateDashboard(requestId: string, _matches: MatchResult[]): Promise<void> {
|
||||
console.log(`📊 Updating dashboard for request ${requestId}`)
|
||||
// In production: update real-time analytics dashboard
|
||||
}
|
||||
@@ -387,7 +387,7 @@ export class RealTimeProcessingPipeline {
|
||||
await this.routeForHumanReview(request, [])
|
||||
}
|
||||
|
||||
private async trackDecision(request: StudentRequest, match: MatchResult, decision: string): Promise<void> {
|
||||
private async trackDecision(request: StudentRequest, _match: MatchResult, decision: string): Promise<void> {
|
||||
console.log(`📈 Tracking decision: ${decision} for request ${request.id}`)
|
||||
// In production: log decision for ML model training
|
||||
}
|
||||
|
||||
@@ -531,7 +531,7 @@ export class StudentAssistanceAI {
|
||||
return candidates.map(candidate => this.calculateRuleBasedScore(candidate, analysis, request))
|
||||
}
|
||||
|
||||
private calculateRuleBasedScore(candidate: any, analysis: RequestAnalysis, request: StudentRequest): MatchResult {
|
||||
private calculateRuleBasedScore(candidate: any, analysis: RequestAnalysis, _request: StudentRequest): MatchResult {
|
||||
let score = 0.5 // Base score
|
||||
|
||||
// Category match bonus
|
||||
@@ -581,7 +581,7 @@ export class StudentAssistanceAI {
|
||||
estimatedCost: candidate.avgCost,
|
||||
fulfillmentTimeline: this.estimateTimeline(analysis.urgencyScore, analysis.complexityEstimate),
|
||||
reasoningFactors: this.generateReasoningFactors(candidate, analysis),
|
||||
riskFactors: this.identifyRiskFactors(candidate, analysis, request)
|
||||
riskFactors: this.identifyRiskFactors(candidate, analysis)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -465,7 +465,7 @@ function ConfidenceIndicator({ confidence }: { confidence: number }) {
|
||||
}
|
||||
|
||||
function AIPerformanceMetrics() {
|
||||
const [metrics, setMetrics] = useState<AIMetrics>({
|
||||
const [metrics] = useState<AIMetrics>({
|
||||
accuracyRate: 0.87,
|
||||
accuracyTrend: 2.3,
|
||||
avgProcessingTime: 1.8,
|
||||
|
||||
@@ -49,6 +49,26 @@
|
||||
@apply text-sm font-medium text-neutral-600 transition hover:text-primary-600 dark:text-neutral-300 dark:hover:text-primary-400;
|
||||
}
|
||||
|
||||
/* Form Components */
|
||||
.input-field {
|
||||
@apply w-full rounded-xl border border-gray-300 bg-white px-4 py-3 text-sm text-gray-900 placeholder-gray-500 transition focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 dark:focus:border-primary-400;
|
||||
}
|
||||
|
||||
/* Text Utilities */
|
||||
.line-clamp-2 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.line-clamp-3 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.input {
|
||||
@apply w-full rounded-xl border border-white/30 bg-white/70 px-3 py-2 text-sm backdrop-blur transition focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20 dark:border-white/10 dark:bg-white/10 dark:focus:border-primary-400;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user