main
This commit is contained in:
@@ -0,0 +1,435 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useAuth } from '@/components/providers/MockAuthProvider'
|
||||
import { useLanguage } from '@/components/providers/LanguageProvider'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import {
|
||||
Heart,
|
||||
MessageCircle,
|
||||
Phone,
|
||||
Calendar,
|
||||
LogOut,
|
||||
Languages,
|
||||
ArrowLeft,
|
||||
AlertTriangle,
|
||||
CheckCircle,
|
||||
Clock,
|
||||
Users
|
||||
} from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function WellbeingPage() {
|
||||
const { user, userProfile, logout } = useAuth()
|
||||
const { t, language, setLanguage } = useLanguage()
|
||||
const router = useRouter()
|
||||
const [messages, setMessages] = useState<Array<{id: string; text: string; sender: 'user' | 'bot'; timestamp: Date}>>([])
|
||||
const [inputText, setInputText] = useState('')
|
||||
const [isTyping, setIsTyping] = useState(false)
|
||||
const [showEmergencyModal, setShowEmergencyModal] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!user) {
|
||||
router.push('/')
|
||||
}
|
||||
}, [user, router])
|
||||
|
||||
useEffect(() => {
|
||||
// Start with a welcome message
|
||||
setMessages([
|
||||
{
|
||||
id: '1',
|
||||
text: 'Hello! I\'m here to support your mental health and wellbeing. How are you feeling today?',
|
||||
sender: 'bot',
|
||||
timestamp: new Date()
|
||||
}
|
||||
])
|
||||
}, [])
|
||||
|
||||
const handleSendMessage = async () => {
|
||||
if (!inputText.trim()) return
|
||||
|
||||
const userMessage = inputText.trim()
|
||||
setInputText('')
|
||||
|
||||
const newMessage = {
|
||||
id: Date.now().toString(),
|
||||
text: userMessage,
|
||||
sender: 'user' as const,
|
||||
timestamp: new Date()
|
||||
}
|
||||
|
||||
setMessages(prev => [...prev, newMessage])
|
||||
setIsTyping(true)
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/chat', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
message: userMessage,
|
||||
mode: 'mental_health',
|
||||
history: messages,
|
||||
}),
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
setIsTyping(false)
|
||||
|
||||
const botMessage = {
|
||||
id: (Date.now() + 1).toString(),
|
||||
text: data.response,
|
||||
sender: 'bot' as const,
|
||||
timestamp: new Date()
|
||||
}
|
||||
|
||||
setMessages(prev => [...prev, botMessage])
|
||||
|
||||
// Check for escalation
|
||||
if (data.shouldEscalate) {
|
||||
setShowEmergencyModal(true)
|
||||
}
|
||||
} catch (error) {
|
||||
setIsTyping(false)
|
||||
console.error('Chat error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout()
|
||||
}
|
||||
|
||||
const toggleLanguage = () => {
|
||||
setLanguage(language === 'en' ? 'ar' : 'en')
|
||||
}
|
||||
|
||||
if (!user || !userProfile) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-pink-600 mx-auto mb-4"></div>
|
||||
<p className="text-gray-600">Loading wellbeing support...</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-pink-50 to-purple-50">
|
||||
{/* Header */}
|
||||
<header className="bg-white shadow-sm border-b">
|
||||
<div className="container mx-auto px-4 py-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Link href="/dashboard" className="flex items-center space-x-2 text-pink-600 hover:text-pink-800">
|
||||
<ArrowLeft size={20} />
|
||||
<span>Back to Dashboard</span>
|
||||
</Link>
|
||||
<div className="text-gray-300">|</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Heart className="text-pink-600" size={24} />
|
||||
<h1 className="text-xl font-bold text-gray-900">
|
||||
{t('wellbeing')} Support
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-4">
|
||||
<button
|
||||
onClick={toggleLanguage}
|
||||
className="flex items-center space-x-2 px-3 py-2 rounded-lg bg-gray-100 hover:bg-gray-200 transition-colors"
|
||||
>
|
||||
<Languages size={16} />
|
||||
<span className="text-sm font-medium">{language.toUpperCase()}</span>
|
||||
</button>
|
||||
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="w-8 h-8 bg-pink-600 rounded-full flex items-center justify-center">
|
||||
<span className="text-white text-sm font-medium">
|
||||
{userProfile.name.charAt(0)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="hidden md:block">
|
||||
<p className="text-sm font-medium text-gray-900">{userProfile.name}</p>
|
||||
<p className="text-xs text-gray-500">{userProfile.role}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="flex items-center space-x-2 px-3 py-2 rounded-lg bg-red-100 hover:bg-red-200 transition-colors text-red-700"
|
||||
>
|
||||
<LogOut size={16} />
|
||||
<span className="text-sm font-medium">{t('logout')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="container mx-auto px-4 py-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
{/* Welcome Section */}
|
||||
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-8">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-4">
|
||||
Welcome to Mental Health Support
|
||||
</h2>
|
||||
<p className="text-gray-600 mb-6">
|
||||
Your wellbeing is important to us. This is a safe space where you can talk about how you're feeling.
|
||||
Our AI assistant is trained to provide empathetic support and can connect you with professional help when needed.
|
||||
</p>
|
||||
|
||||
{/* Emergency Resources */}
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
|
||||
<div className="flex items-start space-x-3">
|
||||
<AlertTriangle className="text-red-600 mt-0.5" size={20} />
|
||||
<div>
|
||||
<h3 className="font-medium text-red-900 mb-2">
|
||||
Emergency Resources
|
||||
</h3>
|
||||
<p className="text-sm text-red-800 mb-3">
|
||||
If you're experiencing a mental health emergency, please contact:
|
||||
</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Phone className="text-red-600" size={16} />
|
||||
<span className="text-sm text-red-800">Crisis Line: 988</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Phone className="text-red-600" size={16} />
|
||||
<span className="text-sm text-red-800">Campus Security: (555) 123-4567</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
{/* Chat Interface */}
|
||||
<div className="lg:col-span-2">
|
||||
<div className="bg-white rounded-lg shadow-sm border border-gray-200 h-[600px] flex flex-col">
|
||||
<div className="p-4 border-b bg-pink-50">
|
||||
<h3 className="font-semibold text-gray-900 flex items-center space-x-2">
|
||||
<MessageCircle className="text-pink-600" size={20} />
|
||||
<span>Wellbeing Chat</span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{/* Messages */}
|
||||
<div className="flex-1 overflow-y-auto p-4 space-y-4">
|
||||
{messages.map((message) => (
|
||||
<div
|
||||
key={message.id}
|
||||
className={`flex ${message.sender === 'user' ? 'justify-end' : 'justify-start'}`}
|
||||
>
|
||||
<div
|
||||
className={`max-w-xs px-4 py-2 rounded-lg ${
|
||||
message.sender === 'user'
|
||||
? 'bg-pink-600 text-white'
|
||||
: 'bg-pink-100 text-pink-900'
|
||||
}`}
|
||||
>
|
||||
<p className="text-sm">{message.text}</p>
|
||||
<p className="text-xs opacity-75 mt-1">
|
||||
{message.timestamp.toLocaleTimeString()}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{isTyping && (
|
||||
<div className="flex justify-start">
|
||||
<div className="bg-pink-100 px-4 py-2 rounded-lg text-pink-900">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex space-x-1">
|
||||
<div className="w-2 h-2 bg-pink-600 rounded-full animate-bounce"></div>
|
||||
<div className="w-2 h-2 bg-pink-600 rounded-full animate-bounce" style={{ animationDelay: '0.1s' }}></div>
|
||||
<div className="w-2 h-2 bg-pink-600 rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
|
||||
</div>
|
||||
<span className="text-xs">Typing...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Input */}
|
||||
<div className="p-4 border-t">
|
||||
<div className="flex space-x-2">
|
||||
<input
|
||||
type="text"
|
||||
value={inputText}
|
||||
onChange={(e) => setInputText(e.target.value)}
|
||||
onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()}
|
||||
placeholder={t('type_message')}
|
||||
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-pink-500"
|
||||
/>
|
||||
<button
|
||||
onClick={handleSendMessage}
|
||||
disabled={!inputText.trim()}
|
||||
className="bg-pink-600 text-white px-4 py-2 rounded-lg hover:bg-pink-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{t('send')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sidebar */}
|
||||
<div className="space-y-6">
|
||||
{/* Quick Actions */}
|
||||
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
||||
<h3 className="font-semibold text-gray-900 mb-4">Quick Actions</h3>
|
||||
<div className="space-y-3">
|
||||
<button
|
||||
onClick={() => setShowEmergencyModal(true)}
|
||||
className="w-full flex items-center space-x-3 p-3 bg-red-50 border border-red-200 rounded-lg hover:bg-red-100 transition-colors"
|
||||
>
|
||||
<Phone className="text-red-600" size={20} />
|
||||
<span className="text-red-900 font-medium">Emergency Help</span>
|
||||
</button>
|
||||
|
||||
<a
|
||||
href="https://calendly.com/university-counseling"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="w-full flex items-center space-x-3 p-3 bg-blue-50 border border-blue-200 rounded-lg hover:bg-blue-100 transition-colors"
|
||||
>
|
||||
<Calendar className="text-blue-600" size={20} />
|
||||
<span className="text-blue-900 font-medium">{t('book_counselor')}</span>
|
||||
</a>
|
||||
|
||||
<Link
|
||||
href="/wellbeing/resources"
|
||||
className="w-full flex items-center space-x-3 p-3 bg-green-50 border border-green-200 rounded-lg hover:bg-green-100 transition-colors"
|
||||
>
|
||||
<Heart className="text-green-600" size={20} />
|
||||
<span className="text-green-900 font-medium">Self-Care Resources</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Counseling Services */}
|
||||
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
||||
<h3 className="font-semibold text-gray-900 mb-4">Counseling Services</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center space-x-3">
|
||||
<CheckCircle className="text-green-600" size={16} />
|
||||
<span className="text-sm text-gray-700">Individual counseling</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<CheckCircle className="text-green-600" size={16} />
|
||||
<span className="text-sm text-gray-700">Group therapy sessions</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<CheckCircle className="text-green-600" size={16} />
|
||||
<span className="text-sm text-gray-700">Crisis intervention</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<CheckCircle className="text-green-600" size={16} />
|
||||
<span className="text-sm text-gray-700">Stress management workshops</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Office Hours */}
|
||||
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
||||
<h3 className="font-semibold text-gray-900 mb-4">Office Hours</h3>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-gray-700">Monday - Friday</span>
|
||||
<span className="text-sm font-medium text-gray-900">8:00 AM - 6:00 PM</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-gray-700">Saturday</span>
|
||||
<span className="text-sm font-medium text-gray-900">10:00 AM - 4:00 PM</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-gray-700">Sunday</span>
|
||||
<span className="text-sm font-medium text-gray-900">Closed</span>
|
||||
</div>
|
||||
<div className="border-t pt-3">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Clock className="text-blue-600" size={16} />
|
||||
<span className="text-sm text-blue-900">24/7 Crisis Line Available</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{/* Emergency Modal */}
|
||||
{showEmergencyModal && (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div className="bg-white rounded-lg p-8 w-full max-w-md">
|
||||
<div className="flex items-center space-x-3 mb-6">
|
||||
<AlertTriangle className="text-red-600" size={24} />
|
||||
<h3 className="text-xl font-bold text-gray-900">Emergency Support</h3>
|
||||
</div>
|
||||
|
||||
<p className="text-gray-600 mb-6">
|
||||
If you're experiencing a mental health emergency, please contact one of these resources immediately:
|
||||
</p>
|
||||
|
||||
<div className="space-y-4 mb-6">
|
||||
<div className="flex items-center space-x-3 p-3 bg-red-50 border border-red-200 rounded-lg">
|
||||
<Phone className="text-red-600" size={20} />
|
||||
<div>
|
||||
<p className="font-medium text-red-900">Crisis Lifeline</p>
|
||||
<p className="text-sm text-red-800">988</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-3 p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<Users className="text-blue-600" size={20} />
|
||||
<div>
|
||||
<p className="font-medium text-blue-900">Campus Counseling</p>
|
||||
<p className="text-sm text-blue-800">(555) 123-4567</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-3 p-3 bg-green-50 border border-green-200 rounded-lg">
|
||||
<Calendar className="text-green-600" size={20} />
|
||||
<div>
|
||||
<p className="font-medium text-green-900">Schedule Appointment</p>
|
||||
<a
|
||||
href="https://calendly.com/university-counseling"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-green-800 hover:underline"
|
||||
>
|
||||
Book with Counselor
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex space-x-4">
|
||||
<button
|
||||
onClick={() => setShowEmergencyModal(false)}
|
||||
className="flex-1 bg-gray-300 text-gray-700 py-2 rounded-lg hover:bg-gray-400 transition-colors"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
<a
|
||||
href="tel:988"
|
||||
className="flex-1 bg-red-600 text-white py-2 rounded-lg hover:bg-red-700 transition-colors text-center"
|
||||
>
|
||||
Call 988
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user