feat: Add mobile responsive layout, open room access, and admin room management
Mobile Responsive Layout: - Add useMediaQuery, useIsMobile, useIsTablet, useIsDesktop hooks for device detection - Create MobileHeader component with hamburger menu and action drawer - Create BottomToolbar for mobile navigation (Files, Members) - Create SlidePanel component for full-screen mobile sidebars - Update RoomDetail.tsx with mobile/desktop conditional rendering - Update RoomList.tsx with single-column grid and touch-friendly buttons - Add CSS custom properties for safe areas and touch targets (min 44px) - Add mobile viewport meta tags for notched devices Open Room Access: - All authenticated users can view all rooms (not just their own) - Users can join active rooms they're not members of - Add is_member field to room responses - Update room list API to return all rooms by default Admin Room Management: - Add permanent delete functionality for system admins - Add delete confirmation dialog with room title verification - Broadcast room deletion via WebSocket to connected users - Add users search API for adding members 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
52
app/modules/auth/users_router.py
Normal file
52
app/modules/auth/users_router.py
Normal file
@@ -0,0 +1,52 @@
|
||||
"""User management API endpoints
|
||||
|
||||
Provides:
|
||||
- GET /api/users/search - Search users by name or email
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.modules.auth import get_current_user
|
||||
from app.modules.auth.services.user_service import search_users
|
||||
|
||||
router = APIRouter(prefix="/api/users", tags=["Users"])
|
||||
|
||||
|
||||
class UserSearchResult(BaseModel):
|
||||
"""User search result"""
|
||||
user_id: str
|
||||
display_name: str
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
@router.get("/search", response_model=List[UserSearchResult])
|
||||
async def search_users_endpoint(
|
||||
q: str = Query(..., min_length=1, description="Search query (name or email)"),
|
||||
db: Session = Depends(get_db),
|
||||
current_user: dict = Depends(get_current_user)
|
||||
):
|
||||
"""Search users by display_name or email
|
||||
|
||||
Returns up to 20 matching users. Requires authentication.
|
||||
Search is case-insensitive and matches partial strings.
|
||||
"""
|
||||
if not q or len(q.strip()) == 0:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Search query required"
|
||||
)
|
||||
|
||||
users = search_users(db, q.strip(), limit=20)
|
||||
|
||||
return [
|
||||
UserSearchResult(
|
||||
user_id=user.user_id,
|
||||
display_name=user.display_name
|
||||
)
|
||||
for user in users
|
||||
]
|
||||
Reference in New Issue
Block a user