Version 1.1 initial commit
This commit is contained in:
+18
-1
@@ -175,6 +175,7 @@ export default function AdminPage() {
|
||||
|
||||
const [reportModalOpen, setReportModalOpen] = useState(false)
|
||||
const [selectedUserForReport, setSelectedUserForReport] = useState<UserData | null>(null)
|
||||
const [instanceName, setInstanceName] = useState<string>("")
|
||||
|
||||
// Global real-time updates
|
||||
const { isConnected: globalConnected, refetch: refetchGlobal } = useRealTimeUpdates((data) => {
|
||||
@@ -333,6 +334,22 @@ export default function AdminPage() {
|
||||
setUser(parsedUser)
|
||||
}, [router])
|
||||
|
||||
useEffect(() => {
|
||||
const loadInstance = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/instance")
|
||||
const data = await response.json()
|
||||
if (response.ok && data.instance) {
|
||||
setInstanceName(data.instance)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load instance name:", error)
|
||||
}
|
||||
}
|
||||
|
||||
loadInstance()
|
||||
}, [])
|
||||
|
||||
const fetchManagedTypes = async () => {
|
||||
setManagedTypesLoading(true)
|
||||
try {
|
||||
@@ -1837,7 +1854,7 @@ export default function AdminPage() {
|
||||
<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 || "לא זוהה"}
|
||||
סביבה: {instanceName || process.env.NEXT_PUBLIC_HOSTNAME || process.env.HOSTNAME || "לא זוהה"}
|
||||
<br/>
|
||||
גרסה: {process.env.APPVERSION || "לא הוצהר ב-Dockerfile!"}
|
||||
<br/>
|
||||
|
||||
@@ -19,14 +19,14 @@ export async function POST(request: NextRequest) {
|
||||
const { adminId, targetUserId, field, department, team } = await request.json()
|
||||
|
||||
if (!adminId || !targetUserId || !field || !department || !team) {
|
||||
return NextResponse.json({ error: "Missing required fields." }, { status: 400 })
|
||||
return NextResponse.json({ error: "חסרים שדות חובה." }, { status: 400 })
|
||||
}
|
||||
|
||||
const adminRows = (await safeQuery("SELECT role, field, department, team FROM users WHERE national_id = ?", [
|
||||
adminId,
|
||||
])) as any[]
|
||||
if (adminRows.length === 0) {
|
||||
return NextResponse.json({ error: "Admin not found." }, { status: 404 })
|
||||
return NextResponse.json({ error: "הרשאת מנהל לא נמצאה" }, { status: 404 })
|
||||
}
|
||||
|
||||
const admin = adminRows[0]
|
||||
@@ -35,7 +35,7 @@ export async function POST(request: NextRequest) {
|
||||
targetUserId,
|
||||
])) as any[]
|
||||
if (userRows.length === 0) {
|
||||
return NextResponse.json({ error: "User not found." }, { status: 404 })
|
||||
return NextResponse.json({ error: "משתמש לא נמצא." }, { status: 404 })
|
||||
}
|
||||
const targetUser = userRows[0]
|
||||
|
||||
@@ -46,7 +46,7 @@ export async function POST(request: NextRequest) {
|
||||
])
|
||||
|
||||
if (!fieldOk || !departmentOk || !teamOk) {
|
||||
return NextResponse.json({ error: "Invalid field, department, or team." }, { status: 400 })
|
||||
return NextResponse.json({ error: "תחום, מסגרת או צוות שגויים." }, { status: 400 })
|
||||
}
|
||||
|
||||
const fieldRows = (await safeQuery("SELECT id FROM managed_types WHERE type = 'field' AND name = ?", [
|
||||
@@ -62,49 +62,49 @@ export async function POST(request: NextRequest) {
|
||||
)) as Array<{ id: number; parentId: number | null }>
|
||||
|
||||
if (fieldRows.length === 0 || departmentRows.length === 0 || teamRows.length === 0) {
|
||||
return NextResponse.json({ error: "Invalid field, department, or team." }, { status: 400 })
|
||||
return NextResponse.json({ error: "תחום, מסגרת או צוות שגויים." }, { status: 400 })
|
||||
}
|
||||
|
||||
if (departmentRows[0].parentId !== fieldRows[0].id) {
|
||||
return NextResponse.json({ error: "Department does not belong to field." }, { status: 400 })
|
||||
return NextResponse.json({ error: "מסגרת לא משוייכת לתחום הנבחר." }, { status: 400 })
|
||||
}
|
||||
|
||||
if (teamRows[0].parentId !== departmentRows[0].id) {
|
||||
return NextResponse.json({ error: "Team does not belong to department." }, { status: 400 })
|
||||
return NextResponse.json({ error: "צוות לא משוייך למסגרת הנבחרת." }, { status: 400 })
|
||||
}
|
||||
|
||||
if (admin.role === "field_admin") {
|
||||
if (targetUser.field !== admin.field) {
|
||||
return NextResponse.json({ error: "Target user is outside your field." }, { status: 403 })
|
||||
return NextResponse.json({ error: "המשתמש הנבחר לא משוייך לתחום שלך." }, { status: 403 })
|
||||
}
|
||||
if (field !== admin.field) {
|
||||
return NextResponse.json({ error: "Field admins can only assign within their field." }, { status: 403 })
|
||||
return NextResponse.json({ error: "מנהלי תחומים רשאים לנהל אך ורק את התחום שלהם." }, { status: 403 })
|
||||
}
|
||||
} else if (admin.role === "department_admin") {
|
||||
if (targetUser.department !== admin.department) {
|
||||
return NextResponse.json({ error: "Target user is outside your department." }, { status: 403 })
|
||||
return NextResponse.json({ error: "המשתמש הנבחר לא משוייך למסגרת שלך." }, { status: 403 })
|
||||
}
|
||||
if (department !== admin.department) {
|
||||
return NextResponse.json({ error: "Department admins can only assign within their department." }, { status: 403 })
|
||||
return NextResponse.json({ error: "מנהלי מסגרות רשאים לנהל אך ורק את המסגרת שלהם." }, { status: 403 })
|
||||
}
|
||||
if (admin.field && field !== admin.field) {
|
||||
return NextResponse.json({ error: "Department admins can only assign within their field." }, { status: 403 })
|
||||
return NextResponse.json({ error: "מנהלי מסגרות רשאים לנהל אך ורק באותו התחום." }, { status: 403 })
|
||||
}
|
||||
} else if (admin.role === "team_admin") {
|
||||
if (targetUser.team !== admin.team) {
|
||||
return NextResponse.json({ error: "Target user is outside your team." }, { status: 403 })
|
||||
return NextResponse.json({ error: "המשתמש הנבחר לא משוייך לצוות שלך." }, { status: 403 })
|
||||
}
|
||||
if (team !== admin.team) {
|
||||
return NextResponse.json({ error: "Team admins can only assign within their team." }, { status: 403 })
|
||||
return NextResponse.json({ error: "מנהלי צוותים רשאים לנהל אך ורק את הצוות שלהם." }, { status: 403 })
|
||||
}
|
||||
if (admin.department && department !== admin.department) {
|
||||
return NextResponse.json({ error: "Team admins can only assign within their department." }, { status: 403 })
|
||||
return NextResponse.json({ error: "מנהלי צוותים רשאים לנהל אך ורק באותה המסגרת." }, { status: 403 })
|
||||
}
|
||||
if (admin.field && field !== admin.field) {
|
||||
return NextResponse.json({ error: "Team admins can only assign within their field." }, { status: 403 })
|
||||
return NextResponse.json({ error: "מנהלי צוותים ראשאים לנהל אך ורק באותו התחום." }, { status: 403 })
|
||||
}
|
||||
} else if (admin.role !== "global_admin") {
|
||||
return NextResponse.json({ error: "Insufficient permissions." }, { status: 403 })
|
||||
return NextResponse.json({ error: "הרשאות לא מספיקות." }, { status: 403 })
|
||||
}
|
||||
|
||||
await safeQuery("UPDATE users SET field = ?, department = ?, team = ? WHERE national_id = ?", [
|
||||
@@ -114,9 +114,9 @@ export async function POST(request: NextRequest) {
|
||||
targetUserId,
|
||||
])
|
||||
|
||||
return NextResponse.json({ success: true, message: "User assignment updated." })
|
||||
return NextResponse.json({ success: true, message: "משתמש עודכן בהצלחה." })
|
||||
} catch (error) {
|
||||
console.error("Update user scope error:", error)
|
||||
return NextResponse.json({ error: "Failed to update user." }, { status: 500 })
|
||||
return NextResponse.json({ error: "עדכון משתמש נכשל." }, { status: 500 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { NextResponse } from "next/server"
|
||||
import os from "os"
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
return NextResponse.json({ instance: os.hostname() })
|
||||
} catch (error) {
|
||||
console.error("Instance fetch error:", error)
|
||||
return NextResponse.json({ error: "Failed to load instance name." }, { status: 500 })
|
||||
}
|
||||
}
|
||||
+18
-1
@@ -12,6 +12,7 @@ export default function DashboardPage() {
|
||||
const [selectedStatus, setSelectedStatus] = useState<string | null>(null)
|
||||
const [lastUpdated, setLastUpdated] = useState<string | null>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [instanceName, setInstanceName] = useState<string>("")
|
||||
const router = useRouter()
|
||||
|
||||
const refreshUser = async (currentUser: User) => {
|
||||
@@ -58,6 +59,22 @@ export default function DashboardPage() {
|
||||
return () => window.removeEventListener("visibilitychange", handleVisibility)
|
||||
}, [router])
|
||||
|
||||
useEffect(() => {
|
||||
const loadInstance = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/instance")
|
||||
const data = await response.json()
|
||||
if (response.ok && data.instance) {
|
||||
setInstanceName(data.instance)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load instance name:", error)
|
||||
}
|
||||
}
|
||||
|
||||
loadInstance()
|
||||
}, [])
|
||||
|
||||
const handleStatusUpdate = async (status: string) => {
|
||||
if (!user) return
|
||||
|
||||
@@ -195,7 +212,7 @@ export default function DashboardPage() {
|
||||
<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 || "לא זוהה"}
|
||||
סביבה: {instanceName || process.env.NEXT_PUBLIC_HOSTNAME || process.env.HOSTNAME || "לא זוהה"}
|
||||
<br/>
|
||||
גרסה: {process.env.APPVERSION || "לא הוגדרה גרסה ב-Dockerfile!"}
|
||||
<br/>
|
||||
|
||||
Reference in New Issue
Block a user