Skip to content

Commit f0e2f95

Browse files
UI Upgrades (#290)
* Make rendering of the Google Login button conditional on if env var is set * Swap Google and form login position and add AAQ dark logo on small screen size * Remove content ID from cards view * improve login page breakpoints * Large navbar revamp draft * make mouse become a pointer over the configure dropdown * Fix selected page name persistance issue * add event type * Standardise off-white background across the app * Update shadow on plaground textbox * Add margin to top of content edit page * Update playground option names * cleanup and create deeper primary color for highlighted menu items * Fix small navbar * CardsGrid: Clean up and add no cards message * update small screen menu colors * fix playground json modal colors * Update tags filtering aesthetics * Reorganise tags on edit page for clarity * standardise fonts * Fix urgency rule page padding and line wrapping * FIX: Don't load pages before login token is checked * Make google signin button bigger and manual sign in button smaller * space out navbar items a bit * fix text styling of playground menu and empty content page; fix margins and menu width in playground text field --------- Co-authored-by: Suzin You <[email protected]>
1 parent d74a757 commit f0e2f95

File tree

15 files changed

+633
-448
lines changed

15 files changed

+633
-448
lines changed

admin_app/public/logo-dark.png

25.3 KB
Loading

admin_app/src/app/content/edit/page.tsx

+141-133
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ const AddEditContentPage = () => {
8383
}
8484
return (
8585
<FullAccessComponent>
86-
<Layout.FlexBox flexDirection={"column"} sx={{ p: sizes.doubleBaseGap }}>
86+
<Layout.FlexBox
87+
flexDirection={"column"}
88+
sx={{ p: sizes.doubleBaseGap, marginTop: 5 }}
89+
>
8790
<Header
8891
content_id={content_id}
8992
onBack={() =>
@@ -171,11 +174,11 @@ const ContentBox = ({
171174
const defaultTags =
172175
content && content.content_tags.length > 0
173176
? content.content_tags.map((tag_id) =>
174-
data.find((tag) => tag.tag_id === tag_id)
177+
data.find((tag) => tag.tag_id === tag_id),
175178
)
176179
: [];
177180
setContentTags(
178-
defaultTags.filter((tag): tag is Tag => tag !== undefined)
181+
defaultTags.filter((tag): tag is Tag => tag !== undefined),
179182
);
180183
setAvailableTags(data.filter((tag) => !defaultTags.includes(tag)));
181184
} catch (error) {
@@ -234,7 +237,7 @@ const ContentBox = ({
234237
}
235238
const handleChange = (
236239
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
237-
key: keyof Content
240+
key: keyof Content,
238241
) => {
239242
const emptyContent = createEmptyContent(contentTags);
240243

@@ -286,7 +289,7 @@ const ContentBox = ({
286289
setRefreshKey((prevKey) => prevKey + 1);
287290
setOpenDeleteModal(false);
288291
handleTagsChange(
289-
contentTags.filter((tag) => tag.tag_id !== tagToDelete.tag_id)
292+
contentTags.filter((tag) => tag.tag_id !== tagToDelete.tag_id),
290293
);
291294
setSnackMessage(`Tag "${tagToDelete.tag_name}" deleted successfully`);
292295
setTagToDelete(null);
@@ -325,140 +328,19 @@ const ContentBox = ({
325328
</Button>
326329
</DialogActions>
327330
</Dialog>
328-
<Layout.Spacer multiplier={1} />
329-
<Autocomplete
330-
autoSelect
331-
selectOnFocus
332-
clearOnBlur
333-
handleHomeEndKeys
334-
multiple
335-
limitTags={3}
336-
id="tags-autocomplete"
337-
options={availableTags}
338-
getOptionLabel={(option) => option!.tag_name}
339-
noOptionsText="No tags found. Start typing to create one."
340-
value={contentTags}
341-
onChange={(event: React.SyntheticEvent, updatedTags: Tag[]) => {
342-
handleTagsChange(updatedTags);
343-
}}
344-
onHighlightChange={(event, option) => {
345-
setHighlightedOption(option);
346-
}}
347-
renderInput={(params) => (
348-
<TextField
349-
{...params}
350-
variant="outlined"
351-
label="Tags"
352-
placeholder="Find or create tags"
353-
onChange={(event) => setInputVal(event.target.value)}
354-
onKeyDown={(event) => {
355-
if (
356-
!highlightedOption ||
357-
highlightedOption.tag_name.startsWith('Add "')
358-
) {
359-
if (
360-
event.key === "Enter" &&
361-
inputVal &&
362-
!availableTags.some(
363-
(tag) =>
364-
tag.tag_name.toUpperCase() === inputVal.toUpperCase()
365-
) &&
366-
!contentTags.some(
367-
(tag) =>
368-
tag.tag_name.toUpperCase() === inputVal.toUpperCase()
369-
)
370-
) {
371-
event.preventDefault();
372-
373-
handleNewTag(inputVal);
374-
}
375-
}
376-
}}
377-
/>
378-
)}
379-
filterOptions={(options, params) => {
380-
const filtered = filter(options, params);
381-
const { inputValue } = params;
382-
const isExisting = options.some(
383-
(option) => inputValue.toUpperCase() === option.tag_name
384-
);
385-
386-
const isSelected = contentTags.some(
387-
(tag) => inputValue.toUpperCase() === tag.tag_name
388-
);
389-
390-
if (inputValue !== "" && !isExisting && !isSelected) {
391-
filtered.push({ tag_id: 0, tag_name: `Create "${inputValue}"` });
392-
}
393-
394-
return filtered;
395-
}}
396-
renderOption={(props, option) => {
397-
const { key, ...newProps } =
398-
props as React.HTMLAttributes<HTMLLIElement> & {
399-
key: React.Key;
400-
};
401-
const { onKeyDown, ...rest } = newProps;
402-
if (
403-
option.tag_name &&
404-
!availableTags.some(
405-
(tag) =>
406-
tag.tag_name.toUpperCase() === option.tag_name.toUpperCase()
407-
) &&
408-
!contentTags.some(
409-
(tag) =>
410-
tag.tag_name.toUpperCase() === option.tag_name.toUpperCase()
411-
)
412-
) {
413-
return (
414-
<li key={key} {...rest}>
415-
<Button fullWidth onClick={() => handleNewTag(option.tag_name)}>
416-
{option.tag_name}
417-
</Button>
418-
</li>
419-
);
420-
}
421-
return (
422-
<li
423-
key={option.tag_id}
424-
{...rest}
425-
style={{
426-
justifyContent: "space-between",
427-
}}
428-
>
429-
{option.tag_name}
430-
<IconButton
431-
onClick={(e) => {
432-
e.stopPropagation();
433-
openDeleteConfirmModal(option);
434-
}}
435-
>
436-
<Delete fontSize="small" color="secondary" />
437-
</IconButton>
438-
</li>
439-
);
440-
}}
441-
sx={{ width: "500px" }}
442-
isOptionEqualToValue={(option, value) =>
443-
value.tag_name === option.tag_name || value.tag_name === ""
444-
}
445-
/>
446-
<Layout.Spacer multiplier={2} />
331+
<Layout.Spacer />
447332
<Layout.FlexBox
448-
flexDirection={"column"}
449333
sx={{
450334
maxWidth: "800px",
451335
minWidth: "300px",
452-
border: 1,
453-
borderColor: appColors.darkGrey,
454-
backgroundColor: appColors.lightGrey,
336+
border: 0.5,
337+
borderColor: appColors.outline,
455338
borderRadius: 2,
456339
p: sizes.baseGap,
457340
}}
458341
>
459-
{/* <LanguageButtonBar expandable={true} /> */}
460-
<Layout.Spacer multiplier={1} />
461-
<Typography variant="body2">Title</Typography>
342+
<Layout.Spacer multiplier={0.5} />
343+
<Typography variant="body1">Title</Typography>
462344
<Layout.Spacer multiplier={0.5} />
463345
<TextField
464346
required
@@ -473,7 +355,7 @@ const ContentBox = ({
473355
value={content ? content.content_title : ""}
474356
onChange={(e) => handleChange(e, "content_title")}
475357
/>
476-
<Typography variant="body2">Content</Typography>
358+
<Typography variant="body1">Content</Typography>
477359
<Layout.Spacer multiplier={0.5} />
478360
<TextField
479361
required
@@ -490,6 +372,132 @@ const ContentBox = ({
490372
value={content ? content.content_text : ""}
491373
onChange={(e) => handleChange(e, "content_text")}
492374
/>
375+
<Layout.Spacer multiplier={0.25} />
376+
<Autocomplete
377+
autoSelect
378+
selectOnFocus
379+
clearOnBlur
380+
handleHomeEndKeys
381+
multiple
382+
limitTags={3}
383+
id="tags-autocomplete"
384+
options={availableTags}
385+
getOptionLabel={(option) => option!.tag_name}
386+
noOptionsText="No tags found. Start typing to create one."
387+
value={contentTags}
388+
onChange={(event: React.SyntheticEvent, updatedTags: Tag[]) => {
389+
handleTagsChange(updatedTags);
390+
}}
391+
onHighlightChange={(event, option) => {
392+
setHighlightedOption(option);
393+
}}
394+
renderInput={(params) => (
395+
<TextField
396+
{...params}
397+
variant="outlined"
398+
label="Tags (optional)"
399+
placeholder="Find or create tags"
400+
onChange={(event) => setInputVal(event.target.value)}
401+
onKeyDown={(event) => {
402+
if (
403+
!highlightedOption ||
404+
highlightedOption.tag_name.startsWith('Add "')
405+
) {
406+
if (
407+
event.key === "Enter" &&
408+
inputVal &&
409+
!availableTags.some(
410+
(tag) =>
411+
tag.tag_name.toUpperCase() === inputVal.toUpperCase(),
412+
) &&
413+
!contentTags.some(
414+
(tag) =>
415+
tag.tag_name.toUpperCase() === inputVal.toUpperCase(),
416+
)
417+
) {
418+
event.preventDefault();
419+
420+
handleNewTag(inputVal);
421+
}
422+
}
423+
}}
424+
InputProps={{
425+
...params.InputProps,
426+
style: { backgroundColor: "white" },
427+
}}
428+
/>
429+
)}
430+
filterOptions={(options, params) => {
431+
const filtered = filter(options, params);
432+
const { inputValue } = params;
433+
const isExisting = options.some(
434+
(option) => inputValue.toUpperCase() === option.tag_name,
435+
);
436+
437+
const isSelected = contentTags.some(
438+
(tag) => inputValue.toUpperCase() === tag.tag_name,
439+
);
440+
441+
if (inputValue !== "" && !isExisting && !isSelected) {
442+
filtered.push({ tag_id: 0, tag_name: `Create "${inputValue}"` });
443+
}
444+
445+
return filtered;
446+
}}
447+
renderOption={(props, option) => {
448+
const { key, ...newProps } =
449+
props as React.HTMLAttributes<HTMLLIElement> & {
450+
key: React.Key;
451+
};
452+
const { onKeyDown, ...rest } = newProps;
453+
if (
454+
option.tag_name &&
455+
!availableTags.some(
456+
(tag) =>
457+
tag.tag_name.toUpperCase() === option.tag_name.toUpperCase(),
458+
) &&
459+
!contentTags.some(
460+
(tag) =>
461+
tag.tag_name.toUpperCase() === option.tag_name.toUpperCase(),
462+
)
463+
) {
464+
return (
465+
<li key={key} {...rest}>
466+
<Button
467+
fullWidth
468+
onClick={() => handleNewTag(option.tag_name)}
469+
>
470+
{option.tag_name}
471+
</Button>
472+
</li>
473+
);
474+
}
475+
return (
476+
<li
477+
key={option.tag_id}
478+
{...rest}
479+
style={{
480+
justifyContent: "space-between",
481+
}}
482+
>
483+
{option.tag_name}
484+
<IconButton
485+
onClick={(e) => {
486+
e.stopPropagation();
487+
openDeleteConfirmModal(option);
488+
}}
489+
>
490+
<Delete fontSize="small" color="secondary" />
491+
</IconButton>
492+
</li>
493+
);
494+
}}
495+
sx={{ width: "500px" }}
496+
isOptionEqualToValue={(option, value) =>
497+
value.tag_name === option.tag_name || value.tag_name === ""
498+
}
499+
/>
500+
<Layout.Spacer multiplier={1.5} />
493501
<Layout.FlexBox
494502
flexDirection="row"
495503
sx={{ justifyContent: "space-between" }}
@@ -514,7 +522,7 @@ const ContentBox = ({
514522
if (content_id) {
515523
const actionType = content.content_id ? "edit" : "add";
516524
router.push(
517-
`/content/?content_id=${content_id}&action=${actionType}`
525+
`/content/?content_id=${content_id}&action=${actionType}`,
518526
);
519527
}
520528
};

0 commit comments

Comments
 (0)