✨ 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
174 lines
4.2 KiB
TypeScript
174 lines
4.2 KiB
TypeScript
'use client';
|
|
|
|
import { createContext, useContext, useState, useEffect } from 'react';
|
|
|
|
interface User {
|
|
id: string;
|
|
email: string;
|
|
name: string;
|
|
}
|
|
|
|
interface UserProfile {
|
|
id: string;
|
|
email: string;
|
|
name: string;
|
|
role: 'STUDENT' | 'ADMIN' | 'FACULTY' | 'PRESIDENT' | 'STAFF' | 'PROSPECTIVE';
|
|
studentId?: string;
|
|
facultyId?: string;
|
|
department?: string;
|
|
position?: string;
|
|
faculty?: string;
|
|
balance?: number;
|
|
accessLevel?: number; // 1-5 scale for different access levels
|
|
}
|
|
|
|
interface AuthContextType {
|
|
user: User | null;
|
|
userProfile: UserProfile | null;
|
|
login: (email: string, password: string) => Promise<boolean>;
|
|
logout: () => void;
|
|
loading: boolean;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
|
|
|
export function useAuth() {
|
|
const context = useContext(AuthContext);
|
|
if (context === undefined) {
|
|
throw new Error('useAuth must be used within an AuthProvider');
|
|
}
|
|
return context;
|
|
}
|
|
|
|
// Mock user data for demo - Enhanced role system
|
|
const mockUsers = [
|
|
{
|
|
id: '1',
|
|
email: 'student@utas.edu.au',
|
|
name: 'Sarah Chen',
|
|
role: 'STUDENT' as const,
|
|
studentId: 'ST001234',
|
|
faculty: 'College of Sciences and Engineering',
|
|
department: 'Marine and Antarctic Studies',
|
|
balance: 5420.50,
|
|
accessLevel: 2,
|
|
password: 'password123'
|
|
},
|
|
{
|
|
id: '2',
|
|
email: 'admin@utas.edu.au',
|
|
name: 'Dr. Michael Thompson',
|
|
role: 'ADMIN' as const,
|
|
department: 'Student Services',
|
|
position: 'Director of Student Affairs',
|
|
accessLevel: 4,
|
|
password: 'admin123'
|
|
},
|
|
{
|
|
id: '3',
|
|
email: 'president@utas.edu.au',
|
|
name: 'Prof. Rufus Black',
|
|
role: 'PRESIDENT' as const,
|
|
position: 'Vice-Chancellor and President',
|
|
department: 'Executive Office',
|
|
accessLevel: 5,
|
|
password: 'president123'
|
|
},
|
|
{
|
|
id: '4',
|
|
email: 'faculty@utas.edu.au',
|
|
name: 'Dr. Emma Wilson',
|
|
role: 'FACULTY' as const,
|
|
facultyId: 'FAC5678',
|
|
department: 'Institute for Marine and Antarctic Studies',
|
|
position: 'Senior Research Fellow',
|
|
faculty: 'College of Sciences and Engineering',
|
|
accessLevel: 3,
|
|
password: 'faculty123'
|
|
},
|
|
{
|
|
id: '5',
|
|
email: 'staff@utas.edu.au',
|
|
name: 'James Rodriguez',
|
|
role: 'STAFF' as const,
|
|
department: 'International Office',
|
|
position: 'International Student Advisor',
|
|
accessLevel: 2,
|
|
password: 'staff123'
|
|
},
|
|
{
|
|
id: '6',
|
|
email: 'prospective@example.com',
|
|
name: 'Lisa Zhang',
|
|
role: 'PROSPECTIVE' as const,
|
|
accessLevel: 1,
|
|
password: 'prospect123'
|
|
}
|
|
];
|
|
|
|
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
const [user, setUser] = useState<User | null>(null);
|
|
const [userProfile, setUserProfile] = useState<UserProfile | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
// Initialize from localStorage
|
|
useEffect(() => {
|
|
const savedUser = localStorage.getItem('demo_user');
|
|
const savedProfile = localStorage.getItem('demo_profile');
|
|
|
|
if (savedUser && savedProfile) {
|
|
setUser(JSON.parse(savedUser));
|
|
setUserProfile(JSON.parse(savedProfile));
|
|
}
|
|
|
|
setLoading(false);
|
|
}, []);
|
|
|
|
const login = async (email: string, password: string): Promise<boolean> => {
|
|
// Find matching user
|
|
const mockUser = mockUsers.find(u => u.email === email && u.password === password);
|
|
|
|
if (!mockUser) {
|
|
return false;
|
|
}
|
|
|
|
const user: User = {
|
|
id: mockUser.id,
|
|
email: mockUser.email,
|
|
name: mockUser.name
|
|
};
|
|
|
|
const profile: UserProfile = {
|
|
id: mockUser.id,
|
|
email: mockUser.email,
|
|
name: mockUser.name,
|
|
role: mockUser.role,
|
|
studentId: mockUser.studentId,
|
|
faculty: mockUser.faculty,
|
|
balance: mockUser.balance
|
|
};
|
|
|
|
setUser(user);
|
|
setUserProfile(profile);
|
|
|
|
// Save to localStorage
|
|
localStorage.setItem('demo_user', JSON.stringify(user));
|
|
localStorage.setItem('demo_profile', JSON.stringify(profile));
|
|
|
|
return true;
|
|
};
|
|
|
|
const logout = () => {
|
|
setUser(null);
|
|
setUserProfile(null);
|
|
localStorage.removeItem('demo_user');
|
|
localStorage.removeItem('demo_profile');
|
|
};
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ user, userProfile, login, logout, loading }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|