177 lines
6.2 KiB
TypeScript
177 lines
6.2 KiB
TypeScript
"use client"
|
||
|
||
import { useState, useEffect } from "react"
|
||
import { useRouter } from "next/navigation"
|
||
import { Button } from "@/components/ui/button"
|
||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||
import { Shield, ShieldAlert, ShieldX, Settings, LogOut, Users, ShieldCheck, Home, Sun, Smile } from "lucide-react"
|
||
import { type User, ROLE_NAMES } from "@/types/user"
|
||
|
||
export default function DashboardPage() {
|
||
const [user, setUser] = useState<User | null>(null)
|
||
const [selectedStatus, setSelectedStatus] = useState<string | null>(null)
|
||
const [lastUpdated, setLastUpdated] = useState<string | null>(null)
|
||
const [loading, setLoading] = useState(false)
|
||
const router = useRouter()
|
||
|
||
useEffect(() => {
|
||
const userData = localStorage.getItem("user")
|
||
if (!userData) {
|
||
router.push("/login")
|
||
return
|
||
}
|
||
|
||
const parsedUser = JSON.parse(userData)
|
||
setUser(parsedUser)
|
||
setSelectedStatus(parsedUser.in_shelter)
|
||
setLastUpdated(parsedUser.last_updated)
|
||
}, [router])
|
||
|
||
const handleStatusUpdate = async (status: string) => {
|
||
if (!user) return
|
||
|
||
setLoading(true)
|
||
try {
|
||
const response = await fetch("/api/status/update", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({
|
||
nationalId: user.national_id,
|
||
status,
|
||
}),
|
||
})
|
||
|
||
if (response.ok) {
|
||
setSelectedStatus(status)
|
||
setLastUpdated(new Date().toLocaleString("he-IL"))
|
||
}
|
||
} catch (err) {
|
||
console.error("Error updating status:", err)
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}
|
||
|
||
const handleLogout = () => {
|
||
localStorage.removeItem("user")
|
||
router.push("/login")
|
||
}
|
||
|
||
const canAccessAdmin = () => {
|
||
return !!user?.role && user.role !== "user"
|
||
}
|
||
|
||
if (!user) return null
|
||
|
||
const getStatusText = (status: string) => {
|
||
switch (status) {
|
||
case "yes":
|
||
return "במקלט/חדר מוגן"
|
||
case "no":
|
||
return "לא במקלט - אין מקלט בקרבת מקום"
|
||
case "no_alarm":
|
||
return "אין אזעקה באזור שלי"
|
||
case "safe_after_exit":
|
||
return "אני בטוח (אחרי יציאה מהמקלט)"
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gray-50 p-4" dir="rtl">
|
||
<div className="max-w-md mx-auto space-y-6">
|
||
<Card>
|
||
<CardHeader className="text-center">
|
||
<CardTitle className="text-xl">שלום {user.name}</CardTitle>
|
||
<div className="text-sm text-gray-600 mb-2">
|
||
{ROLE_NAMES[user.role] || user.role}
|
||
{user.field && ` - תחום ${user.field}`}
|
||
{user.department && ` - מסגרת ${user.department}`}
|
||
{user.team && ` - צוות ${user.team}`}
|
||
</div>
|
||
<div className="flex justify-between items-center">
|
||
<Button variant="outline" size="sm" onClick={handleLogout} className="flex items-center gap-2">
|
||
<LogOut className="h-4 w-4" />
|
||
התנתקות
|
||
</Button>
|
||
{canAccessAdmin() && (
|
||
<Button
|
||
variant="outline"
|
||
size="sm"
|
||
onClick={() => router.push("/admin")}
|
||
className="flex items-center gap-2"
|
||
>
|
||
{user.role === "user" ? <Settings className="h-4 w-4" /> : <Users className="h-4 w-4" />}
|
||
{user.role === "user" ? "ניהול" : "ניהול"}
|
||
</Button>
|
||
)}
|
||
</div>
|
||
</CardHeader>
|
||
</Card>
|
||
|
||
<div className="space-y-4">
|
||
<Button
|
||
variant={selectedStatus === "safe_after_exit" ? "default" : "outline"}
|
||
className={`w-full h-16 text-lg ${selectedStatus === "safe_after_exit" ? "bg-green-600 hover:bg-green-700" : ""}`}
|
||
onClick={() => handleStatusUpdate("safe_after_exit")}
|
||
disabled={loading}
|
||
>
|
||
<Shield className="ml-2 h-6 w-6" />
|
||
אני בטוח.ה (אחרי יציאה מהמקלט)
|
||
</Button>
|
||
|
||
<Button
|
||
variant={selectedStatus === "yes" ? "default" : "outline"}
|
||
className={`w-full h-20 text-xl ${selectedStatus === "yes" ? "bg-green-600 hover:bg-green-700" : ""}`}
|
||
onClick={() => handleStatusUpdate("yes")}
|
||
disabled={loading}
|
||
>
|
||
<ShieldCheck className="ml-2 h-8 w-8" />
|
||
במקלט/מרחב מוגן
|
||
</Button>
|
||
|
||
<Button
|
||
variant={selectedStatus === "no" ? "default" : "outline"}
|
||
className={`w-full h-16 text-lg ${selectedStatus === "no" ? "bg-green-600 hover:bg-green-700" : ""}`}
|
||
onClick={() => handleStatusUpdate("no")}
|
||
disabled={loading}
|
||
>
|
||
<ShieldX className="ml-2 h-6 w-6" />
|
||
לא במקלט - אין מקלט בקרבת מקום
|
||
</Button>
|
||
<Button
|
||
variant={selectedStatus === "no_alarm" ? "default" : "outline"}
|
||
className={`w-full h-16 text-lg ${selectedStatus === "no_alarm" ? "bg-green-600 hover:bg-green-700" : ""}`}
|
||
onClick={() => handleStatusUpdate("no_alarm")}
|
||
disabled={loading}
|
||
>
|
||
<Smile className="ml-2 h-6 w-6" />
|
||
אין אזעקה באזור שלי
|
||
</Button>
|
||
</div>
|
||
|
||
{selectedStatus && lastUpdated && (
|
||
<Card>
|
||
<CardContent className="pt-6 text-center">
|
||
<p className="text-sm text-gray-600">סטטוס נוכחי:</p>
|
||
<p className="font-semibold text-green-600">{getStatusText(selectedStatus)}</p>
|
||
<p className="text-xs text-gray-500 mt-2">עודכן: {lastUpdated}</p>
|
||
</CardContent>
|
||
</Card>
|
||
)}
|
||
{/* Hostname Footer */}
|
||
<Card className="mt-8">
|
||
<CardContent className="py-3">
|
||
<div className="text-center text-xs text-gray-500">
|
||
סביבה: {process.env.NEXT_PUBLIC_HOSTNAME || process.env.HOSTNAME || "לא זוהה"}
|
||
<br />
|
||
2025 COPYRIGHT TR-WEB
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|