feat: enhance Mini App design guidelines and refactor layout components

- Updated Mini App design guidelines to include detailed instructions on UI changes, accessibility rules, and verification processes.
- Refactored multiple components to utilize `MiniAppScreen` and `MiniAppScreenContent` for consistent layout structure across the application.
- Improved error handling in `GlobalError` and `NotFound` components by integrating new layout components for better user experience.
- Introduced new hooks for admin functionality, streamlining access checks and data loading processes.
- Enhanced documentation to reflect changes in design policies and component usage, ensuring clarity for future development.
This commit is contained in:
2026-03-06 17:51:33 +03:00
parent 43cd3bbd7d
commit fa22976e75
38 changed files with 1166 additions and 512 deletions

View File

@@ -100,6 +100,12 @@ Use **only** these tokens and Tailwind/shadcn aliases (`bg-background`, `text-mu
- **Sticky headers:** Use `top-[var(--app-safe-top)]` (not `top-0`) for sticky elements (e.g. calendar header, admin header) so they sit below the Telegram UI instead of overlapping it.
- Lists that extend to the bottom should also account for bottom inset (e.g. `padding-bottom: var(--tg-viewport-content-safe-area-inset-bottom, 12px)` in `.container-app`).
Official terminology (Telegram docs) uses `safeAreaInset` and `contentSafeAreaInset`
plus events `safeAreaChanged` and `contentSafeAreaChanged`. In our code, these values
are exposed through SDK CSS bindings and consumed via app aliases (`--app-safe-*`).
When updating safe-area code, preserve this mapping and avoid mixing raw `env(...)`
and Telegram content-safe insets within the same component.
### 3.4 Sheets and modals
Bottom sheets and modals that sit at the bottom of the screen must add safe area to their padding, e.g.:
@@ -203,6 +209,31 @@ See `webapp-next/src/components/day-detail/DayDetail.tsx` for the Sheet content.
- `setBottomBarColor('bottom_bar_bg_color')` when available (Bot API 7.10+).
- **Surface contrast:** When `--surface` equals `--bg` (e.g. some iOS OLED themes), `fixSurfaceContrast()` in `use-telegram-theme.ts` adjusts `--surface` using ThemeParams or a light color-mix so cards and panels remain visible.
### 8.1 Native control policy
- Use platform wrappers in `src/hooks/telegram/` rather than direct SDK calls in
feature components.
- **BackButton:** preferred for route-level back navigation in Telegram context.
- **SettingsButton:** use for route actions like opening `/admin` from calendar.
- **Main/Secondary button:** optional; use only if action must align with Telegram
bottom action affordance (do not duplicate with conflicting in-app primary CTA).
- **Haptics:** trigger only on meaningful user actions (submit, confirm, close).
### 8.2 Swipe and closing policy
- Keep vertical swipes enabled by default (`enableVerticalSwipes` behavior).
- Disable vertical swipes only on screens with explicit gesture conflict and document
the reason in code review.
- Enable closing confirmation only for stateful flows where accidental close can
lose user intent (e.g. reassignment flow in admin sheet).
### 8.3 Fullscreen/newer APIs policy
- Fullscreen APIs (`requestFullscreen`, `exitFullscreen`) are currently optional and
out of scope unless a feature explicitly requires immersive mode.
- If fullscreen is introduced, review safe area/content safe area and verify
`safeAreaChanged`, `contentSafeAreaChanged`, and `fullscreenChanged` handling.
---
## 9. Checklist for new screens and components
@@ -215,3 +246,18 @@ Use this for review when adding or changing UI:
- [ ] Safe area is respected for bottom padding and for sheets/modals.
- [ ] Interactive elements and grids/lists have appropriate `aria-label`s and roles.
- [ ] New animations respect `prefers-reduced-motion` and `data-perf="low"` (short or minimal on low-end Android).
- [ ] User-facing strings and `aria-label`/`sr-only` text are localized via i18n (no hardcoded English in shared UI).
- [ ] Telegram controls are connected through platform hooks (`src/hooks/telegram/*`) instead of direct SDK calls.
- [ ] Vertical swipe and closing confirmation behavior follows the policy above.
## 10. Verification matrix (Mini App)
At minimum verify:
- Telegram light + dark themes.
- iOS and Android safe area/content-safe-area behavior (portrait + landscape).
- Android low-performance behavior (`data-perf="low"`).
- Deep link current duty (`startParam=duty`).
- Direct `/admin` open and reassignment flow.
- Access denied, not-found, and error boundary screens.
- Calendar swipe navigation with sticky header and native Telegram controls.

View File

@@ -0,0 +1,119 @@
# Webapp-next Refactor Baseline Audit
This note captures the baseline before the phased refactor. It defines current risks,
duplication hotspots, and expected behavior that must not regress.
## 1) Screens and boundaries
- Home route orchestration: `webapp-next/src/app/page.tsx`
- Chooses among `AccessDeniedScreen`, `CurrentDutyView`, `CalendarPage`.
- Controls app visibility via `appContentReady`.
- Admin route orchestration: `webapp-next/src/app/admin/page.tsx`
- Thin route, but still owns shell duplication and content-ready signaling.
- Calendar composition root: `webapp-next/src/components/CalendarPage.tsx`
- Combines sticky layout, swipe, month loading, auto-refresh, settings button.
- Current duty feature root: `webapp-next/src/components/current-duty/CurrentDutyView.tsx`
- Combines data loading, error/access states, back button, and close action.
- Admin feature state root: `webapp-next/src/components/admin/useAdminPage.ts`
- Combines SDK button handling, admin access, users/duties loading, sheet state,
mutation and infinite scroll concerns.
## 2) Telegram integration touchpoints
- SDK/provider bootstrap:
- `webapp-next/src/components/providers/TelegramProvider.tsx`
- `webapp-next/src/components/ReadyGate.tsx`
- `webapp-next/src/lib/telegram-ready.ts`
- Direct control usage in feature code:
- `backButton` in `CurrentDutyView` and `useAdminPage`
- `settingsButton` in `CalendarPage`
- `closeMiniApp` in `CurrentDutyView`
- Haptics in feature-level handlers:
- `webapp-next/src/lib/telegram-haptic.ts`
Risk: platform behavior is spread across feature components instead of a narrow
platform boundary.
## 3) Layout and shell duplication
Repeated outer wrappers appear across route and state screens:
- `content-safe min-h-[var(--tg-viewport-stable-height,100vh)] bg-background`
- `mx-auto flex w-full max-w-[var(--max-width-app)] flex-col`
Known locations:
- `webapp-next/src/app/page.tsx`
- `webapp-next/src/app/admin/page.tsx`
- `webapp-next/src/components/CalendarPage.tsx`
- `webapp-next/src/components/states/FullScreenStateShell.tsx`
- `webapp-next/src/app/not-found.tsx`
- `webapp-next/src/app/global-error.tsx`
Risk: future safe-area or viewport fixes require multi-file edits.
## 4) Readiness and lifecycle coupling
`appContentReady` is set by multiple screens/routes:
- `page.tsx`
- `admin/page.tsx`
- `CalendarPage.tsx`
- `CurrentDutyView.tsx`
`ReadyGate` is route-agnostic, but signaling is currently ad hoc.
Risk: race conditions or deadlock-like "hidden app" scenarios when screen states
change in future refactors.
## 5) Async/data-loading duplication
Repeated manual patterns (abort, retries, state machine):
- `webapp-next/src/hooks/use-month-data.ts`
- `webapp-next/src/components/current-duty/CurrentDutyView.tsx`
- `webapp-next/src/components/admin/useAdminPage.ts`
Risk: inconsistent retry/access-denied behavior and difficult maintenance.
## 6) Store mixing concerns
`webapp-next/src/store/app-store.ts` currently mixes:
- session/platform concerns (`lang`, `appContentReady`, `isAdmin`)
- calendar/domain concerns (`currentMonth`, `pendingMonth`, duties/events)
- view concerns (`currentView`, `selectedDay`, `error`, `accessDenied`)
Risk: high coupling and larger blast radius for otherwise local changes.
## 7) i18n/a11y gaps to close
- Hardcoded grid label in `CalendarGrid`: `aria-label="Calendar"`.
- Hardcoded sr-only close text in shared `Sheet`: `"Close"`.
- Mixed language access strategy (`useTranslation()` vs `getLang()/translate()`),
valid for bootstrap/error boundary, but not explicitly codified in one place.
## 8) Telegram Mini Apps compliance checklist (baseline)
Already implemented well:
- Dynamic theme + runtime sync.
- Safe-area/content-safe-area usage via CSS vars and layout classes.
- `ready()` gate and Telegram loader handoff.
- Android low-performance class handling.
Needs explicit policy/consistency:
- Vertical swipes policy for gesture-heavy screens.
- Closing confirmation policy for stateful admin flows.
- Main/Secondary button usage policy for primary actions.
- Terminology alignment with current official docs:
`safeAreaInset`, `contentSafeAreaInset`, fullscreen events.
## 9) Expected behavior (non-regression)
- `/`:
- Shows access denied screen if not allowed.
- Opens current-duty view for `startParam=duty`.
- Otherwise opens calendar.
- `/admin`:
- Denies non-admin users.
- Loads users and duties for selected admin month.
- Allows reassignment with visible feedback.
- Error/fallback states:
- `not-found` and global error remain full-screen and theme-safe.
- Telegram UX:
- Back/settings controls remain functional in Telegram context.
- Ready handoff happens when first useful screen is visible.