Skip to content

fix(golf,baseball): calendar mobile clip + retired accent-stripe card#806

Merged
njrini99-code merged 3 commits into
mainfrom
fix/calendar-mobile-clip-stripe
Jul 12, 2026
Merged

fix(golf,baseball): calendar mobile clip + retired accent-stripe card#806
njrini99-code merged 3 commits into
mainfrom
fix/calendar-mobile-clip-stripe

Conversation

@njrini99-code

Copy link
Copy Markdown
Owner

Summary

Three mobile defects reported from a live phone screenshot of the baseball player Schedule page — all three live in the shared calendar surface (PremiumCalendarClient), so this heals golf player, golf coach, baseball player, and baseball coach calendars at once:

  1. Clipped "Today" pill at 390px — the CalendarHeader control bar root carried flex-shrink-0, so as a flex child of the calendar's horizontal header row it refused to compress and overflowed into the glass container's overflow:hidden rounded edge. Replaced with w-full (+ existing min-w-0): the date title now truncates as designed (~9 visible chars at 390px) instead of the controls clipping. Verified the calendar header variant's only consumer is PremiumCalendarClient.
  2. Clipped notification bell badge — root cause was the ui Button primitive's overflow-hidden (ripple containment) cutting the -top-1 -right-1 unread badge at the button's own bounds. The trigger now sets overflow-visible (twMerge instance override); badge position and ring untouched.
  3. Retired accent-stripe event card (MOBILE_DOCTRINE rule 11) — MobileEventCard still painted an absolute colored left stripe with its own off-palette color switch (bg-sky-500/bg-purple-500/bg-amber-500). Replaced with the sanctioned ringed event-type dot (v3 design language: 3px soft ring at 18% alpha), sourced from the shared getEventTypeConfig map — a new dotRingColor field was added to EventTypeConfig and all 13 entries in event-styles.ts, keeping one source of truth and deleting the divergent local color map.

Partner-readable summary

On phones, the team calendar had a cut-off "Today" button, a cut-off notification counter, and an outdated event-card style. All three are fixed across both sports' calendars, and event cards now match the premium design language.

Type of change

  • Bug fix
  • Feature / new behavior
  • Security / RLS / auth
  • Database migration
  • CI / tooling / chore
  • Docs only

Area

golf · baseball · dashboard · mobile

Risk level

  • Low
  • Medium — shared component changed (Button overflow override is instance-scoped; header shrink verified single-consumer)
  • High

Git Activity Timeline note

Fixes cut-off calendar controls and notification badge on phones and brings event cards in line with the premium design system across golf and baseball.

Checklist

  • npm run lint and npm run typecheck pass (tsc clean; eslint --max-warnings 0 on touched files incl. helm/no-banned-color)
  • Unit/contract tests pass — 312 passed across golf/baseball calendar + ui suites
  • No migrations, no RLS changes, no secrets
  • UI change uses design-system primitives and the shared event-styles token map

Screenshots / notes

Reported from live phone use (baseball player Schedule, 390px). Before: Today pill clipped at card edge, bell badge half-cut, blue accent stripe on event card. The fix removes the last divergent copy of the event-type color map.

🤖 Generated with Claude Code

https://claude.ai/code/session_019WJ1Gzjj9MT3UsxhMoMzSV


Generated by Claude Code

…/baseball surface

- CalendarHeader control bar could not shrink inside the glass container's
  horizontal header row (flex-shrink-0 on the header root), so at 390px the
  Today pill clipped at the container's overflow-hidden rounded edge —
  observed live on baseball player Schedule (shared PremiumCalendarClient,
  affects golf + baseball coach too). The header now fills and shrinks;
  the date title truncates as designed.
- NotificationCenter unread badge rendered clipped on the mobile mount;
  the clipping element was the ui Button primitive itself — its baseStyles
  apply overflow-hidden to contain the tap ripple, cutting off the badge
  positioned at -top-1/-right-1. The bell trigger now opts into
  overflow-visible (twMerge lets the instance class win), keeping the
  ring-2 ring-cream-50 separation intact.
- MobileEventCard still used the retired accent-stripe idiom
  (MOBILE_DOCTRINE rule 11) with off-palette raw colors; replaced with the
  sanctioned ringed event-type dot sourced from the shared
  getEventTypeConfig map (event-styles.ts), unifying the two divergent
  color maps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019WJ1Gzjj9MT3UsxhMoMzSV
@supabase

supabase Bot commented Jul 11, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project qmnssrrolpinvwjjnufo because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
helmv3 Ignored Ignored Preview Jul 11, 2026 7:55pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Calendar event types gain ring styling and two new variants. Mobile event cards use shared ringed dots, while calendar header shrinking and notification badge overflow behavior are adjusted.

Changes

Calendar UI updates

Layer / File(s) Summary
Event style contract and configurations
src/lib/types/calendar.ts, src/lib/calendar/event-styles.ts
EventType adds showcase and tryout; configurations define dotRingColor, and unknown keys fall back safely to other.
Mobile event indicator rendering
src/components/golf/calendar/MobileEventCard.tsx
Mobile event cards use shared event configuration for ringed title dots and remove the left accent stripe.
Calendar layout and badge visibility
src/components/ui/page-header.tsx, src/components/golf/calendar/NotificationCenter.tsx
Calendar headers can shrink within constrained rows, and the notification bell allows badge overflow.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: design-system

🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Conventional Commits ❓ Inconclusive HEAD subject matches the regex, but the PR title isn’t present in the local repo/context to verify. Provide the actual PR title (or PR metadata export) so it can be checked against the conventional-commit regex.
✅ Passed checks (11 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No Service-Role In Client Bundles ✅ Passed PASS: The five changed files contain no SUPABASE_SERVICE_ROLE_KEY references or service-role Supabase client creation; only UI/calendar code changed.
Rls Coverage On New Tables ✅ Passed No migration files changed in the PR diff, so there’s no CREATE TABLE/RLS surface to check.
Auth Check In Server Actions ✅ Passed No changed files under src/app//actions//*.ts; the PR only touches calendar UI and shared type/style files.
Sport-Prefixed Table Names ✅ Passed No Supabase table queries in changed TS/TSX files; only UI/type changes in MobileEventCard.tsx:15-224, NotificationCenter.tsx:3-333, page-header.tsx:1-1300, event-styles.ts:1-273, types/calendar.ts...
No Destructive Writes ✅ Passed PASS: The only touched file is src/lib/calendar/event-styles.ts, which contains pure event-type config and a getter; no save/submit/sync code or DELETE/INSERT path exists.
No Edits To Historical Migrations ✅ Passed Diff from origin/main touches only src files; no supabase/migrations files are modified, so no historical migration edits are present.
Title check ✅ Passed The title is a Conventional Commits fix and names the golf/baseball calendar mobile bugfixes.
Description check ✅ Passed The description directly matches the shared calendar, bell badge, and event-card changes in the diff.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/calendar-mobile-clip-stripe
  • 🛠️ helm safety pass
  • 🛠️ dashboard ux pass
  • 🛠️ rls test pass

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 11, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes shared mobile calendar presentation issues across the golf and baseball calendar surfaces. The main changes are:

  • Allows the calendar header to shrink so controls do not clip on narrow phones.
  • Lets the notification badge render outside the bell button bounds.
  • Replaces the retired mobile event-card accent stripe with the shared event-type dot style.
  • Adds shared styling entries for baseball showcase and tryout event types.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
src/components/golf/calendar/MobileEventCard.tsx Replaces the mobile event-card stripe with a shared event-type dot.
src/components/golf/calendar/NotificationCenter.tsx Overrides the bell trigger overflow so the unread badge is visible.
src/components/ui/page-header.tsx Updates the calendar header root sizing so it can shrink inside the shared calendar container.
src/lib/calendar/event-styles.ts Adds dot ring colors to event style configs and includes baseball showcase and tryout styles.
src/lib/types/calendar.ts Extends shared calendar event types and config fields for the new dot ring styling.

Reviews (2): Last reviewed commit: "fix(calendar): own-key guard in getEvent..." | Re-trigger Greptile

}
};
// Cast string type to EventType for styling (fallback to 'other' if not matched)
const config = getEventTypeConfig(event.event_type as EventType);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Baseball Types Lose Styling

When baseball calendar rows use known event types like showcase or tryout, this cast sends those strings through the shared golf/baseball styling lookup even though they are not in the shared EventType config. The new dot becomes the only visible event-type marker on mobile, so those events fall back to neutral other styling and become visually indistinguishable from miscellaneous events.

Context Used: Review for Helm Sports Labs (a commercial multi-sp... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/golf/calendar/MobileEventCard.tsx
Line: 96

Comment:
**Baseball Types Lose Styling**

When baseball calendar rows use known event types like `showcase` or `tryout`, this cast sends those strings through the shared golf/baseball styling lookup even though they are not in the shared `EventType` config. The new dot becomes the only visible event-type marker on mobile, so those events fall back to neutral `other` styling and become visually indistinguishable from miscellaneous events.

**Context Used:** Review for Helm Sports Labs (a commercial multi-sp... ([source](.greptile))

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

…type config

Greptile on #806: with the accent stripe gone, the type dot is the only
mobile marker, and baseball's recruiting-facing showcase/tryout types
(event-ink 'pursuit') fell through to the neutral 'other' styling. Both
join the shared EventType union and event-styles config in the violet
recruiting family (solid/soft split mirroring their ink variants).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019WJ1Gzjj9MT3UsxhMoMzSV

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/golf/calendar/MobileEventCard.tsx`:
- Around line 25-26: Update the EventType type import in MobileEventCard.tsx to
use the public '`@/lib/types`' barrel instead of the deep '`@/lib/types/calendar`'
path, leaving the formatTime and getEventTypeConfig import unchanged.
- Around line 95-96: Normalize event.event_type before passing it to
getEventTypeConfig in MobileEventCard: accept only recognized own EventType keys
and fall back to "other" for inherited or unknown values such as "__proto__" and
"constructor", ensuring the returned config always has valid styling fields.

In `@src/lib/calendar/event-styles.ts`:
- Line 34: Update the event style definitions in event-styles.ts, including
dotRingColor and the related amber, stone, teal, violet, orange, sky, rose, and
purple entries, to use only canonical primary-*, destructive, warm-*, or cream-*
classes. Preserve each style’s intended semantic role and ensure MobileEventCard
continues consuming valid approved token classes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: eecadda1-7ebe-433e-b2f4-6659e08ed268

📥 Commits

Reviewing files that changed from the base of the PR and between 784138e and f074fb6.

📒 Files selected for processing (5)
  • src/components/golf/calendar/MobileEventCard.tsx
  • src/components/golf/calendar/NotificationCenter.tsx
  • src/components/ui/page-header.tsx
  • src/lib/calendar/event-styles.ts
  • src/lib/types/calendar.ts

Comment on lines +25 to +26
import { formatTime, getEventTypeConfig } from '@/lib/calendar/event-styles';
import type { EventType } from '@/lib/types/calendar';

@coderabbitai coderabbitai Bot Jul 11, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Import EventType through the public type barrel.

Use import type { EventType } from '@/lib/types' instead of the deep @/lib/types/calendar import.

As per coding guidelines, import types from @/lib/types for type definitions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/golf/calendar/MobileEventCard.tsx` around lines 25 - 26,
Update the EventType type import in MobileEventCard.tsx to use the public
'`@/lib/types`' barrel instead of the deep '`@/lib/types/calendar`' path, leaving
the formatTime and getEventTypeConfig import unchanged.

Source: Coding guidelines

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Skipped deliberately: @/lib/types/index.ts does not re-export the calendar module, so the barrel import would not compile. The deep @/lib/types/calendar path is the established idiom for these types — the sibling EventCard.tsx (pre-existing) imports EventType the same way. Expanding the barrel is out of scope for this fix (69 existing exports, collision risk with inline calendar-event types already in index.ts).


Generated by Claude Code

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -t f 'index.ts' src/lib/types
echo "---"
cat src/lib/types/index.ts 2>/dev/null | head -50
echo "---"
rg -n "EventType" src/lib/types/index.ts
echo "---"
rg -n "from '`@/lib/types`" src/components/golf/calendar/EventCard.tsx

Length of output: 6102


@njrini99-code Confirmed — src/lib/types/index.ts has no re-export of ./calendar, and src/components/golf/calendar/EventCard.tsx:8 already imports EventType the same way (from '@/lib/types/calendar'). The barrel import would indeed fail to compile as-is, and this is the established pattern for these types. Withdrawing this nit.


🧬 Code Graph Analysis Results

Relevant snippets

src/components/golf/calendar/MobileEventCard.tsx

  • (No additional snippets provided with line numbers; file contents already show the relevant imports/casts, e.g., type { EventType } from @/lib/types/calendar and casting event.event_type as EventType.)

src/lib/types/calendar.ts (lines 5-20)

export type EventType =
  | 'game'
  | 'practice'
  | 'scrimmage'
  | 'recruiting_visit'
  | 'camp'
  | 'tournament'
  | 'meeting'
  | 'workout'
  | 'class'
  | 'blocked_time'
  | 'qualifier'  // Golf-specific
  | 'travel'     // Golf-specific
  | 'showcase'   // Baseball-specific (recruiting-facing — event-ink 'pursuit')
  | 'tryout'     // Baseball-specific (recruiting-facing — event-ink 'pursuit')
  | 'other';

src/lib/calendar/event-styles.ts (lines 165-172)

export function getEventTypeConfig(type: EventType): EventTypeConfig {
  // Own-key guard: callers pass raw DB strings (cast to EventType), and a
  // plain index would resolve inherited keys like '__proto__' to a truthy
  // prototype object with no styling fields instead of the 'other' fallback.
  return Object.prototype.hasOwnProperty.call(eventTypeConfigs, type)
    ? eventTypeConfigs[type]
    : eventTypeConfigs.other;
}

src/lib/calendar/event-styles.ts (lines 177-196)

export function formatTime(timeString: string): string {
  // Handle time-only strings (HH:MM:SS or HH:MM)
  if (timeString && !timeString.includes('T') && !timeString.includes(' ')) {
    const parts = timeString.split(':').map(Number);
    const hours = parts[0] ?? 0;
    const minutes = parts[1] ?? 0;
    const period = hours >= 12 ? 'PM' : 'AM';
    const displayHour = hours % 12 || 12;
    const displayMinutes = String(minutes).padStart(2, '0');
    return `${displayHour}:${displayMinutes} ${period}`;
  }

  // Handle full datetime strings
  const date = new Date(timeString);
  return date.toLocaleTimeString('en-US', {
    hour: 'numeric',
    minute: '2-digit',
    hour12: true,
  });
}

src/hooks/useCalendarEvents.ts (lines 6-34)

export interface CalendarEvent {
  id: string;
  team_id: string;
  title: string;
  event_type: string; // Accepts any event type string for flexibility across sports
  start_date: string; // Mapped from start_time (timestamptz)
  end_date: string | null; // Mapped from end_time (timestamptz)
  start_time: string | null; // Raw start_time from DB
  end_time: string | null; // Raw end_time from DB
  location?: string | null;
  description?: string | null;
  status?: string;
  all_day?: boolean;
  recurring?: boolean;
  created_by?: string | null;
  requires_rsvp?: boolean;
  rsvp_deadline?: string | null;
  max_attendees?: number | null;
  rsvp_confirmed_count?: number;
  rsvp_maybe_count?: number;
  rsvp_declined_count?: number;
  rsvp_pending_count?: number;
  rsvp_total_count?: number;
  // Recurring-series identity. Series root has recurrence_rule populated and
  // parent_event_id null; sibling occurrences carry parent_event_id pointing
  // back to the root.
  parent_event_id?: string | null;
  recurrence_rule?: string | null;
}

src/components/golf/calendar/MobileRSVPButtons.tsx (line 20)

export type RSVPResponse = 'accepted' | 'tentative' | 'declined';

src/lib/utils.ts (lines 5-7)

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

Comment thread src/components/golf/calendar/MobileEventCard.tsx
color: 'amber',
bgColor: 'bg-amber-50/60',
dotColor: 'bg-amber-500',
dotRingColor: 'ring-amber-500/[0.18]',

@coderabbitai coderabbitai Bot Jul 11, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Keep the added ring classes on the approved design-token palette.

The new styles introduce amber, stone, teal, violet, orange, sky, rose, and purple families in src/lib/calendar/event-styles.ts:34-156. These are consumed directly by src/components/golf/calendar/MobileEventCard.tsx:146, but repository guidance permits only primary-*, destructive, warm-*, and cream-*. Map these styles to approved tokens or add sanctioned semantic event tokens before merging.

As per coding guidelines, use only canonical color families: primary-*, destructive, warm-*, and cream-*.

Also applies to: 44-44, 54-54, 64-64, 74-74, 84-84, 94-94, 104-104, 114-114, 124-156

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/calendar/event-styles.ts` at line 34, Update the event style
definitions in event-styles.ts, including dotRingColor and the related amber,
stone, teal, violet, orange, sky, rose, and purple entries, to use only
canonical primary-*, destructive, warm-*, or cream-* classes. Preserve each
style’s intended semantic role and ensure MobileEventCard continues consuming
valid approved token classes.

Source: Coding guidelines

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Skipped deliberately: the amber/stone/teal/violet/orange/sky/rose/purple families are pre-existing in event-styles.ts — this PR only added a dotRingColor mirroring each entry's existing dotColor family. They are the sanctioned categorical event-type palette that EventCard (desktop) has consumed all along; the canonical-family rule (helm/no-banned-color) bans the legacy green aliases (helm-green-*, sf-green, emerald-*, raw green-*, #DC2626), not data-viz accent families, and ESLint passes on this file. Collapsing 13 event types onto 4 neutral families would destroy type distinguishability — if the palette should be re-tokenized, that's a design-system-wide change, not this bug-fix PR.


Generated by Claude Code

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@njrini99-code Fair point, and I've confirmed it against the file: every one of the flagged families (amber, stone, teal, violet, orange, sky, rose, purple) already exists on the corresponding dotColor/bgColor/textColor keys prior to this PR — this diff only adds dotRingColor mirroring the existing family per entry (e.g., qualifier.dotColor: 'bg-amber-500'dotRingColor: 'ring-amber-500/[0.18]'). No new color family is introduced. Since these are the established categorical event-type accents already consumed by the desktop EventCard, flagging them under the canonical UI-token rule was out of scope for this fix. Withdrawing the concern.

@njrini99-code njrini99-code changed the title fix(calendar): mobile clip + retired accent-stripe card — shared golf/baseball surface fix(golf,baseball): calendar mobile clip + retired accent-stripe card Jul 11, 2026
CodeRabbit on #806: callers index the config with raw DB strings cast to
EventType, so an inherited key ('__proto__', 'constructor') would resolve
to a truthy prototype object with undefined styling fields instead of the
'other' fallback. Guard with hasOwnProperty so every consumer gets a
complete config.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019WJ1Gzjj9MT3UsxhMoMzSV

Copy link
Copy Markdown
Owner Author

@coderabbitai review


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

@njrini99-code Got it, I'll review the changes now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@njrini99-code njrini99-code marked this pull request as ready for review July 12, 2026 01:34
@njrini99-code njrini99-code merged commit a65001b into main Jul 12, 2026
45 of 46 checks passed
@njrini99-code njrini99-code deleted the fix/calendar-mobile-clip-stripe branch July 12, 2026 01:34
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix mobile calendar clipping and unify event card dot styling

🐞 Bug fix ✨ Enhancement 🕐 20-40 Minutes

Grey Divider

AI Description

• Allow the calendar header to shrink so the Today control doesn’t clip on mobile.
• Prevent notification bell unread badge clipping by overriding Button overflow on the trigger.
• Replace retired accent-stripe mobile event cards with ringed-dot tokens; add showcase/tryout
 types.
Diagram

graph TD
  A["PremiumCalendarClient"] --> B["CalendarHeader (w-full)"]
  A --> C["NotificationCenter (overflow-visible)"] --> D["Button primitive (ripple)"]
  A --> E["MobileEventCard (ringed dot)"] --> F["event-styles tokens"] --> G["calendar types"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Remove/replace overflow-hidden in Button primitive
  • ➕ Would eliminate the need for per-instance overflow overrides
  • ➕ Prevents future badge/tooltip clipping across the app
  • ➖ Higher blast radius: could break ripple containment and visual assumptions
  • ➖ Requires broader audit of components relying on overflow-hidden behavior
2. Wrap bell button in an overflow-visible container and position badge relative to wrapper
  • ➕ Keeps Button primitive untouched while ensuring badge visibility
  • ➕ Can be reused for other icon+badge patterns
  • ➖ More markup/positioning complexity and easy to drift from the design system
  • ➖ Badge alignment becomes a wrapper-specific concern rather than a simple class override

Recommendation: Keep the current approach: instance-scoped overflow-visible on the bell trigger is the lowest-risk fix that preserves the Button primitive’s ripple containment everywhere else. If badge/tooltip clipping recurs in multiple places, then consider the more systemic Button primitive redesign (ripple via pseudo-element or separate layer) as a follow-up.

Files changed (5) +68 / -26

Enhancement (3) +59 / -23
MobileEventCard.tsxReplace accent stripe with ringed event-type dot via shared tokens +14/-22

Replace accent stripe with ringed event-type dot via shared tokens

• Removes the local accent-stripe color switch and the left-side stripe element. Adds a leading ringed dot next to the event title, sourcing dot and ring colors from 'getEventTypeConfig', with 'EventType' typing for the event_type string.

src/components/golf/calendar/MobileEventCard.tsx

event-styles.tsAdd dot ring token, new baseball event types, and safer config lookup +41/-1

Add dot ring token, new baseball event types, and safer config lookup

• Extends all event type configs with a 'dotRingColor' field and adds configs for 'showcase' and 'tryout'. Hardens 'getEventTypeConfig' with an own-key guard to ensure unknown/raw strings (or inherited keys) correctly fall back to 'other'.

src/lib/calendar/event-styles.ts

calendar.tsExtend calendar typing for dot ring and baseball recruiting types +4/-0

Extend calendar typing for dot ring and baseball recruiting types

• Adds 'showcase' and 'tryout' to the 'EventType' union and adds 'dotRingColor' to 'EventTypeConfig', aligning type contracts with the updated shared event-style tokens.

src/lib/types/calendar.ts

Bug fix (2) +9 / -3
NotificationCenter.tsxFix unread badge clipping by overriding Button overflow +4/-2

Fix unread badge clipping by overriding Button overflow

• Updates the bell trigger Button to use 'overflow-visible', overriding the primitive’s ripple-containing 'overflow-hidden' so the absolute-positioned unread badge is no longer cut off on mobile.

src/components/golf/calendar/NotificationCenter.tsx

page-header.tsxAllow CalendarHeader to shrink within PremiumCalendarClient row +5/-1

Allow CalendarHeader to shrink within PremiumCalendarClient row

• Replaces 'flex-shrink-0' with 'w-full' on the CalendarHeader root while preserving 'min-w-0', allowing the header controls to compress and the title to truncate instead of clipping the Today control inside overflow-hidden containers.

src/components/ui/page-header.tsx

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📜 Skill insights (2)

Context used
✅ Compliance rules (platform): 98 rules

Grey Divider


Action required

1. Bell icon Button lacks tooltip 📜 Skill insight ☑ Accessibility
Description
The icon-only bell Button has an aria-label but is not wrapped in a tooltip component. This
fails the requirement that icon-only buttons provide both a screen-reader label and a visible
tooltip.
Code

src/components/golf/calendar/NotificationCenter.tsx[R154-159]

      <Button variant="ghost"
        onClick={handleToggle}
-        className="relative p-2.5 rounded-xl bg-cream-100/75 backdrop-blur-sm border border-warm-200/45 shadow-sm text-warm-500 hover:text-warm-800 hover:bg-cream-50/92 hover:shadow-md active:scale-95 transition-all duration-200"
+        className="relative overflow-visible p-2.5 rounded-xl bg-cream-100/75 backdrop-blur-sm border border-warm-200/45 shadow-sm text-warm-500 hover:text-warm-800 hover:bg-cream-50/92 hover:shadow-md active:scale-95 transition-all duration-200"
        aria-label={unreadCount > 0 ? `Notifications, ${unreadCount} unread` : 'Notifications'}
        aria-expanded={isOpen}
      >
Relevance

⭐⭐ Medium

A11y work enforces aria-labels (PR #166), but no evidence of tooltip requirement enforcement.

PR-#166

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1519430 requires icon-only buttons to include a tooltip and a screen-reader label.
The changed button shows only <IconBell /> content and no tooltip wrapper around it.

src/components/golf/calendar/NotificationCenter.tsx[149-161]
Skill: modern-saas-ui

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The notification bell is an icon-only button without a tooltip.

## Issue Context
Compliance requires icon-only buttons to include both an accessible label and a tooltip for sighted users.

## Fix Focus Areas
- src/components/golf/calendar/NotificationCenter.tsx[149-172]
- src/components/ui/tooltip.tsx[57-80]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Showcase type unstyled 🐞 Bug ≡ Correctness
Description
The PR adds showcase as an EventType and defines its violet styling via getEventTypeConfig,
but the premium grid cards render via PremiumEventBlockpremium-utilscalendar-tokens.css,
where showcase is not mapped. As a result, showcase events will fall back to event-type-other
and the other dot color in week/month/day views, diverging from the new config-based styling used
elsewhere (e.g., MobileEventCard).
Code

src/lib/types/calendar.ts[R18-19]

+  | 'showcase'   // Baseball-specific (recruiting-facing — event-ink 'pursuit')
+  | 'tryout'     // Baseball-specific (recruiting-facing — event-ink 'pursuit')
Relevance

⭐⭐⭐ High

Calendar correctness issues are accepted; PR #806 accepted EventType handling fixes, so missing
showcase mapping likely accepted.

PR-#806
PR-#20
PR-#259

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR introduces showcase as a supported calendar event type and assigns it explicit styling in
event-styles.ts. However, the premium grid event renderer (PremiumEventBlock used by
WeekView/MonthView) does not use getEventTypeConfig; it uses premium-utils to map event_type
to CSS classes/tokens. premium-utils and calendar-tokens.css do not include showcase, so
showcase events fall back to other styling in those views.

src/lib/types/calendar.ts[5-20]
src/lib/calendar/event-styles.ts[118-149]
src/components/golf/calendar/PremiumEventBlock.tsx[15-94]
src/components/golf/calendar/WeekView.tsx[404-423]
src/components/golf/calendar/MonthView.tsx[81-114]
src/lib/calendar/premium-utils.ts[14-38]
src/lib/calendar/premium-utils.ts[72-79]
src/styles/calendar-tokens.css[9-27]
src/styles/calendar-tokens.css[171-180]
src/components/baseball/calendar/CalendarFairway.tsx[34-49]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`showcase` was added as a first-class `EventType` with styling in `event-styles.ts`, but the premium grid renderer (Week/Month/Day views) still derives its type ribbon + dot color from `src/lib/calendar/premium-utils.ts` and `src/styles/calendar-tokens.css`. Those legacy maps/tokens do not include `showcase`, so `showcase` falls back to the neutral `other` styling.

### Issue Context
- `PremiumEventBlock` is used in WeekView and MonthView, and it calls `getEventClasses()` and `getEventDotColorVar()` from `premium-utils`.
- `premium-utils` currently only recognizes baseball types up through `tryout`.
- `calendar-tokens.css` defines `--event-*` tokens and `.event-type-*` classes, also only up through `tryout`.

### Fix Focus Areas
- src/lib/calendar/premium-utils.ts[14-38]
- src/lib/calendar/premium-utils.ts[72-79]
- src/styles/calendar-tokens.css[9-27]
- src/styles/calendar-tokens.css[171-180]

### Suggested fix
1. Add `showcase` to `typeMap` in `getEventTypeClass()` (e.g., `showcase: 'event-type-showcase'`).
2. Add `showcase` to the `known` set in `getEventDotColorVar()`.
3. Define `--event-showcase` in `calendar-tokens.css` using a violet consistent with `event-styles.ts` (e.g., `theme(colors.violet.500)`), and add `.event-type-showcase { border-left-color: var(--event-showcase); }`.
4. (Optional but recommended) Update the header comment in `calendar-tokens.css` to include `showcase` in the listed baseball DB types, to keep the “canonical source” documentation accurate.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. EventType imported from subpath 📘 Rule violation ⚙ Maintainability
Description
MobileEventCard imports the EventType type from @/lib/types/calendar instead of the required
@/lib/types entrypoint. This fragments shared type imports and violates the standardized type
import path requirement.
Code

src/components/golf/calendar/MobileEventCard.tsx[R25-27]

+import { formatTime, getEventTypeConfig } from '@/lib/calendar/event-styles';
+import type { EventType } from '@/lib/types/calendar';
import type { CalendarEvent } from '@/hooks/useCalendarEvents';
Relevance

⭐ Low

Same type-import barrel suggestion was rejected in PR #806 and earlier similar cases.

PR-#806
PR-#290
PR-#776

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1519311 requires type imports to use @/lib/types and disallows
alternate/deprecated paths. The changed import in MobileEventCard.tsx adds a type-only import from
@/lib/types/calendar, violating that requirement.

Rule 1519311: Type imports must use '@/lib/types' and disallow deprecated paths
src/components/golf/calendar/MobileEventCard.tsx[25-27]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`EventType` is imported from `@/lib/types/calendar` instead of the required `@/lib/types` barrel.

## Issue Context
Compliance requires shared type imports to come from `@/lib/types` (not subpaths like `@/lib/types/calendar`).

## Fix Focus Areas
- src/components/golf/calendar/MobileEventCard.tsx[25-27]
- src/lib/types/index.ts[1-30]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Bell Button uses raw glass 📜 Skill insight ⚙ Maintainability
Description
NotificationCenter's bell Button uses raw glass styling (backdrop-blur-sm + translucent
background) and non-standard spacing/timing utilities (p-2.5, duration-200) instead of the
approved tokens/utilities. This diverges from the design-system conventions required by the
checklist.
Code

src/components/golf/calendar/NotificationCenter.tsx[R154-157]

      <Button variant="ghost"
        onClick={handleToggle}
-        className="relative p-2.5 rounded-xl bg-cream-100/75 backdrop-blur-sm border border-warm-200/45 shadow-sm text-warm-500 hover:text-warm-800 hover:bg-cream-50/92 hover:shadow-md active:scale-95 transition-all duration-200"
+        className="relative overflow-visible p-2.5 rounded-xl bg-cream-100/75 backdrop-blur-sm border border-warm-200/45 shadow-sm text-warm-500 hover:text-warm-800 hover:bg-cream-50/92 hover:shadow-md active:scale-95 transition-all duration-200"
        aria-label={unreadCount > 0 ? `Notifications, ${unreadCount} unread` : 'Notifications'}
Relevance

⭐ Low

Token/utility policing (radius/spacing/blur/colors) is consistently rejected in UI reviews.

PR-#274
PR-#290
PR-#797

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1555264 requires using the approved .glass-* utilities instead of ad-hoc
backdrop-blur-* + translucent background styling. PR Compliance IDs 1519417 and 1519442 require
spacing and duration utilities to follow the defined scales; the modified className includes
p-2.5 and duration-200.

Rule 1555264: Use glass utility classes instead of raw Tailwind glass styles
src/components/golf/calendar/NotificationCenter.tsx[151-157]
Skill: modern-saas-ui

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The bell `Button` uses raw Tailwind glass styles plus non-standard spacing (`p-2.5`) and timing (`duration-200`) utilities.

## Issue Context
The repo defines standardized glass utilities (`.glass-subtle`/`.glass-standard`/`.glass-prominent`) and a strict spacing/timing scale.

## Fix Focus Areas
- src/components/golf/calendar/NotificationCenter.tsx[151-157]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines 154 to 159
<Button variant="ghost"
onClick={handleToggle}
className="relative p-2.5 rounded-xl bg-cream-100/75 backdrop-blur-sm border border-warm-200/45 shadow-sm text-warm-500 hover:text-warm-800 hover:bg-cream-50/92 hover:shadow-md active:scale-95 transition-all duration-200"
className="relative overflow-visible p-2.5 rounded-xl bg-cream-100/75 backdrop-blur-sm border border-warm-200/45 shadow-sm text-warm-500 hover:text-warm-800 hover:bg-cream-50/92 hover:shadow-md active:scale-95 transition-all duration-200"
aria-label={unreadCount > 0 ? `Notifications, ${unreadCount} unread` : 'Notifications'}
aria-expanded={isOpen}
>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Bell icon button lacks tooltip 📜 Skill insight ☑ Accessibility

The icon-only bell Button has an aria-label but is not wrapped in a tooltip component. This
fails the requirement that icon-only buttons provide both a screen-reader label and a visible
tooltip.
Agent Prompt
## Issue description
The notification bell is an icon-only button without a tooltip.

## Issue Context
Compliance requires icon-only buttons to include both an accessible label and a tooltip for sighted users.

## Fix Focus Areas
- src/components/golf/calendar/NotificationCenter.tsx[149-172]
- src/components/ui/tooltip.tsx[57-80]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/lib/types/calendar.ts
Comment on lines +18 to +19
| 'showcase' // Baseball-specific (recruiting-facing — event-ink 'pursuit')
| 'tryout' // Baseball-specific (recruiting-facing — event-ink 'pursuit')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

4. Showcase type unstyled 🐞 Bug ≡ Correctness

The PR adds showcase as an EventType and defines its violet styling via getEventTypeConfig,
but the premium grid cards render via PremiumEventBlockpremium-utilscalendar-tokens.css,
where showcase is not mapped. As a result, showcase events will fall back to event-type-other
and the other dot color in week/month/day views, diverging from the new config-based styling used
elsewhere (e.g., MobileEventCard).
Agent Prompt
### Issue description
`showcase` was added as a first-class `EventType` with styling in `event-styles.ts`, but the premium grid renderer (Week/Month/Day views) still derives its type ribbon + dot color from `src/lib/calendar/premium-utils.ts` and `src/styles/calendar-tokens.css`. Those legacy maps/tokens do not include `showcase`, so `showcase` falls back to the neutral `other` styling.

### Issue Context
- `PremiumEventBlock` is used in WeekView and MonthView, and it calls `getEventClasses()` and `getEventDotColorVar()` from `premium-utils`.
- `premium-utils` currently only recognizes baseball types up through `tryout`.
- `calendar-tokens.css` defines `--event-*` tokens and `.event-type-*` classes, also only up through `tryout`.

### Fix Focus Areas
- src/lib/calendar/premium-utils.ts[14-38]
- src/lib/calendar/premium-utils.ts[72-79]
- src/styles/calendar-tokens.css[9-27]
- src/styles/calendar-tokens.css[171-180]

### Suggested fix
1. Add `showcase` to `typeMap` in `getEventTypeClass()` (e.g., `showcase: 'event-type-showcase'`).
2. Add `showcase` to the `known` set in `getEventDotColorVar()`.
3. Define `--event-showcase` in `calendar-tokens.css` using a violet consistent with `event-styles.ts` (e.g., `theme(colors.violet.500)`), and add `.event-type-showcase { border-left-color: var(--event-showcase); }`.
4. (Optional but recommended) Update the header comment in `calendar-tokens.css` to include `showcase` in the listed baseball DB types, to keep the “canonical source” documentation accurate.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants