diff --git a/docs/docs.json b/docs/docs.json
index 71f20c2c5..ad45e7fc8 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -231,8 +231,8 @@
"navbar": {
"primary": {
"type": "button",
- "label": "GitHub",
- "href": "https://github.com/sourcebot-dev/sourcebot"
+ "label": "Book a Call",
+ "href": "https://calendly.com/michael-sourcebot/sourcebot-call?utm_source=docs"
}
},
"footer": {
diff --git a/packages/web/src/app/(app)/@sidebar/components/bookACallSidebarButton.tsx b/packages/web/src/app/(app)/@sidebar/components/bookACallSidebarButton.tsx
new file mode 100644
index 000000000..438163d1c
--- /dev/null
+++ b/packages/web/src/app/(app)/@sidebar/components/bookACallSidebarButton.tsx
@@ -0,0 +1,32 @@
+import {
+ SidebarMenu,
+ SidebarMenuButton,
+ SidebarMenuItem,
+} from "@/components/ui/sidebar"
+import { Phone } from "lucide-react"
+
+const BOOK_A_CALL_BASE_URL = "https://calendly.com/michael-sourcebot/sourcebot-call"
+
+interface BookACallSidebarButtonProps {
+ // When the deployment is the public "ask GitHub" app, attribute bookings
+ // to `public-app` so they can be told apart from self-hosted instances.
+ isAskGhEnabled: boolean
+}
+
+export function BookACallSidebarButton({ isAskGhEnabled }: BookACallSidebarButtonProps) {
+ const utmSource = isAskGhEnabled ? "public-app" : "app"
+ const href = `${BOOK_A_CALL_BASE_URL}?utm_source=${utmSource}`
+
+ return (
+
+
+
+
+
+ Book a Call
+
+
+
+
+ )
+}
diff --git a/packages/web/src/app/(app)/@sidebar/components/defaultSidebar/index.tsx b/packages/web/src/app/(app)/@sidebar/components/defaultSidebar/index.tsx
index 04ff3caf6..a0ccd6269 100644
--- a/packages/web/src/app/(app)/@sidebar/components/defaultSidebar/index.tsx
+++ b/packages/web/src/app/(app)/@sidebar/components/defaultSidebar/index.tsx
@@ -14,6 +14,7 @@ import { RepoVisitHistory } from "./repoVisitHistory";
import { getAuthContext, withAuth } from "@/middleware/withAuth";
import { sew } from "@/middleware/sew";
import { hasEntitlement, isValidLicenseActive } from "@/lib/entitlements";
+import { env } from "@sourcebot/shared";
const SIDEBAR_CHAT_LIMIT = 30;
export const SIDEBAR_REPO_VISITS_LIMIT = 10;
@@ -57,6 +58,7 @@ export async function DefaultSidebar() {
session={session}
collapsible="icon"
isValidLicenseActive={licenseActive}
+ isAskGhEnabled={env.EXPERIMENT_ASK_GH_ENABLED === 'true'}
headerContent={
}
>
diff --git a/packages/web/src/app/(app)/@sidebar/components/sidebarBase.tsx b/packages/web/src/app/(app)/@sidebar/components/sidebarBase.tsx
index 6ca76aff4..3633f15dc 100644
--- a/packages/web/src/app/(app)/@sidebar/components/sidebarBase.tsx
+++ b/packages/web/src/app/(app)/@sidebar/components/sidebarBase.tsx
@@ -45,6 +45,7 @@ import { KeyboardShortcutHint } from "@/app/components/keyboardShortcutHint";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { Separator } from "@/components/ui/separator";
import { WhatsNewSidebarButton } from "./whatsNewSidebarButton";
+import { BookACallSidebarButton } from "./bookACallSidebarButton";
import { UpgradeButton } from "./upgradeButton";
import { useIsMobile } from "@/hooks/use-mobile";
@@ -58,9 +59,10 @@ interface SidebarBaseProps {
headerContent: ReactNode;
children: ReactNode;
isValidLicenseActive: boolean;
+ isAskGhEnabled: boolean;
}
-export function SidebarBase({ session, collapsible = "icon", headerContent, children, isValidLicenseActive }: SidebarBaseProps) {
+export function SidebarBase({ session, collapsible = "icon", headerContent, children, isValidLicenseActive, isAskGhEnabled }: SidebarBaseProps) {
const [isScrolled, setIsScrolled] = useState(false);
const contentRef = useRef(null);
const isMobile = useIsMobile();
@@ -118,6 +120,7 @@ export function SidebarBase({ session, collapsible = "icon", headerContent, chil
}
+
{session ? (
) : (