Skip to content

Commit e0fa577

Browse files
feat: simplify onboarding card
1 parent e8a5ac5 commit e0fa577

File tree

9 files changed

+369
-162
lines changed

9 files changed

+369
-162
lines changed

binary/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/package-lock.json

Lines changed: 111 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/package-lock.json

Lines changed: 67 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/vscode/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/vscode/src/stubs/WorkOsAuthProvider.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,6 @@ export class WorkOsAuthProvider implements AuthenticationProvider, Disposable {
206206

207207
public static useOnboardingUri: boolean = false;
208208
get redirectUri() {
209-
if (WorkOsAuthProvider.useOnboardingUri) {
210-
const url = new URL(controlPlaneEnv.APP_URL);
211-
url.pathname = `/auth/${env.uriScheme}-redirect`;
212-
return url.toString();
213-
}
214209
return this.ideRedirectUri;
215210
}
216211

gui/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gui/src/components/OnboardingCard/components/OnboardingModelsAddOnTab.tsx

Lines changed: 91 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,41 @@
1-
import { ArrowPathIcon } from "@heroicons/react/24/outline";
2-
import { useContext, useEffect, useState } from "react";
1+
import { CheckIcon } from "@heroicons/react/24/outline";
2+
import { useContext } from "react";
33
import { Button } from "../..";
4+
import { useAuth } from "../../../context/Auth";
45
import { IdeMessengerContext } from "../../../context/IdeMessenger";
5-
import { getLocalStorage } from "../../../util/localStorage";
6+
import { useAppDispatch } from "../../../redux/hooks";
7+
import { selectFirstHubProfile } from "../../../redux/thunks/selectFirstHubProfile";
68
import { useOnboardingCard } from "../hooks/useOnboardingCard";
79

810
/**
9-
* Models Add-On tab component displaying pricing and tier information
11+
* Models Add-On tab component with two-step onboarding:
12+
* 1. Create Account - Uses auth.login(true) to sign up and redirect back to IDE
13+
* 2. Purchase Credits - Opens /settings/billing to purchase credits
1014
*/
1115
export function OnboardingModelsAddOnTab() {
1216
const ideMessenger = useContext(IdeMessengerContext);
1317
const { close } = useOnboardingCard();
14-
const [isPolling, setIsPolling] = useState(false);
18+
const auth = useAuth();
19+
const dispatch = useAppDispatch();
1520

16-
const isJetbrains = getLocalStorage("ide") === "jetbrains";
21+
const isLoggedIn = !!auth.session;
1722

18-
// Polling effect for JetBrains
19-
// This is because jetbrains doesn't support deeplinking the same way as VS Code
20-
useEffect(() => {
21-
if (!isPolling || !isJetbrains) return;
22-
23-
const interval = setInterval(() => {
24-
ideMessenger.post("config/refreshProfiles", {
25-
reason: "Jetbrains onboarding polling",
26-
selectProfileId: "local",
27-
});
28-
}, 7000);
29-
30-
return () => clearInterval(interval);
31-
}, [isPolling, isJetbrains, ideMessenger]);
32-
33-
async function openBillingSettings() {
34-
try {
35-
await ideMessenger.request("controlPlane/openUrl", {
36-
path: "settings/billing",
37-
});
38-
} catch (error) {
39-
console.error("Error during upgrade process:", error);
40-
} finally {
41-
if (isJetbrains) {
42-
setIsPolling(true);
43-
} else {
44-
close();
23+
function handleCreateAccount() {
24+
void auth.login(true).then((success) => {
25+
if (success) {
26+
// A new assistant is created when the account is created
27+
// Switch to it immediately
28+
void dispatch(selectFirstHubProfile());
29+
ideMessenger.post("showToast", ["info", "Account created!"]);
4530
}
46-
}
31+
});
32+
}
33+
34+
function handlePurchaseCredits() {
35+
ideMessenger.post("controlPlane/openUrl", {
36+
path: "settings/billing",
37+
});
38+
close();
4739
}
4840

4941
function openPricingPage() {
@@ -52,28 +44,14 @@ export function OnboardingModelsAddOnTab() {
5244
});
5345
}
5446

55-
// Show polling UI for JetBrains after upgrade
56-
if (isPolling && isJetbrains) {
57-
return (
58-
<div className="flex h-full w-full flex-col items-center justify-center text-center">
59-
<h2 className="text-foreground mb-4 items-center text-lg font-semibold">
60-
<ArrowPathIcon className="text-foreground animate-spin-slow mr-2 h-4 w-4" />
61-
You may close this dialog after upgrading
62-
</h2>
63-
</div>
64-
);
65-
}
66-
6747
return (
6848
<div className="flex h-full w-full flex-col items-center justify-center text-center">
6949
<div className="mb-4 flex flex-col items-center text-center">
70-
<div className="mb-1">
71-
<h2 className="text-foreground mb-1 text-2xl font-semibold">
72-
Models Add-on
73-
</h2>
74-
</div>
50+
<h2 className="text-foreground mb-1 text-2xl font-semibold">
51+
Models Add-on
52+
</h2>
7553

76-
<span className="text-description text-base">
54+
<span className="text-description text-xs">
7755
Use a{" "}
7856
<span
7957
className="cursor-pointer underline hover:brightness-125"
@@ -85,21 +63,67 @@ export function OnboardingModelsAddOnTab() {
8563
</span>
8664
</div>
8765

88-
<div className="w-full">
89-
<Button onClick={openBillingSettings} className="w-full max-w-xs">
90-
Purchase Credits
91-
</Button>
92-
</div>
93-
<div className="w-full text-center">
94-
<span className="text-description">
95-
<span
96-
className="cursor-pointer underline hover:brightness-125"
97-
onClick={openPricingPage}
98-
>
99-
Click here
100-
</span>{" "}
101-
to view pricing details
102-
</span>
66+
{/* Vertical step indicators */}
67+
<div className="flex w-full flex-col gap-4">
68+
{/* Step 1: Create Account */}
69+
<div className="flex flex-col gap-2">
70+
<div className="flex items-center gap-2">
71+
<div
72+
className={`flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full text-xs font-medium ring-1 ring-inset ${
73+
isLoggedIn
74+
? "bg-green-500 text-white ring-green-500"
75+
: "text-foreground ring-foreground bg-transparent"
76+
}`}
77+
>
78+
{isLoggedIn ? <CheckIcon className="h-3 w-3" /> : "1"}
79+
</div>
80+
<span
81+
className={`text-sm ${isLoggedIn ? "text-description" : "text-foreground font-medium"}`}
82+
>
83+
Create Account
84+
</span>
85+
</div>
86+
<div className="flex gap-2">
87+
<div className="w-5 flex-shrink-0" />
88+
<Button
89+
onClick={handleCreateAccount}
90+
className="flex-1"
91+
disabled={isLoggedIn}
92+
>
93+
Create Account
94+
</Button>
95+
</div>
96+
</div>
97+
98+
{/* Step 2: Purchase Credits */}
99+
<div className="flex flex-col gap-2">
100+
<div className="flex items-center gap-2">
101+
<div
102+
className={`flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full text-xs font-medium ring-1 ring-inset ${
103+
isLoggedIn
104+
? "text-foreground ring-foreground bg-transparent"
105+
: "text-description ring-description bg-transparent"
106+
}`}
107+
>
108+
2
109+
</div>
110+
<span
111+
className={`text-sm ${isLoggedIn ? "text-foreground font-medium" : "text-description"}`}
112+
>
113+
Purchase Credits
114+
</span>
115+
</div>
116+
<div className="flex gap-2">
117+
<div className="w-5 flex-shrink-0" />
118+
<Button
119+
onClick={handlePurchaseCredits}
120+
className="flex-1"
121+
disabled={!isLoggedIn}
122+
>
123+
Purchase Credits
124+
</Button>
125+
</div>
126+
</div>
103127
</div>
104128
</div>
105129
);

gui/src/components/ReusableCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ export function ReusableCard({
2828
}: ReusableCardProps) {
2929
return (
3030
<StyledCard
31-
className={`xs:py-4 xs:px-4 relative px-2 py-3 ${className}`}
31+
className={`xs:py-4 xs:px-4 relative px-2 !pt-0 pb-3 ${className}`}
3232
data-testid={testId}
3333
>
3434
{showCloseButton && (
3535
<CloseButton onClick={onClose}>
3636
<XMarkIcon className="flex h-5 w-5 hover:brightness-125" />
3737
</CloseButton>
3838
)}
39-
<div className="content py-2">{children}</div>
39+
<div className="content">{children}</div>
4040
</StyledCard>
4141
);
4242
}

0 commit comments

Comments
 (0)