various changes to add terms and security info (#225)

* add terms and security to footer

* add security card

* add demo card
This commit is contained in:
Michael Sukkarieh 2025-03-04 15:19:50 -08:00 committed by GitHub
parent eab0007602
commit a212e857c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 220 additions and 71 deletions

View file

@ -17,6 +17,7 @@ import { CodeHostIconButton } from "../../components/codeHostIconButton";
import useCaptureEvent from "@/hooks/useCaptureEvent"; import useCaptureEvent from "@/hooks/useCaptureEvent";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import posthog from "posthog-js"; import posthog from "posthog-js";
import SecurityCard from "@/app/components/securityCard";
interface ConnectCodeHostProps { interface ConnectCodeHostProps {
nextStep: OnboardingSteps; nextStep: OnboardingSteps;
@ -48,7 +49,10 @@ export const ConnectCodeHost = ({ nextStep }: ConnectCodeHostProps) => {
if (!selectedCodeHost) { if (!selectedCodeHost) {
return ( return (
<>
<CodeHostSelection onSelect={setSelectedCodeHost} /> <CodeHostSelection onSelect={setSelectedCodeHost} />
<SecurityCard />
</>
) )
} }

View file

@ -0,0 +1,39 @@
"use client"
import { ExternalLink } from "lucide-react"
import Link from "next/link"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import useCaptureEvent from "@/hooks/useCaptureEvent"
export default function DemoCard() {
const captureEvent = useCaptureEvent();
return (
<Card className="mb-6 w-full border bg-card text-card-foreground">
<CardContent className="p-4">
<div className="flex flex-col space-y-4">
<div className="flex items-center justify-between">
<div className="space-y-1">
<h3 className="text-sm font-medium">New to Sourcebot?</h3>
<p className="text-xs text-muted-foreground">Try our public demo before creating an account</p>
</div>
<Button asChild variant="outline" size="sm" className="h-8 text-xs">
<Link
href="https://sourcebot.dev/search"
target="_blank"
className="flex items-center gap-1.5"
onClick={() => captureEvent('wa_demo_card_click', {})}
>
Try demo
<ExternalLink className="h-3.5 w-3.5" />
</Link>
</Button>
</div>
</div>
</CardContent>
</Card>
)
}

View file

@ -7,6 +7,8 @@ import { InviteTeam } from "./components/inviteTeam";
import { CompleteOnboarding } from "./components/completeOnboarding"; import { CompleteOnboarding } from "./components/completeOnboarding";
import { Checkout } from "./components/checkout"; import { Checkout } from "./components/checkout";
import { LogoutEscapeHatch } from "@/app/components/logoutEscapeHatch"; import { LogoutEscapeHatch } from "@/app/components/logoutEscapeHatch";
import SecurityCard from "@/app/components/securityCard";
interface OnboardProps { interface OnboardProps {
params: { params: {
domain: string domain: string

View file

@ -5,7 +5,7 @@ import { UpgradeToast } from "./components/upgradeToast";
import Link from "next/link"; import Link from "next/link";
import { getOrgFromDomain } from "@/data/org"; import { getOrgFromDomain } from "@/data/org";
import { PageNotFound } from "./components/pageNotFound"; import { PageNotFound } from "./components/pageNotFound";
import { Footer } from "./components/footer"; import { Footer } from "@/app/components/footer";
import { SourcebotLogo } from "../components/sourcebotLogo"; import { SourcebotLogo } from "../components/sourcebotLogo";
import { RepositorySnapshot } from "./components/repositorySnapshot"; import { RepositorySnapshot } from "./components/repositorySnapshot";
import { KeyboardShortcutHint } from "./components/keyboardShortcutHint"; import { KeyboardShortcutHint } from "./components/keyboardShortcutHint";

View file

@ -13,7 +13,7 @@ export default async function ReposPage({ params: { domain } }: { params: { doma
<Header> <Header>
<h1 className="text-3xl">Repositories</h1> <h1 className="text-3xl">Repositories</h1>
</Header> </Header>
<div className="h-screen flex flex-col items-center"> <div className="flex flex-col items-center">
<div className="w-full"> <div className="w-full">
<RepositoryTable /> <RepositoryTable />
</div> </div>

View file

@ -6,7 +6,9 @@ export function Footer() {
<footer className="w-full mt-auto py-4 flex flex-row justify-center items-center gap-4"> <footer className="w-full mt-auto py-4 flex flex-row justify-center items-center gap-4">
<Link href="https://sourcebot.dev" className="text-gray-400 text-sm hover:underline">About</Link> <Link href="https://sourcebot.dev" className="text-gray-400 text-sm hover:underline">About</Link>
<Separator orientation="vertical" className="h-4" /> <Separator orientation="vertical" className="h-4" />
<Link href="https://github.com/sourcebot-dev/sourcebot/issues/new" className="text-gray-400 text-sm hover:underline">Support</Link> <Link href="https://sourcebot.dev/terms" className="text-gray-400 text-sm hover:underline">Terms</Link>
<Separator orientation="vertical" className="h-4" />
<Link href="https://sourcebot.dev/security" className="text-gray-400 text-sm hover:underline">Security</Link>
<Separator orientation="vertical" className="h-4" /> <Separator orientation="vertical" className="h-4" />
<Link href="mailto:team@sourcebot.dev" className="text-gray-400 text-sm hover:underline">Contact Us</Link> <Link href="mailto:team@sourcebot.dev" className="text-gray-400 text-sm hover:underline">Contact Us</Link>
</footer> </footer>

View file

@ -0,0 +1,86 @@
"use client"
import Link from "next/link"
import { Shield, Lock, CheckCircle, ExternalLink, Mail } from "lucide-react"
import useCaptureEvent from "@/hooks/useCaptureEvent"
export default function SecurityCard() {
const captureEvent = useCaptureEvent();
return (
<div className="mt-12 max-w-md mx-auto text-center">
<div className="bg-backgroundSecondary border border-[#1E2A3A] rounded-lg p-6 shadow-lg">
<div className="flex justify-center mb-4">
<Shield className="h-10 w-10 text-[#9D5CFF]" />
</div>
<h3 className="text-xl font-semibold mb-3">Multi-Layered Security</h3>
<p className="text-[#A1A1AA] mb-6">
We take the security and privacy of your data seriously. All code and secret tokens you provide are protected
using multiple layers of security.
</p>
<div className="space-y-4 mb-5">
<div className="flex items-start">
<CheckCircle className="h-5 w-5 text-[#9D5CFF] mr-3 mt-0.5 flex-shrink-0" />
<span className="text-sm text-foregroundSecondary text-left">
All data is stored on Google Cloud Platform in the United States (us-west-1)
</span>
</div>
<div className="flex items-start">
<CheckCircle className="h-5 w-5 text-[#9D5CFF] mr-3 mt-0.5 flex-shrink-0" />
<span className="text-sm text-foregroundSecondary text-left">
All data is encrypted in transit using TLS 1.2+, and at rest using AES-256
</span>
</div>
<div className="flex items-start">
<CheckCircle className="h-5 w-5 text-[#9D5CFF] mr-3 mt-0.5 flex-shrink-0" />
<div className="text-sm text-foregroundSecondary text-left">
<div className="flex items-center">
<span>Sourcebot is open-source and trusted by thousands of developers</span>
<Link
href="https://github.com/sourcebot-dev/sourcebot"
target="_blank"
className="inline-flex items-center ml-2 text-[#9D5CFF] hover:text-[#B47EFF] transition-colors"
>
<svg
className="h-4 w-4 mr-0.5"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>
<ExternalLink className="h-3 w-3" />
</Link>
</div>
</div>
</div>
</div>
<div className="text-sm text-[#A1A1AA] mb-5">
Have questions?
<Link
href="mailto:team@sourcebot.dev"
className="inline-flex items-center ml-2 text-[#9D5CFF] hover:text-[#B47EFF] transition-colors"
>
<Mail className="h-3.5 w-3.5 mr-1" />
<span>Get in touch</span>
</Link>
</div>
<Link
href="https://sourcebot.dev/security"
target="_blank"
className="inline-flex items-center justify-center px-5 py-2.5 rounded-md bg-backgroundSecondary border border-[#1E2A3A] text-foreground hover:bg-backgroundSecondary/80 transition-colors"
onClick={() => captureEvent('wa_security_page_click', {})}
>
<Lock className="h-4 w-4 mr-2" />
<span>Learn about our security measures</span>
</Link>
</div>
</div>
)
}

View file

@ -12,7 +12,7 @@ import { CredentialsForm } from "./credentialsForm";
import { SourcebotLogo } from "@/app/components/sourcebotLogo"; import { SourcebotLogo } from "@/app/components/sourcebotLogo";
import { TextSeparator } from "@/app/components/textSeparator"; import { TextSeparator } from "@/app/components/textSeparator";
import useCaptureEvent from "@/hooks/useCaptureEvent"; import useCaptureEvent from "@/hooks/useCaptureEvent";
import DemoCard from "@/app/[domain]/onboard/components/demoCard";
interface LoginFormProps { interface LoginFormProps {
callbackUrl?: string; callbackUrl?: string;
error?: string; error?: string;
@ -52,6 +52,9 @@ export const LoginForm = ({ callbackUrl, error, enabledMethods }: LoginFormProps
/> />
<h2 className="text-lg font-bold text-center">Sign in to your account</h2> <h2 className="text-lg font-bold text-center">Sign in to your account</h2>
</div> </div>
<div className="w-full sm:w-[500px] max-w-[500px]">
<DemoCard />
</div>
<Card className="flex flex-col items-center border p-6 sm:p-12 rounded-lg gap-4 sm:gap-6 w-full sm:w-[500px] max-w-[500px] bg-background"> <Card className="flex flex-col items-center border p-6 sm:p-12 rounded-lg gap-4 sm:gap-6 w-full sm:w-[500px] max-w-[500px] bg-background">
{error && ( {error && (
<div className="text-sm text-destructive text-center text-wrap border p-2 rounded-md border-destructive"> <div className="text-sm text-destructive text-center text-wrap border p-2 rounded-md border-destructive">

View file

@ -2,6 +2,8 @@ import { auth } from "@/auth";
import { LoginForm } from "./components/loginForm"; import { LoginForm } from "./components/loginForm";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { getProviders } from "@/auth"; import { getProviders } from "@/auth";
import { Footer } from "@/app/components/footer";
interface LoginProps { interface LoginProps {
searchParams: { searchParams: {
callbackUrl?: string; callbackUrl?: string;
@ -27,7 +29,8 @@ export default async function Login({ searchParams }: LoginProps) {
}); });
return ( return (
<div className="flex flex-col items-center p-4 sm:p-12 min-h-screen w-full bg-backgroundSecondary"> <div className="flex flex-col min-h-screen">
<div className="flex-1 flex flex-col items-center p-4 sm:p-12 w-full bg-backgroundSecondary">
<LoginForm <LoginForm
callbackUrl={searchParams.callbackUrl} callbackUrl={searchParams.callbackUrl}
error={searchParams.error} error={searchParams.error}
@ -39,5 +42,7 @@ export default async function Login({ searchParams }: LoginProps) {
}} }}
/> />
</div> </div>
<Footer />
</div>
) )
} }

View file

@ -12,6 +12,7 @@ import { useCallback, useState, Suspense } from "react"
import VerificationFailed from "./verificationFailed" import VerificationFailed from "./verificationFailed"
import { SourcebotLogo } from "@/app/components/sourcebotLogo" import { SourcebotLogo } from "@/app/components/sourcebotLogo"
import useCaptureEvent from "@/hooks/useCaptureEvent" import useCaptureEvent from "@/hooks/useCaptureEvent"
import { Footer } from "@/app/components/footer"
function VerifyPageContent() { function VerifyPageContent() {
const [value, setValue] = useState("") const [value, setValue] = useState("")
@ -41,7 +42,8 @@ function VerifyPageContent() {
} }
return ( return (
<div className="flex flex-col items-center p-4 sm:p-12 min-h-screen w-full bg-backgroundSecondary"> <div className="flex flex-col min-h-screen">
<div className="flex-1 flex flex-col items-center p-4 sm:p-12 w-full bg-backgroundSecondary">
<div className="w-full max-w-md"> <div className="w-full max-w-md">
<div className="flex justify-center mb-6"> <div className="flex justify-center mb-6">
<SourcebotLogo className="h-16" size="large" /> <SourcebotLogo className="h-16" size="large" />
@ -94,6 +96,8 @@ function VerifyPageContent() {
</div> </div>
</div> </div>
</div> </div>
<Footer />
</div>
) )
} }

View file

@ -238,6 +238,10 @@ export type PosthogEventMap = {
wa_onboard_gitlab_selected: {}, wa_onboard_gitlab_selected: {},
wa_onboard_gitea_selected: {}, wa_onboard_gitea_selected: {},
wa_onboard_gerrit_selected: {}, wa_onboard_gerrit_selected: {},
//////////////////////////////////////////////////////////////////
wa_security_page_click: {},
//////////////////////////////////////////////////////////////////
wa_demo_card_click: {},
} }
export type PosthogEvent = keyof PosthogEventMap; export type PosthogEvent = keyof PosthogEventMap;