diff --git a/src/App.jsx b/src/App.jsx index 130e2db..7db60fa 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -43,6 +43,7 @@ import KanbanPage from './pages/KanbanPage'; import LeadProjectPage from './pages/LeadProjectPage'; import StormIntelPage from './pages/StormIntelPage'; import FieldStormZonePage from './pages/FieldStormZonePage'; +import UserDetailsPage from './pages/UserDetailsPage'; // ... (existing imports) const ProtectedRoute = ({ children, allowedRoles }) => { @@ -88,6 +89,13 @@ function App() { } /> + {/* Self-service profile for internal roles */} + + + + } /> + { diff --git a/src/pages/UserDetailsPage.jsx b/src/pages/UserDetailsPage.jsx new file mode 100644 index 0000000..d296fd1 --- /dev/null +++ b/src/pages/UserDetailsPage.jsx @@ -0,0 +1,577 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { useAuth } from '../context/AuthContext'; +import { useMockStore } from '../data/mockStore'; +import { SpotlightCard } from '../components/SpotlightCard'; +import { + User, Phone, Info, BookOpen, Calendar, + Shield, Star, Save, Loader2, X, Plus +} from 'lucide-react'; +import { toast } from 'sonner'; + +// ── Local helpers ──────────────────────────────────────────────────────────── + +const SectionHeader = ({ icon: Icon, label, color = 'text-blue-500 dark:text-blue-400' }) => ( +
+ +

{label}

+
+); + +const FieldInput = ({ + id, label, value, onChange, type = 'text', placeholder = '', required = false, optional = false, +}) => ( +
+ + onChange(e.target.value)} + placeholder={placeholder} + className="w-full px-4 py-2 bg-zinc-100 dark:bg-zinc-800/50 border border-zinc-200 dark:border-zinc-700 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all text-sm text-zinc-900 dark:text-zinc-100" + /> +
+); + +const FieldTextarea = ({ id, label, value, onChange, placeholder = '', rows = 4 }) => ( +
+ +