From 541995e272e49a225c6d2f558b52e70ae44f53ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Thu, 26 Feb 2026 15:20:23 -0300 Subject: [PATCH 1/5] feat: wip add sponsor custom page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/sponsor-pages-actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index c9b184e3b..cf51c24c8 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -165,7 +165,7 @@ export const saveSponsorManagedPage = dispatch(startLoading()); - const normalizedEntity = normalizeSponsorManagedPage(entity); + const normalizedEntity = normalizeSponsorPage(entity); const params = { access_token: accessToken, From a2315d7780e6fbe528d79fd0c270e9de1f30608f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Thu, 26 Feb 2026 17:29:39 -0300 Subject: [PATCH 2/5] fix: add component for add ons on page popup, adjust reducer and actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/sponsor-pages-actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index cf51c24c8..c9b184e3b 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -165,7 +165,7 @@ export const saveSponsorManagedPage = dispatch(startLoading()); - const normalizedEntity = normalizeSponsorPage(entity); + const normalizedEntity = normalizeSponsorManagedPage(entity); const params = { access_token: accessToken, From eea9f2e8167bcdc0842ddc7a4bc45913aac9ca4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Mon, 2 Mar 2026 18:47:23 -0300 Subject: [PATCH 3/5] feat: add custom sponsor page archive/unarchive functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/sponsor-pages-actions.js | 69 +++++++++++++++++++ src/i18n/en.json | 4 +- .../__tests__/sponsor-pages-tab.test.js | 60 +++++++++++++++- src/pages/sponsors/sponsor-pages-tab/index.js | 14 +++- .../sponsor-page-pages-list-reducer.js | 30 +++++++- 5 files changed, 170 insertions(+), 7 deletions(-) diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index c9b184e3b..15cd232b4 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -49,6 +49,10 @@ export const RECEIVE_SPONSOR_CUSTOMIZED_PAGE = export const SPONSOR_CUSTOMIZED_PAGE_ADDED = "SPONSOR_CUSTOMIZED_PAGE_ADDED"; export const SPONSOR_CUSTOMIZED_PAGE_UPDATED = "SPONSOR_CUSTOMIZED_PAGE_UPDATED"; +export const SPONSOR_CUSTOMIZED_PAGE_ARCHIVED = + "SPONSOR_CUSTOMIZED_PAGE_ARCHIVED"; +export const SPONSOR_CUSTOMIZED_PAGE_UNARCHIVED = + "SPONSOR_CUSTOMIZED_PAGE_UNARCHIVED"; export const cloneGlobalPage = (pagesIds, sponsorIds, allSponsors) => async (dispatch, getState) => { @@ -390,6 +394,71 @@ export const saveSponsorCustomizedPage = }); }; +export const archiveCustomizedPage = (pageId) => async (dispatch, getState) => { + const { currentSummitState, currentSponsorState } = getState(); + const { currentSummit } = currentSummitState; + const { + entity: { id: sponsorId } + } = currentSponsorState; + const accessToken = await getAccessTokenSafely(); + const params = { access_token: accessToken }; + + dispatch(startLoading()); + + return putRequest( + null, + createAction(SPONSOR_CUSTOMIZED_PAGE_ARCHIVED)({ pageId }), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/sponsor-pages/${pageId}/archive`, + null, + snackbarErrorHandler + )(params)(dispatch) + .then(() => { + dispatch( + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate("edit_sponsor.pages_tab.customized_page_archived") + }) + ); + }) + .finally(() => { + dispatch(stopLoading()); + }); +}; + +export const unarchiveCustomizedPage = + (pageId) => async (dispatch, getState) => { + const { currentSummitState, currentSponsorState } = getState(); + const { currentSummit } = currentSummitState; + const { + entity: { id: sponsorId } + } = currentSponsorState; + const accessToken = await getAccessTokenSafely(); + const params = { access_token: accessToken }; + + dispatch(startLoading()); + + return deleteRequest( + null, + createAction(SPONSOR_CUSTOMIZED_PAGE_UNARCHIVED)({ pageId }), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/sponsor-pages/${pageId}/archive`, + null, + snackbarErrorHandler + )(params)(dispatch) + .then(() => { + dispatch( + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate( + "edit_sponsor.pages_tab.customized_page_unarchived" + ) + }) + ); + }) + .finally(() => { + dispatch(stopLoading()); + }); + }; + const normalizeSponsorCustomPage = (entity, summitTZ) => { const normalizedEntity = { ...entity, diff --git a/src/i18n/en.json b/src/i18n/en.json index 7b7300ab7..7a859adf9 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -2495,7 +2495,9 @@ "add_selected_page_template": "Add Selected Page Template", "managed_page_saved": "Managed Page updated successfully.", "custom_page_saved": "Custom Sponsor Page saved", - "custom_page_created": "Custom Sponsor Page created" + "custom_page_created": "Custom Sponsor Page created", + "customized_page_archived": "Customized Sponsor Page successfully archived.", + "customized_page_unarchived": "Customized Sponsor Page successfully unarchived." }, "cart_tab": { "new_form": "New Form", diff --git a/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js b/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js index 10d610185..fcd48e220 100644 --- a/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js +++ b/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js @@ -4,7 +4,11 @@ import { act, screen, waitFor } from "@testing-library/react"; import SponsorPagesTab from "../index"; import { renderWithRedux } from "../../../../utils/test-utils"; import { DEFAULT_STATE as sponsorPagesDefaultState } from "../../../../reducers/sponsors/sponsor-page-pages-list-reducer"; -import { getSponsorCustomizedPage } from "../../../../actions/sponsor-pages-actions"; +import { + getSponsorCustomizedPage, + archiveCustomizedPage, + unarchiveCustomizedPage +} from "../../../../actions/sponsor-pages-actions"; // Mocks @@ -46,7 +50,9 @@ jest.mock("../../../../actions/sponsor-pages-actions", () => ({ ), saveSponsorCustomizedPage: jest.fn(() => () => Promise.resolve()), saveSponsorManagedPage: jest.fn(() => () => Promise.resolve()), - resetSponsorPage: jest.fn(() => ({ type: "MOCK_ACTION" })) + resetSponsorPage: jest.fn(() => ({ type: "MOCK_ACTION" })), + archiveCustomizedPage: jest.fn(() => () => Promise.resolve()), + unarchiveCustomizedPage: jest.fn(() => () => Promise.resolve()) })); // Helpers @@ -219,4 +225,54 @@ describe("SponsorPagesTab", () => { ).not.toBeInTheDocument(); }); }); + + it("should call archiveCustomizedPage for non-archived item", async () => { + renderWithRedux( + , + { + initialState: { + sponsorPagePagesListState: { + ...defaultState.sponsorPagePagesListState, + customizedPages: { + ...defaultState.sponsorPagePagesListState.customizedPages, + pages: [createCustomizedPage(1, { is_archived: false })], + totalItems: 1 + } + } + } + } + ); + + const archiveButton = screen.getByText("general.archive"); + await act(async () => { + await userEvent.click(archiveButton); + }); + + expect(archiveCustomizedPage).toHaveBeenCalledWith(1); + }); + + it("should call unarchiveCustomizedPage for archived item", async () => { + renderWithRedux( + , + { + initialState: { + sponsorPagePagesListState: { + ...defaultState.sponsorPagePagesListState, + customizedPages: { + ...defaultState.sponsorPagePagesListState.customizedPages, + pages: [createCustomizedPage(1, { is_archived: true })], + totalItems: 1 + } + } + } + } + ); + + const unarchiveButton = screen.getByText("general.unarchive"); + await act(async () => { + await userEvent.click(unarchiveButton); + }); + + expect(unarchiveCustomizedPage).toHaveBeenCalledWith(1); + }); }); diff --git a/src/pages/sponsors/sponsor-pages-tab/index.js b/src/pages/sponsors/sponsor-pages-tab/index.js index 165493b81..cd683c507 100644 --- a/src/pages/sponsors/sponsor-pages-tab/index.js +++ b/src/pages/sponsors/sponsor-pages-tab/index.js @@ -30,7 +30,9 @@ import { saveSponsorCustomizedPage, getSponsorCustomizedPage, deleteSponsorManagedPage, - resetSponsorPage + unarchiveCustomizedPage, + archiveCustomizedPage, + resetSponsorPage, } from "../../../actions/sponsor-pages-actions"; import CustomAlert from "../../../components/mui/custom-alert"; import SearchInput from "../../../components/mui/search-input"; @@ -56,7 +58,9 @@ const SponsorPagesTab = ({ getSponsorCustomizedPages, saveSponsorCustomizedPage, getSponsorCustomizedPage, - deleteSponsorManagedPage, + deleteSponsorManagedPage, + unarchiveCustomizedPage, + archiveCustomizedPage, resetSponsorPage }) => { const [openPopup, setOpenPopup] = useState(null); @@ -170,7 +174,9 @@ const SponsorPagesTab = ({ }; const handleArchiveCustomizedPage = (item) => - console.log("ARCHIVE CUSTOMIZED ", item); + item.is_archived + ? unarchiveCustomizedPage(item.id) + : archiveCustomizedPage(item.id); const handleArchiveManagedPage = (item) => console.log("ARCHIVE MANAGED ", item); @@ -453,5 +459,7 @@ export default connect(mapStateToProps, { getSponsorCustomizedPages, saveSponsorCustomizedPage, deleteSponsorManagedPage, + unarchiveCustomizedPage, + archiveCustomizedPage, resetSponsorPage })(SponsorPagesTab); diff --git a/src/reducers/sponsors/sponsor-page-pages-list-reducer.js b/src/reducers/sponsors/sponsor-page-pages-list-reducer.js index c11d02f5b..3ad921478 100644 --- a/src/reducers/sponsors/sponsor-page-pages-list-reducer.js +++ b/src/reducers/sponsors/sponsor-page-pages-list-reducer.js @@ -18,7 +18,9 @@ import { RECEIVE_SPONSOR_CUSTOMIZED_PAGES, REQUEST_SPONSOR_CUSTOMIZED_PAGES, RECEIVE_SPONSOR_CUSTOMIZED_PAGE, - RESET_EDIT_PAGE + RESET_EDIT_PAGE, + SPONSOR_CUSTOMIZED_PAGE_ARCHIVED, + SPONSOR_CUSTOMIZED_PAGE_UNARCHIVED } from "../../actions/sponsor-pages-actions"; import { SET_CURRENT_SUMMIT } from "../../actions/summit-actions"; import { RECEIVE_GLOBAL_SPONSORSHIPS } from "../../actions/sponsor-forms-actions"; @@ -174,6 +176,32 @@ const sponsorPagePagesListReducer = (state = DEFAULT_STATE, action) => { const customizedPage = payload.response; return { ...state, currentEditPage: customizedPage }; } + case SPONSOR_CUSTOMIZED_PAGE_ARCHIVED: { + const { pageId } = payload; + const pages = state.customizedPages.pages.map((page) => + page.id === pageId ? { ...page, is_archived: true } : page + ); + return { + ...state, + customizedPages: { + ...state.customizedPages, + pages: [...pages] + } + }; + } + case SPONSOR_CUSTOMIZED_PAGE_UNARCHIVED: { + const { pageId } = payload; + const pages = state.customizedPages.pages.map((page) => + page.id === pageId ? { ...page, is_archived: false } : page + ); + return { + ...state, + customizedPages: { + ...state.customizedPages, + pages: [...pages] + } + }; + } case RESET_EDIT_PAGE: { return { ...state, currentEditPage: DEFAULT_PAGE }; } From 05446183e21c6c1edf400ca42e996a5cde83c48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Tue, 17 Mar 2026 12:01:21 -0300 Subject: [PATCH 4/5] fix: add missing constant, fix tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- .../__tests__/sponsor-pages-tab.test.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js b/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js index fcd48e220..27f9b9d39 100644 --- a/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js +++ b/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js @@ -55,6 +55,11 @@ jest.mock("../../../../actions/sponsor-pages-actions", () => ({ unarchiveCustomizedPage: jest.fn(() => () => Promise.resolve()) })); +jest.mock("../../../../actions/sponsor-forms-actions", () => ({ + ...jest.requireActual("../../../../actions/sponsor-forms-actions"), + getSponsorships: jest.fn(() => () => Promise.resolve()) +})); + // Helpers const createSponsor = (overrides = {}) => ({ @@ -92,6 +97,12 @@ const defaultState = { }, hideArchived: false, term: "" + }, + currentSummitState: { + currentSummit: { + id: 1, + time_zone: { name: "UTC" } + } } }; From d7eaf9204062bea3b9882ff1b7af3bd5c20704d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Tue, 24 Mar 2026 18:08:30 -0300 Subject: [PATCH 5/5] fix: update table after archive/unarchive customized pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/pages/sponsors/sponsor-pages-tab/index.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/pages/sponsors/sponsor-pages-tab/index.js b/src/pages/sponsors/sponsor-pages-tab/index.js index cd683c507..cc362d9f7 100644 --- a/src/pages/sponsors/sponsor-pages-tab/index.js +++ b/src/pages/sponsors/sponsor-pages-tab/index.js @@ -32,7 +32,7 @@ import { deleteSponsorManagedPage, unarchiveCustomizedPage, archiveCustomizedPage, - resetSponsorPage, + resetSponsorPage } from "../../../actions/sponsor-pages-actions"; import CustomAlert from "../../../components/mui/custom-alert"; import SearchInput from "../../../components/mui/search-input"; @@ -58,7 +58,7 @@ const SponsorPagesTab = ({ getSponsorCustomizedPages, saveSponsorCustomizedPage, getSponsorCustomizedPage, - deleteSponsorManagedPage, + deleteSponsorManagedPage, unarchiveCustomizedPage, archiveCustomizedPage, resetSponsorPage @@ -174,9 +174,20 @@ const SponsorPagesTab = ({ }; const handleArchiveCustomizedPage = (item) => - item.is_archived + (item.is_archived ? unarchiveCustomizedPage(item.id) - : archiveCustomizedPage(item.id); + : archiveCustomizedPage(item.id) + ).then(() => { + const { perPage, order, orderDir, currentPage } = customizedPages; + return getSponsorCustomizedPages( + term, + currentPage, + perPage, + order, + orderDir, + hideArchived + ); + }); const handleArchiveManagedPage = (item) => console.log("ARCHIVE MANAGED ", item);