[Fix] Issue-988 updated the UI of the admin dashboard to follow the new design#989
[Fix] Issue-988 updated the UI of the admin dashboard to follow the new design#989L-Tarun-Aditya wants to merge 12 commits intostagefrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR revamps the Admin Dashboard UI to better align with the newer design system by updating styling for shared UI components (dropdown), analytics cards/layout, and the catalog table/list presentation.
Changes:
- Replaced the common
Dropdownwith a custom trigger/menu UI and new styling (including dark theme rules). - Updated catalog and analytics CSS modules to the new card/table visual style and responsive layouts.
- Introduced new
AdminDashboard.module.cssand added anadmin-dashboardwrapper class hook inAdminDashboard.jsx.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ui/src/components/common/dropdown/Dropdown.module.css | New dropdown trigger/menu styling, animations, and dark-mode rules. |
| packages/ui/src/components/common/dropdown/Dropdown.jsx | Reworked dropdown into a custom trigger + menu while keeping a hidden <select>. |
| packages/ui/src/components/catalog/ImageUploadModal.module.css | Tweaked preview/dropzone form layout styles. |
| packages/ui/src/components/catalog/CatalogItem.module.css | Updated catalog row styling and added placeholder/name/meta styling. |
| packages/ui/src/components/catalog/CatalogItem.jsx | Added a preview placeholder and richer name/meta presentation. |
| packages/ui/src/components/catalog/Catalog.module.css | Reworked catalog header/table/footer styling to a card/table layout. |
| packages/ui/src/components/analytics/AnalyticsCard.module.css | Updated analytics cards to the new visual style and simplified responsive rules. |
| packages/ui/src/components/analytics/Analytics.module.css | Switched analytics layout to a responsive grid. |
| packages/ui/src/components/admin/AdminDashboard.module.css | Added new admin dashboard container/header/title styles. |
| packages/ui/src/components/admin/AdminDashboard.jsx | Added wrapper class + test id on the root dashboard container. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -27,37 +54,48 @@ | |||
| justify-content: flex-end; | |||
| } | |||
There was a problem hiding this comment.
CatalogItem.jsx still uses styles["created"] and styles["updated"], but those class selectors are no longer defined in CatalogItem.module.css. This will result in missing styling (and may render literal "undefined" class names in some string interpolations elsewhere). Reintroduce .created/.updated styles (and any responsive variants) or update the JSX to use the new/remaining class names.
| <div className={styles["admin-dashboard"]} data-testid="admin-dashboard"> | ||
| <div className={styles["page-header"]}> | ||
| <div className={styles["title-section"]}> |
There was a problem hiding this comment.
AdminDashboard.jsx applies styles["admin-dashboard"], but styles is passed in from Dashboard.jsx and Dashboard.module.css does not define admin-dashboard. As a result, this wrapper styling won’t apply. Import and use AdminDashboard.module.css inside AdminDashboard.jsx (and stop passing styles), or add the admin-dashboard class to the stylesheet that is actually being passed in.
| [data-theme="dark"] .dropdown-trigger { | ||
| background-color: #1e293b; | ||
| border-color: #334155; | ||
| color: #f8fafc; | ||
| } | ||
|
|
||
| [data-theme="dark"] .dropdown-menu { | ||
| background-color: #1e293b; | ||
| border-color: #334155; | ||
| } |
There was a problem hiding this comment.
This module defines dark-theme styles for the new .dropdown-trigger/menu/items, but the file still contains a [data-theme="dark"] .dropdown { ... } rule later on (targeting the removed .dropdown select). Since .dropdown is no longer rendered, that selector is now dead and should be removed or updated to target the new trigger/menu classes to avoid confusion and keep dark theme styling consistent.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <div className={styles["admin-dashboard"]} data-testid="admin-dashboard"> | ||
| <div className={styles["page-header"]}> | ||
| <div className={styles["title-section"]}> | ||
| <h1 className={styles["dashboard-title"]}>Admin Dashboard</h1> |
There was a problem hiding this comment.
AdminDashboard now reads styles["admin-dashboard"], but the styles prop passed from Dashboard.jsx comes from Dashboard.module.css and does not define admin-dashboard (so the className becomes undefined and the new layout/padding won’t apply). Either add an .admin-dashboard rule to Dashboard.module.css, or (preferably) have AdminDashboard.jsx import its own CSS module and stop receiving styles as a prop.
| .catalog-footer-nav-btn:disabled { | ||
| opacity: 0.5; | ||
| cursor: not-allowed; | ||
| } | ||
|
|
There was a problem hiding this comment.
Catalog.jsx still references removed classes like catalog-footer-nav-btn-disable, catalog-nav-left-arrow, and catalog-nav-right-arrow. Because these keys no longer exist in the CSS module, the template literals that build className will stringify false/undefined into the DOM, and the previous/next buttons also lose their pseudo-text labels. Either restore these selectors or remove the class references and add explicit accessible labels (e.g., aria-label="Previous page" / aria-label="Next page").
| .catalog-footer-nav-btn:disabled { | |
| opacity: 0.5; | |
| cursor: not-allowed; | |
| } | |
| .catalog-footer-nav-btn:disabled, | |
| .catalog-footer-nav-btn-disable { | |
| opacity: 0.5; | |
| cursor: not-allowed; | |
| } | |
| .catalog-nav-left-arrow::before { | |
| content: "←"; | |
| } | |
| .catalog-nav-right-arrow::after { | |
| content: "→"; | |
| } |
| @media (max-width: 780px) { | ||
| .catalog-item { | ||
| flex-direction: column; | ||
| align-items: initial; | ||
| align-items: flex-start; | ||
| gap: 0.75rem; | ||
| padding: 1rem; | ||
| } | ||
|
|
||
| .catalog-item-inner { | ||
| width: 100%; | ||
| display: flex; | ||
| justify-content: space-between; | ||
| } | ||
|
|
||
| .created:before { | ||
| content: "Created "; | ||
| color: var(--smooth-gray); | ||
| } | ||
|
|
||
| .updated:before { | ||
| content: "Updated "; | ||
| color: var(--smooth-gray); | ||
| } | ||
|
|
||
| .reupload-btn { | ||
| .catalog-item-column-last { | ||
| width: 100%; | ||
| } | ||
|
|
||
| .catalog-item-column-first { | ||
| font-weight: 500; | ||
| } | ||
| } |
There was a problem hiding this comment.
On small screens the catalog header is hidden (Catalog.module.css), but this module no longer adds any labels for the created/updated date values (the previous .created:before / .updated:before rules were removed). This makes the two dates ambiguous on mobile. Consider reintroducing the labels via pseudo-elements or rendering explicit (visually-hidden) “Created/Updated” text in the markup for the mobile layout.
sachinkmrsin
left a comment
There was a problem hiding this comment.
PR is good to go. Just minor issues to bee addressed.
| color: var(--label-color); | ||
| } | ||
|
|
||
| .reupload-btn { |
There was a problem hiding this comment.
why are so many !important's used for this component.
| flex: 4; | ||
| display: grid; | ||
| grid-template-columns: repeat(2, 1fr); | ||
| .catalog-item:hover { |
There was a problem hiding this comment.
the bg change on hover is not visible in light theme.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
packages/ui/src/components/catalog/Catalog.jsx:316
Catalog.jsxstill references CSS module classNames that no longer exist inCatalog.module.css(e.g.,catalog-search-modal-cross,web-search-catalog-body,web-search-actions,catalog-search-modal-title,search-modal-row,search-modal-img,search-modal-company-name). With CSS modules these resolve toundefinedand the web-search modal will lose styling; either restore these selectors or update the JSX to use the new class structure.
<div className={styles["catalog-search-modal"]}>
<div className={styles["catalog-search-modal-header"]}>
Image Not Found
<button
type="button"
className={styles["catalog-search-modal-cross"]}
onClick={() => setShowWebCatalog(false)}
aria-label="Close"
>
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| {company.imageUrl ? ( | ||
| <img | ||
| src={company.imageUrl} | ||
| alt={company.company_name} | ||
| className={styles["preview-image"]} | ||
| onError={(e) => { e.currentTarget.style.display = "none"; }} | ||
| /> |
There was a problem hiding this comment.
When company.imageUrl is present but fails to load, the onError handler hides the <img> but does not render the fallback initial, leaving an empty placeholder. Track load failure in component state (or swap the src) so the fallback content is shown on error.
| const imagesData = images.map((image) => { | ||
| const imageData = image.data(); | ||
| const imagePath = `${image.extension}/${image.company_name}.${image.extension}`; | ||
| const signedUrlResult = cloudFrontSignedURL(`/${imagePath}`); | ||
| imageData.imageUrl = signedUrlResult.success ? signedUrlResult.data : null; | ||
| return imageData; |
There was a problem hiding this comment.
imagePath is built directly from company_name and extension and then signed. Since these values can contain characters that are unsafe in URLs/keys (spaces, /, etc.), the generated signed URL can be invalid or point to an unintended key. Encode/sanitize the path segments (and/or enforce an allowed character set for company_name) before signing.
|


Description
closes #988
this PR updates the UI of the admin dashboard to make it consistent with the new design style
What type of PR is this? (Check all applicable)
Screenshots (if applicable)
Checklist