Feat/responsive - #1060
Conversation
…ted under explore
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe pull request standardizes responsive layouts across public, device, map, documentation, authentication, and settings views. It also localizes device-detail content, improves overlay behavior, updates accessibility metadata, and removes runtime viewport detection. ChangesResponsive UI and navigation
Public and application pages
Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: 🟡 Moderate · up to This responsive UI change can leave tablet search results with reduced touch targets, render dates inconsistently across locales and time zones, and shift desktop content when the globe appears after hydration. These are bounded but actionable current-head risks, so merge should wait for fixes or explicit owner acceptance. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Actionable comments posted: 7
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: f6928b6e-2c50-4134-9e77-a104f3a92bf1
📒 Files selected for processing (61)
app/components/device-detail/device-detail-box.tsxapp/components/device-detail/graph.tsxapp/components/device/new/custom-device-config.tsxapp/components/device/new/general-info.tsxapp/components/device/new/location-info.tsxapp/components/device/new/new-device-stepper.tsxapp/components/error-message.tsxapp/components/header/download.tsxapp/components/header/home/index.tsxapp/components/header/info/index.tsxapp/components/header/menu/index.tsxapp/components/header/nav-bar/index.tsxapp/components/landing/footer.tsxapp/components/landing/header/header.tsxapp/components/landing/header/language-selector.tsxapp/components/landing/header/theme-toggle.tsxapp/components/landing/sections/connect.tsxapp/components/landing/sections/features.tsxapp/components/landing/sections/integrations.tsxapp/components/landing/sections/partners.tsxapp/components/landing/sections/pricing-plans.tsxapp/components/landing/stats.tsxapp/components/language-select.tsxapp/components/map/legend.tsxapp/components/map/topbar.tsxapp/components/markdown-content.tsxapp/components/mydevices/dt/data-table.tsxapp/components/nav-bar.tsxapp/components/search/search-list-item.tsxapp/components/search/search-list.tsxapp/components/theme-select.tsxapp/components/ui/alert-dialog.tsxapp/components/ui/dialog.tsxapp/components/ui/drawer.tsxapp/components/ui/sheet.tsxapp/components/ui/table.tsxapp/components/ui/tabs.tsxapp/components/ui/toast.tsxapp/components/viewport-portal.tsxapp/root.tsxapp/routes/about.tsxapp/routes/account.password-reset.tsxapp/routes/device.$deviceId.dataupload.tsxapp/routes/device.$deviceId.edit.security.tsxapp/routes/device.$deviceId.edit.sensors.tsxapp/routes/device.$deviceId.edit.transfer.tsxapp/routes/device.$deviceId.edit.tsxapp/routes/device.dashboard.$deviceId.tsxapp/routes/device.new.tsxapp/routes/device.transfer.tsxapp/routes/docs.tsxapp/routes/explore.forgot.tsxapp/routes/explore.login.tsxapp/routes/explore.register.tsxapp/routes/imprint.tsxapp/routes/privacy.tsxapp/routes/profile.$username.tsxapp/routes/settings.account.tsxapp/routes/settings.preferences.tsxapp/routes/settings.profile.tsxapp/routes/settings.tsx
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/components/device-detail/device-detail-box.tsx (1)
100-104: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winTimezone-dependent date formatting runs during server render in both components. Neither call site sets
timeZone, so the server output uses the server timezone and the client output uses the user timezone. This produces hydration mismatches, and for date-only output it can show a different day.
app/components/device-detail/device-detail-box.tsx#L100-L104: add an explicittimeZoneto theIntl.DateTimeFormatoptions, and wrap the formatter inuseMemo.app/components/device-detail/entry-logs.tsx#L48-L48: pass an options object with an explicittimeZonetotoLocaleString, and apply the same change to theLogListcall on line 105.Source: Linters/SAST tools
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e84fa16f-1bb7-4cb1-9ae6-599172607358
📒 Files selected for processing (15)
app/components/device-detail/device-detail-box.tsxapp/components/device-detail/entry-logs.tsxapp/components/header/nav-bar/index.tsxapp/components/landing/header/header.tsxapp/components/landing/sections/pricing-plans.tsxapp/components/map/topbar.tsxapp/routes/about.tsxapp/routes/account.password-reset.tsxapp/routes/device.$deviceId.edit.tsxapp/routes/explore.forgot.tsxapp/routes/explore.login.tsxapp/routes/explore.register.tsxapp/routes/explore.tsxapp/routes/settings.preferences.tsxpackage.json
💤 Files with no reviewable changes (1)
- app/routes/account.password-reset.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- app/routes/settings.preferences.tsx
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.
| const latestEntry = entryLogs.at(-1) | ||
|
|
||
| if (isDesktop) { | ||
| return ( | ||
| <div className="flex flex-col"> | ||
| <p className="pb-4 font-bold">{t('logs')}</p> | ||
| <div className="flex items-center"> | ||
| <div className="flex w-full items-start space-x-4"> | ||
| <div className="border-muted-foreground text-muted-foreground flex h-10 w-10 shrink-0 items-center justify-center rounded-full border-4"> | ||
| <Activity className="h-5 w-5" /> | ||
| </div> | ||
| <div className="grow"> | ||
| <p className="mb-2 text-sm font-medium"> | ||
| {entryLogs[entryLogs.length - 1].content} | ||
| </p> | ||
| <div className="text-muted-foreground flex items-center text-xs"> | ||
| <Clock className="mr-1 h-3 w-3" /> | ||
| {new Date(entryLogs[0].createdAt).toLocaleString(i18n.language)} | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <div className="shrink"> | ||
| <Dialog open={open} onOpenChange={setOpen}> | ||
| <DialogTrigger asChild> | ||
| <Button variant="ghost"> | ||
| <TooltipProvider> | ||
| <Tooltip> | ||
| <TooltipTrigger> | ||
| {' '} | ||
| <ExternalLink className="ml-2 h-5 w-5" /> | ||
| </TooltipTrigger> | ||
| <TooltipContent className="z-auto overflow-visible"> | ||
| <p>{t('show_all_logs')}</p> | ||
| </TooltipContent> | ||
| </Tooltip> | ||
| </TooltipProvider> | ||
| </Button> | ||
| </DialogTrigger> | ||
| <DialogContent className="sm:max-w-2/3"> | ||
| <DialogHeader> | ||
| <DialogTitle>{t('device_logs')}</DialogTitle> | ||
| <DialogDescription>{t('logs_owner_hint')}</DialogDescription> | ||
| </DialogHeader> | ||
| <LogList entryLogs={entryLogs} locale={i18n.language} /> | ||
| </DialogContent> | ||
| </Dialog> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ) | ||
| } | ||
| if (!latestEntry) return null |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find where logEntries are loaded and check the ordering clause.
set -euo pipefail
rg -n -C6 'logEntries' --type=ts --type=tsx | head -100
fd -t f 'log-entry' | while IFS= read -r f; do echo "=== $f ==="; cat -n "$f"; done
rg -n -C8 'logEntry' app/db/models 2>/dev/null || rg -n -C8 'logEntry' app/dbRepository: openSenseMap/frontend
Length of output: 191
🏁 Script executed:
set -euo pipefail
printf '%s\n' '=== target file ==='
cat -n app/components/device-detail/entry-logs.tsx
printf '%s\n' '=== log-entry schema and related files ==='
cat -n app/db/schema/log-entry.ts
printf '%s\n' '=== candidate source files ==='
git ls-files | rg '(^|/)(log-entry|entry-log|device-detail|loader|loaders|api|route)' | head -200
printf '%s\n' '=== logEntries references ==='
rg -n -C8 'logEntries|entryLogs|LogEntry' --glob '*.ts' --glob '*.tsx' . | head -300
printf '%s\n' '=== ordering expressions ==='
rg -n -C6 'createdAt|orderBy|order\(' --glob '*.ts' --glob '*.tsx' app | head -400Repository: openSenseMap/frontend
Length of output: 50377
🏁 Script executed:
set -euo pipefail
printf '%s\n' '=== device model relation query ==='
cat -n app/db/models/device.server.ts | sed -n '80,145p'
printf '%s\n' '=== log-entry model ==='
cat -n app/db/models/log-entry.server.ts | sed -n '1,65p'
printf '%s\n' '=== device detail data loaders ==='
rg -n -C10 'getDevice|device-detail-box|DeviceDetailBox|logEntries' \
app/routes/device.\$deviceId.overview.tsx \
app/routes/device.dashboard.\$deviceId.tsx \
app/components/device-detail/device-detail-box.tsx \
app/db/models/device.server.ts
printf '%s\n' '=== all relation query orderBy options ==='
rg -n -C5 'with:|logEntries:|orderBy:' app/db app/routes --glob '*.ts' --glob '*.tsx' | head -250Repository: openSenseMap/frontend
Length of output: 36016
🏁 Script executed:
set -euo pipefail
printf '%s\n' '=== consumer route ==='
rg -n -C12 'getDevice\(|DeviceDetailBox|loader' \
app/routes/explore.\$deviceId.tsx \
app/components/device-detail/device-detail-box.tsx
printf '%s\n' '=== device model declarations and uses ==='
rg -n -C4 'export function getDevice|export async function getDevice|getDevice\(' \
app/db/models/device.server.ts app/routes --glob '*.ts' --glob '*.tsx'
printf '%s\n' '=== read-only structural check of the logEntries relation config ==='
python3 - <<'PY'
from pathlib import Path
import re
path = Path("app/db/models/device.server.ts")
text = path.read_text()
match = re.search(r"logEntries:\s*\{(?P<body>.*?)\n\s*\},\n\s*locations:", text, re.S)
if not match:
raise SystemExit("logEntries relation block not found")
body = match.group("body")
print("logEntries relation block:")
print(body)
print("contains orderBy:", bool(re.search(r"\borderBy\s*:", body)))
print("contains createdAt:", "createdAt" in body)
PYRepository: openSenseMap/frontend
Length of output: 24086
Define the logEntries order before using .at(-1). The getDevice relation has no orderBy, so entryLogs.at(-1) is not guaranteed to return the newest entry. Use an explicit ascending order or select the entry with the greatest createdAt.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
app/routes/about.tsx (1)
200-202: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick winReserve the desktop globe space before mounting
GlobeComponent.
useMediaQueryreturnsfalseon the first render and updates inuseEffect(app/hooks/use-media-query.ts:3-17). On desktop, thishiddenwrapper therefore has no layout space during SSR and hydration. After the effect, the globe appears and shiftsStatsand the following content down. Keep a fixed-size desktop wrapper and hide only the globe content until the query resolves.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 03bb3ccd-ba42-4178-b883-89cbccf53fda
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (5)
app/components/device-detail/entry-logs.tsxapp/components/landing/header/header.tsxapp/db/models/device.server.tsapp/hooks/use-media-query.tsapp/routes/about.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- app/components/landing/header/header.tsx
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.
Type of Change
Implementation
Checklist
devbranchAdditional Information