# Admin Panel Troubleshooting Guide ## Common Issues & Solutions ### 1. Cache Viewer - 404 Error on `/api/v1/admin/cache/list` **Problem:** ``` GET http://localhost:3000/api/v1/admin/cache/list 404 (Not Found) ``` **Root Cause:** The frontend dev server is hitting `localhost:3000` instead of the backend at `localhost:8080`. This happens when the frontend environment variables aren't loaded properly. **Solution:** 1. Verify `frontend/.env` contains: ```env REACT_APP_API_URL=http://localhost:8080/api/v1 ``` 2. **Restart the frontend dev server:** ```bash cd frontend npm start ``` > **Important:** React dev server only loads `.env` variables on startup. Changes require a restart. 3. Verify in browser console that API calls hit `localhost:8080`: ```javascript // Open browser console and check: console.log(process.env.REACT_APP_API_URL); // Should output: http://localhost:8080/api/v1 ``` **Backend Route:** The route exists in `internal/routes/routes.go:294`: ```go cache.GET("/list", baseController.GetAdminCacheList) ``` --- ### 2. User Management - Editor Role Getting 403 Errors **Problem:** ``` 403 Přístup odepřen Rozhodčí píská: tato část hřiště je jen pro kapitány (adminy). ``` **Root Cause:** **This is CORRECT behavior!** The editor role is designed with limited permissions. **Permissions Breakdown:** #### Admin Role (Full Access) - ✅ User management - ✅ Settings & configuration - ✅ Cache & prefetch management - ✅ All CRUD operations - ✅ Newsletter management - ✅ Analytics - ✅ All admin pages #### Editor Role (Limited Access) - ✅ Create/edit articles - ✅ Create/edit events - ✅ Create/edit teams & players - ✅ Create/edit sponsors - ❌ User management - ❌ Settings - ❌ Cache/prefetch - ❌ Newsletter management - ❌ Analytics **Implementation:** See `internal/routes/routes.go:174-176`: ```go admin := protected.Group("/admin") admin.Use(middleware.RoleAuth("admin")) // ← Requires admin role ``` All routes under `/admin/*` require the admin role. Editors cannot access these endpoints. **If you need to grant editor access to specific admin features:** 1. Move those routes outside the admin group 2. Apply `middleware.RoleAuth("editor")` to allow both admins and editors 3. Or create a separate middleware that accepts both roles --- ### 3. User Update - 404 Error on PUT `/admin/users/:id` **Problem:** ``` PUT http://localhost:8080/api/v1/admin/users/2 404 (Not Found) ``` **Possible Causes:** #### A. Backend Not Running ```bash # Check if backend is running: curl http://localhost:8080/api/v1/health # If no response, start the backend: go run main.go ``` #### B. Route Not Registered The route should be registered in `routes.go:225`: ```go admin.PUT("/users/:id", authController.AdminUpdateUser) ``` Verify it exists and the controller method is implemented. #### C. Authentication Issue Ensure you're logged in as an admin: ```bash # Check auth token in browser DevTools → Application → Cookies # Look for: auth_token ``` **Testing the Endpoint:** ```bash # Get auth token from browser cookies, then: curl -X PUT http://localhost:8080/api/v1/admin/users/2 \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Test User","email":"test@test.com","role":"editor","isActive":true}' ``` --- ### 4. Password Reset - 500 Internal Server Error **Problem:** ``` POST http://localhost:8080/api/v1/admin/users/2/reset-password 500 (Internal Server Error) Error: failed to send reset email ``` **Root Cause:** SMTP email configuration is missing or invalid. **Solution:** #### Step 1: Configure SMTP in `.env` Add valid SMTP credentials to your `.env` file: ```env # Basic SMTP Configuration (required) SMTP_HOST=smtp.gmail.com # Your SMTP server SMTP_PORT=587 # 587 for TLS, 465 for SSL SMTP_USER=your-email@gmail.com # Your email address SMTP_PASSWORD=your-app-password # App password (not regular password) SMTP_FROM=noreply@yourclub.com # From email address SMTP_FROM_NAME="Your Club Name" # From name SMTP_ENCRYPTION=tls # tls, ssl, or none SMTP_AUTH=true SMTP_SKIP_VERIFY=false # Email Templates (should already exist) EMAIL_TEMPLATE_DIR=./templates/emails ``` #### Step 2: Optional - Admin-Specific SMTP Override For password resets triggered by admins, you can use separate credentials: ```env # Optional: Admin-specific SMTP for password resets ADMIN_RESET_SMTP_HOST=smtp.purelymail.com ADMIN_RESET_SMTP_PORT=465 ADMIN_RESET_SMTP_USER=system@yourclub.com ADMIN_RESET_SMTP_PASS=secure_password_here ADMIN_RESET_SMTP_FROM=system@yourclub.com ADMIN_RESET_SMTP_FROM_NAME="Club Admin" ``` #### Step 3: Restart Backend ```bash # Stop the backend (Ctrl+C) # Restart: go run main.go ``` #### Step 4: Test SMTP Configuration Try sending a test email from the admin panel: 1. Navigate to Newsletter settings 2. Use the "Send Test Email" feature 3. Verify you receive the email **Common SMTP Providers:** ##### Gmail - Host: `smtp.gmail.com` - Port: `587` (TLS) or `465` (SSL) - **Important:** Use an App Password, not your regular password - Generate one at: https://myaccount.google.com/apppasswords ##### Outlook/Hotmail - Host: `smtp-mail.outlook.com` - Port: `587` - Use your Microsoft account credentials ##### Purelymail - Host: `smtp.purelymail.com` - Port: `465` (SSL) - Very reliable for transactional emails **Improved Error Messages:** The system now shows detailed SMTP errors in the frontend: - Configuration validation errors - SMTP connection errors - Authentication failures Check the error toast for specific details about what went wrong. --- ## Environment Variables Checklist ### Required for Full Functionality ```env # Backend API PORT=8080 APP_ENV=development DEBUG=true # Database DB_HOST=db DB_PORT=5432 DB_USER=postgres DB_PASSWORD=postgres DB_NAME=fotbal_club # Authentication JWT_SECRET=your_secure_secret_here # Change this! JWT_EXPIRATION_HOURS=24 # Email/SMTP (Required for password resets) SMTP_HOST=smtp.yourprovider.com SMTP_PORT=587 SMTP_USER=your-email@example.com SMTP_PASSWORD=your-password SMTP_FROM=noreply@yourclub.com SMTP_FROM_NAME="Your Club" SMTP_ENCRYPTION=tls SMTP_AUTH=true # Frontend (for CORS and API calls) ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8080 REACT_APP_API_URL=http://localhost:8080/api/v1 ``` --- ## Quick Debugging Commands ### Check Backend Health ```bash curl http://localhost:8080/api/v1/health ``` ### Check If You're Authenticated ```bash # In browser console: fetch('/api/v1/auth/me', { credentials: 'include' }) .then(r => r.json()) .then(console.log) ``` ### List All Registered Routes (Go) ```bash # Add this temporarily to main.go after routes.SetupRoutes(): # r.Routes() will show all registered routes ``` ### Check Backend Logs Look for errors in the terminal where you ran `go run main.go`. Common issues: - Database connection errors - SMTP configuration warnings - Missing environment variables --- ## Role-Based Access Control (RBAC) ### Middleware Chain ``` Request → JWTAuth → RoleAuth → Controller ``` 1. **JWTAuth**: Validates JWT token, loads user 2. **RoleAuth**: Checks if user.role matches required role 3. **Controller**: Executes business logic ### Customizing Access To allow editors to access specific admin features: ```go // Option 1: Move route outside admin group protected.PUT("/articles/:id", baseController.UpdateArticle) // Option 2: Create editor-accessible subgroup editorAdmin := protected.Group("/editor-admin") editorAdmin.Use(middleware.RoleAuth("editor")) { editorAdmin.GET("/stats", statsController.GetEditorStats) } // Option 3: Custom middleware for multiple roles func RoleAuthMultiple(roles ...string) gin.HandlerFunc { return func(c *gin.Context) { userRole := c.GetString("userRole") for _, role := range roles { if userRole == role { c.Next() return } } c.JSON(403, gin.H{"error": "Insufficient permissions"}) c.Abort() } } ``` --- ## Testing Checklist After making changes, test: - [ ] Backend health endpoint responds - [ ] Frontend loads without errors - [ ] Admin can log in - [ ] Editor can log in - [ ] Admin can access user management - [ ] Editor CANNOT access user management (403) - [ ] Admin can create/edit users - [ ] Password reset emails send successfully - [ ] Cache viewer loads data - [ ] All API calls hit correct port (8080, not 3000) --- ## Need More Help? ### Check Logs - **Backend:** Terminal where `go run main.go` is running - **Frontend:** Browser DevTools → Console - **Network:** Browser DevTools → Network tab ### Common Log Messages #### Backend ``` [startup] NewsletterEnabled=true (from settings) Server starting on port 8080 ``` #### Frontend Console Errors ```javascript // BAD - hitting wrong port GET http://localhost:3000/api/v1/admin/cache/list 404 // GOOD - hitting correct port GET http://localhost:8080/api/v1/admin/cache/list 200 ``` ### 14. Rich Text Editor Not Visible **Problem:** The Quill rich text editor appears blank or invisible in articles, activities, or other content forms. The editor toolbar and text area don't show up. **Root Cause:** Quill CSS files weren't loading due to component-level imports not working properly with CRACO/Create React App build setup. **Solution:** The CSS imports have been moved to `frontend/src/index.tsx` to load globally: ```typescript // Quill editor styles (MUST be imported globally) import 'react-quill/dist/quill.snow.css'; import 'react-image-crop/dist/ReactCrop.css'; import './styles/custom-editor.css'; ``` **After applying this fix:** 1. **Restart the frontend dev server** (required for CSS changes): ```bash cd frontend npm start ``` 2. Clear browser cache or do a hard refresh (`Ctrl+Shift+R` / `Cmd+Shift+R`) 3. Verify the editor is now visible with: - Toolbar buttons (bold, italic, headers, etc.) - White text area with proper styling - Image upload and formatting controls **Technical Note:** Component-level CSS imports (`import './style.css'` inside a component) don't always process correctly with webpack/CRACO. Critical third-party CSS like Quill must be imported at the app entry point. --- ### Still Stuck? 1. Verify all environment variables are set correctly 2. Restart both frontend and backend 3. Clear browser cache and cookies 4. Check database is running (`docker-compose ps` if using Docker) 5. Review recent code changes that might affect routing