From 37d0e3132b5056535c1553784bddece8af7170da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Z=C3=B6ller?= Date: Thu, 4 Dec 2025 08:09:44 +0100 Subject: [PATCH] Follower UI --- CLAUDE.md | 20 +- .../fitpub/config/SecurityConfig.java | 5 + .../controller/ProfileViewController.java | 13 + src/main/resources/templates/layout.html | 5 + .../resources/templates/profile/view.html | 9 +- .../resources/templates/users/discover.html | 382 ++++++++++++++++++ 6 files changed, 429 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/templates/users/discover.html diff --git a/CLAUDE.md b/CLAUDE.md index f345873..e98205e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -698,7 +698,7 @@ For ActivityPub federated posts and thumbnails: - [x] Public user profile page (profile/public.html) - [x] User profile display (avatar, bio, display name) - [x] User's activity list on profile with pagination -- [x] Follower/following counts display (static for now) +- [x] Follower/following counts display (real data from backend) - [x] Profile edit page (profile/edit.html) - [x] Avatar URL input - [x] Profile settings form with validation @@ -718,9 +718,20 @@ For ActivityPub federated posts and thumbnails: - [x] Settings page placeholder (settings.html) - [x] Client-side authentication checks for protected pages +**User Discovery UI** ✅ +- [x] Discover users page (users/discover.html) +- [x] User search functionality with live search bar +- [x] Browse all users with pagination +- [x] User cards grid layout with avatar, bio, and stats +- [x] Responsive design for mobile and desktop +- [x] Empty state for no results +- [x] Loading indicators +- [x] View controller route (GET /discover) +- [x] Integration with backend search and browse APIs + **Navigation & Layout** ✅ - [x] Top navigation bar with logo -- [x] Navigation links (Timeline, My Activities, Upload, Profile) +- [x] Navigation links (Timeline, Discover, My Activities, Upload, Profile) - [x] User menu dropdown (Profile, Settings, Logout) - [x] Footer with app info - [x] Mobile hamburger menu (Bootstrap responsive navbar) @@ -761,9 +772,10 @@ For ActivityPub federated posts and thumbnails: - [x] Activity image generation with track overlay (ActivityImageService) - [x] FIT epoch timestamp fix (631065600 second offset for proper date handling) - [x] Web Mercator projection for accurate track-to-map alignment -- [x] User search and discovery (UserRepository.searchUsers, UserRepository.findAllEnabledUsers, GET /api/users/search, GET /api/users/browse) +- [x] User search and discovery backend (UserRepository.searchUsers, UserRepository.findAllEnabledUsers, GET /api/users/search, GET /api/users/browse) +- [x] User search and discovery UI (users/discover.html, /discover route, search bar with live filtering, user cards grid, pagination) - [x] Followers/following lists (ActorDTO, GET /api/users/{username}/followers, GET /api/users/{username}/following) -- [ ] Follower/following counts (populate with real data) +- [x] Follower/following counts (UserController.populateSocialCounts, UserDTO with followersCount/followingCount, frontend displays real counts) - [ ] Notifications system - [ ] Enhanced privacy controls UI - [ ] Follow/unfollow buttons on user profiles diff --git a/src/main/java/org/operaton/fitpub/config/SecurityConfig.java b/src/main/java/org/operaton/fitpub/config/SecurityConfig.java index 96a77d7..6bfd8ef 100644 --- a/src/main/java/org/operaton/fitpub/config/SecurityConfig.java +++ b/src/main/java/org/operaton/fitpub/config/SecurityConfig.java @@ -58,6 +58,7 @@ public class SecurityConfig { // Public endpoints - Web UI pages .requestMatchers("/", "/login", "/register", "/timeline", "/timeline/**", "/activities", "/activities/**").permitAll() .requestMatchers("/profile", "/profile/**", "/settings").permitAll() // Auth checked client-side + .requestMatchers("/discover").permitAll() // User discovery page // Public endpoints - ActivityPub federation .requestMatchers("/.well-known/**").permitAll() @@ -110,6 +111,10 @@ public class SecurityConfig { .requestMatchers(HttpMethod.PUT, "/api/users/me").authenticated() .requestMatchers(HttpMethod.GET, "/api/users/{username}").permitAll() .requestMatchers(HttpMethod.GET, "/api/users/id/*").permitAll() + .requestMatchers(HttpMethod.GET, "/api/users/search").permitAll() // User search + .requestMatchers(HttpMethod.GET, "/api/users/browse").permitAll() // Browse all users + .requestMatchers(HttpMethod.GET, "/api/users/*/followers").permitAll() // User followers list + .requestMatchers(HttpMethod.GET, "/api/users/*/following").permitAll() // User following list // All other requests require authentication .anyRequest().authenticated() diff --git a/src/main/java/org/operaton/fitpub/controller/ProfileViewController.java b/src/main/java/org/operaton/fitpub/controller/ProfileViewController.java index 0d376c5..ee0766d 100644 --- a/src/main/java/org/operaton/fitpub/controller/ProfileViewController.java +++ b/src/main/java/org/operaton/fitpub/controller/ProfileViewController.java @@ -94,4 +94,17 @@ public class ProfileViewController { model.addAttribute("username", username); return "profile/following"; } + + /** + * User discovery page. + * Allows searching and browsing all users. + * + * @param model the model + * @return discover template + */ + @GetMapping("/discover") + public String discoverUsers(Model model) { + model.addAttribute("pageTitle", "Discover Users"); + return "users/discover"; + } } diff --git a/src/main/resources/templates/layout.html b/src/main/resources/templates/layout.html index 3bb2540..60f1413 100644 --- a/src/main/resources/templates/layout.html +++ b/src/main/resources/templates/layout.html @@ -55,6 +55,11 @@ Timeline +