Skip to content

Commit c747f84

Browse files
committed
better new state
1 parent ebe71df commit c747f84

File tree

4 files changed

+76
-86
lines changed

4 files changed

+76
-86
lines changed

apps/web/src/app/[id]/page.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,6 @@ export default function AppPage({ params }: { params: Promise<{ id: string }> })
4545
checkInstallation();
4646
}, [token, id, setToken, router]);
4747

48-
if (!token || !isValidToken) {
49-
return (
50-
<div className="py-6">
51-
<TokenPrompt error={error} />
52-
</div>
53-
);
54-
}
55-
5648
if (!(id in TOOLS)) {
5749
return <div>Tool not found</div>;
5850
}
@@ -74,6 +66,9 @@ export default function AppPage({ params }: { params: Promise<{ id: string }> })
7466
{error && (
7567
<p className="text-sm text-red-500">{error}</p>
7668
)}
69+
{!token || !isValidToken && (
70+
<TokenPrompt error={error} />
71+
)}
7772
<Component />
7873
</div>
7974
</div>

apps/web/src/app/page.tsx

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,53 @@
33
import { useQueryState } from 'nuqs';
44
import { Suspense } from 'react';
55
import TokenPrompt from '@/components/token-prompt';
6+
import Link from 'next/link';
7+
import { SquareArrowOutUpRight } from 'lucide-react';
68

79
function HomeContent() {
810
const [token] = useQueryState('token');
911

10-
if (!token) {
11-
return <TokenPrompt />;
12-
}
13-
1412
return (
1513
<div className="py-6">
1614
<div className="space-y-4">
1715
<h1 className="text-2xl font-bold">Welcome to Tinynest</h1>
18-
<p className="text-muted-foreground">
19-
Select an app from the sidebar to get started. Apps are organized by their status:
20-
</p>
21-
<ul className="list-disc list-inside space-y-2 text-muted-foreground">
22-
<li><strong>Configured Apps</strong> - These apps are fully set up and have data. They&apos;re ready to use!</li>
23-
<li><strong>Installed Apps</strong> - Your Tinybird Workspace has the Data Sources installed, but you&apos;re not receiving data.</li>
24-
<li><strong>Available Apps</strong> - Your Tinybird Workspace doesn&apos;t have the Data Sources installed yet.</li>
25-
</ul>
16+
{token && (
17+
<>
18+
<p className="text-muted-foreground">
19+
Select an app from the sidebar to get started. Apps are organized by their status:
20+
</p>
21+
<ul className="list-disc list-inside space-y-2 text-muted-foreground">
22+
<li><strong>Configured Apps</strong> - These apps are fully set up and have data. They&apos;re ready to use!</li>
23+
<li><strong>Installed Apps</strong> - Your Tinybird Workspace has the Data Sources installed, but you&apos;re not receiving data.</li>
24+
<li><strong>Available Apps</strong> - Your Tinybird Workspace doesn&apos;t have the Data Sources installed yet.</li>
25+
</ul>
26+
</>
27+
)}
28+
{!token && (
29+
<div className="prose">
30+
<p>Tinynest lets you see what&apos;s going on in your SaaS stack.</p>
31+
<p>Modern products use a nest of SaaS tools as building blocks, like Tinybird for Analytics, Clerk for Auth, Stripe for Payments, and more.</p>
32+
<p>This lets you focus on building your product and delighting your users.</p>
33+
<p>But it can also make it hard to see the complete picture of how your users are interacting with your product.</p>
34+
<p>Tinynest helps you to bring that data together in one place.</p>
35+
<TokenPrompt />
36+
37+
<h2>New here? Deploy now</h2>
38+
<p>
39+
Deploy a new project to Tinybird to get started
40+
</p>
41+
<Link
42+
href="https://app.tinybird.co/?starter_kit=https://github.com/tinybirdco/tinynest/tinybird"
43+
target="_blank"
44+
className="inline-flex items-center gap-1 rounded-md bg-primary px-3 py-2 text-sm font-semibold text-primary-foreground shadow hover:bg-primary/90"
45+
>
46+
Deploy to Tinybird
47+
<SquareArrowOutUpRight className="h-4 w-4" />
48+
</Link>
49+
</div>
50+
)}
2651
</div>
27-
</div>
52+
</div >
2853
);
2954
}
3055

apps/web/src/components/sidebar.tsx

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function AppCard({
1919
}: {
2020
app: AppGridItem;
2121
state: ToolState;
22-
token?: string;
22+
token?: string | null;
2323
isActive: boolean;
2424
}) {
2525
const stateColors = {
@@ -35,7 +35,6 @@ function AppCard({
3535
>
3636
<Card className={`p-3 hover:bg-accent mb-2 ${stateColors[state]} ${isActive ? 'bg-accent' : ''}`}>
3737
<div className="flex items-center gap-3">
38-
{/* <div className="text-xl">{app.icon}</div> */}
3938
{app.icon_url && <Image src={app.icon_url} width={16} height={16} alt={app.name} />}
4039
<div>
4140
<div className="flex items-center gap-2">
@@ -77,7 +76,6 @@ function SidebarContent({ activeAppId }: { activeAppId?: string }) {
7776
useEffect(() => {
7877
async function fetchToolStates() {
7978
if (!token) return;
80-
8179
setIsLoading(true);
8280
setError(undefined);
8381
try {
@@ -98,12 +96,9 @@ function SidebarContent({ activeAppId }: { activeAppId?: string }) {
9896
setIsLoading(false);
9997
}
10098
}
101-
102-
fetchToolStates();
99+
if (token) fetchToolStates();
103100
}, [token, setToken]);
104101

105-
if (!token || error) return null;
106-
107102
return (
108103
<div className="w-64 border-r h-screen">
109104
<div className="p-4 border-b">
@@ -183,26 +178,30 @@ function SidebarContent({ activeAppId }: { activeAppId?: string }) {
183178
)}
184179

185180
{/* Available Apps */}
186-
<div className="space-y-2">
187-
<SectionHeader
188-
title="Available Apps"
189-
tooltip="Your Tinybird Workspace doesn't have the Data Sources installed yet. Click an app to learn how to install it."
190-
/>
181+
{Object.values(TOOLS).some(app => toolStates[app.id] === 'available') && (
191182
<div className="space-y-2">
192-
{Object.values(TOOLS)
193-
.filter(app => !toolStates[app.id] || toolStates[app.id] === 'available')
194-
.map(app => (
195-
<AppCard
196-
key={app.id}
197-
app={app}
198-
state={toolStates[app.id] || 'available'}
199-
token={token}
200-
isActive={app.id === activeAppId}
201-
/>
202-
))}
183+
<SectionHeader
184+
title="Available Apps"
185+
tooltip="Your Tinybird Workspace doesn't have the Data Sources installed yet. Click an app to learn how to install it."
186+
/>
187+
<div className="space-y-2">
188+
{Object.values(TOOLS)
189+
.filter(app => !toolStates[app.id] || toolStates[app.id] === 'available')
190+
.map(app => (
191+
<AppCard
192+
key={app.id}
193+
app={app}
194+
state={toolStates[app.id] || 'available'}
195+
token={token}
196+
isActive={app.id === activeAppId}
197+
/>
198+
))}
199+
</div>
203200
</div>
204-
</div>
201+
)}
202+
205203
</div>
204+
206205
)}
207206
</ScrollArea>
208207
</div>

apps/web/src/components/token-prompt.tsx

Lines changed: 12 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { useQueryState } from 'nuqs'
55
import { useState } from 'react'
66
import { Button } from './ui/button'
77
import { Input } from './ui/input'
8-
import Link from 'next/link'
98

109
export default function TokenPrompt({ error }: { error?: string }) {
1110
const [token, setToken] = useQueryState('token')
@@ -19,46 +18,18 @@ export default function TokenPrompt({ error }: { error?: string }) {
1918
if (token) return null
2019

2120
return (
22-
<div className="fixed inset-0 bg-background/80 backdrop-blur-sm z-50">
23-
<div className="fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg">
24-
<div className="space-y-8">
25-
<div className="space-y-2">
26-
<h2 className="text-lg font-semibold tracking-tight">Already deployed?</h2>
27-
<p className="text-sm text-muted-foreground">
28-
Enter your Tinybird admin token to continue
29-
</p>
30-
<div className="flex w-full max-w-sm flex-col gap-2">
31-
<div className="flex items-center space-x-2">
32-
<Input
33-
placeholder="Enter your token"
34-
value={inputToken}
35-
onChange={(e) => setInputToken(e.target.value)}
36-
onKeyDown={(e) => e.key === 'Enter' && handleSave()}
37-
/>
38-
<Button onClick={handleSave}>Save</Button>
39-
</div>
40-
{error && (
41-
<p className="text-sm text-red-500">{error}</p>
42-
)}
43-
</div>
44-
</div>
45-
46-
<div className="space-y-2">
47-
<h2 className="text-lg font-semibold tracking-tight">New here?</h2>
48-
<p className="text-sm text-muted-foreground">
49-
Deploy a new project to Tinybird to get started
50-
</p>
51-
<Link
52-
href="https://app.tinybird.co/?starter_kit=https://github.com/tinybirdco/tinynest/tinybird"
53-
target="_blank"
54-
className="inline-flex items-center gap-1 rounded-md bg-primary px-3 py-2 text-sm font-semibold text-primary-foreground shadow hover:bg-primary/90"
55-
>
56-
Deploy to Tinybird
57-
<SquareArrowOutUpRight className="h-4 w-4" />
58-
</Link>
59-
</div>
60-
</div>
21+
<>
22+
<h2>Already deployed? Enter your token</h2>
23+
<div className="flex w-full max-w-sm items-center space-x-2">
24+
<Input
25+
type="password"
26+
placeholder="Enter your 'read' token from Tinybird"
27+
value={inputToken}
28+
onChange={(e) => setInputToken(e.target.value)}
29+
onKeyDown={(e) => e.key === 'Enter' && handleSave()} />
30+
<Button type="submit" onClick={handleSave}>Save</Button>
6131
</div>
62-
</div>
32+
</>
33+
6334
)
6435
}

0 commit comments

Comments
 (0)