Skip to content

Commit 5f898bb

Browse files
committed
auth updates
1 parent 556540a commit 5f898bb

File tree

7 files changed

+121
-89
lines changed

7 files changed

+121
-89
lines changed

apps/desktop/src/components/settings/account.tsx

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,54 +43,57 @@ export function SettingsAccount() {
4343
if (!isAuthenticated) {
4444
if (isPending && devMode) {
4545
return (
46-
<Container
47-
title="Manual callback"
48-
description="Paste the callback URL below."
49-
>
50-
<div className="flex flex-col gap-2">
51-
<Input
52-
type="text"
53-
className="text-sm"
54-
placeholder="hyprnote://auth?access_token=...&refresh_token=..."
55-
value={callbackUrl}
56-
onChange={(e) => setCallbackUrl(e.target.value)}
57-
/>
58-
<div className="flex gap-2">
59-
<Button
60-
onClick={() => auth?.handleAuthCallback(callbackUrl)}
61-
className="flex-1"
62-
>
63-
Submit
64-
</Button>
65-
<Button variant="outline" onClick={() => setDevMode(false)}>
66-
Back
67-
</Button>
68-
</div>
46+
<div className="flex flex-col gap-3">
47+
<div className="flex flex-col gap-1.5">
48+
<h2 className="text-sm font-medium">Manual callback</h2>
49+
<p className="text-xs text-neutral-500">
50+
Paste the callback URL from your browser
51+
</p>
52+
</div>
53+
<Input
54+
type="text"
55+
className="text-xs font-mono"
56+
placeholder="hyprnote://auth?access_token=...&refresh_token=..."
57+
value={callbackUrl}
58+
onChange={(e) => setCallbackUrl(e.target.value)}
59+
/>
60+
<div className="flex gap-2">
61+
<Button
62+
onClick={() => auth?.handleAuthCallback(callbackUrl)}
63+
className="flex-1"
64+
>
65+
Submit
66+
</Button>
67+
<Button variant="outline" onClick={() => setDevMode(false)}>
68+
Back
69+
</Button>
6970
</div>
70-
</Container>
71+
</div>
7172
);
7273
}
7374

7475
if (isPending) {
7576
return (
76-
<Container
77-
title="Not redirected?"
78-
description="Click below to reopen the sign-in page."
79-
action={
80-
<Button onClick={handleSignIn}>
81-
<span>Reopen sign-in page</span>
77+
<div className="flex flex-col gap-4">
78+
<div className="flex flex-col gap-1.5">
79+
<h2 className="text-sm font-medium">Waiting for sign-in...</h2>
80+
<p className="text-xs text-neutral-500">
81+
Complete the sign-in process in your browser
82+
</p>
83+
</div>
84+
<div className="flex flex-col gap-2">
85+
<Button onClick={handleSignIn} variant="outline" className="w-full">
86+
Reopen sign-in page
8287
</Button>
83-
}
84-
>
85-
{import.meta.env.DEV && (
86-
<p
88+
<Button
8789
onClick={() => setDevMode(true)}
88-
className="text-xs text-neutral-600 cursor-pointer hover:text-neutral-900"
90+
variant="ghost"
91+
className="w-full text-xs"
8992
>
90-
Click here to workaround deeplink.
91-
</p>
92-
)}
93-
</Container>
93+
Having trouble? Paste callback URL manually
94+
</Button>
95+
</div>
96+
</div>
9497
);
9598
}
9699

@@ -181,7 +184,7 @@ function Container({
181184
children,
182185
}: {
183186
title: string;
184-
description: string;
187+
description?: string;
185188
action?: ReactNode;
186189
children?: ReactNode;
187190
}) {
@@ -190,7 +193,9 @@ function Container({
190193
<div className="flex flex-row items-center justify-between gap-4">
191194
<div className="flex flex-col gap-2">
192195
<h1 className="text-md font-semibold">{title}</h1>
193-
<p className="text-sm text-neutral-600">{description}</p>
196+
{description && (
197+
<p className="text-sm text-neutral-600">{description}</p>
198+
)}
194199
</div>
195200
{action ? <div className="flex-shrink-0">{action}</div> : null}
196201
</div>

apps/desktop/src/hooks/useLLMConnection.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { useMemo } from "react";
1414
import type { AIProviderStorage } from "@hypr/store";
1515

1616
import { useAuth } from "../auth";
17+
import { useBillingAccess } from "../billing";
1718
import {
1819
type ProviderId,
1920
PROVIDERS,
@@ -34,6 +35,7 @@ export type LLMConnectionStatus =
3435
| { status: "pending"; reason: "missing_model"; providerId: ProviderId }
3536
| { status: "error"; reason: "provider_not_found"; providerId: string }
3637
| { status: "error"; reason: "unauthenticated"; providerId: "hyprnote" }
38+
| { status: "error"; reason: "not_pro"; providerId: "hyprnote" }
3739
| {
3840
status: "error";
3941
reason: "missing_config";
@@ -138,6 +140,7 @@ export const useLanguageModel = (): Exclude<LanguageModel, string> | null => {
138140

139141
export const useLLMConnection = (): LLMConnectionResult => {
140142
const auth = useAuth();
143+
const billing = useBillingAccess();
141144

142145
const { current_llm_provider, current_llm_model } = main.UI.useValues(
143146
main.STORE_ID,
@@ -192,6 +195,13 @@ export const useLLMConnection = (): LLMConnectionResult => {
192195
};
193196
}
194197

198+
if (!billing.isPro) {
199+
return {
200+
conn: null,
201+
status: { status: "error", reason: "not_pro", providerId },
202+
};
203+
}
204+
195205
const conn: LLMConnectionInfo = {
196206
providerId,
197207
modelId: current_llm_model,
@@ -244,7 +254,13 @@ export const useLLMConnection = (): LLMConnectionResult => {
244254
conn,
245255
status: { status: "success", providerId, isHosted: false },
246256
};
247-
}, [auth, current_llm_model, current_llm_provider, providerConfig]);
257+
}, [
258+
auth,
259+
billing.isPro,
260+
current_llm_model,
261+
current_llm_provider,
262+
providerConfig,
263+
]);
248264
};
249265

250266
export const useLLMConnectionStatus = (): LLMConnectionStatus => {

apps/desktop/src/hooks/useSTTConnection.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import { commands as localSttCommands } from "@hypr/plugin-local-stt";
55
import type { AIProviderStorage } from "@hypr/store";
66

77
import { useAuth } from "../auth";
8+
import { useBillingAccess } from "../billing";
89
import { ProviderId } from "../components/settings/ai/stt/shared";
910
import { env } from "../env";
1011
import * as main from "../store/tinybase/main";
1112

1213
export const useSTTConnection = () => {
1314
const auth = useAuth();
15+
const billing = useBillingAccess();
1416
const { current_stt_provider, current_stt_model } = main.UI.useValues(
1517
main.STORE_ID,
1618
) as {
@@ -85,7 +87,7 @@ export const useSTTConnection = () => {
8587
}
8688

8789
if (isCloudModel) {
88-
if (!auth?.session) {
90+
if (!auth?.session || !billing.isPro) {
8991
return null;
9092
}
9193

@@ -116,6 +118,7 @@ export const useSTTConnection = () => {
116118
baseUrl,
117119
apiKey,
118120
auth,
121+
billing.isPro,
119122
]);
120123

121124
return {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { createContext, useContext } from "react";
2+
3+
interface HeroContextType {
4+
onTrigger: (() => void) | null;
5+
setOnTrigger: (callback: () => void) => void;
6+
}
7+
8+
export const HeroContext = createContext<HeroContextType | null>(null);
9+
10+
export function useHeroContext() {
11+
return useContext(HeroContext);
12+
}

apps/web/src/routes/_view/callback/auth.tsx

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -111,38 +111,45 @@ function Component() {
111111
</div>
112112

113113
{attempted && (
114-
<div className="pt-8 space-y-6">
115-
<div className="space-y-2">
116-
<p className="text-sm text-neutral-600">Popup didn't appear?</p>
117-
<button
118-
onClick={handleDeeplink}
119-
className="px-6 py-3 bg-stone-600 hover:bg-stone-700 text-white rounded-lg transition-colors font-medium"
120-
>
121-
Click here to retry
122-
</button>
123-
</div>
124-
125-
<div className="pt-4 border-t border-stone-200 space-y-3">
126-
<p className="text-sm text-neutral-500">Having trouble?</p>
127-
<p className="text-xs text-neutral-400">
128-
Copy the URL below and paste it in the app's address bar
129-
</p>
130-
<button
131-
onClick={handleCopy}
132-
className="inline-flex items-center gap-2 px-4 py-2 text-sm text-stone-600 border border-stone-300 hover:bg-stone-50 rounded-lg transition-colors"
133-
>
134-
{copied ? (
135-
<>
136-
<CheckIcon className="size-4" />
137-
Copied!
138-
</>
139-
) : (
140-
<>
141-
<CopyIcon className="size-4" />
142-
Copy URL
143-
</>
144-
)}
145-
</button>
114+
<div className="pt-8 space-y-4">
115+
<h2 className="text-lg font-medium text-stone-700">
116+
Not redirected?
117+
</h2>
118+
119+
<div className="space-y-3">
120+
<div className="flex flex-col gap-2 p-4 bg-stone-50 rounded-lg">
121+
<p className="text-sm font-medium text-stone-700">
122+
Not redirected to the app?
123+
</p>
124+
<button
125+
onClick={handleDeeplink}
126+
className="w-full px-4 py-2 bg-stone-800 hover:bg-stone-900 text-white rounded-lg transition-colors font-medium text-sm"
127+
>
128+
Reopen
129+
</button>
130+
</div>
131+
132+
<div className="flex flex-col gap-2 p-4 bg-stone-50 rounded-lg">
133+
<p className="text-sm font-medium text-stone-700">
134+
Still having trouble?
135+
</p>
136+
<button
137+
onClick={handleCopy}
138+
className="w-full inline-flex items-center justify-center gap-2 px-4 py-2 text-sm text-stone-600 border border-stone-300 hover:bg-stone-100 rounded-lg transition-colors"
139+
>
140+
{copied ? (
141+
<>
142+
<CheckIcon className="size-4" />
143+
Copied!
144+
</>
145+
) : (
146+
<>
147+
<CopyIcon className="size-4" />
148+
Copy URL
149+
</>
150+
)}
151+
</button>
152+
</div>
146153
</div>
147154
</div>
148155
)}

apps/web/src/routes/_view/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ import { SocialCard } from "@/components/social-card";
1818
import { VideoModal } from "@/components/video-modal";
1919
import { VideoThumbnail } from "@/components/video-thumbnail";
2020
import { addContact } from "@/functions/loops";
21+
import { useHeroContext } from "@/hooks/use-hero-context";
2122
import { getHeroCTA, getPlatformCTA, usePlatform } from "@/hooks/use-platform";
2223
import { useAnalytics } from "@/hooks/use-posthog";
2324

24-
import { useHeroContext } from "./route";
25-
2625
const MUX_PLAYBACK_ID = "bpcBHf4Qv5FbhwWD02zyFDb24EBuEuTPHKFUrZEktULQ";
2726

2827
const mainFeatures = [

apps/web/src/routes/_view/route.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import {
55
useRouterState,
66
} from "@tanstack/react-router";
77
import { allHandbooks } from "content-collections";
8-
import { createContext, useContext, useMemo, useRef, useState } from "react";
8+
import { useMemo, useRef, useState } from "react";
99

1010
import { Footer } from "@/components/footer";
1111
import { Header } from "@/components/header";
1212
import { SidebarNavigation } from "@/components/sidebar-navigation";
1313
import { DocsDrawerContext } from "@/hooks/use-docs-drawer";
1414
import { HandbookDrawerContext } from "@/hooks/use-handbook-drawer";
15+
import { HeroContext } from "@/hooks/use-hero-context";
1516

1617
import { handbookStructure } from "./company-handbook/-structure";
1718
import { getDocsBySection } from "./docs/-structure";
@@ -20,17 +21,6 @@ export const Route = createFileRoute("/_view")({
2021
component: Component,
2122
});
2223

23-
interface HeroContextType {
24-
onTrigger: (() => void) | null;
25-
setOnTrigger: (callback: () => void) => void;
26-
}
27-
28-
const HeroContext = createContext<HeroContextType | null>(null);
29-
30-
export function useHeroContext() {
31-
return useContext(HeroContext);
32-
}
33-
3424
function Component() {
3525
const router = useRouterState();
3626
const isDocsPage = router.location.pathname.startsWith("/docs");

0 commit comments

Comments
 (0)