Ver Fonte

fix: проверка роли executor при создании услуги; role-based toolbar

neyrogovnarik há 1 mês atrás
pai
commit
b1c340fa31
2 ficheiros alterados com 34 adições e 20 exclusões
  1. 6 0
      backend/internal/handlers/services.go
  2. 28 20
      frontend/src/components/Header.tsx

+ 6 - 0
backend/internal/handlers/services.go

@@ -104,6 +104,12 @@ type updateServiceRequest struct {
 
 func (h *ServiceHandler) Create(w http.ResponseWriter, r *http.Request) {
 	userID := middleware.GetUserID(r.Context())
+	role := middleware.GetUserRole(r.Context())
+
+	if role != "executor" && role != "moderator" && role != "superadmin" {
+		writeError(w, http.StatusForbidden, "only executors can create services", nil)
+		return
+	}
 
 	r.Body = http.MaxBytesReader(w, r.Body, maxRequestBodySize)
 	var req createServiceRequest

+ 28 - 20
frontend/src/components/Header.tsx

@@ -6,48 +6,56 @@ import { useAuth } from '@/hooks/useAuth'
 import LoginModal from './LoginModal'
 import RegisterModal from './RegisterModal'
 
+const roleLinks: Record<string, { href: string; label: string }> = {
+  customer: { href: '/places/add', label: 'Мои места' },
+  executor: { href: '/services/add', label: 'Мои услуги' },
+  landlord: { href: '/studios/add', label: 'Мои студии' },
+}
+
 export default function Header() {
   const { user, isLoading, logout } = useAuth()
   const [showLogin, setShowLogin] = useState(false)
   const [showRegister, setShowRegister] = useState(false)
 
   return (
-    <header className="absolute left-0 right-0 top-0 z-30 flex items-center justify-between px-4 py-3">
-      <Link href="/" className="text-lg font-bold text-white">
-        PhotoPlaces
-      </Link>
+    <>
+      <header className="absolute left-0 right-0 top-0 z-30 flex items-center justify-between px-4 py-3">
+        <Link href="/" className="text-lg font-bold text-white">
+          PhotoPlaces
+        </Link>
+      </header>
 
       {showLogin && <LoginModal onClose={() => setShowLogin(false)} />}
       {showRegister && <RegisterModal onClose={() => setShowRegister(false)} />}
 
-      <nav className="flex items-center gap-4">
+      <div className="absolute right-4 top-4 z-30 inline-flex items-center gap-3 rounded-lg bg-white/10 backdrop-blur-md px-4 py-2">
         {isLoading ? null : user ? (
           <>
-            <span className="text-sm text-white/60">{user.email}</span>
-            <button
-              onClick={logout}
-              className="rounded-lg bg-white/10 backdrop-blur-md px-4 py-2 text-sm text-white hover:bg-white/20 transition"
-            >
+            <span className="text-sm text-white/60">{user.name || user.email}</span>
+            {(user.role === 'moderator' || user.role === 'superadmin') ? (
+              <Link href="/admin" className="text-sm text-white hover:text-green-400 transition">
+                Админка
+              </Link>
+            ) : roleLinks[user.role] ? (
+              <Link href={roleLinks[user.role].href} className="text-sm text-white hover:text-green-400 transition">
+                {roleLinks[user.role].label}
+              </Link>
+            ) : null}
+            <button onClick={logout} className="text-sm text-white/60 hover:text-white transition">
               Выйти
             </button>
           </>
         ) : (
           <>
-            <button
-              onClick={() => setShowLogin(true)}
-              className="rounded-lg bg-white/10 backdrop-blur-md px-4 py-2 text-sm text-white hover:bg-white/20 transition"
-            >
+            <button onClick={() => setShowLogin(true)} className="text-sm text-white hover:text-green-400 transition">
               Войти
             </button>
-            <button
-              onClick={() => setShowRegister(true)}
-              className="rounded-lg bg-green-600 px-4 py-2 text-sm text-white hover:bg-green-500 transition"
-            >
+            <button onClick={() => setShowRegister(true)} className="text-sm text-white hover:text-green-400 transition">
               Регистрация
             </button>
           </>
         )}
-      </nav>
-    </header>
+      </div>
+    </>
   )
 }