Skip to content

feat: sponsor media upload tab#783

Open
santipalenque wants to merge 4 commits intomasterfrom
feature/sponsor-media-upload-tab
Open

feat: sponsor media upload tab#783
santipalenque wants to merge 4 commits intomasterfrom
feature/sponsor-media-upload-tab

Conversation

@santipalenque
Copy link

@santipalenque santipalenque commented Feb 5, 2026

https://app.clickup.com/t/86b7991cx

Summary by CodeRabbit

  • New Features
    • Added a Sponsor Media Uploads tab showing sponsor and general media requests with auto-load, pagination, sorting, and row actions (view, download, upload, delete).
  • Localization
    • New English labels and messages for the media upload tab and its actions.
  • Other
    • Added media upload status labels (Pending, Deadline Alert, Deadline Missed, Complete), file-size display (MB), and updated scopes to include media-upload/read.

@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a Sponsor Media Upload feature: new Redux actions and reducer, store wiring, a React tab component with tables and pagination, new constants/utilities/i18n entries, and an update to .env.example to include media-upload/read in sponsor scopes.

Changes

Cohort / File(s) Summary
Env / Config
​.env.example
Updated SPONSOR_PAGES_SCOPES to include media-upload/read; SCOPES still references it.
Redux Actions
src/actions/sponsor-mu-actions.js
New action types and thunks (getSponsorMURequests, getGeneralMURequests) to fetch sponsor and general media uploads; dispatch loading, build API requests, handle errors.
Redux Reducer
src/reducers/sponsors/sponsor-page-mu-list-reducer.js
New reducer managing sponsorRequests and generalRequests, pagination/sorting, summitTZ, mapping media objects and computing deadlines/status.
Store Wiring
src/store.js
Registers sponsorPageMUListState in persisted root reducers.
UI — Sponsor Page
src/pages/sponsors/edit-sponsor-page.js
Adds Sponsor Media Upload tab and shifts existing panels to accommodate new tab.
UI — Media Upload Tab
src/pages/sponsors/sponsor-media-upload-tab/index.js
New connected React component SponsorMediaUploadTab: fetches lists on mount, supports pagination/sorting, renders sponsor and general tables with status chips and actions (view/download/upload/delete).
Constants / Utils
src/utils/constants.js, src/utils/methods.js
Fixed PURCHASE_STATUS closure; added SPONSOR_MEDIA_UPLOAD_STATUS, BYTES_IN_MEGABYTE, DEADLINE_ALERT_DAYS; added bytesToMb(bytes) util.
i18n
src/i18n/en.json
Added mu_tab localization keys for labels/messages used by the new tab.

Sequence Diagram

sequenceDiagram
    participant UI as SponsorMediaUploadTab
    participant Store as Redux Store
    participant Action as Thunk Action
    participant API as Sponsor Pages API
    participant Reducer as sponsorPageMUListReducer

    UI->>Store: dispatch getSponsorMURequests()
    activate Action
    Action->>Store: dispatch REQUEST_SPONSOR_MEDIA_UPLOADS
    activate Reducer
    Reducer-->>Store: clear requests, set params (page, order, summitTZ)
    deactivate Reducer

    Action->>API: GET /summits/{id}/sponsors/{id}/media-uploads?...
    API-->>Action: 200 { pagination, data }

    Action->>Store: dispatch RECEIVE_SPONSOR_MEDIA_UPLOADS
    activate Reducer
    Reducer-->>Store: map data, compute deadline/status, set pagination
    deactivate Reducer
    deactivate Action

    Store-->>UI: updated props via mapStateToProps
    UI->>UI: re-render sponsor and general tables
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • smarcet

Poem

🐰
I hopped through tabs where uploads hide,
I nudged the chips and checked the tide,
Requests lined up in tidy rows,
Deadlines flicker, cookies and prose,
I nibble bytes and watch it glide.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: sponsor media upload tab' accurately describes the main change in the PR, which introduces a new SponsorMediaUploadTab component with associated Redux actions, reducer, and utilities.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/sponsor-media-upload-tab

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.env.example (1)

16-20: ⚠️ Potential issue | 🟡 Minor

Fix dotenv-linter UnorderedKey warning.

SPONSOR_PAGES_SCOPES should appear before SPONSOR_USERS_API_SCOPES to satisfy the linter.

🔧 Reorder example
-PURCHASES_API_SCOPES="purchases-show-medata/read purchases-show-medata/write show-form/read show-form/write customized-form/write customized-form/read carts/read carts/write"
-SPONSOR_USERS_API_SCOPES="show-medata/read show-medata/write access-requests/read access-requests/write sponsor-users/read sponsor-users/write groups/read groups/write"
+PURCHASES_API_SCOPES="purchases-show-medata/read purchases-show-medata/write show-form/read show-form/write customized-form/write customized-form/read carts/read carts/write"
+SPONSOR_PAGES_SCOPES="page-template/read page-template/write show-page/read show-page/write media-upload/read"
+SPONSOR_USERS_API_SCOPES="show-medata/read show-medata/write access-requests/read access-requests/write sponsor-users/read sponsor-users/write groups/read groups/write"
src/pages/sponsors/edit-sponsor-page.js (1)

214-244: ⚠️ Potential issue | 🟠 Major

Fix tab/panel index mismatch (Users vs Pages).

Lines 236–241 render the Users list under index 2 (Pages), while index 1 (Users) shows placeholder text. This misroutes the tab content. Use SPONSOR_TABS.* values for CustomTabPanel indices to prevent drift.

✅ Suggested alignment
-        <CustomTabPanel value={selectedTab} index={1}>
-          USERS
-        </CustomTabPanel>
-        <CustomTabPanel value={selectedTab} index={2}>
-          <SponsorUsersListPerSponsorPage sponsor={entity} />
-        </CustomTabPanel>
-        <CustomTabPanel value={selectedTab} index={3}>
+        <CustomTabPanel value={selectedTab} index={SPONSOR_TABS.USERS}>
+          <SponsorUsersListPerSponsorPage sponsor={entity} />
+        </CustomTabPanel>
+        <CustomTabPanel value={selectedTab} index={SPONSOR_TABS.MEDIA_UPLOADS}>
           <SponsorMediaUploadTab sponsor={entity} summitId={currentSummit.id} />
         </CustomTabPanel>
🤖 Fix all issues with AI agents
In `@src/actions/sponsor-mu-actions.js`:
- Around line 45-69: The code dispatches startLoading() before calling
getRequest but only dispatches stopLoading() inside the .then branch so
stopLoading() is never called on rejection; modify the call that invokes
getRequest(createAction(REQUEST_SPONSOR_MEDIA_UPLOADS),
createAction(RECEIVE_SPONSOR_MEDIA_UPLOADS), ...)(params)(dispatch) so that
stopLoading() is always executed by using a try/finally around an await of that
request or by appending .finally(() => dispatch(stopLoading())), keeping the
same parameters and handlers (snackbarErrorHandler) and preserving
startLoading()/stopLoading() calls.
- Around line 31-67: The action getSponsorMURequests is passing currentPage in
the payload object to getRequest but the reducer expects page; change the
payload object passed in the getRequest call (the object currently written as {
order, orderDir, currentPage, perPage, summitTZ }) to use page: currentPage
instead of currentPage so the reducer (which destructures page) receives the
correct pagination key and currentPage is preserved in state.

In `@src/pages/sponsors/sponsor-media-upload-tab/index.js`:
- Around line 101-123: The renderers for the View and Download IconButton
components are disabling buttons when a file exists due to the condition
"!!row.file"; change the condition to disable when the file is missing (use
"!row.file" or equivalent) so that handleSponsorView and handleSponsorDownload
are enabled when row.file is truthy and disabled when falsy; update both
IconButton render blocks associated with the View (uses handleSponsorView) and
Download (uses handleSponsorDownload) columns accordingly.

In `@src/reducers/sponsors/sponsor-page-mu-list-reducer.js`:
- Around line 65-78: The mapped object in the payload.response.data mapping
(inside the reducer that builds rows for SponsorMediaUploadTab) only returns id,
code, name, items_count and expires_at, but the UI expects add_on, max_size,
format, deadline, status and file; update the mapping logic that constructs each
row (the payload.response.data.map callback) to extract and normalize the
corresponding API fields (e.g., add_on, max_size, format, deadline—converting
deadline via epochToMomentTimeZone like expires_at—and compute a safe status
value and file metadata) so the returned object includes keys add_on, max_size,
format, deadline, status, file along with the existing fields used by
SponsorMediaUploadTab and ensure any missing fields use sensible defaults (e.g.,
"N/A" or null).

Comment on lines 45 to 69
dispatch(startLoading());

const params = {
page: currentPage,
// fields: "id,code,name,level,expire_date",
// relations: "add_ons",
per_page: perPage,
access_token: accessToken
};

// order
if (order != null && orderDir != null) {
const orderDirSign = orderDir === 1 ? "" : "-";
params.order = `${orderDirSign}${order}`;
}

return getRequest(
createAction(REQUEST_SPONSOR_MEDIA_UPLOADS),
createAction(RECEIVE_SPONSOR_MEDIA_UPLOADS),
`${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsor.id}/custom-media-request-modules`,
snackbarErrorHandler,
{ order, orderDir, currentPage, perPage, summitTZ }
)(params)(dispatch).then(() => {
dispatch(stopLoading());
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Ensure loading stops on errors (use finally).

If the request rejects, stopLoading() isn’t called, leaving the UI in a loading state. Wrap the call in try/finally or use .finally(...).

✅ Suggested fix (try/finally)
-    return getRequest(
-      createAction(REQUEST_SPONSOR_MEDIA_UPLOADS),
-      createAction(RECEIVE_SPONSOR_MEDIA_UPLOADS),
-      `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsor.id}/custom-media-request-modules`,
-      snackbarErrorHandler,
-      { order, orderDir, currentPage, perPage, summitTZ }
-    )(params)(dispatch).then(() => {
-      dispatch(stopLoading());
-    });
+    try {
+      return await getRequest(
+        createAction(REQUEST_SPONSOR_MEDIA_UPLOADS),
+        createAction(RECEIVE_SPONSOR_MEDIA_UPLOADS),
+        `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsor.id}/custom-media-request-modules`,
+        snackbarErrorHandler,
+        { order, orderDir, currentPage, perPage, summitTZ }
+      )(params)(dispatch);
+    } finally {
+      dispatch(stopLoading());
+    }
🤖 Prompt for AI Agents
In `@src/actions/sponsor-mu-actions.js` around lines 45 - 69, The code dispatches
startLoading() before calling getRequest but only dispatches stopLoading()
inside the .then branch so stopLoading() is never called on rejection; modify
the call that invokes getRequest(createAction(REQUEST_SPONSOR_MEDIA_UPLOADS),
createAction(RECEIVE_SPONSOR_MEDIA_UPLOADS), ...)(params)(dispatch) so that
stopLoading() is always executed by using a try/finally around an await of that
request or by appending .finally(() => dispatch(stopLoading())), keeping the
same parameters and handlers (snackbarErrorHandler) and preserving
startLoading()/stopLoading() calls.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.

In `@src/pages/sponsors/sponsor-media-upload-tab/index.js`:
- Around line 67-75: handleGeneralPageChange and handleGeneralSort are using
sponsorRequests and calling getSponsorMURequests, so the "general" table can't
paginate/sort; update both handlers to read pagination/sort state from
generalRequests (use currentPage/perPage or perPage/order/orderDir as
appropriate from generalRequests) and call getSponsorGeneralRequests instead of
getSponsorMURequests (preserve parameter order: page, perPage, order, orderDir /
key, dir). Ensure you reference the existing handler names
handleGeneralPageChange and handleGeneralSort and replace
sponsorRequests/getSponsorMURequests with
generalRequests/getSponsorGeneralRequests.

In `@src/reducers/sponsors/sponsor-page-mu-list-reducer.js`:
- Around line 52-82: In mapMediaObject, guard nullable fields to avoid crashes:
treat mediaObject.add_ons as an empty array when null before calling .map (e.g.,
(mediaObject.add_ons || []) ), coalesce mediaObject.max_file_size to a safe
numeric fallback (e.g., 0) before passing to bytesToMb to prevent NaN, and
handle mediaObject.file_type and file_type.allowed_extensions as possibly
null/undefined and join the array (e.g.,
(mediaObject.file_type?.allowed_extensions || []).join(", ") or return "N/A"
when empty); keep all changes inside the mapMediaObject function to preserve
existing return shape.

Comment on lines +67 to +75
const handleGeneralPageChange = (page) => {
const { perPage, order, orderDir } = sponsorRequests;
getSponsorMURequests(page, perPage, order, orderDir);
};

const handleGeneralSort = (key, dir) => {
const { currentPage, perPage } = sponsorRequests;
getSponsorMURequests(currentPage, perPage, key, dir);
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix general pagination/sort to use general requests/actions.

Both handlers currently read from sponsorRequests and call getSponsorMURequests, so the general table can’t paginate/sort correctly.

✅ Corrected handlers
   const handleGeneralPageChange = (page) => {
-    const { perPage, order, orderDir } = sponsorRequests;
-    getSponsorMURequests(page, perPage, order, orderDir);
+    const { perPage, order, orderDir } = generalRequests;
+    getGeneralMURequests(page, perPage, order, orderDir);
   };

   const handleGeneralSort = (key, dir) => {
-    const { currentPage, perPage } = sponsorRequests;
-    getSponsorMURequests(currentPage, perPage, key, dir);
+    const { currentPage, perPage } = generalRequests;
+    getGeneralMURequests(currentPage, perPage, key, dir);
   };
🤖 Prompt for AI Agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.
In `@src/pages/sponsors/sponsor-media-upload-tab/index.js` around lines 67 - 75,
handleGeneralPageChange and handleGeneralSort are using sponsorRequests and
calling getSponsorMURequests, so the "general" table can't paginate/sort; update
both handlers to read pagination/sort state from generalRequests (use
currentPage/perPage or perPage/order/orderDir as appropriate from
generalRequests) and call getSponsorGeneralRequests instead of
getSponsorMURequests (preserve parameter order: page, perPage, order, orderDir /
key, dir). Ensure you reference the existing handler names
handleGeneralPageChange and handleGeneralSort and replace
sponsorRequests/getSponsorMURequests with
generalRequests/getSponsorGeneralRequests.

Comment on lines +52 to +82
const mapMediaObject = (mediaObject, summitTZ) => {
const deadline = mediaObject.upload_deadline
? epochToMomentTimeZone(mediaObject.upload_deadline, summitTZ)?.format(
"YYYY/MM/DD"
)
: "N/A";

let status = SPONSOR_MEDIA_UPLOAD_STATUS.COMPLETE;
if (!mediaObject.media_upload) {
if (mediaObject.upload_deadline < moment().unix()) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_MISSED;
} else if (
mediaObject.upload_deadline <
moment().add(DEADLINE_ALERT_DAYS, "days").unix()
) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_ALERT;
} else {
status = SPONSOR_MEDIA_UPLOAD_STATUS.PENDING;
}
}

return {
id: mediaObject.id,
name: mediaObject.name,
add_on: mediaObject.add_ons.map((a) => a.name).join(", "),
max_size: `${bytesToMb(mediaObject.max_file_size)} MB`,
format: mediaObject.file_type?.allowed_extensions || "N/A",
media_upload: mediaObject.media_upload,
deadline,
status
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard nullable media fields to avoid crashes/NaN UI.

add_ons.map(...) will throw if the API returns null, and max_file_size can display NaN MB. Also allowed_extensions is likely an array, so join it for a readable string.

🛠️ Suggested hardening
   return {
     id: mediaObject.id,
     name: mediaObject.name,
-    add_on: mediaObject.add_ons.map((a) => a.name).join(", "),
-    max_size: `${bytesToMb(mediaObject.max_file_size)} MB`,
-    format: mediaObject.file_type?.allowed_extensions || "N/A",
+    add_on: (mediaObject.add_ons ?? []).map((a) => a.name).join(", ") || "N/A",
+    max_size: Number.isFinite(mediaObject.max_file_size)
+      ? `${bytesToMb(mediaObject.max_file_size)} MB`
+      : "N/A",
+    format:
+      (mediaObject.file_type?.allowed_extensions ?? []).join(", ") || "N/A",
     media_upload: mediaObject.media_upload,
     deadline,
     status
   };
🤖 Prompt for AI Agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.
In `@src/reducers/sponsors/sponsor-page-mu-list-reducer.js` around lines 52 - 82,
In mapMediaObject, guard nullable fields to avoid crashes: treat
mediaObject.add_ons as an empty array when null before calling .map (e.g.,
(mediaObject.add_ons || []) ), coalesce mediaObject.max_file_size to a safe
numeric fallback (e.g., 0) before passing to bytesToMb to prevent NaN, and
handle mediaObject.file_type and file_type.allowed_extensions as possibly
null/undefined and join the array (e.g.,
(mediaObject.file_type?.allowed_extensions || []).join(", ") or return "N/A"
when empty); keep all changes inside the mapMediaObject function to preserve
existing return shape.

@santipalenque santipalenque force-pushed the feature/sponsor-media-upload-tab branch from 28df7f0 to 9e5df33 Compare February 16, 2026 20:02
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.

In @.env.example:
- Line 20: Move the SPONSOR_PAGES_SCOPES environment variable line so it appears
before SPONSOR_USERS_API_SCOPES in .env.example to satisfy dotenv-linter
ordering; specifically locate the SPONSOR_PAGES_SCOPES and
SPONSOR_USERS_API_SCOPES entries and reorder them so SPONSOR_PAGES_SCOPES comes
first.

In `@src/pages/sponsors/edit-sponsor-page.js`:
- Around line 249-257: The Users and Pages tab panels are swapped:
CustomTabPanel with index={1} currently renders a "USERS" placeholder while
index={2} renders the actual SponsorUsersListPerSponsorPage; update the
tab-panel children so that CustomTabPanel value={selectedTab} index={1} renders
SponsorUsersListPerSponsorPage (the users list) and CustomTabPanel
value={selectedTab} index={2} renders the Pages content (or remove the
placeholder if Pages is not implemented); ensure you keep SponsorMediaUploadTab
at index={3} and only adjust the children of the CustomTabPanel components and
their index assignments to reflect this corrected mapping.

In `@src/reducers/sponsors/sponsor-page-mu-list-reducer.js`:
- Around line 59-69: The logic that computes status in the sponsor media reducer
assumes mediaObject.upload_deadline is a number and when it's null it falls into
the DEADLINE_MISSED branch; update the condition around the deadline comparisons
in the block that sets status (the variable status, the
mediaObject.upload_deadline checks, SPONSOR_MEDIA_UPLOAD_STATUS constants,
moment(), and DEADLINE_ALERT_DAYS) to first guard for a missing upload_deadline
(null or undefined) and treat that case as PENDING (or another explicit status
you choose), only performing moment()-based comparisons when upload_deadline is
present.
🧹 Nitpick comments (1)
🤖 Fix all nitpicks with AI agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.

In @.env.example:
- Line 20: Move the SPONSOR_PAGES_SCOPES environment variable line so it appears
before SPONSOR_USERS_API_SCOPES in .env.example to satisfy dotenv-linter
ordering; specifically locate the SPONSOR_PAGES_SCOPES and
SPONSOR_USERS_API_SCOPES entries and reorder them so SPONSOR_PAGES_SCOPES comes
first.
.env.example (1)

20-20: Optional: reorder SPONSOR_PAGES_SCOPES to satisfy dotenv-linter.

dotenv-linter flags SPONSOR_PAGES_SCOPES ordering; consider moving it before SPONSOR_USERS_API_SCOPES to keep lint output clean.

🤖 Prompt for AI Agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.
In @.env.example at line 20, Move the SPONSOR_PAGES_SCOPES environment variable
line so it appears before SPONSOR_USERS_API_SCOPES in .env.example to satisfy
dotenv-linter ordering; specifically locate the SPONSOR_PAGES_SCOPES and
SPONSOR_USERS_API_SCOPES entries and reorder them so SPONSOR_PAGES_SCOPES comes
first.

Comment on lines 249 to +257
<CustomTabPanel value={selectedTab} index={1}>
USERS
</CustomTabPanel>
<CustomTabPanel value={selectedTab} index={2}>
<SponsorUsersListPerSponsorPage sponsor={entity} />
</CustomTabPanel>
<CustomTabPanel value={selectedTab} index={3}>
<SponsorMediaUploadTab sponsor={entity} summitId={currentSummit.id} />
</CustomTabPanel>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix the tab-panel index mismatch (Users and Pages are swapped).

The Users tab now renders a placeholder string while the Pages tab renders the users list, which is a user-visible functional mismatch. Ensure the Users tab renders SponsorUsersListPerSponsorPage at index 1 and the Pages tab renders its intended content at index 2 (or remove the placeholder if Pages is not implemented).

🤖 Prompt for AI Agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.
In `@src/pages/sponsors/edit-sponsor-page.js` around lines 249 - 257, The Users
and Pages tab panels are swapped: CustomTabPanel with index={1} currently
renders a "USERS" placeholder while index={2} renders the actual
SponsorUsersListPerSponsorPage; update the tab-panel children so that
CustomTabPanel value={selectedTab} index={1} renders
SponsorUsersListPerSponsorPage (the users list) and CustomTabPanel
value={selectedTab} index={2} renders the Pages content (or remove the
placeholder if Pages is not implemented); ensure you keep SponsorMediaUploadTab
at index={3} and only adjust the children of the CustomTabPanel components and
their index assignments to reflect this corrected mapping.

Comment on lines +59 to +69
let status = SPONSOR_MEDIA_UPLOAD_STATUS.COMPLETE;
if (!mediaObject.media_upload) {
if (mediaObject.upload_deadline < moment().unix()) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_MISSED;
} else if (
mediaObject.upload_deadline <
moment().add(DEADLINE_ALERT_DAYS, "days").unix()
) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_ALERT;
} else {
status = SPONSOR_MEDIA_UPLOAD_STATUS.PENDING;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Handle missing upload_deadline before deadline comparisons.

If upload_deadline is null, the current comparison marks it as “DEADLINE_MISSED” (because null < now). That contradicts the displayed deadline "N/A". Consider treating missing deadlines as PENDING (or another explicit state).

✅ Suggested guard
-  if (!mediaObject.media_upload) {
-    if (mediaObject.upload_deadline < moment().unix()) {
+  if (!mediaObject.media_upload) {
+    if (!mediaObject.upload_deadline) {
+      status = SPONSOR_MEDIA_UPLOAD_STATUS.PENDING;
+    } else if (mediaObject.upload_deadline < moment().unix()) {
       status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_MISSED;
     } else if (
       mediaObject.upload_deadline <
       moment().add(DEADLINE_ALERT_DAYS, "days").unix()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let status = SPONSOR_MEDIA_UPLOAD_STATUS.COMPLETE;
if (!mediaObject.media_upload) {
if (mediaObject.upload_deadline < moment().unix()) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_MISSED;
} else if (
mediaObject.upload_deadline <
moment().add(DEADLINE_ALERT_DAYS, "days").unix()
) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_ALERT;
} else {
status = SPONSOR_MEDIA_UPLOAD_STATUS.PENDING;
let status = SPONSOR_MEDIA_UPLOAD_STATUS.COMPLETE;
if (!mediaObject.media_upload) {
if (!mediaObject.upload_deadline) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.PENDING;
} else if (mediaObject.upload_deadline < moment().unix()) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_MISSED;
} else if (
mediaObject.upload_deadline <
moment().add(DEADLINE_ALERT_DAYS, "days").unix()
) {
status = SPONSOR_MEDIA_UPLOAD_STATUS.DEADLINE_ALERT;
} else {
status = SPONSOR_MEDIA_UPLOAD_STATUS.PENDING;
}
}
🤖 Prompt for AI Agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.
In `@src/reducers/sponsors/sponsor-page-mu-list-reducer.js` around lines 59 - 69,
The logic that computes status in the sponsor media reducer assumes
mediaObject.upload_deadline is a number and when it's null it falls into the
DEADLINE_MISSED branch; update the condition around the deadline comparisons in
the block that sets status (the variable status, the mediaObject.upload_deadline
checks, SPONSOR_MEDIA_UPLOAD_STATUS constants, moment(), and
DEADLINE_ALERT_DAYS) to first guard for a missing upload_deadline (null or
undefined) and treat that case as PENDING (or another explicit status you
choose), only performing moment()-based comparisons when upload_deadline is
present.

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.

1 participant