feat(frontend): redesign the sign-in screen for the agent workspace positioning#5386
feat(frontend): redesign the sign-in screen for the agent workspace positioning#5386mmabrouk wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
📝 WalkthroughWalkthroughThe PR redesigns the authentication experience, remembers the last successful authentication method, promotes returning sign-in options, adds scoped auth styling and display-font configuration, and updates document titles. ChangesAuthentication redesign
Branding titles
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Visitor
participant AuthPage
participant Storage
participant AuthProvider
participant PostAuth
Visitor->>AuthPage: Open authentication page
AuthPage->>Storage: Read last authentication method
Storage-->>AuthPage: Return email or provider id
AuthPage->>AuthProvider: Render promoted authentication option
Visitor->>AuthProvider: Complete authentication
AuthProvider->>PostAuth: Submit authMethod
PostAuth->>Storage: Persist last authentication method
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
web/oss/src/components/pages/auth/RegionSelector/index.tsx (1)
50-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReplace static inline icon sizes with Tailwind utilities.
web/oss/src/components/pages/auth/RegionSelector/index.tsx#L50-L50: replacestyle={{fontSize: 14}}withclassName="text-sm".web/oss/src/components/pages/auth/SideBanner/index.tsx#L22-L22: replacestyle={{fontSize: 13}}withclassName="text-[13px]".As per coding guidelines, “Prefer Tailwind utility classes over CSS-in-JS, separate CSS files, inline styles,
react-jss, orstyled-components.”Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c91b865e-4ec2-49cf-83dc-00be5171d3c6
⛔ Files ignored due to path filters (14)
web/ee/public/assets/fonts/Fraunces-VF.woff2is excluded by!**/*.woff2web/ee/public/assets/logos/Agenta-logo-full-dark-accent.svgis excluded by!**/*.svgweb/ee/public/assets/logos/Agenta-logo-full-dark.svgis excluded by!**/*.svgweb/ee/public/assets/logos/Agenta-logo-full-light.svgis excluded by!**/*.svgweb/ee/public/assets/logos/Agenta-symbol-dark-accent.svgis excluded by!**/*.svgweb/ee/public/assets/logos/Agenta-symbol-dark.svgis excluded by!**/*.svgweb/ee/public/assets/logos/Agenta-symbol-light.svgis excluded by!**/*.svgweb/oss/public/assets/fonts/Fraunces-VF.woff2is excluded by!**/*.woff2web/oss/public/assets/logos/Agenta-logo-full-dark-accent.svgis excluded by!**/*.svgweb/oss/public/assets/logos/Agenta-logo-full-dark.svgis excluded by!**/*.svgweb/oss/public/assets/logos/Agenta-logo-full-light.svgis excluded by!**/*.svgweb/oss/public/assets/logos/Agenta-symbol-dark-accent.svgis excluded by!**/*.svgweb/oss/public/assets/logos/Agenta-symbol-dark.svgis excluded by!**/*.svgweb/oss/public/assets/logos/Agenta-symbol-light.svgis excluded by!**/*.svg
📒 Files selected for processing (19)
web/ee/public/assets/fonts/OFL.txtweb/ee/src/components/Scripts/assets/CloudScripts.tsxweb/oss/public/assets/fonts/OFL.txtweb/oss/src/components/Scripts/GlobalScripts.tsxweb/oss/src/components/pages/auth/EmailFirst/index.tsxweb/oss/src/components/pages/auth/EmailPasswordAuth/index.tsxweb/oss/src/components/pages/auth/EmailPasswordSignIn/index.tsxweb/oss/src/components/pages/auth/RegionSelector/index.tsxweb/oss/src/components/pages/auth/SendOTP/index.tsxweb/oss/src/components/pages/auth/SideBanner/index.tsxweb/oss/src/components/pages/auth/SocialAuth/index.tsxweb/oss/src/components/pages/auth/assets/lastAuthMethod.test.tsweb/oss/src/components/pages/auth/assets/lastAuthMethod.tsweb/oss/src/components/pages/auth/assets/types.d.tsweb/oss/src/hooks/usePostAuthRedirect.tsweb/oss/src/pages/auth/[[...path]].tsxweb/oss/src/pages/auth/callback/[[...callback]].tsxweb/oss/src/styles/auth.cssweb/oss/src/styles/globals.css
| <Form.Item | ||
| name="email" | ||
| className="[&_.ant-form-item-required]:before:!hidden w-full mb-0 flex flex-col gap-1" | ||
| rules={[ | ||
| {required: true, message: "Please add your email!"}, | ||
| {type: "email", message: "Please enter a valid email address!"}, | ||
| ]} | ||
| > | ||
| <Form.Item | ||
| name="email" | ||
| className="[&_.ant-form-item-required]:before:!hidden [&_.ant-form-item-required]:font-medium w-full mb-0 flex flex-col gap-1" | ||
| rules={[ | ||
| {required: true, message: "Please add your email!"}, | ||
| {type: "email", message: "Please enter a valid email address!"}, | ||
| ]} | ||
| > | ||
| <div className="relative"> | ||
| <Input | ||
| size="large" | ||
| type="email" | ||
| value={email} | ||
| placeholder="Enter your email address" | ||
| status={message.type === "error" ? "error" : ""} | ||
| onChange={(e) => setEmail(e.target.value)} | ||
| disabled={disabled} | ||
| className={clsx("auth-input", promoted && "auth-input-promoted")} | ||
| /> | ||
| </Form.Item> | ||
| {promoted && ( | ||
| <span className="auth-last-used-tag absolute right-3 top-1/2 -translate-y-1/2"> | ||
| Last used | ||
| </span> | ||
| )} | ||
| </div> | ||
| </Form.Item> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
ast-grep outline web/oss/src/components/pages/auth/EmailFirst/index.tsx \
--match EmailFirst --view expanded
sed -n '41,81p' web/oss/src/components/pages/auth/EmailFirst/index.tsxRepository: Agenta-AI/agenta
Length of output: 2241
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,220p' web/oss/src/components/pages/auth/EmailFirst/index.tsxRepository: Agenta-AI/agenta
Length of output: 2937
Bind Form.Item directly to the email input. The named item is attached to the wrapper div, so Ant Design never receives the typed value; onFinish can still see the initial email from initialValues. Move name="email" onto the input’s direct Form.Item child, or use noStyle.
| {promotedProvider && ( | ||
| <> | ||
| <SocialAuth | ||
| authErrorMsg={authErrorMsg} | ||
| disabled={isAuthLoading} | ||
| isLoading={isSocialAuthLoading} | ||
| setIsLoading={setIsSocialAuthLoading} | ||
| providers={[promotedProvider]} | ||
| variant="promoted" | ||
| yellow | ||
| lastUsed | ||
| /> | ||
| <div className="auth-divider">or</div> | ||
| </> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Do not render a trailing “or” divider.
When the remembered provider is the only configured method, this branch renders an orphaned divider. Gate it on an available alternative.
- <div className="auth-divider">or</div>
+ {(otherProviders.length > 0 ||
+ (showEmailEntry && shouldShowEmailFlow)) && (
+ <div className="auth-divider">or</div>
+ )}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {promotedProvider && ( | |
| <> | |
| <SocialAuth | |
| authErrorMsg={authErrorMsg} | |
| disabled={isAuthLoading} | |
| isLoading={isSocialAuthLoading} | |
| setIsLoading={setIsSocialAuthLoading} | |
| providers={[promotedProvider]} | |
| variant="promoted" | |
| yellow | |
| lastUsed | |
| /> | |
| <div className="auth-divider">or</div> | |
| </> | |
| {promotedProvider && ( | |
| <> | |
| <SocialAuth | |
| authErrorMsg={authErrorMsg} | |
| disabled={isAuthLoading} | |
| isLoading={isSocialAuthLoading} | |
| setIsLoading={setIsSocialAuthLoading} | |
| providers={[promotedProvider]} | |
| variant="promoted" | |
| yellow | |
| lastUsed | |
| /> | |
| {(otherProviders.length > 0 || | |
| (showEmailEntry && shouldShowEmailFlow)) && ( | |
| <div className="auth-divider">or</div> | |
| )} | |
| </> |
| {ssoProvidersToShow.map((provider) => ( | ||
| <Button | ||
| key={provider.id} | ||
| icon={provider.icon} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
ast-grep outline 'web/oss/src/pages/auth/[[...path]].tsx' \
--match Auth --view expanded
sed -n '61,78p;615,630p' 'web/oss/src/pages/auth/[[...path]].tsx'Repository: Agenta-AI/agenta
Length of output: 2306
🏁 Script executed:
#!/bin/bash
sed -n '1,220p' 'web/oss/src/pages/auth/[[...path]].tsx'Repository: Agenta-AI/agenta
Length of output: 9593
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file='web/oss/src/pages/auth/[[...path]].tsx'
rg -n "ssoProvidersToShow|provider\.icon|formatSsoProviderLabel|redirectToSsoProvider|providers:" "$file"
sed -n '220,420p' "$file"Repository: Agenta-AI/agenta
Length of output: 8367
Remove the undeclared SSO icon access. availableMethods.sso.providers only carries id, slug, and third_party_id, so icon={provider.icon} fails TypeScript. If these buttons need an icon, map it from a known provider list instead.
| /* ── Scoped design tokens ────────────────────────────────────────────────── */ | ||
| .auth-redesign { | ||
| --a-page: #f6f5f3; | ||
| --a-panel: #ffffff; | ||
| --a-panel-ring: #e5e5e3; | ||
| --a-heading: #242424; | ||
| --a-secondary: #676770; | ||
| --a-faint: #a3a19f; | ||
| --a-hairline: #f0efed; | ||
| --a-chip-bg: #f6f5f3; | ||
| --a-chip-ring: #f0efed; | ||
| --a-surface-bg: #ffffff; | ||
| --a-surface-shadow: 0 0 0 1px rgba(72, 70, 68, 0.08), 0 1px 3px rgba(72, 70, 68, 0.08); | ||
| --a-surface-shadow-strong: 0 0 0 1px #a3a19f, 0 1px 3px rgba(72, 70, 68, 0.1); | ||
| --a-tag-bg: #f6f5f3; | ||
| --a-tag-ring: #f0efed; | ||
| --a-tag-text: #676770; | ||
| --a-pill-sel-bg: #242424; | ||
| --a-pill-sel-text: #ffffff; | ||
| --a-yellow: linear-gradient(180deg, #f2f25c 0%, #e7e712 100%); | ||
| --a-yellow-shadow: inset 0 2px 6.4px rgba(255, 255, 255, 0.8); | ||
| } | ||
|
|
||
| .dark .auth-redesign { | ||
| --a-page: #1e1c1d; | ||
| --a-panel: #242220; | ||
| --a-panel-ring: rgba(229, 229, 227, 0.1); | ||
| --a-heading: #ffffff; | ||
| --a-secondary: rgba(255, 255, 255, 0.64); | ||
| --a-faint: rgba(255, 255, 255, 0.4); | ||
| --a-hairline: rgba(229, 229, 227, 0.1); | ||
| --a-chip-bg: rgba(255, 255, 255, 0.06); | ||
| --a-chip-ring: rgba(229, 229, 227, 0.1); | ||
| --a-surface-bg: rgba(255, 255, 255, 0.04); | ||
| --a-surface-shadow: 0 0 0 1px rgba(229, 229, 227, 0.1); | ||
| --a-surface-shadow-strong: 0 0 0 1px rgba(255, 255, 255, 0.28); | ||
| --a-tag-bg: rgba(255, 255, 255, 0.08); | ||
| --a-tag-ring: rgba(229, 229, 227, 0.1); | ||
| --a-tag-text: rgba(255, 255, 255, 0.72); | ||
| --a-pill-sel-bg: #ffffff; | ||
| --a-pill-sel-text: #242424; | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
Source these theme colors from the shared palette.
This adds an independent light/dark token system with raw color values. Define the colors in web/oss/src/styles/theme/palette.ts, regenerate Tailwind tokens, and consume the generated variables here.
As per coding guidelines, “Theme-aware colors must originate from web/oss/src/styles/theme/palette.ts; edit the palette, run pnpm generate:tailwind-tokens, and never hand-edit generated theme files.”
Source: Coding guidelines
Railway Preview Environment
|
…e config, default to Inter
|
Updated per review: removed the vendored display font entirely (no decorative font ships in the repo). Headlines now render in Inter by default (weighted so they look intentional), and the display font is an optional deploy-time setting — set |
|
The first Comment image shows the prior light, split-panel sign-in page: “Welcome to Agenta AI” and Google/email controls on the left, plus “Build Robust AI Applications” with a product mockup on the right. The second Comment image shows the updated Inter-based design: a compact “Welcome to Agenta” form, yellow Continue button, and a bordered marketing panel with the “Open source · GitHub” chip, “Build agents that automate your work” headline, and three feature rows.
✅ Action performedReview finished.
|
There was a problem hiding this comment.
🧹 Nitpick comments (3)
web/oss/src/styles/auth.css (1)
12-34: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuePrefer Tailwind utility classes over separate CSS classes.
As per coding guidelines, prefer Tailwind utility classes over CSS-in-JS, separate CSS files, or inline styles. Consider migrating these typography styles directly to the React components using Tailwind utility classes (e.g.,
font-[...] text-[34px] leading-[40px] font-semibold).Source: Coding guidelines
web/oss/src/pages/auth/[[...path]].tsx (2)
439-445: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRender the
<style>content as children.React can safely handle string children inside
<style>tags. This approach clears the static analysis warning by avoidingdangerouslySetInnerHTML.♻️ Proposed refactor
- {displayFontUrl && ( - <style - dangerouslySetInnerHTML={{ - __html: `@font-face{font-family:"Agenta Display";src:url("${displayFontUrl}");font-weight:300;font-display:swap;}`, - }} - /> - )} + {displayFontUrl && ( + <style>{`@font-face{font-family:"Agenta Display";src:url("${displayFontUrl}");font-weight:300;font-display:swap;}`}</style> + )}Source: Linters/SAST tools
429-431: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueCondense in-code comments to a single line.
As per coding guidelines, keep in-code comments to at most one short line; use longer comments only for genuinely surprising constraints. Please condense or remove these comments if the code is self-explanatory.
web/oss/src/pages/auth/[[...path]].tsx#L429-L431: Condense the entry screen logic comment.web/oss/src/lib/helpers/dynamicEnv.ts#L109-L110: Condense the display font URL comment.Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 81ebd0eb-b3e9-46c0-9069-05d296dc6571
📒 Files selected for processing (5)
web/entrypoint.shweb/oss/src/components/pages/auth/SideBanner/index.tsxweb/oss/src/lib/helpers/dynamicEnv.tsweb/oss/src/pages/auth/[[...path]].tsxweb/oss/src/styles/auth.css
🚧 Files skipped from review as they are similar to previous changes (1)
- web/oss/src/components/pages/auth/SideBanner/index.tsx
mmabrouk
left a comment
There was a problem hiding this comment.
lgtm. should go in the same release with the ui improvements
The problem
The sign-in / sign-up screen still pitched the old product. The heading said "Welcome to Agenta AI", the sub-line read "Your All-In-One LLM Development Platform. Collaborate on prompts, evaluate, and monitor LLM apps with confidence", the marketing panel talked about "Build Robust AI Applications", and the browser tab said "Agenta: The LLMOps platform." Everything a new or returning user saw first contradicted the new positioning: the open-source workspace for building and running agents.
This is a visual restyle plus one small client-side feature (remembering the last-used sign-in method). No auth behavior changed.
Before / after
The flow
States
The screen now serves new and returning users from one layout: auth form left, marketing panel right. Three states, driven entirely client-side by a remembered last-used method.
What changed
GlobalScriptsand the EECloudScriptstitle strings.localStorage.lastAuthMethod("email"for email flows, otherwise the OIDC provider id). Presence flips the screen into the "Welcome back" state and promotes the last-used method with a yellow keycap + "Last used" tag; absence is the first-visit state. Written through the single sharedhandleAuthSuccessfunnel (covers email password, OTP, and the OAuth callback, where the provider id is derived from the callback path). Generalizes to any configured provider, not just Google/GitHub. Small helper moduleassets/lastAuthMethod.tswith a unit test.shouldShowRegionSelector()) and clicking the other region navigates to the sibling host exactly as before. No "Last used" tag on the pills, and no new region state.Display font
Headlines render in Inter by default on every install — weighted (600) with slightly tighter tracking so they read as an intentional choice, not a fallback. Nothing decorative ships in the repo.
An optional display font is a deploy-time setting: point
NEXT_PUBLIC_AGENTA_DISPLAY_FONT_URL(samedynamicEnv/__env.jsroute as the other frontend config, wired throughentrypoint.sh) at a woff2 and the auth page injects an@font-facefor the"Agenta Display"family and switches the headlines to the lighter display treatment (weight 300). Unset, the family falls through to Inter and no font request is made. Proof that the injection path works, with a font served locally (not committed):Flows preserved unchanged (reskinned only)
Email-first discovery (
POST /auth/discover→ reveal password / OTP / SSO), SSO buttons + auto-redirect, invite flows + the invite-email-mismatch warning, theauth_error=upgrade_requiredalert + org switcher (social still shown, email hidden), Turnstile, and the passwordless-demo pre-sent-OTP jump. These change appearance where they surface, not behavior.QA
Verified live on the EE dev stack at 1440×900 in the default (Inter, no font URL) state:
data-display-font="serif", an@font-faceis injected, the woff2 loads (200), and the headlines compute to weight 300 in the display family. With it unset: no data attribute, no@font-face, no font request, no console error.localStorage.lastAuthMethod = "email"; after sign-out the screen showed the returning "Welcome back" + promoted-email state./auth/discover→ 200).Follow-ups / notes
lastAuthMethod, and its write path is the same sharedhandleAuthSuccessfunnel the email path uses (verified live).socialAvailableis false, leaving residency + email only).