Skip to content

Commit 7dcd554

Browse files
committed
fix(ui): Clients onboarding — single generic 3-step card, always shown
Replaces the dual-track "Auto / Manual" breakdown with one beginner-oriented walkthrough that shows every time there are no connected clients. The dense side-by-side A/B tracks assumed the user already understood what deep-link vs. copy-config means; we were overexplaining to first-time users instead of just pointing at the IDE grid and saying "pick one, follow its prompt." * One welcome Card with "Let's hook up your first IDE" heading, lead sentence framing mcpmux ("one connection your AI client uses to reach every MCP server"), and three numbered steps: 1. Pick your IDE below and follow its prompt. 2. Open or restart the IDE. 3. Approve the connection right here. * Per-IDE "what this button does" detail lives where it belongs — inside the ConnectIDEs card popover, so users see it at the point of action rather than up-front. * No dismiss / localStorage flag. If the Clients page is empty, the user hasn't finished onboarding yet; showing the walkthrough every time is the right default. * Amber "gateway is stopped" inline warning is preserved — it solves the hang-at-initialize issue we hit earlier. Also dropped now-unused `RotateCcw` + `CheckCircle2` icon imports. Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
1 parent ce1d384 commit 7dcd554

1 file changed

Lines changed: 52 additions & 101 deletions

File tree

apps/desktop/src/features/clients/ClientsPage.tsx

Lines changed: 52 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ import {
2626
AlertCircle,
2727
Zap,
2828
PlugZap,
29-
RotateCcw,
30-
CheckCircle2,
3129
} from 'lucide-react';
3230
import { ConnectIDEs } from '@/components/ConnectIDEs';
3331
import type { GatewayStatus } from '@/lib/api/gateway';
@@ -147,6 +145,7 @@ export default function ClientsPage() {
147145
active_sessions: 0,
148146
connected_backends: 0,
149147
});
148+
150149

151150
// Feature set grant state
152151
const viewSpace = useViewSpace();
@@ -640,116 +639,68 @@ export default function ClientsPage() {
640639
// the IDE, then come back and approve. Each step is a distinct
641640
// visual block so users don't skim past "and then approve here".
642641
<div className="max-w-4xl mx-auto space-y-6" data-testid="clients-empty-connect">
643-
<Card>
642+
{/* Generic 3-step welcome. Always visible while there are no
643+
connected clients — no dismiss — because a user hitting
644+
this page with nothing connected needs the instructions
645+
every time, not just the first time. */}
646+
<Card data-testid="clients-empty-onboarding">
644647
<CardContent className="p-8">
645-
<div className="flex items-start gap-4 mb-2">
648+
<div className="flex items-start gap-4 mb-1">
646649
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-primary-500 to-primary-600 text-white shadow-[0_6px_16px_-4px_rgb(99_102_241/0.45)] flex-shrink-0">
647650
<PlugZap className="h-6 w-6" />
648651
</div>
649652
<div>
650-
<h2 className="text-xl font-semibold">Connect your first IDE</h2>
653+
<h2 className="text-xl font-semibold">Let&apos;s hook up your first IDE</h2>
651654
<p className="text-sm text-[rgb(var(--muted))] mt-1">
652-
Nothing has connected to mcpmux yet. Pick the path that matches your IDE
653-
below — the approval prompt shows up on this page either way.
655+
mcpmux is one connection your AI client uses to reach every MCP server.
656+
Three steps and you&apos;re done:
654657
</p>
655658
</div>
656659
</div>
657660

658-
{/* Two distinct install paths. Mixing them into a single
659-
numbered list made users think "copy config" auto-installs
660-
somewhere — it doesn't; it's clipboard content they have
661-
to paste themselves. Keep them separated. */}
662-
<div className="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
663-
{/* Track A — one-click install (VS Code, Cursor) */}
664-
<div className="rounded-xl border border-primary-300/60 dark:border-primary-700/40 bg-gradient-to-br from-primary-50/50 to-transparent dark:from-primary-900/15 p-4">
665-
<div className="flex items-center gap-2 mb-3">
666-
<div className="flex h-7 w-7 items-center justify-center rounded-lg bg-primary-500 text-white text-xs font-bold">
667-
A
668-
</div>
669-
<h3 className="font-semibold text-sm">
670-
VS Code&nbsp;·&nbsp;Cursor
671-
<span className="ml-2 text-[10px] uppercase tracking-wide text-primary-700 dark:text-primary-300 bg-primary-500/10 rounded px-1.5 py-0.5">
672-
One-click
673-
</span>
674-
</h3>
661+
<ol className="mt-6 space-y-3 text-sm">
662+
<li className="flex gap-3 items-start">
663+
<span className="flex-shrink-0 flex h-7 w-7 items-center justify-center rounded-full bg-primary-100 dark:bg-primary-900/40 text-primary-700 dark:text-primary-300 font-semibold text-sm">
664+
1
665+
</span>
666+
<div className="flex-1">
667+
<p className="font-medium">Pick your IDE below and follow its prompt</p>
668+
<p className="text-[rgb(var(--muted))] text-xs mt-0.5">
669+
Each card tells you exactly what the button does — either one-click
670+
install or copy a small config for you to paste.
671+
</p>
675672
</div>
676-
<ol className="space-y-2 text-xs">
677-
<li className="flex gap-2">
678-
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">1.</span>
679-
<span>
680-
Click the IDE icon below → click <span className="font-medium">Add to VS Code</span> /
681-
<span className="font-medium"> Add to Cursor</span>. The IDE opens and registers mcpmux.
682-
</span>
683-
</li>
684-
<li className="flex gap-2">
685-
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">2.</span>
686-
<span>
687-
Start a new chat / reload the MCP server in that IDE so it actually
688-
connects.
689-
</span>
690-
</li>
691-
<li className="flex gap-2">
692-
<span className="font-semibold text-emerald-600 dark:text-emerald-400 w-4 shrink-0">3.</span>
693-
<span>
694-
<span className="font-medium text-emerald-700 dark:text-emerald-300">
695-
Approve here.
696-
</span>{' '}
697-
mcpmux will pop a dialog on this app — nothing is routed to the IDE
698-
until you accept.
699-
</span>
700-
</li>
701-
</ol>
702-
</div>
703-
704-
{/* Track B — manual copy-paste (everyone else) */}
705-
<div className="rounded-xl border border-[rgb(var(--border))] bg-[rgb(var(--surface))] p-4">
706-
<div className="flex items-center gap-2 mb-3">
707-
<div className="flex h-7 w-7 items-center justify-center rounded-lg bg-[rgb(var(--muted))] text-white text-xs font-bold">
708-
B
709-
</div>
710-
<h3 className="font-semibold text-sm">
711-
Windsurf&nbsp;·&nbsp;Claude Code&nbsp;·&nbsp;JetBrains&nbsp;·&nbsp;Android Studio
712-
<span className="ml-2 text-[10px] uppercase tracking-wide text-[rgb(var(--muted))] bg-[rgb(var(--surface-elevated))] rounded px-1.5 py-0.5 border border-[rgb(var(--border))]">
713-
Manual
714-
</span>
715-
</h3>
673+
</li>
674+
<li className="flex gap-3 items-start">
675+
<span className="flex-shrink-0 flex h-7 w-7 items-center justify-center rounded-full bg-primary-100 dark:bg-primary-900/40 text-primary-700 dark:text-primary-300 font-semibold text-sm">
676+
2
677+
</span>
678+
<div className="flex-1">
679+
<p className="font-medium">Open or restart the IDE</p>
680+
<p className="text-[rgb(var(--muted))] text-xs mt-0.5">
681+
Your client only connects to mcpmux the next time its MCP servers
682+
start up.
683+
</p>
716684
</div>
717-
<ol className="space-y-2 text-xs">
718-
<li className="flex gap-2">
719-
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">1.</span>
720-
<span>
721-
Click the IDE icon below → <span className="font-medium">Copy config</span> or
722-
<span className="font-medium"> Copy command</span> (your clipboard now has the
723-
snippet).
724-
</span>
725-
</li>
726-
<li className="flex gap-2">
727-
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">2.</span>
728-
<span>
729-
Paste it into that IDE&apos;s MCP config file (or run the copied
730-
command for Claude Code).
731-
</span>
732-
</li>
733-
<li className="flex gap-2">
734-
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">3.</span>
735-
<span>
736-
Restart the IDE or reload its MCP servers — mcpmux is not picked up
737-
until you do.
738-
</span>
739-
</li>
740-
<li className="flex gap-2">
741-
<span className="font-semibold text-emerald-600 dark:text-emerald-400 w-4 shrink-0">4.</span>
742-
<span>
743-
<span className="font-medium text-emerald-700 dark:text-emerald-300">
744-
Approve here.
745-
</span>{' '}
746-
mcpmux will pop a dialog on this app as soon as the IDE reaches the
747-
gateway.
685+
</li>
686+
<li className="flex gap-3 items-start">
687+
<span className="flex-shrink-0 flex h-7 w-7 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900/40 text-emerald-700 dark:text-emerald-300 font-semibold text-sm">
688+
3
689+
</span>
690+
<div className="flex-1">
691+
<p className="font-medium">
692+
Approve the connection{' '}
693+
<span className="ml-1 inline-flex items-center px-1.5 py-0.5 rounded-md bg-emerald-500/15 text-emerald-700 dark:text-emerald-300 text-[10px] font-semibold uppercase tracking-wide">
694+
right here
748695
</span>
749-
</li>
750-
</ol>
751-
</div>
752-
</div>
696+
</p>
697+
<p className="text-[rgb(var(--muted))] text-xs mt-0.5">
698+
mcpmux will pop a dialog on this app the moment your IDE reaches
699+
the gateway. Until you accept it, nothing is routed.
700+
</p>
701+
</div>
702+
</li>
703+
</ol>
753704

754705
{!gatewayStatus.running && (
755706
<div className="mt-5 flex items-start gap-2 p-3 rounded-lg border border-amber-300 dark:border-amber-700/60 bg-amber-50 dark:bg-amber-900/20 text-xs">
@@ -768,8 +719,8 @@ export default function ClientsPage() {
768719
</CardContent>
769720
</Card>
770721

771-
{/* Reuse the shared ConnectIDEs grid from the Dashboard so users
772-
don't have to navigate away. */}
722+
{/* IDE grid — each card's popover tells the user what pressing
723+
the button actually does + what to do next. */}
773724
<ConnectIDEs
774725
gatewayUrl={gatewayStatus.url || 'http://localhost:45818'}
775726
gatewayRunning={gatewayStatus.running}

0 commit comments

Comments
 (0)