diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index fac9322..0a1710c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,3 +1,4 @@ +import { useState, useEffect } from 'react' import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom' import { AuthProvider, useAuth } from './context/AuthContext' import { DeveloperModeProvider } from './context/DeveloperModeContext' @@ -12,16 +13,44 @@ import Modify from './pages/Modify' import Tags from './pages/Tags' import FacesMaintenance from './pages/FacesMaintenance' import ApproveIdentified from './pages/ApproveIdentified' +import ManageUsers from './pages/ManageUsers' +import ReportedPhotos from './pages/ReportedPhotos' import Settings from './pages/Settings' import Help from './pages/Help' import Layout from './components/Layout' +import PasswordChangeModal from './components/PasswordChangeModal' +import AdminRoute from './components/AdminRoute' function PrivateRoute({ children }: { children: React.ReactNode }) { - const { isAuthenticated, isLoading } = useAuth() + const { isAuthenticated, isLoading, passwordChangeRequired } = useAuth() + const [showPasswordModal, setShowPasswordModal] = useState(false) + + useEffect(() => { + if (isAuthenticated && passwordChangeRequired) { + setShowPasswordModal(true) + } + }, [isAuthenticated, passwordChangeRequired]) + if (isLoading) { return
+ You must change your password before continuing. Please enter your current password + (provided by your administrator) and choose a new password. +
+ + {error && ( +| + Username + | ++ Email + | ++ Full Name + | ++ Status + | ++ Role + | ++ Created + | ++ Last Login + | ++ Actions + | +
|---|---|---|---|---|---|---|---|
| + {user.username} + | ++ {user.email || '-'} + | ++ {user.full_name || '-'} + | ++ + {user.is_active ? 'Active' : 'Inactive'} + + | ++ + {user.is_admin ? 'Admin' : 'User'} + + | ++ {formatDate(user.created_date)} + | ++ {formatDate(user.last_login)} + | ++ + + | +
+ Minimum 6 characters. Leave empty to keep the current password. +
+Loading reported photos...
+Error loading data
+{error}
+ +No reported photos found.
+| + Photo + | ++ Reported By + | ++ Reported At + | ++ Status + | ++ Decision + | ++ Review Notes + | +
|---|---|---|---|---|---|
|
+
+ {reported.photo_id ? (
+
+ {
+ const photoUrl = `${apiClient.defaults.baseURL}/api/v1/photos/${reported.photo_id}/image`
+ window.open(photoUrl, '_blank')
+ }}
+ title="Click to open full photo"
+ >
+
+ ) : (
+ Photo not found
+ )}
+
+ {reported.photo_filename || `Photo #${reported.photo_id}`}
+
+ |
+
+
+ {reported.user_name || 'Unknown'}
+
+
+ {reported.user_email || '-'}
+
+ |
+
+
+ {formatDate(reported.reported_at)}
+
+ |
+ + + {reported.status} + + | +
+
+
+
+
+ |
+
+ {isReviewed || isDismissed ? (
+
+ {reported.review_notes ? (
+
+ ) : (
+
+ {reported.review_notes}
+
+ ) : (
+ -
+ )}
+
+ {reported.review_notes && (
+
+ )}
+
+
+ )}
+
+ Existing notes:
+
+
+ {reported.review_notes}
+
+ |
+