feat: overhaul UI components for mobile responsiveness#166
Conversation
- Add mobile navigation with hamburger menu and drawer (MobileMenu component) - Update HeaderBar to include mobile menu toggle for authenticated users - Hide desktop Sidebar on mobile (< 1024px), show via mobile drawer instead - Make all grid layouts responsive across Dashboard, UserProfile, StickerList, MyCollection - Stats cards now stack vertically on mobile and adapt to tablet/desktop - Grid breakpoints: mobile (1 col), tablet (2 cols), desktop (3-4 cols) - Update Landing page cards to use responsive Tailwind grid instead of fixed CSS grid - Add horizontal scroll wrapper for UserProfile sticker table on mobile - Implement responsive typography (text-2xl sm:text-3xl) for all page titles - Add responsive padding (p-4 sm:p-6 lg:p-8) to main content areas - Increase touch target sizes for all navigation links (py-2 padding) - Remove fixed grid styles from App.css, replaced with Tailwind responsive classes All components now provide an optimized mobile experience while maintaining desktop functionality. Co-authored-by: James Eastham <jeastham1993@users.noreply.github.com>
|
Some screenshots / animations of the changes would be great ! |
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
There was a problem hiding this comment.
Pull request overview
This PR implements comprehensive mobile responsiveness improvements for the Stickerlandia web application, ensuring the UI adapts properly across mobile, tablet, and desktop screen sizes.
Changes:
- Added mobile navigation with hamburger menu and Material-UI drawer component
- Converted all grid layouts to use responsive Tailwind breakpoints (sm:, lg:, xl:)
- Implemented responsive typography and spacing adjustments across all pages
- Enhanced touch target sizes by adding vertical padding to navigation links
- Wrapped tables in overflow containers for horizontal scrolling on mobile
- Removed deprecated CSS grid styles in favor of Tailwind utility classes
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| web-frontend/src/components/UserProfile.jsx | Made grid responsive with 1/2/4 columns, added responsive typography and padding, wrapped table in overflow container |
| web-frontend/src/components/StickerList.jsx | Implemented responsive grid (1/2/3/4 columns) and responsive heading sizes |
| web-frontend/src/components/Sidebar.jsx | Hidden on mobile (lg:hidden), increased touch targets with py-2 padding |
| web-frontend/src/components/MyCollection.jsx | Made grid responsive with breakpoint-based columns, added responsive typography |
| web-frontend/src/components/MobileMenu.jsx | New mobile navigation drawer with hamburger menu, replicating Sidebar navigation |
| web-frontend/src/components/Landing.jsx | Converted flexbox layout to responsive grid (1/2/3 columns) |
| web-frontend/src/components/HeaderBar.jsx | Integrated MobileMenu component for authenticated users on mobile |
| web-frontend/src/components/Dashboard.jsx | Implemented responsive grid layout and typography |
| web-frontend/src/App.css | Removed deprecated landing-wrapper styles in favor of Tailwind utilities |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <div className="my-4 px-5 flex gap-4 items-center"> | ||
| <div className="flex-shrink-0"> | ||
| <p className="bg-gray-200 rounded-full inline-block p-4 font-bold"> | ||
| {user?.name | ||
| ? user.name | ||
| .split(" ") | ||
| .map((n) => n[0]) | ||
| .join("") | ||
| .substring(0, 2) | ||
| .toUpperCase() | ||
| : "UN"} | ||
| </p> | ||
| </div> | ||
| <div className="flex-1 min-w-0"> | ||
| <span className="block font-bold"> | ||
| {user?.name || user?.email || "User Name"} | ||
| </span> | ||
| <span className="block text-sm text-gray-600"> | ||
| {isLoading ? "..." : "Sticker Collector"} | ||
| </span> | ||
| </div> | ||
| </div> | ||
|
|
||
| <nav className="flex-1"> | ||
| <ul> | ||
| <li className="my-3 px-5"> | ||
| <Link | ||
| className="block py-2" | ||
| to="/dashboard" | ||
| onClick={handleLinkClick} | ||
| > | ||
| <HomeOutlinedIcon /> | ||
| User Dashboard | ||
| </Link> | ||
| </li> | ||
| <li className="my-3 px-5"> | ||
| <Link | ||
| className="block py-2" | ||
| to="/collection" | ||
| onClick={handleLinkClick} | ||
| > | ||
| <MenuBookOutlinedIcon /> | ||
| My Collection | ||
| </Link> | ||
| </li> | ||
| <li className="my-3 px-5"> | ||
| <Link | ||
| className="block py-2" | ||
| to="/catalogue" | ||
| onClick={handleLinkClick} | ||
| > | ||
| <AssessmentOutlinedIcon /> | ||
| Catalogue | ||
| </Link> | ||
| </li> | ||
| <li className="my-3 px-5"> | ||
| <Link | ||
| className="block py-2" | ||
| to="/public-dashboard" | ||
| onClick={handleLinkClick} | ||
| > | ||
| <AssessmentOutlinedIcon /> | ||
| Public Dashboard | ||
| </Link> | ||
| </li> | ||
| <li className="my-3 px-5"> | ||
| <a className="block py-2" href=""> | ||
| <LocalPrintshopOutlinedIcon /> | ||
| Print Station | ||
| </a> | ||
| </li> | ||
| </ul> | ||
| </nav> | ||
|
|
||
| <nav className="border-t border-gray-300 mt-auto"> | ||
| <ul> | ||
| <li className="my-3 px-5"> | ||
| <a className="block py-2" href=""> | ||
| <PersonOutlineOutlinedIcon /> | ||
| Profile | ||
| </a> | ||
| </li> | ||
| <li className="my-3 px-5"> | ||
| <a className="block py-2" href=""> | ||
| <SettingsOutlinedIcon /> | ||
| Settings | ||
| </a> | ||
| </li> | ||
| <li className="my-3 px-5"> | ||
| <button className="block w-full text-left py-2" onClick={logout}> | ||
| <LogoutOutlinedIcon /> | ||
| Sign Out | ||
| </button> | ||
| </li> | ||
| </ul> | ||
| </nav> |
There was a problem hiding this comment.
There is significant code duplication between MobileMenu.jsx and Sidebar.jsx for the navigation structure, user display logic, and menu items. Consider extracting the shared navigation items and user info display into reusable components to reduce duplication and ensure consistency.
| <IconButton | ||
| edge="start" | ||
| color="inherit" | ||
| aria-label="menu" | ||
| onClick={toggleDrawer(true)} | ||
| className="lg:hidden" | ||
| sx={{ color: "black" }} | ||
| > | ||
| <MenuIcon /> | ||
| </IconButton> |
There was a problem hiding this comment.
The hamburger menu button lacks an accessible label that announces its current state. Consider adding aria-expanded attribute to indicate whether the drawer is open or closed to improve screen reader experience.
| <MenuIcon /> | ||
| </IconButton> | ||
|
|
||
| <Drawer anchor="left" open={isOpen} onClose={toggleDrawer(false)}> |
There was a problem hiding this comment.
The Drawer component should have aria-label or aria-labelledby to describe its purpose for screen reader users. Consider adding aria-label="Navigation menu" to improve accessibility.
| <Drawer anchor="left" open={isOpen} onClose={toggleDrawer(false)}> | |
| <Drawer | |
| anchor="left" | |
| open={isOpen} | |
| onClose={toggleDrawer(false)} | |
| aria-label="Navigation menu" | |
| > |
| color="inherit" | ||
| aria-label="menu" | ||
| onClick={toggleDrawer(true)} | ||
| className="lg:hidden" |
There was a problem hiding this comment.
The lg:hidden class is redundant here since the parent div in HeaderBar.jsx already has lg:hidden. This creates unnecessary specificity duplication.
| className="lg:hidden" |
| <a className="block py-2" href=""> | ||
| <LocalPrintshopOutlinedIcon /> | ||
| Print Station | ||
| </a> |
There was a problem hiding this comment.
This link has inconsistent accessibility compared to other navigation items. Consider using a Link component from react-router instead of an anchor tag if this is an internal route, or provide a proper href if it's external. Empty href attributes create poor user experience and accessibility issues.
| <a className="block py-2" href=""> | ||
| <PersonOutlineOutlinedIcon /> | ||
| Profile | ||
| </a> | ||
| </li> | ||
| <li className="my-3 px-5"> | ||
| <a className="block py-2" href=""> | ||
| <SettingsOutlinedIcon /> | ||
| Settings | ||
| </a> |
There was a problem hiding this comment.
These links have inconsistent accessibility compared to other navigation items. Consider using Link components from react-router instead of anchor tags if these are internal routes, or provide proper href values if they're external. Empty href attributes create poor user experience and accessibility issues.
| </li> | ||
| <li className="my-3 px-5"> | ||
| <a className="block" href=""> | ||
| <a className="block py-2" href=""> |
There was a problem hiding this comment.
Empty href attribute will cause navigation to the current page. Consider either removing the href attribute and styling as a button, or providing a valid URL destination for the Print Station link.
| <a className="block py-2" href=""> | ||
| <PersonOutlineOutlinedIcon /> | ||
| Profile | ||
| </a> | ||
| </li> | ||
| <li className="my-3 px-5"> | ||
| <a className="block" href=""> | ||
| <a className="block py-2" href=""> | ||
| <SettingsOutlinedIcon /> | ||
| Settings |
There was a problem hiding this comment.
Empty href attributes will cause navigation to the current page. Consider either removing the href attribute and styling as buttons, or providing valid URL destinations for Profile and Settings links.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…tickerlandia into claude/issue-164-20260122-0828
Fixes #164
Summary
This PR implements comprehensive mobile UI improvements for the /web-frontend application, addressing all mobile responsiveness issues identified in issue #164.
Changes
Testing
Please test on mobile devices (375px, 428px), tablets (768px), and desktop (1024px+) to verify all layouts adapt properly.
UI screenshots
Generated with Claude Code