Add comprehensive mobile-responsive documentation
This commit is contained in:
314
MOBILE_RESPONSIVE.md
Normal file
314
MOBILE_RESPONSIVE.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# Mobile-Responsive Implementation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the mobile-responsive updates implemented for the CPAS Tracker application. The design targets **standard phones (375px+ width)** with graceful degradation for smaller devices.
|
||||
|
||||
## Key Changes
|
||||
|
||||
### 1. **Responsive Utility Stylesheet** (`client/src/styles/mobile.css`)
|
||||
|
||||
A centralized CSS file providing:
|
||||
- Media query breakpoints (768px, 480px)
|
||||
- Touch-friendly tap targets (min 44px height)
|
||||
- iOS input zoom prevention (16px font size)
|
||||
- Utility classes for mobile layouts
|
||||
- Card-based layout helpers
|
||||
- Horizontal scroll containers
|
||||
|
||||
**Utility Classes:**
|
||||
- `.hide-mobile` - Hide on screens ≤768px
|
||||
- `.hide-tablet` - Hide on screens ≤1024px
|
||||
- `.mobile-full-width` - Full width on mobile
|
||||
- `.mobile-stack` - Stack flex items vertically
|
||||
- `.mobile-scroll-x` - Enable horizontal scrolling
|
||||
- `.mobile-card` - Card layout container
|
||||
- `.mobile-sticky-top` - Sticky header positioning
|
||||
|
||||
### 2. **App Navigation** (`client/src/App.jsx`)
|
||||
|
||||
**Desktop Behavior:**
|
||||
- Horizontal navigation bar
|
||||
- Logo left, tabs center, docs button right
|
||||
- Full tab labels displayed
|
||||
|
||||
**Mobile Behavior (768px):**
|
||||
- Logo centered with full width
|
||||
- Tabs stacked horizontally below logo
|
||||
- Docs button positioned absolutely top-right
|
||||
- Shortened tab labels ("📊 Dashboard" → "📊")
|
||||
- Flexible padding (40px → 16px)
|
||||
|
||||
**Features:**
|
||||
- `useMediaQuery()` hook for responsive detection
|
||||
- Dynamic style injection via `<style>` tag
|
||||
- Separate mobile CSS classes for targeted overrides
|
||||
|
||||
### 3. **Dashboard Layout** (`client/src/components/Dashboard.jsx`)
|
||||
|
||||
**Desktop View:**
|
||||
- Traditional HTML table layout
|
||||
- 7 columns (Index, Employee, Dept, Supervisor, Tier, Points, Violations)
|
||||
- Horizontal scrolling for overflow
|
||||
|
||||
**Mobile View (768px):**
|
||||
- Switches to card-based layout (DashboardMobile component)
|
||||
- Each employee = one card with vertical data rows
|
||||
- Touch-optimized tap targets
|
||||
- Improved readability with larger fonts
|
||||
|
||||
**Mobile Stat Cards:**
|
||||
- 2 columns on phones (480px+)
|
||||
- 1 column on small phones (<480px)
|
||||
- Reduced font sizes (28px → 24px)
|
||||
- Compact padding
|
||||
|
||||
**Toolbar Adjustments:**
|
||||
- Search input: 260px → 100% width
|
||||
- Buttons stack vertically
|
||||
- Full-width button styling
|
||||
|
||||
### 4. **Mobile Dashboard Component** (`client/src/components/DashboardMobile.jsx`)
|
||||
|
||||
A dedicated mobile-optimized employee card component:
|
||||
|
||||
**Card Structure:**
|
||||
```
|
||||
+--------------------------------+
|
||||
| Employee Name [Button] |
|
||||
| [At Risk Badge if applicable] |
|
||||
|--------------------------------|
|
||||
| Tier / Standing: [Badge] |
|
||||
| Active Points: [Large #] |
|
||||
| 90-Day Violations: [#] |
|
||||
| Department: [Name] |
|
||||
| Supervisor: [Name] |
|
||||
+--------------------------------+
|
||||
```
|
||||
|
||||
**Visual Features:**
|
||||
- At-risk employees: Gold border + dark gold background
|
||||
- Touch-friendly employee name buttons
|
||||
- Color-coded point displays matching tier colors
|
||||
- Compact spacing (12px margins)
|
||||
- Subtle shadows for depth
|
||||
|
||||
### 5. **Responsive Breakpoints**
|
||||
|
||||
| Breakpoint | Target Devices | Layout Changes |
|
||||
|------------|----------------|----------------|
|
||||
| **1024px** | Tablets & below | Reduced padding, simplified nav |
|
||||
| **768px** | Phones (landscape) | Card layouts, stacked navigation |
|
||||
| **480px** | Small phones | Single-column stats, minimal spacing |
|
||||
| **375px** | iPhone SE/6/7/8 | Optimized for minimum supported width |
|
||||
|
||||
### 6. **Touch Optimization**
|
||||
|
||||
**Tap Target Sizes:**
|
||||
- All buttons: 44px minimum height (iOS/Android guidelines)
|
||||
- Form inputs: 44px minimum height
|
||||
- Navigation tabs: 44px touch area
|
||||
|
||||
**Typography:**
|
||||
- Form inputs: 16px font size (prevents iOS zoom-in on focus)
|
||||
- Readable body text: 13-14px
|
||||
- Headers scale down appropriately
|
||||
|
||||
**Scrolling:**
|
||||
- `-webkit-overflow-scrolling: touch` for smooth momentum scrolling
|
||||
- Horizontal scroll on tables (desktop fallback)
|
||||
- Vertical card scrolling on mobile
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Media Query Hook
|
||||
|
||||
```javascript
|
||||
function useMediaQuery(query) {
|
||||
const [matches, setMatches] = useState(false);
|
||||
useEffect(() => {
|
||||
const media = window.matchMedia(query);
|
||||
if (media.matches !== matches) setMatches(media.matches);
|
||||
const listener = () => setMatches(media.matches);
|
||||
media.addEventListener('change', listener);
|
||||
return () => media.removeEventListener('change', listener);
|
||||
}, [matches, query]);
|
||||
return matches;
|
||||
}
|
||||
```
|
||||
|
||||
**Usage:**
|
||||
```javascript
|
||||
const isMobile = useMediaQuery('(max-width: 768px)');
|
||||
```
|
||||
|
||||
### Conditional Rendering Pattern
|
||||
|
||||
```javascript
|
||||
{isMobile ? (
|
||||
<DashboardMobile employees={filtered} onEmployeeClick={setSelectedId} />
|
||||
) : (
|
||||
<table style={s.table}>
|
||||
{/* Desktop table layout */}
|
||||
</table>
|
||||
)}
|
||||
```
|
||||
|
||||
### Dynamic Style Injection
|
||||
|
||||
```javascript
|
||||
const mobileStyles = `
|
||||
@media (max-width: 768px) {
|
||||
.dashboard-wrap {
|
||||
padding: 16px !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<style>{mobileStyles}</style>
|
||||
{/* Component JSX */}
|
||||
</>
|
||||
);
|
||||
```
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Desktop (>768px)
|
||||
- [ ] Navigation displays horizontally
|
||||
- [ ] Dashboard shows full table
|
||||
- [ ] All columns visible
|
||||
- [ ] Docs button on right side
|
||||
- [ ] Full tab labels visible
|
||||
|
||||
### Tablet (768px - 1024px)
|
||||
- [ ] Reduced padding maintains readability
|
||||
- [ ] Stats cards wrap to 2-3 columns
|
||||
- [ ] Table scrolls horizontally if needed
|
||||
|
||||
### Mobile Portrait (375px - 768px)
|
||||
- [ ] Logo centered, tabs stacked
|
||||
- [ ] Dashboard shows card layout
|
||||
- [ ] Search input full width
|
||||
- [ ] Buttons stack vertically
|
||||
- [ ] Employee cards display all data
|
||||
- [ ] Tap targets ≥44px
|
||||
- [ ] No horizontal scroll required
|
||||
|
||||
### Small Mobile (<480px)
|
||||
- [ ] Stat cards single column
|
||||
- [ ] Text remains readable
|
||||
- [ ] No layout breakage
|
||||
- [ ] Footer wraps properly
|
||||
|
||||
### iOS-Specific
|
||||
- [ ] Input focus doesn't zoom page (16px font)
|
||||
- [ ] Smooth momentum scrolling
|
||||
- [ ] Tap highlights work correctly
|
||||
|
||||
### Android-Specific
|
||||
- [ ] Touch feedback visible
|
||||
- [ ] Back button behavior correct
|
||||
- [ ] Keyboard doesn't break layout
|
||||
|
||||
## Browser Support
|
||||
|
||||
- **Chrome/Edge:** 88+
|
||||
- **Firefox:** 85+
|
||||
- **Safari:** 14+
|
||||
- **iOS Safari:** 14+
|
||||
- **Chrome Android:** 88+
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
1. **Media query hook** re-renders only on breakpoint changes, not continuous resize
|
||||
2. **Card layout** renders fewer DOM elements than table on mobile
|
||||
3. **CSS injection** happens once per component mount
|
||||
4. **No external CSS libraries** (zero KB bundle increase)
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Phase 2 (Optional)
|
||||
- [ ] ViolationForm mobile optimization with multi-step wizard
|
||||
- [ ] Modal responsive sizing and animations
|
||||
- [ ] Swipe gestures for employee cards
|
||||
- [ ] Pull-to-refresh on mobile
|
||||
- [ ] Offline support with service workers
|
||||
|
||||
### Phase 3 (Advanced)
|
||||
- [ ] Progressive Web App (PWA) capabilities
|
||||
- [ ] Native app shell with Capacitor
|
||||
- [ ] Biometric authentication
|
||||
- [ ] Push notifications
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
client/src/
|
||||
├── App.jsx # Updated with mobile nav
|
||||
├── components/
|
||||
│ ├── Dashboard.jsx # Responsive table/card switch
|
||||
│ ├── DashboardMobile.jsx # Mobile card layout (NEW)
|
||||
│ └── ... # Other components
|
||||
└── styles/
|
||||
└── mobile.css # Responsive utilities (NEW)
|
||||
```
|
||||
|
||||
## Maintenance Notes
|
||||
|
||||
### Adding New Components
|
||||
|
||||
When creating new components, follow this pattern:
|
||||
|
||||
1. **Import mobile.css utility classes:**
|
||||
```javascript
|
||||
import '../styles/mobile.css';
|
||||
```
|
||||
|
||||
2. **Use media query hook:**
|
||||
```javascript
|
||||
const isMobile = useMediaQuery('(max-width: 768px)');
|
||||
```
|
||||
|
||||
3. **Provide mobile-specific styles:**
|
||||
```javascript
|
||||
const mobileStyles = `
|
||||
@media (max-width: 768px) {
|
||||
.my-component { /* mobile overrides */ }
|
||||
}
|
||||
`;
|
||||
```
|
||||
|
||||
4. **Test on real devices** (Chrome DevTools is insufficient for touch testing)
|
||||
|
||||
### Debugging Tips
|
||||
|
||||
- Use Chrome DevTools Device Mode (Ctrl+Shift+M)
|
||||
- Test on actual devices when possible
|
||||
- Check console for media query match state
|
||||
- Verify tap target sizes with Chrome Lighthouse audit
|
||||
- Test keyboard behavior on Android
|
||||
|
||||
## Deployment
|
||||
|
||||
1. Merge `feature/mobile-responsive` into `master`
|
||||
2. Rebuild client bundle: `cd client && npm run build`
|
||||
3. Restart server
|
||||
4. Clear browser cache (Ctrl+Shift+R)
|
||||
5. Test on production URL with mobile devices
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions about mobile-responsive implementation:
|
||||
- Check browser console for errors
|
||||
- Verify `mobile.css` is loaded
|
||||
- Test with different screen sizes
|
||||
- Review media query breakpoints
|
||||
|
||||
---
|
||||
|
||||
**Branch:** `feature/mobile-responsive`
|
||||
**Target Width:** 375px+ (standard phones)
|
||||
**Last Updated:** March 8, 2026
|
||||
**Maintainer:** Jason Stedwell
|
||||
Reference in New Issue
Block a user