Skip to content

Commit 1d2eefc

Browse files
feature/dep315: Modified app layout, added new landing components, refactored landing components, other misc fixes.
1 parent 9bb1104 commit 1d2eefc

33 files changed

Lines changed: 763 additions & 704 deletions

CHANGELOG.MD

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## Jul 7, 2026
2+
3+
- **Feature** Integrated new landing hero section and introduction [🎟️ DEP-315](https://citz-gdx.atlassian.net/browse/DEP-315)
4+
- Refactored existing landing code for structural simplicity
5+
- Created a reusable container/section block that can be reused anywhere
6+
- Added params to URL for future filter updating (can be decoupled easily if not desired)
7+
- Implemented UX designs (mobile and desktop)
8+
- Removed app's square box that appears at bigger viewports
9+
- Ensured that other layouts were not negatively affected by change (admin, admin landing preview, admin engagement preview)
10+
- Added constrained option for internal header component as an optional boolean prop
11+
- Fixed: Engagement preview was looking for route loader address that didn't exist
12+
- Fixed: Slug was not being populated with SuggestedEngagementAttachment, so Suggested Engagement links were not working
13+
- Fixed: Small typo in security response headers of API
14+
- Fixed: Console error for authoring section details tabs, selection/list mismatch
15+
- Enhanced: Notification banner now supports multiple lines for mobile (or long messages, if needed in the future)
16+
117
## June 23, 2026
218

319
- **Feature** Imported CHEFS components into DEP [🎟️ DEP-275](https://citz-gdx.atlassian.net/browse/DEP-275)

api/src/api/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ def _deprecated_print(*args, **kwargs):
5757
csp = (
5858
secure.ContentSecurityPolicy()
5959
.default_src("'self'")
60-
.script_src("'self' 'unsafe-inline'")
61-
.style_src("'self' 'unsafe-inline'")
62-
.img_src("'self' data:")
60+
.script_src("'self'", "'unsafe-inline'")
61+
.style_src("'self'", "'unsafe-inline'")
62+
.img_src("'self'", "'data:'")
6363
.object_src("'self'")
6464
.connect_src("'self'")
6565
)

api/src/api/schemas/suggested_engagement.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class SuggestedEngagementAttachment(Schema):
7070
is_internal = fields.Bool(data_key='is_internal')
7171
consent_message = fields.Str(data_key='consent_message')
7272
sponsor_name = fields.Str(data_key='sponsor_name')
73+
slug = fields.Str(data_key='slug')
7374

7475
def get_banner_url(self, obj):
7576
"""Return the object storage URL for the banner image."""

web/src/DocumentTitle.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ const DocumentTitle = () => {
3939
const resolveTitle = async () => {
4040
const crumbs = await getResolvedCrumbs(matches);
4141
if (cancelled) return;
42-
console.log('Resolved crumbs for title:', crumbs);
4342
const filteredCrumbs = crumbs
4443
// Exclude crumbs that are marked as index pages UNLESS they are the current page
4544
.filter((crumb, index) => (crumb?.title ?? crumb?.name) && (index == 0 || !crumb?.isIndex))

web/src/components/appLayouts/PublicLayout.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,16 @@ export const PublicLayout = () => {
3030
>
3131
<Box
3232
sx={{
33-
maxWidth: '1926px',
34-
margin: '0 auto',
3533
background: colors.surface.white,
3634
}}
3735
>
3836
<DocumentTitle />
3937
<PageViewTracker />
4038
<Notification />
4139
<NotificationModal />
42-
{isAuthenticated ? <InternalHeader showSideNav={false} /> : <PublicHeader />}
40+
{isAuthenticated ? <InternalHeader constrained showSideNav={false} /> : <PublicHeader />}
4341
<ScrollToTop />
44-
<Box component="main" sx={isAuthenticated ? { marginTop: { xs: '3.5em', md: '6.5em' } } : undefined}>
42+
<Box component="main" sx={{ marginTop: isAuthenticated ? '3.375em' : 0 }}>
4543
<Outlet />
4644
</Box>
4745
<FeedbackModal />

web/src/components/engagement/admin/create/authoring/AuthoringDetails.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ const AuthoringDetails = () => {
566566
</AuthoringFormContainer>
567567

568568
{/* Tab instructions */}
569-
{currentTab && (
569+
{currentTab && authoringDetailsTabs?.length > 0 && (
570570
<TabContext value={currentTab}>
571571
<AuthoringFormContainer rowSpacing="2rem" pt="0.5rem" isHydrating={isHydrating}>
572572
{tabsEnabled && (

web/src/components/engagement/preview/EngagementPreview.tsx

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ const MeasurementBar: React.FC = () => {
186186
* modifying the actual engagement.
187187
*/
188188
export const EngagementPreview: React.FC = () => {
189-
const loaderData = useRouteLoaderData('public-single-engagement') as EngagementLoaderPublicData;
189+
const loaderData = useRouteLoaderData('engagement-preview') as EngagementLoaderPublicData;
190+
const { engagement, widgets, details, metadata, suggestions } = loaderData ?? {};
190191
const { engagementId, languageCode } = useParams();
191192
const revalidator = useRevalidator();
192193
const [previewState, setPreviewState] = useState<SubmissionStatusTypes>('Upcoming');
@@ -243,12 +244,12 @@ export const EngagementPreview: React.FC = () => {
243244

244245
useEffect(() => {
245246
setContentVersion((previous) => previous + 1);
246-
}, [loaderData.engagement, loaderData.widgets, loaderData.details, loaderData.metadata, loaderData.suggestions]);
247+
}, [engagement, widgets, details, metadata, suggestions]);
247248

248249
useEffect(() => {
249250
let isMounted = true;
250251

251-
loaderData.engagement
252+
engagement
252253
.then((engagement) => {
253254
if (!isMounted) return;
254255
setResolvedEngagement(engagement);
@@ -261,19 +262,13 @@ export const EngagementPreview: React.FC = () => {
261262
return () => {
262263
isMounted = false;
263264
};
264-
}, [loaderData.engagement]);
265+
}, [engagement]);
265266

266267
useEffect(() => {
267268
if (!isReloading) return;
268269

269270
let isMounted = true;
270-
Promise.allSettled([
271-
loaderData.engagement,
272-
loaderData.widgets,
273-
loaderData.details,
274-
loaderData.metadata,
275-
loaderData.suggestions,
276-
]).finally(() => {
271+
Promise.allSettled([engagement, widgets, details, metadata, suggestions]).finally(() => {
277272
if (isMounted) {
278273
setIsReloading(false);
279274
}
@@ -282,14 +277,7 @@ export const EngagementPreview: React.FC = () => {
282277
return () => {
283278
isMounted = false;
284279
};
285-
}, [
286-
isReloading,
287-
loaderData.engagement,
288-
loaderData.widgets,
289-
loaderData.details,
290-
loaderData.metadata,
291-
loaderData.suggestions,
292-
]);
280+
}, [isReloading, engagement, widgets, details, metadata, suggestions]);
293281

294282
useEffect(() => {
295283
const animateScrollToElement = (targetId: string) => {
@@ -377,7 +365,7 @@ export const EngagementPreview: React.FC = () => {
377365
...resolvedEngagement,
378366
submission_status: getSubmissionStatusId(previewState),
379367
})
380-
: loaderData.engagement,
368+
: engagement,
381369
}),
382370
[loaderData, resolvedEngagement, previewState],
383371
);

web/src/components/engagement/preview/PreviewLoaderDataContext.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ export const PreviewLoaderDataProvider: React.FC<PreviewLoaderDataProviderProps>
1414
};
1515

1616
export const useEngagementLoaderData = (): EngagementLoaderPublicData => {
17-
const previewLoaderData = useContext(PreviewLoaderDataContext);
18-
const routeLoaderData = useRouteLoaderData('public-single-engagement') as EngagementLoaderPublicData;
19-
return previewLoaderData ?? routeLoaderData;
17+
const adminData = useContext(PreviewLoaderDataContext);
18+
const publicData = useRouteLoaderData('public-single-engagement');
19+
return adminData ?? publicData;
2020
};
2121

2222
export default PreviewLoaderDataContext;

web/src/components/engagement/public/view/SuggestedEngagements.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import { Heading2 } from 'components/common/Typography';
66
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
77
import { faArrowLeftLong } from '@fortawesome/pro-regular-svg-icons';
88
import { Link } from 'components/common/Navigation';
9-
import { Await, useRouteLoaderData } from 'react-router';
9+
import { Await } from 'react-router';
1010

11-
import { EngagementLoaderPublicData } from './EngagementLoaderPublic';
1211
import { EngagementViewSections } from '.';
1312
import { SuggestedEngagementWithAttachment } from 'models/suggestedEngagement';
1413
import { Engagement } from 'models/engagement';
@@ -17,11 +16,10 @@ import { usePreview } from 'engagements/preview/PreviewContext';
1716
import { EngagementPreviewTag } from './EngagementPreviewTag';
1817
import { getPath, ROUTES } from 'routes/routes';
1918
import { TranslationBundle, resolveTranslationValue } from './engagementTranslationResolution';
19+
import { useEngagementLoaderData } from 'engagements/preview/PreviewLoaderDataContext';
2020

2121
export const SuggestedEngagements = () => {
22-
const { suggestions, engagement, translationBundle } = useRouteLoaderData(
23-
'public-single-engagement',
24-
) as EngagementLoaderPublicData;
22+
const { suggestions, engagement, translationBundle } = useEngagementLoaderData();
2523
const engagementSlots = Array.from({ length: 3 });
2624
const { isPreviewMode } = usePreview();
2725

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import LandingSection from './LandingSection';
2+
import React from 'react';
3+
import FilterBlock from './FilterBlock';
4+
import TileBlock from './TileBlock';
5+
import { EngagementSearchProps } from './types';
6+
7+
const EngagementSearch = (props: EngagementSearchProps) => {
8+
return (
9+
<LandingSection>
10+
<FilterBlock {...props} />
11+
<TileBlock {...props} />
12+
</LandingSection>
13+
);
14+
};
15+
16+
export default EngagementSearch;

0 commit comments

Comments
 (0)