feat(admin): responsive UI refresh — adaptive nav, PWA, dark mode, logo & motion#40
Merged
Conversation
Responsive layout (sidebar + bottom nav), installable PWA, and dark mode for the admin app. Brainstormed scope and decisions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduces a shared next-themes wrapper (ThemeProvider) and a light/dark/system ThemeToggle, and updates the Sonner Toaster to follow the active theme. Falls back to light when no provider is present, so checkin/signage are unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…iring Replace the desktop-only top header/nav with an adaptive shell: a fixed left sidebar on desktop and a mobile top bar + bottom tab bar (with safe-area inset) on small screens, both driven by a single nav-items source of truth. Wrap the app in ThemeProvider for dark mode. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a web manifest (Android/Chromium), appleWebApp metadata (iOS), a theme-aware viewport (light/dark status bar, zoom allowed), and programmatically generated app icons (icon.tsx / apple-icon.tsx). No binary assets committed; mirrors checkin's standalone, no-offline setup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wide data tables (dashboard, participants, mentors, pre-registrations) now render as stacked cards under md and as tables at md+, via a shared RecordCard/RecordField. Stats keeps its narrow table with a 2-up KPI grid on mobile. PageHeader stacks, summary cards shrink, and the login page gets a brand mark. Also fixes a nested <main> in the shell. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Chrome rejected the .ico manifest entry as an invalid image; keep only the generated /icon PNG (favicon stays auto-linked for the tab). Hide summary-card icons under the sm breakpoint so KPI labels have room. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PreToolUse: block writing secret/lockfile (.dev.vars*, .env*, service-account JSON, pnpm-lock.yaml) per CLAUDE.md §7; PostToolUse: run Biome autofix on edited files to keep CI green. Also broaden .gitignore to .dev.vars.* (wrangler env-specific secret files). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Read-only reviewers encoding project constraints CI cannot check: Cloudflare Workers compatibility (CLAUDE.md §1/§2) and the children's-data PII boundary (CLAUDE.md §5). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
create-migration wraps the drizzle-kit generate -> wrangler D1 apply flow; pre-pr-check mirrors CI (Biome + type-check), runs @tecnova/shared tests CI omits, and scans the diff for secrets before commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- bottom-nav: active tab used dark --primary (2.6:1, an inversion); use the lighter sidebar-primary in dark to meet WCAG AA, add focus-visible ring - stats: loaded KPI grid was missing the base grid-cols-2, so it stacked 1-up on mobile and the total's col-span-2 was dead — restore 2-up - mobile top bar: enlarge theme/account controls to 40px touch targets - record-card: enrich tappable-card aria-labels with grade + status - mentors: document the card/row dual-mount edit-state trade-off Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the placeholder "tec" wordmark with the official logo (public/logo_tecnova.png, the same asset checkin/signage use). - BrandLogo component renders the logo; the wordmark is dark, so on dark-mode surfaces it sits on a white plate (dark:bg-white) to stay legible while preserving the brand colors (no plate in light mode). - icon.tsx / apple-icon.tsx now embed the logo centered on a white square via ImageResponse (readFile -> data URL; Satori needs a native <img>, so next/image is intentionally not used). - Drop the unused Next.js scaffolding SVGs from public/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mirror checkin's "Cohesive Elevation" motion (motion/react), all prefers-reduced-motion aware: - Shared tokens in lib/motion.ts; Reveal (one cohesive section/body fade-up) and AnimatedNumber (summary count-up). - Sliding active indicator via shared layoutId: a filled pill in the desktop sidebar and a bar in the mobile bottom nav. - Login adopts the logo (decorative alt to avoid double-announce next to the brand text) plus an entrance and CTA tap feedback. Each page wraps its swapping data area in a single always-mounted Reveal (flex flex-col gap-6 preserves the layout gap) so the entrance plays once and does not replay on every refetch/search; no per-card stagger. Nav a11y/contrast (from review): add aria-current + aria-label to the sidebar nav, and use the AA-compliant primary pairing for the active pill in light mode (light --sidebar-primary was 3.77:1), matching bottom-nav. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Note the BrandLogo dark-mode plate, the motion approach (Reveal / AnimatedNumber / layoutId nav indicators, all reduced-motion aware), and that the PWA icons embed public/logo_tecnova.png via ImageResponse. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The design system makes buttons pill-shaped (rounded-4xl), but the sidebar active-pill background was rounded-md, so the active item read as a rounded rectangle behind a pill-shaped button. Use rounded-4xl so the indicator matches the button (and the ghost hover) shape. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The menu content already carried the data-open/data-closed enter/exit classes (zoom/fade/slide) and tw-animate-css provides the keyframes, but a stray `animate-none!` (!important) in the same className forced `animation: none`, so the menus popped in/out with no transition. - Drop the `animate-none!` override on DropdownMenuContent / DropdownMenuSubContent and SelectContent. - Switch Select to position="popper" so the menu opens below the trigger (the component already had popper support wired); item-aligned positioning intentionally suppresses animation, which is why it never played. No new dependency needed (Animate UI not required). In practice admin is the only consumer of both components. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ntent The loading fallback was two generic blocks that looked nothing like the final layout, so the swap to real data jumped. Replace it with a content-shaped placeholder: a stat-card skeleton (badge + id + 2-col label/value grid) and a history section (heading + rows), mirroring DetailBody so the transition is smooth. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
管理画面(admin)の UI リフレッシュ。レスポンシブ対応・モバイル PWA・ダークモード・公式ロゴ・控えめなモーションをまとめて入れる。
主な変更
nav-itemsを唯一の真実の源にロール出し分け)。広いテーブルはmd未満でカード一覧に切替。appleWebApp)/ Android(manifest.ts)二重設定。アイコンは公式ロゴをImageResponseで白地正方形に生成。@tecnova/uiのThemeProvider(next-themes)+ThemeToggle。Toasterがテーマ追従(checkin/signage は不変)。tec-nova Nagasakiロゴをサイドバー/トップバー/ログイン/PWA アイコンへ。ダークでは白プレートで視認性確保(BrandLogo)。Reveal)・サマリのカウントアップ(AnimatedNumber)・ナビのアクティブインジケータ(layoutId)。prefers-reduced-motion尊重。animate-none!除去+Select を popper 化)、利用者詳細のローディングをコンテンツ型スケルトンに。aria-current、ライトのアクティブピルを AA 達成の primary ペアに)。検証
備考
packages/uiの共有変更(theme provider / dropdown / select)は実質 admin のみが利用。.claude/のツール設定コミット(chore(claude))が本ブランチに同梱されている。🤖 Generated with Claude Code