Skip to content

Add Personal Timesheet View to Me Tab on Dashboard - #469

Open
Dharp02 wants to merge 46 commits into
mainfrom
redesign-ui
Open

Add Personal Timesheet View to Me Tab on Dashboard#469
Dharp02 wants to merge 46 commits into
mainfrom
redesign-ui

Conversation

@Dharp02

@Dharp02 Dharp02 commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Overview

This branch implements the full mobile/desktop UI redesign for TimeHuddle — bringing the app to parity with the redesign prototype across layout, navigation, and interaction patterns — plus several quality-of-life fixes and feature additions on top.

Changes by Commit

Navigation & Shell

  • Swap Settings for Huddle in mobile bottom nav — Huddle replaces Settings in the 4-item bottom nav; Settings moves to the sidebar
  • Reorder desktop sidebar Workspace nav — Clock moved up, Work moved to the bottom to match prototype priority
  • Sidebar: embed org/team switcher inline on desktop — then reverted after testing revealed conflicts with the existing popover approach

OrgTeamSwitcher

  • Rebuild OrgTeamSwitcher as prototype-matching bottom-sheet/dialog Modal — full rebuild matching the prototype's trigger button and animated sheet
  • OrgTeamSwitcher: match prototype exactly — refined trigger appearance and transition animation

Dashboard

  • Dashboard: 4-column stat row at desktop widths — stat cards expand to a single 4-col row on wider screens
  • Dashboard: add Me/Team toggle beside the title, scoped stats per tab — Me tab shows your own numbers; Team tab shows the whole team

Clock Page

  • Clock: cap layout to centered max-w-2xl on desktop — content column constrained and centered
  • Clock page: full attach bar, bold session timer, recent sessions — full-width attach bar, bolder session timer, recent sessions shown inline
  • Clock page: widen column, stop dimming the bottom-nav FAB — wider content column; FAB no longer grayed out while clocked in

Huddle

  • Huddle: edge-to-edge feed on mobile — feed goes full width on small screens
  • Huddle: flatten composer chrome, widen feed column — composer chrome reduced; feed column widened on desktop

Tickets

  • Tickets filters: horizontally scrollable chip row on mobile — filter chips scroll horizontally instead of wrapping
  • Tickets: narrow to centered max-w-4xl column on desktop — content column constrained
  • Tickets: fix clipped ticket options menu — overflow clipping on the options dropdown fixed

Teams Page

  • Redesign Teams page: move admin timesheet to Dashboard, add team pill switcher — admin timesheet panel relocated to Dashboard → Team → Timesheet; Teams page gets a pill-style team switcher

Modals & Toasts

  • Mobile bottom-sheet variant for @mieweb/ui Modal — Modal slides up as a sheet on mobile (<768px), centered dialog on desktop
  • Confirm desktop centered-dialog Modal variant preserved — verified modal behavior across breakpoints
  • Toast: shrink-to-content and center at desktop widths — toasts no longer stretch full-width on desktop
  • Fix modals to appear centered instead of full-screen on mobile — corrected modal positioning regression

New Features

  • Add personal timesheet view to Me tab on Dashboard — Overview/Timesheet secondary toggle on the Me tab; loads the current user's own clock history via AdminTimesheetPanel
  • Add share button to team header with compact icon-button strip — share/copy team join link from the team header
  • Add header notification bell and sidebar app info/test push — notification bell in the app header; app version/info in sidebar footer

Docs

  • Add redesign prototype and mobile/desktop implementation plan — prototype HTML and phased implementation checklist added to design/
  • docs(redesign): mark acceptance criteria — tracked completed phases in the plan doc

Acceptance Criteria

  • Mobile bottom nav shows Clock, Huddle, Tickets, Dashboard
  • OrgTeamSwitcher opens as a bottom sheet on mobile, centered modal on desktop
  • Dashboard Me/Team toggle scopes all stat cards correctly
  • Me tab Timesheet view loads current user's clock history
  • Admin timesheet accessible via Dashboard → Team → Timesheet
  • Modals are centered dialogs on desktop, bottom sheets on mobile
  • Toasts are centered and content-width on desktop
  • npm run typecheck and npm run lint pass clean
Screenshot 2026-08-04 at 3 25 18 PM Screenshot 2026-08-04 at 3 25 38 PM Screenshot 2026-08-04 at 3 25 58 PM Screenshot 2026-08-04 at 3 26 19 PM Screenshot 2026-08-04 at 3 26 42 PM Screenshot 2026-08-04 at 3 27 14 PM Screenshot 2026-08-04 at 3 27 29 PM

Dharp02 added 30 commits August 3, 2026 12:09
Step 1 of the redesign plan. Bottom nav tabs are now Dashboard, Huddle,
Clock (center FAB), Tickets, Teams. Settings is still reachable via the
avatar dropdown in the header, matching the prototype's priority order.
Step 2 of the redesign plan. Adds a CSS-only override that turns the
@mieweb/ui Modal into a bottom-sheet on mobile: slides up from the
bottom, full width, rounded top corners only, capped at 88dvh with
internal scroll. Applies to every consumer of the shared Modal (tickets,
teams, org, invite, confirm-delete, feedback, media, etc.) without
forking the component. Desktop behavior is unchanged.
Step 3. Huddle now uses AppPage flush + fill so PostCards stretch to the
viewport edges on mobile (no side gutter, no card radius). Tabs,
composer, drafts, and search input keep px-4 mobile gutter so they still
look inset. Desktop keeps the max-w-4xl reading column (Phase 2 will
tighten this to max-w-2xl). No changes to composer logic or post
rendering.
The quick-stats grid in DashboardPage.tsx already uses
'grid grid-cols-2 gap-3', which satisfies the mobile 2-column requirement
from the redesign plan. Me/Team scope is controlled by the existing
OrgTeamSwitcher / TeamContext, not a separate toggle inside the page, so
no layout change is needed for step 4. Numbers populate correctly for
both personal and team scopes.
Step 5. ClockPage was already a single-column stack (banner status ->
plan/wrap-up composer -> primary action -> punch-clock display). On
mobile the primary action row (Post plan and clock in / Post wrap-up
and clock out / Clock in / Clock out / Break) now stacks vertically
with each Button spanning w-full so the tap target reaches the full
column width. Desktop keeps the horizontal flex-wrap row via
sm:flex-row + sm:w-auto.

Plan-first gate logic in useClockToggle is untouched -- all 11 tests in
useClockToggle.test.ts still pass.
Replaces the anchored Dropdown popover with the shared Modal primitive:
- Mobile: full-width bottom sheet (existing Modal CSS from step 2)
- Desktop: centered dialog (existing Modal CSS from step 10)
- Organization select + Team list with member counts + '+ New team',
  matching design/redesign-prototype/index.html's OrgTeamSwitcher exactly
- Portals the Modal to document.body so it escapes AppHeader's
  backdrop-blur containing block (backdrop-filter creates a new
  containing block for position:fixed descendants, which was pinning
  the sheet near the header instead of the viewport)
- Preserves existing features not in the prototype: org role labels,
  pending join-request badges, awaiting-approval section
- Header trigger now matches the prototype's stacked two-line layout:
  brand mark + bold team name on top, muted 'Org name ▾' below —
  replacing the single-line 'Org > Team' pill.
- Replaced the large translateY(100%) slide-up keyframe with the
  prototype Modal's actual animation: a quiet fade + 4px settle
  (150ms ease-out). The prototype never really 'slides' a large
  distance — it docks the sheet to the bottom and just fades/settles
  it in, which is what read as clean instead of a 'jump'.
- AppPage gains an optional titleActions slot so pages can render
  controls on the same row as the page title (right-aligned), used
  here for the Me/Team segmented toggle from the redesign prototype.
- DashboardPage: 'Me' (default) shows the signed-in user's own hours
  today, open/closed/high-priority tickets, and running timers; 'Team'
  shows the existing team-wide aggregates unchanged.
- The toggle is always visible now (previously personal-team users had
  the team members / time-logged sections silently hidden via
  isPersonalTeam) — switching to Team on a personal team just shows a
  team of one instead of hiding the section.
The prototype's desktop sidebar renders the Organization select + Team
list + '+ New team' inline, always visible — no header button/modal.
Extracted that content into OrgTeamSwitcherPanel (shared with the
mobile bottom sheet) and render it directly in Sidebar.tsx's brand
block for the expanded desktop rail. The header pill + Modal in
OrgTeamSwitcher is now md:hidden (mobile-only) since desktop no longer
needs it — mobile behavior is unchanged.
… switcher

- Teams page: replace tabs with always-visible Members/Pending sections
- Add horizontal-scroll team pill switcher (Personal + selected team lead, rest follow)
- Consolidate Rename/Delete/Copy/Share into Team Settings modal; keep code+copy under team name
- Restore per-member 3-dot menu (Make/Remove Admin, Set Password, Remove Member) for all rows, including self (minus self-demote/remove)
- Compact icon-only Create/Join Team buttons in page title actions
- Move admin Timesheet view from Teams to Dashboard's Team tab with Overview/Timesheet toggle and deep-link support
- Scope the mobile bottom-sheet Modal treatment to only the org/team switcher modal, restoring default centered dialogs everywhere else
- Update e2e tests and notification deep links to match
Give the plan/wrap-up composer the same Photo/Video/Doc/Pulse/Ticket/
@Mention bar as the Huddle composer (extracted into shared
ComposerAttachButtons/ComposerChips so both stay in sync), and match the
redesign prototype's status card (bold elapsed-session timer instead of
the wall clock) and Recent sessions list.
- Override @mieweb/ui's mobile full-screen defaults (min-h-dvh, rounded-none)
  so all modals render as centered popups on every screen size
- Add horizontal margin on small screens so modals don't touch viewport edges
- Move org-switcher bottom-sheet rules outside the 767px media query so the
  bottom-sheet treatment applies on all screen sizes (not just mobile)
Drop the avatar circle and nested flex wrapper from the expanded
composer, trim its padding, and widen the feed's max-width from 2xl to
4xl so it isn't stranded in a narrow strip on wide dashboards.
Replace text "Copy" link with a tight code badge + copy + share icon
button group so the invite code row stays uncluttered. Share uses the
Web Share API with a clipboard fallback for desktop.
Match Clock's column width to Huddle's (max-w-2xl -> max-w-4xl). Also
drop the opacity/saturate dimming on the bottom-nav Clock In/Out FAB
when a plan or wrap-up is pending — it's a plain link to the clock
page, not a disabled control, so it shouldn't look blocked.
The per-row "..." menu used the plain library Dropdown, which
positions its menu absolutely inside the ticket list's
overflow-y-scroll container. Per the CSS overflow spec, once one axis
is scrollable the other axis clips too, so the menu was silently cut
off for rows near the bottom of the list -- the same class of bug
FilterDropdown already works around elsewhere in this file. Portal the
menu to document.body with fixed coordinates computed from the
trigger's rect, same pattern.
- Add meView state ('overview' | 'timesheet') to the Me tab
- Add Overview / Timesheet secondary toggle under Me tab
- Render AdminTimesheetPanel pre-loaded with the current user when meView is 'timesheet'
- Add userToTeamMember helper to convert TimecoreUser to TeamMember shape
AppHeader: add a bell icon beside the profile avatar that navigates to
/app/notifications, matching the pattern already used in Huddle and
the bottom nav.

Sidebar: add a footer row showing the app version/build (real values
via App.getInfo() on native/TestFlight, falling back to the web
build's VITE_APP_VERSION otherwise) plus a "Test push notification"
button wired to the same notifications.testPush endpoint Settings
already uses.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

⏳ Preview Build In Progress

Docker image is building — this takes a few minutes (Meteor bundle compilation happens at image-build time, not container start time).

A new comment will appear here when the preview is ready or if the build fails.

@Dharp02 Dharp02 self-assigned this Aug 3, 2026
npm run format (prettier --check .) was failing on 5 files that had
drifted from Prettier's style, blocking the Frontend Checks job on
PR #469.
The composer was wrapped in an extra px-4 inset on mobile that
PostCard never had, so it rendered as a narrower floating bar next to
full-bleed post rows below it. Drop the wrapper padding so both are
flush edge-to-edge on mobile, matching PostCard's own sizing.
@Dharp02 Dharp02 added the enhancement New feature or request label Aug 4, 2026
@Dharp02 Dharp02 moved this from Ready to In Progress in Scrum Team Jerry Aug 4, 2026
Dharp02 added 5 commits August 4, 2026 14:39
- BottomNav: replace Teams tab with a bottom-sliding "More" sheet containing Teams, Organization, and Profile (mirrors the redesign prototype); remove the mobile hamburger drawer from AppHeader/Sidebar since it's no longer reachable.
- ddp.ts/TeamContext: add DdpClient.onDisconnect() fired the instant the socket drops, and reset the teams subscription's ready guard on disconnect so a reconnect's transient partial team list can no longer silently reset the selected team back to Personal.
- TicketsPage: clamp filter dropdown menus (Team/Priority/Status/Assignee) to the ticket list card's actual bounds after mount, fixing menus rendering partly outside the card/viewport on mobile.
UserDropdown: hide Admin, Developers, and Help sections on mobile widths (hidden md:contents) — only Profile, Settings, and Sign out remain in the top account menu on mobile.
BottomNav: More sheet gains drill-down Admin (Enterprise, Members), Developers (Seeder), and Help (Report an Issue, Share Your Feedback, TestFlight) cards with a back button, mirroring the desktop account menu.
DashboardPage: persist the Me/Team toggle to localStorage (app:dashboardTab) so navigating away and back no longer silently resets it to Me.
DashboardPage: add a Recent Activity card showing everyone's published plan/wrap-up huddle posts for the team (live via the huddlePosts.byTeam DDP subscription), each row linking to /app/huddle?postId=<id>.
Huddle page: support the postId deep link — scrolls to and briefly highlights the matching post once the feed loads, then strips the query param.
PostCard: accept a highlighted prop (ring highlight) and a stable id for scroll-to-post targeting.
DashboardPage: only show the Recent Activity card for actual teams — a personal workspace has no 'everyone' to show activity for.
Rows now use a plain <button> instead of the @mieweb/ui Button (which enforces a fixed h-10 and was clipping/overlapping the two-line content on mobile), with larger avatar, more padding, and clamped 2-line post preview so it's no longer congested on mobile or web.
The indigo highlight ring around a deep-linked post (from the dashboard's Recent Activity feed) now clears as soon as the user clicks/taps anywhere, instead of only after the 2.5s timeout.
@Dharp02
Dharp02 requested review from horner and a lite review from Copilot August 4, 2026 19:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements a broad UI redesign across the app shell (mobile bottom nav + desktop sidebar/header), and moves/extends timesheet functionality so both personal and admin team timesheets are accessible from the Dashboard (including deep-link support).

Changes:

  • Adds Dashboard “Me/Team” scoping, including a personal Timesheet view on “Me” and an admin-only Team Timesheet view (migrated from Teams) with deep-link support.
  • Reworks navigation/shell: mobile “More” bottom sheet, revised sidebar ordering, updated Org/Team switcher UI, and a notifications bell in the header.
  • Updates Huddle/Tickets/Clock/Teams layouts and e2e tests to match the new routes and UI structure.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/e2e/timesheet/timesheet-calculation-fixes.spec.ts Updates deep-link navigation and UI interactions to land on Dashboard Team Timesheet.
tests/e2e/teams/teams.spec.ts Moves admin timesheet filter assertions from Teams → Dashboard Team tab.
tests/e2e/teams/profile-routing.spec.ts Removes obsolete “Members tab” navigation now that members are always visible.
src/ui/UserDropdown.tsx Hides Admin/Developers/Help sections on mobile to align with mobile “More” sheet pattern.
src/ui/Sidebar.tsx Reorders nav items and adds sidebar footer app info + test push action; removes mobile drawer.
src/ui/OrgTeamSwitcher.tsx Rebuilds the org/team switcher to use an @mieweb/ui Modal + Select with team list.
src/ui/BottomNav.tsx Adds new mobile bottom nav (Dashboard/Huddle/Clock/Tickets/More) and “More” bottom sheet.
src/ui/AppPage.tsx Adds titleActions to support right-aligned controls alongside the page title.
src/ui/AppLayout.tsx Adjusts toast sizing/centering behavior for desktop widths.
src/ui/AppHeader.tsx Removes mobile hamburger and adds notifications bell button linking to notifications page.
src/styles.css Adds global Modal overrides and OrgTeamSwitcher modal styling/animations.
src/pages/Huddle.tsx Adds deep-link-to-post highlighting and adjusts layout spacing for mobile/desktop.
src/lib/TeamContext.tsx Fixes a reconnect race by resetting subscription readiness on DDP disconnect.
src/lib/ddp.ts Adds onDisconnect listener support to allow callers to reset “ready” state on socket drop.
src/features/tickets/TicketsPage.tsx Fixes clipped menus by portaling dropdowns and adds mobile horizontal filter chip row.
src/features/teams/TeamsPage.tsx Removes timesheet from Teams UI, adds pill-style team switcher, refactors settings/rename UX.
src/features/huddle/PostCard/index.tsx Adds post id anchor + optional highlight ring for deep-link navigation.
src/features/huddle/HuddleComposer.tsx Extracts attachment/ticket/mention UI into a shared component.
src/features/huddle/ComposerAttachments.tsx New shared composer attachment controls and chips (reused by Huddle + Clock).
src/features/dashboard/DashboardPage.tsx Implements Me/Team tabs, personal timesheet view, admin team timesheet view, and recent activity.
src/features/clock/ClockPage.tsx Redesigns clock page structure, adds shared composer attachments, and shows recent sessions.
meteor-backend/server/timers.js Updates notification deep-link URL to point to Dashboard Team Timesheet.
meteor-backend/server/notify-core.js Updates notification deep-link URL to point to Dashboard Team Timesheet.
meteor-backend/package.json Adds production server-only build scripts for Meteor backend.
docs/redesign-implementation-prompt.md Adds implementation plan documentation for the redesign phases and constraints.

Comment thread src/styles.css Outdated
Comment on lines +143 to +160
/* Org/team switcher Modal — always a bottom sheet on all screen sizes.
* `align-self:end` pushes it to the bottom of the library's centering flex
* container without forking the Modal component.
*/
[data-slot='modal'].org-switcher-modal {
align-self: end !important;
min-height: auto !important;
max-height: 88dvh !important;
width: 100% !important;
border-radius: 1rem 1rem 0 0 !important;
animation: none !important;
}
[data-slot='modal'].org-switcher-modal[data-state='open'] {
animation: mieweb-modal-fade-in 150ms ease-out both !important;
}
[data-slot='modal'].org-switcher-modal[data-state='closed'] {
animation: mieweb-modal-fade-out 120ms ease-in both !important;
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Committed the suggested change

Dharp02 added 7 commits August 4, 2026 15:35
The border above the like/comment/share row now stretches to the card's full corners (-mx-5/px-5 instead of -mx-1) instead of stopping short.
Clicking the author avatar or name in the huddle feed now navigates to their profile page.
Meteor.users has no idGeneration override, so its _id is the default Random.id() format (17-char alphanumeric) — not the 24-char hex ObjectId the /app/profile/:id route's regex expected. Raw userIds without a known username (e.g. huddle post authors) were falling through to the username branch and failing lookup ('Unknown user'), including when clicking your own profile from the Huddle feed. Broadened the ID regex to also match Meteor's default 17-char user id format.
Bumped the dashboard's Recent Activity feed cap from 6 to 10 posts; older activity remains reachable via 'View all' on the Huddle page.
Addresses Copilot review comment on PR #469: the .org-switcher-modal overrides (align-self:end, width:100%, top-only rounding) applied unconditionally, forcing a bottom sheet on desktop too. This contradicted OrgTeamSwitcher's own doc comment and the redesign spec (bottom sheet on mobile, centered dialog on desktop). Wrapped the overrides in the same 767px mobile breakpoint used elsewhere in this file.
design/redesign-prototype/index.html was a static mockup used as design reference during the redesign work — not needed in the shipped PR.
- AppHeader: hide the clock-page shortcut on /app/clock so its 'Clock in' aria-label doesn't collide with the ClockPage's own Clock In button (Playwright strict-mode fail).

- ClockPage e2e page object: .clock-banner → .clock-status; status text 'On shift' → 'Clocked in'; plan gate text 'Write a plan before starting this session' → 'Plan before you clock in' — the underlying DOM was renamed during the redesign.

- Team switcher tests (team-qr-share, team-auto-accept, org-invite-by-email, timesheet-calc): getByRole('menuitem', {teamName}) → getByRole('dialog').getByRole('button', {teamName}); the switcher renders a modal of plain buttons now, not a menu.

- team-qr-share: 'Share team QR code' button lives inside Team Settings; the main teams page opens the share modal via 'Share team invite link'.

- teams: 'Copy' button is now 'Copy team code'; disambiguate the created team header by asserting the h3 CardTitle instead of unscoped getByText.

- dashboard: scope sidebar nav-item assertions to the 'Main navigation' nav, since the dashboard body now has its own Timesheet/Team tabs.

- timesheet-calc admin view: scope the 'Timesheet' tab click to <main> to skip the sidebar's identically-named nav button.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

2 participants