Skip to content

Feat/image admin#34

Merged
conradangwz merged 8 commits into
mainfrom
feat/image-admin
Apr 29, 2026
Merged

Feat/image admin#34
conradangwz merged 8 commits into
mainfrom
feat/image-admin

Conversation

@conradangwz
Copy link
Copy Markdown
Contributor

@conradangwz conradangwz commented Apr 27, 2026

📑 Description

Adds dynamic image management to the frontend and backend, allowing admins to upload and replace images directly from the UI. Images are stored in AWS S3 and tracked in MongoDB, with each image slot identified by a pageKey tag.

✏️ Summary of Changes

Backend

  • Added tag field to the Image mongoose model to identify image slots (e.g. "hero", "events")
  • Updated uploadImage in imageController.ts to accept a tag from the request body and automatically delete the previous S3 object and MongoDB record for that tag before uploading the new one
  • Added getImageByTag in imageController.ts to fetch the most recent image for a given tag and return a fresh signed S3 URL
  • Added GET /api/images/tag/:tag route

Frontend

  • Added fetchImageByTag and updated uploadImage in imageApi.ts to send the tag with the upload
  • Created ImageBlock component — fetches and displays an image by tag, shows a placeholder if none exists, and exposes a pencil edit button for admins
  • Created UploadModal component — file picker with preview, sends image to backend, closes and refreshes the image on success
  • Styled both components consistently with the KAC theme

📸 Screenshots

Screen.Recording.2026-04-28.105633.mp4

❗️ For the reviewer

  • The role prop on ImageBlock is hardcoded for now ("admin" or "user") — this will be replaced with real auth later
  • Each image slot is identified by a pageKey string (e.g. "hero", "events"). Make sure any new image blocks on other pages use a unique pageKey to avoid overwriting the wrong image
  • The old image is deleted from both S3 and MongoDB on each upload for the same tag — this is intentional to avoid accumulating unused files
  • Signed URLs expire after 15 minutes — if images are cached in state across a long session they may 403, but a page refresh will re-fetch a fresh URL

✅ Ready?

  • Added documentation/updated README to reflect changes (if necessary)
  • Added in-code documentation (wherever needed)
  • Tested new components/features
  • Branch and PR title adheres to naming conventions
  • Self-reviewed pr

Copy link
Copy Markdown
Collaborator

@RLee64 RLee64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Just gotta resolve the merge conflicts and you should be good to merge in.

Just thinking about future tickets:

  • At some point we'll want to represent a collection of images (i.e. admins can add and delete from a related set of images, e.g. for an event)
  • We'll want more efficient querying at some point where we try to fetch multiple images at once rather than one-by-one, we'll cross that bridge when we get there though and assess what needs to be done
  • User roles probably gets fetched from the User Auth context that Vincent made in #30, so the current flow probably gets adjusted a bit (my bad for saying it should be a prop). Change is insignificant though.

Comment thread .prettierrc.json
@@ -1,7 +1,7 @@
{
"trailingComma": "es5",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prettiered the prettier config 😭

@conradangwz conradangwz merged commit e6186fe into main Apr 29, 2026
1 check passed
@conradangwz conradangwz deleted the feat/image-admin branch April 29, 2026 02:39
@RLee64 RLee64 mentioned this pull request Apr 29, 2026
@anqilique anqilique mentioned this pull request May 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants