Skip to content

Discount banner#5100

Merged
colegottdank merged 5 commits intomainfrom
discount-banner
Oct 22, 2025
Merged

Discount banner#5100
colegottdank merged 5 commits intomainfrom
discount-banner

Conversation

@colegottdank
Copy link
Collaborator

No description provided.

@vercel
Copy link

vercel bot commented Oct 22, 2025

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

Project Deployment Preview Comments Updated (UTC)
helicone Ready Ready Preview Comment Oct 22, 2025 9:23pm
helicone-eu Ready Ready Preview Comment Oct 22, 2025 9:23pm
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
helicone-bifrost Skipped Skipped Oct 22, 2025 9:23pm

@claude
Copy link
Contributor

claude bot commented Oct 22, 2025

Claude finished @colegottdank's task —— View job


Code Review Complete

Score: 6/10 - Good implementation with design system improvements, but contains critical UX bug and minor issues

Critical Issues Found:

1. Logic Bug in Dashboard State Management (web/components/templates/dashboard/dashboardPage.tsx:318)

const [gatewayDiscountDismissed, setGatewayDiscountDismissed] = useState(false);

Problem: State is never initialized from sessionStorage, causing dismissed banners to reappear on component remount.

Fix: Initialize state from sessionStorage:

const [gatewayDiscountDismissed, setGatewayDiscountDismissed] = useState(() => {
  if (typeof window !== "undefined") {
    return sessionStorage.getItem("gateway-discount-dismissed") === "true";
  }
  return false;
});

2. Unused Constant (web/components/templates/dashboard/dashboardPage.tsx:48)

const GATEWAY_DISCOUNT_MIN = 0.10; // 10% - Never used

Fix: Remove the unused constant or implement it if the discount range was intended to be configurable.

Positive Aspects:

Clean Database Migration: The SQL migration follows best practices with proper column defaults
Type Safety: New gateway_discount_enabled field properly added to all type definitions
Design System Compliance: Good use of semantic color tokens and typography components
Proper Security: No sensitive data exposure, safe external link handling with noopener,noreferrer
Performance: Efficient banner logic with proper memoization in authLayout.tsx

Suggestions Summary:

Critical Fixes Needed:

  • Fix sessionStorage initialization bug in dashboard state
  • Remove unused GATEWAY_DISCOUNT_MIN constant

Code Quality Improvements:

  • The redundant sessionStorage check on line 541 becomes unnecessary after fixing the state initialization
  • Consider extracting banner dismissal logic into a custom hook for reusability
  • The inline discount CTA styling looks good but could benefit from consistent hover states

Minor Observations:

  • Good separation of concerns between top banner (authLayout) and inline CTA (dashboard)
  • Proper accessibility with aria-label on dismiss buttons
  • Clean styling migration from hardcoded colors to theme tokens in other dashboard panels

The implementation correctly follows Helicone's design patterns and the feature works as intended, but the state management bug significantly impacts user experience by causing dismissed banners to reappear.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Summary

This PR implements a promotional discount banner feature for organizations eligible for AI Gateway discounts. The implementation adds a new gateway_discount_enabled boolean column to the organization table and displays discount messaging in two locations: a dismissible top banner (when enabled) and an inline call-to-action in the dashboard's cost panel.

Key Changes:

  • Database migration adds gateway_discount_enabled flag to organization table
  • Top banner displays "Save 10-20% on your inference costs for 6 months" message with Calendly link
  • Inline discount CTA in costs panel shows calculated savings based on 20% of current costs
  • Both banners are dismissible and use sessionStorage to persist dismissal
  • Styling updates across dashboard panels to use theme-aware CSS tokens instead of hardcoded colors

Issues Found:

  • Logic bug in dashboardPage.tsx:540-541 where state initialization doesn't read from sessionStorage, causing dismissed banners to reappear on component remount
  • Unused constant GATEWAY_DISCOUNT_MIN defined but never referenced in the code

Confidence Score: 3/5

  • This PR has a logic bug that will cause user experience issues but won't break functionality
  • Score reflects a functional implementation with good database migration and type safety, but contains a critical UX bug where the inline discount banner will reappear on every dashboard remount because the state isn't initialized from sessionStorage. The unused constant is a minor code quality issue.
  • web/components/templates/dashboard/dashboardPage.tsx requires attention to fix the sessionStorage initialization bug

Important Files Changed

File Analysis

Filename Score Overview
supabase/migrations/20251022200052_gateway_discount_column.sql 5/5 Added gateway_discount_enabled boolean column to organization table with default false
web/components/layout/auth/MainContent.tsx 5/5 Added dismissible banner support with close button and styling adjustments
web/components/layout/auth/authLayout.tsx 4/5 Added gateway discount banner for eligible orgs with sessionStorage dismissal logic
web/components/templates/dashboard/dashboardPage.tsx 3/5 Added inline discount CTA in costs panel with unused GATEWAY_DISCOUNT_MIN constant and redundant sessionStorage check

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant AuthLayout
    participant Dashboard
    participant MainContent
    participant SessionStorage
    participant Database

    User->>Browser: Navigate to app
    Browser->>Database: Fetch organization data
    Database-->>Browser: Return org with gateway_discount_enabled flag
    
    alt gateway_discount_enabled === true
        Browser->>AuthLayout: Render with org context
        AuthLayout->>SessionStorage: Check gateway-discount-banner-dismissed
        
        alt Banner not dismissed
            AuthLayout->>MainContent: Pass banner prop with dismissible=true
            MainContent->>User: Display top banner with discount offer
            
            alt User clicks banner
                User->>MainContent: Click banner
                MainContent->>Browser: Open Calendly in new tab
            end
            
            alt User dismisses banner
                User->>MainContent: Click dismiss button
                MainContent->>SessionStorage: Set gateway-discount-banner-dismissed=true
                MainContent->>AuthLayout: Update bannerDismissed state
                MainContent->>User: Hide banner
            end
        end
        
        Browser->>Dashboard: Render dashboard with org context
        Dashboard->>SessionStorage: Check gateway-discount-dismissed
        
        alt Inline discount not dismissed
            Dashboard->>User: Show inline discount under Costs panel
            
            alt User dismisses inline discount
                User->>Dashboard: Click dismiss button
                Dashboard->>SessionStorage: Set gateway-discount-dismissed=true
                Dashboard->>User: Hide inline discount
            end
        end
    end
Loading

17 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

import { Cloud } from "lucide-react";

// Gateway discount configuration
const GATEWAY_DISCOUNT_MIN = 0.10; // 10%
Copy link
Contributor

Choose a reason for hiding this comment

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

style: GATEWAY_DISCOUNT_MIN is unused

Suggested change
const GATEWAY_DISCOUNT_MIN = 0.10; // 10%
const GATEWAY_DISCOUNT_MAX = 0.20; // 20%
Prompt To Fix With AI
This is a comment left during a code review.
Path: web/components/templates/dashboard/dashboardPage.tsx
Line: 48:48

Comment:
**style:** `GATEWAY_DISCOUNT_MIN` is unused

```suggestion
const GATEWAY_DISCOUNT_MAX = 0.20; // 20%
```

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

Comment on lines +540 to +541
!gatewayDiscountDismissed &&
!sessionStorage.getItem("gateway-discount-dismissed") && (
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: redundant check - gatewayDiscountDismissed state is never initialized from sessionStorage, so it will always be false on mount even if the user previously dismissed the banner

Prompt To Fix With AI
This is a comment left during a code review.
Path: web/components/templates/dashboard/dashboardPage.tsx
Line: 540:541

Comment:
**logic:** redundant check - `gatewayDiscountDismissed` state is never initialized from `sessionStorage`, so it will always be `false` on mount even if the user previously dismissed the banner

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

@vercel vercel bot temporarily deployed to Preview – helicone-bifrost October 22, 2025 21:17 Inactive
@colegottdank colegottdank merged commit 87798b1 into main Oct 22, 2025
10 checks passed
@colegottdank colegottdank deleted the discount-banner branch October 22, 2025 21:27
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.

1 participant