🚀 UTAS Oman Portal Demo - Complete AI-Enhanced University Portal

 Features:
• Real AI chatbot with OpenRouter API (bilingual Arabic/English)
• Comprehensive UTAS Oman content with programs and admissions
• Modern responsive design with Tailwind CSS
• Student/Admin authentication and dashboards
• Full course catalog with search and filtering
• Contact forms and application processes

🤖 AI Capabilities:
• Language detection (Arabic/English)
• UTAS Oman knowledge base integration
• Contextual responses about programs, admissions, scholarships
• No mock data - all responses from real AI

🛠️ Technology Stack:
• Next.js 14 + React 19 + TypeScript
• OpenRouter API with Meta LLaMA 3.1
• Prisma ORM with SQLite
• Tailwind CSS for styling

📋 Demo Ready:
• Test users file included (TEST-USERS.md)
• Navigation test checklist (NAVIGATION-TEST.md)
• Clean codebase with proper gitignore
• Production-ready configuration
This commit is contained in:
Krikorios
2025-07-13 19:18:26 +04:00
parent f83b27db61
commit 0c22188feb
52 changed files with 6454 additions and 14454 deletions
+61 -100
View File
@@ -1,109 +1,70 @@
import { NextResponse } from 'next/server';
import { NextRequest, NextResponse } from 'next/server';
import UTASChatBot from '@/lib/chatbot';
// Mock chat responses
const mockResponses = [
{
trigger: ['library', 'hours', 'open'],
response: {
en: 'The library is open Monday-Friday 8:00 AM - 10:00 PM, Saturday 9:00 AM - 6:00 PM, and Sunday 12:00 PM - 8:00 PM. During exam periods, we have extended hours until midnight.',
ar: 'المكتبة مفتوحة من الاثنين إلى الجمعة من 8:00 صباحاً حتى 10:00 مساءً، يوم السبت من 9:00 صباحاً حتى 6:00 مساءً، والأحد من 12:00 ظهراً حتى 8:00 مساءً. خلال فترات الامتحانات، لدينا ساعات ممتدة حتى منتصف الليل.'
}
},
{
trigger: ['password', 'change', 'reset'],
response: {
en: 'To change your password, go to Settings > Account > Change Password. You can also reset it using the "Forgot Password" link on the login page.',
ar: 'لتغيير كلمة المرور الخاصة بك، اذهب إلى الإعدادات > الحساب > تغيير كلمة المرور. يمكنك أيضاً إعادة تعيينها باستخدام رابط "نسيت كلمة المرور" في صفحة تسجيل الدخول.'
}
},
{
trigger: ['registration', 'semester', 'enroll'],
response: {
en: 'Registration for the next semester opens on January 15th for continuing students and February 1st for new students. Please check your academic calendar for specific dates.',
ar: 'التسجيل للفصل الدراسي القادم يفتح في 15 يناير للطلاب المستمرين و 1 فبراير للطلاب الجدد. يرجى مراجعة التقويم الأكاديمي للتواريخ المحددة.'
}
},
{
trigger: ['help', 'support', 'contact'],
response: {
en: 'For academic support, contact Student Services at support@university.edu or call (555) 123-4567. For technical issues, email IT help desk at it@university.edu.',
ar: 'للدعم الأكاديمي، اتصل بخدمات الطلاب على support@university.edu أو اتصل بالرقم (555) 123-4567. للمشاكل التقنية، راسل مكتب المساعدة التقنية على it@university.edu.'
}
}
];
// Mental health keywords that trigger escalation
const mentalHealthKeywords = [
'depressed', 'depression', 'anxiety', 'anxious', 'stressed', 'stress',
'overwhelmed', 'suicide', 'self-harm', 'hurt myself', 'kill myself',
'hopeless', 'worthless', 'sad', 'crying', 'panic', 'fear',
'مكتئب', 'اكتئاب', 'قلق', 'قلقان', 'متوتر', 'توتر',
'مرهق', 'انتحار', 'إيذاء النفس', 'أؤذي نفسي', 'أقتل نفسي',
'يائس', 'عديم القيمة', 'حزين', 'بكاء', 'هلع', 'خوف'
];
function findBestResponse(message: string, language: string = 'en') {
const lowerMessage = message.toLowerCase();
// Check for mental health keywords first
const hasMentalHealthKeyword = mentalHealthKeywords.some(keyword =>
lowerMessage.includes(keyword.toLowerCase())
);
if (hasMentalHealthKeyword) {
return {
response: language === 'ar'
? 'أفهم أنك تمر بوقت صعب. من المهم أن تطلب المساعدة من المختصين. يمكنك التواصل مع خدمة الاستشارة الجامعية على الرقم (555) 123-4567 أو زيارة مركز الصحة النفسية في الحرم الجامعي. في حالات الطوارئ، اتصل بالرقم 911 أو خط المساعدة الوطني للأزمات النفسية.'
: 'I understand you\'re going through a difficult time. It\'s important to seek help from professionals. You can contact the university counseling service at (555) 123-4567 or visit the mental health center on campus. In emergencies, call 911 or the National Crisis Helpline.',
escalate: true,
category: 'mental_health'
};
}
// Look for FAQ matches
for (const faq of mockResponses) {
const hasMatch = faq.trigger.some(trigger =>
lowerMessage.includes(trigger.toLowerCase())
);
if (hasMatch) {
return {
response: faq.response[language as keyof typeof faq.response],
escalate: false,
category: 'faq'
};
}
}
// Default response
return {
response: language === 'ar'
? 'شكراً لك على سؤالك. يمكنني مساعدتك في العثور على المعلومات التي تحتاجها. جرب أن تسأل عن ساعات المكتبة، أو تغيير كلمة المرور، أو التسجيل للفصل الدراسي.'
: 'Thank you for your question. I can help you find the information you need. Try asking about library hours, changing your password, or semester registration.',
escalate: false,
category: 'general'
};
}
export async function POST(request: Request) {
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { message, language = 'en' } = body;
const {
message,
mode = 'general',
history = [],
conversationHistory = [],
systemPrompt = null,
language = 'en'
} = await request.json();
if (!message) {
return NextResponse.json({ error: 'Message is required' }, { status: 400 });
if (!message || typeof message !== 'string') {
return NextResponse.json({
error: 'Message is required and must be a string'
}, { status: 400 });
}
const result = findBestResponse(message, language);
// Initialize the chatbot with API key from environment
const apiKey = process.env.OPENROUTER_API_KEY || '';
const chatbot = new UTASChatBot(apiKey);
// Generate AI response using OpenRouter
const response = await chatbot.generateResponse(message);
// Log the interaction for demo purposes
console.log('UTAS Chat:', {
timestamp: new Date().toISOString(),
message: message.substring(0, 100),
response: response.substring(0, 100)
});
return NextResponse.json({
message: response,
response: response, // for backward compatibility
timestamp: new Date().toISOString(),
source: 'UTAS AI Assistant'
});
} catch (error) {
console.error('Chat API Error:', error);
return NextResponse.json({
response: result.response,
escalate: result.escalate,
category: result.category,
timestamp: new Date().toISOString()
});
} catch (error) {
console.error('Error processing chat:', error);
return NextResponse.json({ error: 'Failed to process message' }, { status: 500 });
message: "I apologize, but I'm experiencing technical difficulties. Please try again or contact UTAS directly at +61 3 6226 6200 or info@utas.edu.au for immediate assistance.",
timestamp: new Date().toISOString(),
source: 'UTAS AI Assistant',
error: true
}, { status: 500 });
}
}
export async function GET() {
return NextResponse.json({
service: 'UTAS AI Chat Assistant',
status: 'active',
features: [
'RAG-powered responses using UTAS knowledge base',
'OpenRouter AI integration (when API key provided)',
'Real-time course and program information',
'Application guidance and support',
'Campus and research information'
],
endpoints: {
POST: 'Send message and conversation history',
GET: 'Service status and information'
}
});
}