This commit is contained in:
Krikorios
2025-07-14 10:14:20 +04:00
parent 890acbd5bc
commit 868c9b252c
21 changed files with 615 additions and 97 deletions
+96
View File
@@ -0,0 +1,96 @@
'use client';
import React, { useState } from 'react';
export default function AIConfigPage() {
const [apiKey, setApiKey] = useState('');
const [ollamaUrl, setOllamaUrl] = useState('http://localhost:11434');
const [modelName, setModelName] = useState('command-r7b-arabic');
const [saveStatus, setSaveStatus] = useState('');
const handleSave = async () => {
try {
setSaveStatus('Saving...');
// In a real implementation, we would update the configuration
// securely through a protected API endpoint
await new Promise(resolve => setTimeout(resolve, 1000));
setSaveStatus('Configuration saved successfully!');
} catch (error) {
console.error('Error saving configuration:', error);
setSaveStatus('Error saving configuration');
}
};
return (
<div className="container mx-auto px-6 py-8">
<h1 className="text-3xl font-bold mb-8">AI Assistant Configuration</h1>
<div className="bg-white p-6 rounded-lg shadow-md mb-6">
<h2 className="text-xl font-semibold mb-4">OpenRouter Configuration</h2>
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
API Key
</label>
<input
type="password"
value={apiKey}
onChange={(e) => setApiKey(e.target.value)}
className="w-full p-2 border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
placeholder="sk-..."
/>
<p className="text-xs text-gray-500 mt-1">
Your OpenRouter API key is stored securely and never exposed to clients.
</p>
</div>
</div>
<div className="bg-white p-6 rounded-lg shadow-md mb-6">
<h2 className="text-xl font-semibold mb-4">Ollama Configuration (Fallback)</h2>
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
Ollama Server URL
</label>
<input
type="text"
value={ollamaUrl}
onChange={(e) => setOllamaUrl(e.target.value)}
className="w-full p-2 border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
/>
</div>
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
Model Name
</label>
<input
type="text"
value={modelName}
onChange={(e) => setModelName(e.target.value)}
className="w-full p-2 border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
/>
<p className="text-xs text-gray-500 mt-1">
The model must be installed on your Ollama server
</p>
</div>
</div>
<div className="flex justify-end">
<button
onClick={handleSave}
className="bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition-colors"
>
Save Configuration
</button>
</div>
{saveStatus && (
<div className={`mt-4 p-3 rounded ${
saveStatus.includes('Error')
? 'bg-red-100 text-red-800'
: 'bg-green-100 text-green-800'
}`}>
{saveStatus}
</div>
)}
</div>
);
}
+6 -4
View File
@@ -3,7 +3,8 @@ import UTASChatBot from '@/lib/chatbot';
export async function POST(request: NextRequest) {
try {
const { message } = await request.json();
// Extract message and userContext from the request
const { message, userContext } = await request.json();
if (!message || typeof message !== 'string') {
return NextResponse.json({
@@ -15,14 +16,15 @@ export async function POST(request: NextRequest) {
const apiKey = process.env.OPENROUTER_API_KEY || '';
const chatbot = new UTASChatBot(apiKey);
// Generate AI response using OpenRouter
const response = await chatbot.generateResponse(message);
// Generate AI response using OpenRouter or Ollama, passing userContext
const response = await chatbot.generateResponse(message, userContext);
// Log the interaction for demo purposes
console.log('UTAS Chat:', {
timestamp: new Date().toISOString(),
message: message.substring(0, 100),
response: response.substring(0, 100)
response: response.substring(0, 100),
userRole: userContext?.role || 'anonymous'
});
// Return both message and response for backward compatibility
+5 -5
View File
@@ -102,7 +102,7 @@ export default function UTASOmanHomePage() {
subtitle: language === 'en'
? "Leading Oman's technological advancement and innovation through excellence in education"
: "قيادة التقدم التكنولوجي والابتكار في عُمان من خلال التميز في التعليم",
image: "https://images.unsplash.com/photo-1562774053-701939374585?w=1200&h=600&fit=crop",
image: "https://images.pexels.com/photos/256490/pexels-photo-256490.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
cta: language === 'en' ? "Explore Our Programs" : "استكشف برامجنا"
},
{
@@ -112,7 +112,7 @@ export default function UTASOmanHomePage() {
subtitle: language === 'en'
? "Empowering students with cutting-edge knowledge and practical skills for the future"
: "تمكين الطلاب بالمعرفة المتطورة والمهارات العملية للمستقبل",
image: "https://images.unsplash.com/photo-1581091226825-a6a2a5aee158?w=1200&h=600&fit=crop",
image: "https://images.pexels.com/photos/267885/pexels-photo-267885.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
cta: language === 'en' ? "Join Our Community" : "انضم إلى مجتمعنا"
},
{
@@ -122,7 +122,7 @@ export default function UTASOmanHomePage() {
subtitle: language === 'en'
? "Building capacities aligned with Oman Vision 2040 for sustainable development"
: "بناء القدرات بما يتماشى مع رؤية عُمان 2040 للتنمية المستدامة",
image: "https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=1200&h=600&fit=crop",
image: "https://images.pexels.com/photos/2982449/pexels-photo-2982449.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
cta: language === 'en' ? "Start Your Journey" : "ابدأ رحلتك"
}
];
@@ -238,7 +238,7 @@ export default function UTASOmanHomePage() {
title: language === 'en'
? "University of Technology and Applied Sciences and Nizwa University sign MoU for academic and research cooperation"
: "جامعة التقنية والعلوم التطبيقية وجامعة نزوى توقعان مذكرة تفاهم للتعاون الأكاديمي والبحثي",
image: "https://images.unsplash.com/photo-1521737711867-e3b97375f902?w=400&h=200&fit=crop",
image: "https://images.pexels.com/photos/1438072/pexels-photo-1438072.jpeg?auto=compress&cs=tinysrgb&w=400&h=200&dpr=2",
date: language === 'en' ? "July 10, 2025" : "10 يوليو 2025"
}
];
@@ -266,7 +266,7 @@ export default function UTASOmanHomePage() {
priority={index === 0}
/>
<div className="relative z-20 flex items-center h-full">
<div className="container mx-auto px-6">
<div className="container max-w-7xl mx-auto px-4 md:px-6 lg:px-8 overflow-x-hidden">
<div className="max-w-4xl">
<h1 className="text-4xl md:text-6xl font-bold text-white mb-6 leading-tight">
{slide.title}