Profile Image Support#202
Merged
Merged
Conversation
- Add UserAvatar wrapper component (src/ui/UserAvatar.tsx) for DRY avatar rendering - Migrate all Avatar usages across the app to UserAvatar - Fix /v1/me endpoint to join profilesCollection and return the uploaded avatar URL - Fix getMembers service to batch-fetch profiles and return avatarUrl per member - Add memberImages state to MessagesPage to show avatars in DM list and channel member picker - Fix absolute URL conversion for TimecoreUser.image in getMe API call - Add ProfileAvatarCropModal for cropping avatar uploads - Add prune-avatars script to clean up orphaned avatar files (backend/scripts/prune-avatars.ts) - Fix ProfileAvatarCropModal: remove unused useRef, fix Modal onClose→onOpenChange, type callback params
- Add profileMedia.ts helper: profileMediaDir, buildProfileMediaFilename, profileMediaUrl, parseProfileMediaUrl - Rewrite profile.controller.ts to use profileMedia helpers - Add uploadBackground / deleteBackground controller + routes - Add backgroundUrl to Profile model, toPublicUser, and /v1/me response - Add PublicUser.backgroundUrl to frontend types + userApi.uploadBackground / deleteBackground / deleteAvatar - Update ProfilePage hero to show uploaded background with overlay + upload UI - Rename prune-avatars.ts → prune-profile-media.ts (scans both avatarUrl + backgroundUrl) - Fix timer start timezone bug: pass client tz in startSession API call; backend isPreviousDate now uses Intl.DateTimeFormat with timezone to correctly determine 'today' in the user's local timezone - Fix route schema: add tz to /timers/entries/:id/start body properties (additionalProperties: false was stripping the tz field)
Restores Tailwind dark-mode gradient classes (dark:from-neutral-900 dark:to-black) that were accidentally replaced with lighter hex values when the background image feature was added.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds server-backed profile media (avatar + background) support and wires those URLs through the app so user images can render in more places. Also includes a maintenance script to prune unused uploaded profile media and updates timer start behavior to accept a client timezone.
Changes:
- Add backend endpoints + storage helpers for uploading/deleting profile avatar and background images, and serve uploaded media via
/uploads/. - Update frontend to upload/crop avatars, upload/remove background images, and render user avatars via a shared
UserAvatarwrapper. - Propagate image fields through user/team APIs; add
tzto timer start requests.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ui/UserDropdown.tsx | Uses UserAvatar and session user.image for dropdown avatars. |
| src/ui/UserAvatar.tsx | Adds a small wrapper around @mieweb/ui Avatar to handle nullable src. |
| src/lib/api.ts | Adds backgroundUrl fields, normalizes relative image URLs to absolute, adds avatar/background upload APIs, adds tz to timer start. |
| src/features/tickets/TicketsPage.tsx | Replaces direct Avatar usage with UserAvatar in ticket lists. |
| src/features/tickets/TicketDetailPage.tsx | Replaces Avatar usage with UserAvatar in activity + metadata sections. |
| src/features/teams/TeamsPage.tsx | Uses member image from API and renders via UserAvatar. |
| src/features/profile/ProfilePage.tsx | Adds UI to upload/crop avatar and upload/remove background image; renders background hero image. |
| src/features/profile/ProfileAvatarCropModal.tsx | New modal using react-easy-crop to crop avatar before upload. |
| src/features/messages/MessagesPage.tsx | Fetches/stores member images and renders DMs with UserAvatar. |
| package.json | Adds react-easy-crop dependency. |
| package-lock.json | Locks react-easy-crop (and transitive deps). |
| backend/src/services/timer.service.ts | Accepts optional tz for “previous day” validation when starting timers. |
| backend/src/services/team.service.ts | Extends team member payload to include image. |
| backend/src/server.ts | Registers multipart upload support and serves backend/data/* at /uploads/. |
| backend/src/routes/users.ts | Includes profile avatar/background in /v1/me and public user payloads; adds /v1/me/avatar and /v1/me/background endpoints. |
| backend/src/routes/timers.ts | Accepts tz in start-session body and forwards to service. |
| backend/src/routes/teams.ts | Extends members response schema to include image. |
| backend/src/models/profile.model.ts | Adds backgroundUrl to Profile model. |
| backend/src/lib/profileMedia.ts | New helpers for profile-media directory, filename generation, and public URL mapping. |
| backend/src/controllers/profile.controller.ts | Implements avatar/background upload + delete handlers, uses shared media helpers. |
| backend/scripts/prune-profile-media.ts | New script to delete orphaned backend/data/profile/* files not referenced in DB. |
| backend/.gitignore | Ignores new media storage folders under backend/data/. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the ability for users to add avatar and background images to their profile page. Includes a script that can prune unused profile media.
Closes #159