Skip to content

[docs] actual api overhaul#1126

Open
madster456 wants to merge 6 commits intodevfrom
docs/actual-api-playground
Open

[docs] actual api overhaul#1126
madster456 wants to merge 6 commits intodevfrom
docs/actual-api-playground

Conversation

@madster456
Copy link
Collaborator

@madster456 madster456 commented Jan 20, 2026

I'm not sure what happened to #1080 but that was supposed to have the UI changes. This contains the actual ui changes now. - I probably never commited the ui changes, and lost them, couldnt find them so redid it.

Summary by CodeRabbit

  • New Features
    • Redesigned API Authentication panel with tabbed "Select Project" and "Manual" flows.
    • Sortable project picker (desktop & mobile) with automatic population of auth headers when a project is selected.
    • Manual header form with per-field validation and inline error banners.
    • Ready/Not configured status indicator and consistent action button.
    • Full mobile-specific UI variants and responsive behavior improvements.

@vercel
Copy link

vercel bot commented Jan 20, 2026

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

Project Deployment Actions Updated (UTC)
stack-backend Ready Ready Preview, Comment Feb 4, 2026 3:49pm
stack-dashboard Ready Ready Preview, Comment Feb 4, 2026 3:49pm
stack-demo Ready Ready Preview, Comment Feb 4, 2026 3:49pm
stack-docs Ready Ready Preview, Comment Feb 4, 2026 3:49pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

A tabbed API Authentication panel was added with "Select Project" and "Manual" modes, project picker (desktop/mobile), automatic admin-token refresh/population when a project is chosen, per-header validation and inline error banners, and responsive status indicators showing Ready / Not configured.

Changes

Cohort / File(s) Summary
API Authentication Panel Redesign
docs/src/components/api/auth-panel.tsx
Adds tabbed UI (Select Project / Manual), desktop & mobile project dropdowns with selection/checkbox UI, client state for selectedProjectId/activeTab/dropdowns, click-outside handling, per-header validation and inline error banners, admin-token refresh/useEffect logic to populate X-Stack-Admin-Access-Token, Ready/Not configured footer status, and layout/styling refactor for responsive behavior.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AuthPanel as Auth Panel UI
    participant Dropdown as Project Dropdown
    participant AdminAPI as Admin API
    participant Status as Status Indicator

    User->>AuthPanel: Open auth panel / switch to "Select Project"
    User->>Dropdown: Open project list
    Dropdown->>Dropdown: Sort projects / show owned projects
    User->>Dropdown: Select project
    Dropdown-->>AuthPanel: emit selectedProjectId
    AuthPanel->>AuthPanel: set headers (X-Stack-Project-Id, X-Stack-Access-Type, ...)
    AuthPanel->>AdminAPI: request admin token refresh (useEffect on header change)
    AdminAPI-->>AuthPanel: return X-Stack-Admin-Access-Token
    AuthPanel->>AuthPanel: populate admin token header
    AuthPanel->>Status: evaluate readiness -> "Ready"
    Status-->>User: display Ready banner
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • N2D4

Poem

🐰 I hopped into tabs both big and small,

Picked a project, watched tokens fall,
Banners blinking, headers trim and neat,
Mobile hops keep everything sweet,
Ready now — let's bound down the API street!

🚥 Pre-merge checks | ❌ 3
❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is largely minimal and lacks the detail expected for documenting significant UI changes affecting the API authentication panel. Expand the description to include specific details about the new tabbed UI, project selection workflow, header redesign, validation states, and mobile-responsive variants for clarity and future reference.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title '[docs] actual api overhaul' is vague and generic, using non-descriptive language that doesn't clearly convey the specific changes made to the authentication panel. Revise the title to be more specific about the main change, such as '[docs] redesign API authentication panel UI with tabbed project selection' to better reflect the scope of modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/actual-api-playground

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 20, 2026

Greptile Overview

Greptile Summary

Implements a tabbed UI overhaul for the API authentication panel, replacing the previous single-view design with a cleaner two-tab interface ("Select Project" and "Manual").

Key changes:

  • Added tabbed navigation between project selection and manual header entry
  • Replaced native <select> dropdown with custom button-based dropdown component featuring search-style UI and checkmark indicators
  • Removed the icon-based header (Key/AlertTriangle icons) in favor of simpler text-only header
  • Updated error banner, status indicators, and success messages with improved styling and positioning
  • Removed auto-populated field indicators and "hideWhenProjectSelected" logic - all fields now show in Manual tab regardless of project selection
  • Added click-outside handler for dropdown with useRef and event listener
  • Changed desktop panel positioning from edge-aligned to inset with rounded corners and shadow
  • Updated footer status indicator logic to show "Ready" vs "Not configured" instead of count

Issues found:

  • State update functions use direct headers object reference instead of functional updates with prevHeaders, which could cause stale state issues in concurrent updates

Confidence Score: 4/5

  • Safe to merge with minor state management improvements recommended
  • The PR implements primarily visual/UI changes with well-structured React patterns. Two state update issues were found where direct object references are used instead of functional updates, but these are unlikely to cause problems in typical usage. The component maintains backward compatibility and all business logic remains intact.
  • The state updates on lines 365 and 560 should use functional form to prevent potential stale state issues

Important Files Changed

Filename Overview
docs/src/components/api/auth-panel.tsx Complete UI overhaul for API authentication panel with tabbed interface, custom dropdown, and improved styling - primarily visual changes with one notable logic issue

Sequence Diagram

sequenceDiagram
    participant User
    participant AuthPanel
    participant SidebarContext
    participant APIContext
    participant InternalUser

    User->>SidebarContext: toggleAuth()
    SidebarContext->>AuthPanel: isAuthOpen = true
    AuthPanel->>InternalUser: useOwnedProjects()
    InternalUser-->>AuthPanel: projects[]
    
    alt Select Project Tab
        User->>AuthPanel: Click "Select Project" tab
        AuthPanel->>AuthPanel: setActiveTab('select-project')
        User->>AuthPanel: Open dropdown
        AuthPanel->>AuthPanel: setIsDropdownOpen(true)
        User->>AuthPanel: Click project
        AuthPanel->>AuthPanel: handleProjectSelect(projectId)
        AuthPanel->>InternalUser: user.getAuthJson()
        InternalUser-->>AuthPanel: { accessToken }
        AuthPanel->>APIContext: updateSharedHeaders({...headers, admin token})
        APIContext-->>AuthPanel: Headers updated
        AuthPanel->>AuthPanel: setIsDropdownOpen(false)
    else Manual Tab
        User->>AuthPanel: Click "Manual" tab
        AuthPanel->>AuthPanel: setActiveTab('manual')
        User->>AuthPanel: Enter header values
        AuthPanel->>APIContext: updateSharedHeaders({...headers, [key]: value})
        APIContext-->>AuthPanel: Headers updated
    end
    
    AuthPanel->>User: Display status indicator (Ready/Not configured)
Loading

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.

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@docs/src/components/api/auth-panel.tsx`:
- Around line 467-506: The mobile dropdown's container div (rendered when
isDropdownOpen is true) is missing the dropdownRef used by the click-outside
handler, so clicks outside won't close it; attach the same dropdownRef (or a new
ref wired into the same click-outside logic) to the dropdown wrapper element
that renders the project list (the absolute top-full left-0 right-0 div) and
ensure the click-outside handler toggles setIsDropdownOpen(false) when events
occur outside that ref; this uses the existing dropdownRef, isDropdownOpen, and
setIsDropdownOpen identifiers referenced in the component.
- Line 6: Replace the lucide-react import in auth-panel.tsx with the local
bundled icons from icons.tsx: remove "AlertTriangle, Check, ChevronDown, X"
import and instead import "TriangleAlert, Check, ChevronDown, X" from the local
icons export; update any usages of AlertTriangle to TriangleAlert to match the
local export and ensure lucide-react is no longer referenced in this file.
🧹 Nitpick comments (4)
docs/src/components/api/auth-panel.tsx (4)

159-161: Dead conditional logic.

Both branches of these ternaries evaluate to the same values:

  • topPosition: 'top-0' in both cases
  • height: 'h-screen' and 'h-[calc(100vh)]' are effectively identical

This appears to be leftover from refactoring. Simplify to constants or remove the conditionals entirely.

♻️ Suggested simplification
-  // Calculate position based on homepage and scroll state (same as AIChatDrawer)
-  const topPosition = isHomePage && isScrolled ? 'top-0' : 'top-0';
-  const height = isHomePage && isScrolled ? 'h-screen' : 'h-[calc(100vh)]';
+  // Position constants
+  const topPosition = 'top-0';
+  const height = 'h-screen';

If different values were intended for homepage vs. non-homepage states, please update accordingly.


167-196: Consider memoizing handleProjectSelect.

This function is recreated on every render. While it's not a performance concern since it's only used in click handlers, wrapping it with useCallback would be more consistent with React best practices and prevent unnecessary re-renders if passed to memoized child components in the future.


380-396: Consider extracting repeated status condition.

The condition missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim()) is repeated three times here and again in the mobile footer. Extract to a memoized value for clarity and DRY.

♻️ Suggested refactor
+ const isReady = useMemo(() => 
+   missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim()),
+   [missingRequiredHeaders, headers]
+ );

  {/* Footer Status */}
  <div className="border-t border-fd-border p-4 rounded-b-xl">
    <div className="flex items-center gap-2 text-sm">
      <div className={`w-2 h-2 rounded-full ${
-       missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim())
-         ? 'bg-green-500'
-         : 'bg-fd-muted-foreground'
+       isReady ? 'bg-green-500' : 'bg-fd-muted-foreground'
      }`} />
      <span className={`${
-       missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim())
-         ? 'text-green-600 dark:text-green-400'
-         : 'text-fd-muted-foreground'
+       isReady ? 'text-green-600 dark:text-green-400' : 'text-fd-muted-foreground'
      }`}>
-       {missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim())
-         ? 'Ready'
-         : 'Not configured'}
+       {isReady ? 'Ready' : 'Not configured'}
      </span>
    </div>
  </div>

203-598: Consider extracting shared sub-components to reduce duplication.

The desktop and mobile panels share nearly identical logic for:

  • Tab buttons (lines 226-247, 421-442)
  • Error banner (lines 249-264, 444-459)
  • Project dropdown (lines 269-337, 463-532)
  • Manual input form (lines 339-376, 534-571)
  • Status footer (lines 379-397, 574-596)

Extracting these into reusable sub-components with size/style props would improve maintainability and ensure consistent behavior across both variants.

Copy link
Contributor

@N2D4 N2D4 left a comment

Choose a reason for hiding this comment

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

go to bed :]

Comment on lines +72 to +80
const isOutsideDesktop = dropdownRef.current && !dropdownRef.current.contains(target);
const isOutsideMobile = mobileDropdownRef.current && !mobileDropdownRef.current.contains(target);

// Only close if click is outside both dropdowns (or if the ref doesn't exist for that viewport)
if (
(!dropdownRef.current || isOutsideDesktop) &&
(!mobileDropdownRef.current || isOutsideMobile)
) {
setIsDropdownOpen(false);
Copy link

Choose a reason for hiding this comment

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

Suggested change
const isOutsideDesktop = dropdownRef.current && !dropdownRef.current.contains(target);
const isOutsideMobile = mobileDropdownRef.current && !mobileDropdownRef.current.contains(target);
// Only close if click is outside both dropdowns (or if the ref doesn't exist for that viewport)
if (
(!dropdownRef.current || isOutsideDesktop) &&
(!mobileDropdownRef.current || isOutsideMobile)
) {
setIsDropdownOpen(false);
// Determine which dropdown is currently visible based on viewport
const isDesktopViewport = window.matchMedia('(min-width: 768px)').matches;
if (isDesktopViewport) {
// On desktop, only check the desktop dropdown ref
const isOutsideDesktop = dropdownRef.current && !dropdownRef.current.contains(target);
if (isOutsideDesktop) {
setIsDropdownOpen(false);
}
} else {
// On mobile, only check the mobile dropdown ref
const isOutsideMobile = mobileDropdownRef.current && !mobileDropdownRef.current.contains(target);
if (isOutsideMobile) {
setIsDropdownOpen(false);
}

Click-outside handler uses AND logic that requires clicks to be outside both desktop and mobile dropdowns, preventing dropdown from closing when clicking outside the currently visible one on the hidden viewport.

Fix on Vercel

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