feat(admin): データ層モダン化(SP1)+即時インタラクティブシェル(SP2)を develop へ統合#43
Merged
Conversation
…ub-project plan) Records the Next.js 16.2.4 research conclusions (PPR/cacheComponents and server-side streaming do not fit the current all-client-fetch + host-only cross-origin cookie architecture) and decomposes the work into three sequenced sub-projects: (1) client data-layer consolidation, (2) resilience + instant shell, (3) server-side data (BFF vs cross-subdomain cookie — its own design). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Shared read-only data primitives to consolidate admin's duplicated fetch
state machines:
- useApiResource<T>(path, {enabled}) — idle|loading|ok|error + reload(),
refetches when `path` changes (query string drives search/filter/page),
with the cancellation guard lifted from participant-detail-sheet.
Mutations are out of scope (read-only).
- DataError — the destructive Alert used for fetch errors.
- EmptyState — the centered "no results" placeholder (non-table).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the duplicated {loading|ok|error} useEffect+apiJson state
machines across the dashboard, participants, stats, mentors,
pre-registrations and the participant detail sheet with the shared
useApiResource hook, and the inline error Alerts / empty blocks with
DataError / EmptyState.
- Query-param-driven pages build the path (date / search+filter+page /
date-range) and rely on refetch-on-path-change; the refresh button and
post-mutation callbacks call reload().
- Mutation callbacks become () => void (reload is fire-and-forget); the
POST/PATCH/DELETE calls still use apiJson/apiFetch directly.
No UI/behavior change. Verified: load, reload, search refetch, detail
sheet, and DataError/EmptyState states all render as before.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MeProvider split into state-only MeProvider + MeGate (backward-compatible: checkin/signage wrap content in MeGate, behavior unchanged). admin renders the shell chrome outside the gate (skeleton nav/account until /api/me), plus (authed)/error.tsx + root error.tsx + (authed)/loading.tsx. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Split the shared MeProvider into a state-only MeProvider (fetches /api/me, handles 401, always renders children + provides state) and a MeGate that does the gating (renders content only when ok, else loading/forbidden/error). useMe() keeps its non-null signature (safe inside a gate); new useMeState() feeds the shell. This is an atomic contract change, so all consumers move together: - checkin / signage: wrap content in <MeGate> (props moved over) — behavior unchanged (the gate logic is the same code, just relocated). - admin: AppShell renders OUTSIDE the gate so the sidebar/top-bar chrome + brand logo paint immediately; sidebar/bottom-nav/mobile-top-bar use useMeState() and show skeleton nav/account until /api/me resolves, then the real role-filtered nav. Page content stays gated by <MeGate>. Verified: admin shows the shell + skeleton nav during loading (desktop & mobile), real nav/account on ok, MeGate forbidden on 403; checkin/signage render through the relocated gate with no module/render errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- (authed)/error.tsx and root error.tsx ('use client') catch render-time
throws that the per-page try/catch can't, reusing DataError + a reset button.
- (authed)/loading.tsx renders a content skeleton during soft navigation;
meaningful now that the shell persists across navigations.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
概要
stack PR (#41 / #42) が兄弟ブランチ同士でマージされ develop に到達しなかったため、その内容を 1 本に統合して develop へ再投入します。
useApiResource)→feat/admin-ui-responsiveに誤マージ ❌refactor/admin-data-layerに誤マージ ❌stack PR の中間ブランチが削除されず、GitHub の auto-retarget が発火しなかったのが原因です。本 PR の差分は SP1 + SP2 のみ(UI リフレッシュは develop 反映済みのため含まれません)。内容は #41 / #42 でレビュー・承認済みのものと同一で、ロジック変更はありません。
含まれる変更
SP1 — データ取得ステートの集約(refactor)
packages/uiに読み取り専用フックを追加:useApiResource+DataError/EmptyStateプリミティブuseApiResourceへ移行(dashboard / participants / stats / mentors / pre-registrations / participant-detail-sheet)SP2 — 即時インタラクティブシェル + クラッシュ境界
MeProvider/MeGateに分割:シェル(ナビ・アカウント)は認証完了前でも即描画し、MeGateが本文のみゲートするerror.tsx(authed / root)・loading.tsxのレンダリングクラッシュ境界を追加<MeGate>でラップするのみで挙動不変(後方互換)マージ後の整理(別途対応)
誤マージで残った中間ブランチ(
feat/admin-ui-responsive/refactor/admin-data-layer)は本 PR マージ後に削除します。コミット
eb9a370feat(ui): add useApiResource hook + DataError/EmptyState primitivesf9a1b33refactor(admin): migrate 6 fetch state machines to useApiResource5aad32bfeat(admin): instant interactive shell via MeProvider/MeGate splitd5605dffeat(admin): add render-crash error boundaries + route loading skeleton🤖 Generated with Claude Code