Skip to content

Commit

Permalink
Merge pull request #1008 from khoj-ai/features/new-sign-in-page
Browse files Browse the repository at this point in the history
- Make it easier to quickly create the account without losing track of where you are
- Show some capabilities before you sign on
  • Loading branch information
sabaimran authored Dec 17, 2024
2 parents 9c64275 + 753859f commit 6f3218f
Show file tree
Hide file tree
Showing 30 changed files with 1,330 additions and 107 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
- name: 📂 Copy Generated Files
run: |
mkdir -p src/khoj/interface/compiled
cp -r /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/khoj/interface/compiled/* src/khoj/interface/compiled/
cp -r /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages/khoj/interface/compiled/* src/khoj/interface/compiled/
- name: ⚙️ Build Python Package
run: |
Expand Down
11 changes: 9 additions & 2 deletions src/interface/web/app/agents/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,25 @@ import { ContentSecurityPolicy } from "../common/layoutHelper";

export const metadata: Metadata = {
title: "Khoj AI - Agents",
description: "Find a specialized agent that can help you address more specific needs.",
description:
"Find or create agents with custom knowledge, tools and personalities to help address your specific needs.",
icons: {
icon: "/static/assets/icons/khoj_lantern.ico",
apple: "/static/assets/icons/khoj_lantern_256x256.png",
},
openGraph: {
siteName: "Khoj AI",
title: "Khoj AI - Agents",
description: "Your Second Brain.",
description:
"Find or create agents with custom knowledge, tools and personalities to help address your specific needs.",
url: "https://app.khoj.dev/agents",
type: "website",
images: [
{
url: "https://assets.khoj.dev/khoj_hero.png",
width: 940,
height: 525,
},
{
url: "https://assets.khoj.dev/khoj_lantern_256x256.png",
width: 256,
Expand Down
2 changes: 2 additions & 0 deletions src/interface/web/app/agents/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ function CreateAgentCard(props: CreateAgentCardProps) {
<LoginPrompt
loginRedirectMessage="Sign in to start chatting with a specialized agent"
onOpenChange={setShowLoginPrompt}
isMobileWidth={props.isMobileWidth}
/>
)}
<AgentModificationForm
Expand Down Expand Up @@ -317,6 +318,7 @@ export default function Agents() {
<LoginPrompt
loginRedirectMessage="Sign in to start chatting with a specialized agent"
onOpenChange={setShowLoginPrompt}
isMobileWidth={isMobileWidth}
/>
)}
<Alert className="bg-secondary border-none my-4">
Expand Down
11 changes: 9 additions & 2 deletions src/interface/web/app/automations/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,25 @@ import { ContentSecurityPolicy } from "../common/layoutHelper";

export const metadata: Metadata = {
title: "Khoj AI - Automations",
description: "Use Autoomations with Khoj to simplify the process of running repetitive tasks.",
description:
"Use Khoj Automations to get tailored research and event based notifications directly in your inbox.",
icons: {
icon: "/static/assets/icons/khoj_lantern.ico",
apple: "/static/assets/icons/khoj_lantern_256x256.png",
},
openGraph: {
siteName: "Khoj AI",
title: "Khoj AI - Automations",
description: "Your Second Brain.",
description:
"Use Khoj Automations to get tailored research and event based notifications directly in your inbox.",
url: "https://app.khoj.dev/automations",
type: "website",
images: [
{
url: "https://assets.khoj.dev/khoj_hero.png",
width: 940,
height: 525,
},
{
url: "https://assets.khoj.dev/khoj_lantern_256x256.png",
width: 256,
Expand Down
1 change: 1 addition & 0 deletions src/interface/web/app/automations/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,7 @@ export default function Automations() {
<LoginPrompt
loginRedirectMessage={"Create an account to make your own automation"}
onOpenChange={setShowLoginPrompt}
isMobileWidth={isMobileWidth}
/>
)}
<Alert className="bg-secondary border-none my-4">
Expand Down
10 changes: 8 additions & 2 deletions src/interface/web/app/chat/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,24 @@ import { ContentSecurityPolicy } from "../common/layoutHelper";
export const metadata: Metadata = {
title: "Khoj AI - Chat",
description:
"Ask anything. Khoj will use the internet and your docs to answer, paint and even automate stuff for you.",
"Ask anything. Research answers from across the internet and your documents, draft messages, summarize documents, generate paintings and chat with personal agents.",
icons: {
icon: "/static/assets/icons/khoj_lantern.ico",
apple: "/static/assets/icons/khoj_lantern_256x256.png",
},
openGraph: {
siteName: "Khoj AI",
title: "Khoj AI - Chat",
description: "Your Second Brain.",
description:
"Ask anything. Research answers from across the internet and your documents, draft messages, summarize documents, generate paintings and chat with personal agents.",
url: "https://app.khoj.dev/chat",
type: "website",
images: [
{
url: "https://assets.khoj.dev/khoj_hero.png",
width: 940,
height: 525,
},
{
url: "https://assets.khoj.dev/khoj_lantern_256x256.png",
width: 256,
Expand Down
9 changes: 5 additions & 4 deletions src/interface/web/app/common/layoutHelper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ export function ContentSecurityPolicy() {
httpEquiv="Content-Security-Policy"
content="default-src 'self' https://assets.khoj.dev;
media-src * blob:;
script-src 'self' https://assets.khoj.dev https://app.chatwoot.com 'unsafe-inline' 'unsafe-eval';
connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110;
style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com;
img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com;
script-src 'self' https://assets.khoj.dev https://app.chatwoot.com https://accounts.google.com 'unsafe-inline' 'unsafe-eval';
connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110 https://accounts.google.com;
style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com https://accounts.google.com;
img-src 'self' data: blob: https://*.khoj.dev https://accounts.google.com https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com;
font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com;
frame-src 'self' https://accounts.google.com;
child-src 'self' https://app.chatwoot.com;
object-src 'none';"
></meta>
Expand Down
1 change: 1 addition & 0 deletions src/interface/web/app/components/agentCard/agentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ export function AgentCard(props: AgentCardProps) {
<LoginPrompt
loginRedirectMessage={`Sign in to start chatting with ${props.data.name}`}
onOpenChange={setShowLoginPrompt}
isMobileWidth={props.isMobileWidth}
/>
)}
<CardHeader>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ export const ChatInputArea = forwardRef<HTMLTextAreaElement, ChatInputProps>((pr
{showLoginPrompt && loginRedirectMessage && (
<LoginPrompt
onOpenChange={setShowLoginPrompt}
isMobileWidth={props.isMobileWidth}
loginRedirectMessage={loginRedirectMessage}
/>
)}
Expand Down Expand Up @@ -628,7 +629,7 @@ export const ChatInputArea = forwardRef<HTMLTextAreaElement, ChatInputProps>((pr
<Button
variant={"ghost"}
className="!bg-none p-0 m-2 h-auto text-3xl rounded-full text-gray-300 hover:text-gray-500"
disabled={props.sendDisabled}
disabled={props.sendDisabled || !props.isLoggedIn}
onClick={handleFileButtonClick}
>
<Paperclip className="w-8 h-8" />
Expand Down Expand Up @@ -668,7 +669,7 @@ export const ChatInputArea = forwardRef<HTMLTextAreaElement, ChatInputProps>((pr
onClick={() => {
setRecording(!recording);
}}
disabled={props.sendDisabled}
disabled={props.sendDisabled || !props.isLoggedIn}
>
<Stop weight="fill" className="w-6 h-6" />
</Button>
Expand Down Expand Up @@ -698,6 +699,7 @@ export const ChatInputArea = forwardRef<HTMLTextAreaElement, ChatInputProps>((pr
<Button
variant="default"
className={`${!message || recording || "hidden"} ${props.agentColor ? convertToBGClass(props.agentColor) : "bg-orange-300 hover:bg-orange-500"} rounded-full p-1 m-2 h-auto text-3xl transition transform md:hover:-translate-y-1`}
disabled={props.sendDisabled || !props.isLoggedIn}
onClick={() => {
setMessage("Listening...");
setRecording(!recording);
Expand All @@ -717,6 +719,7 @@ export const ChatInputArea = forwardRef<HTMLTextAreaElement, ChatInputProps>((pr
)}
<Button
className={`${(!message || recording) && "hidden"} ${props.agentColor ? convertToBGClass(props.agentColor) : "bg-orange-300 hover:bg-orange-500"} rounded-full p-1 m-2 h-auto text-3xl transition transform md:hover:-translate-y-1`}
disabled={props.sendDisabled || !props.isLoggedIn}
onClick={onSendMessage}
>
<ArrowUp className="w-6 h-6" weight="bold" />
Expand All @@ -729,6 +732,7 @@ export const ChatInputArea = forwardRef<HTMLTextAreaElement, ChatInputProps>((pr
<Button
variant="ghost"
className="float-right justify-center gap-1 flex items-center p-1.5 mr-2 h-fit"
disabled={props.sendDisabled || !props.isLoggedIn}
onClick={() => {
setUseResearchMode(!useResearchMode);
chatInputRef?.current?.focus();
Expand Down
20 changes: 20 additions & 0 deletions src/interface/web/app/components/loginPrompt/GoogleSignIn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// GoogleSignIn.tsx
"use client";

import Script from "next/script";

interface GoogleSignInProps {
onLoad?: () => void;
}

export function GoogleSignIn({ onLoad }: GoogleSignInProps) {
return (
<Script
id="google-signin"
src="https://accounts.google.com/gsi/client"
async
defer
onLoad={onLoad}
/>
);
}
50 changes: 50 additions & 0 deletions src/interface/web/app/components/loginPrompt/loginPopup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use client";

import { Button } from "@/components/ui/button";
import { Card, CardDescription, CardHeader } from "@/components/ui/card";
import { KhojLogo } from "../logo/khojLogo";
import { Drawer, DrawerContent } from "@/components/ui/drawer";

export interface LoginPopupProps {
isMobileWidth?: boolean;
setShowLoginPrompt: (show: boolean) => void;
}

export default function LoginPopup(props: LoginPopupProps) {
if (props.isMobileWidth) {
return (
<Drawer open={true} onClose={() => props.setShowLoginPrompt(false)}>
<DrawerContent>
<PopUpContent {...props} />
</DrawerContent>
</Drawer>
);
}

return (
<div className="fixed inset-x-0 bottom-8 z-30 flex items-center justify-center">
<PopUpContent {...props} />
</div>
);
}

function PopUpContent(props: LoginPopupProps) {
return (
<Card className="rounded-lg p-6 flex flex-col items-center justify-between gap-8 md:w-fit border-none md:flex-row md:z-30 md:shadow-lg">
{!props.isMobileWidth && <KhojLogo className="w-12 h-auto" />}
<div className="flex flex-col items-start justify-center gap-8 md:gap-2">
<CardHeader className="p-0 text-xl font-bold">Welcome to Khoj!</CardHeader>
<CardDescription>
Sign in to get started with Khoj, your AI-powered knowledge assistant.
</CardDescription>
</div>
<Button
variant={"default"}
className="p-6 text-lg"
onClick={() => props.setShowLoginPrompt(true)}
>
Get started for free
</Button>
</Card>
);
}
114 changes: 114 additions & 0 deletions src/interface/web/app/components/loginPrompt/loginPrompt.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
.gsiMaterialButton {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-webkit-appearance: none;
background-image: none;
/* border: 1px solid #747775; */
-webkit-border-radius: 20px;
border-radius: 20px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #1f1f1f;
cursor: pointer;
font-family: "Roboto", arial, sans-serif;
font-size: 14px;
height: 40px;
letter-spacing: 0.25px;
outline: none;
overflow: hidden;
padding: 0;
position: relative;
text-align: center;
-webkit-transition:
background-color 0.218s,
border-color 0.218s,
box-shadow 0.218s;
transition:
background-color 0.218s,
border-color 0.218s,
box-shadow 0.218s;
vertical-align: middle;
white-space: nowrap;
width: 40px;
max-width: 400px;
min-width: min-content;
}

.gsiMaterialButton .gsiMaterialButtonIcon {
height: 100%;
margin-right: 12px;
min-width: 20px;
width: 100%;
margin: 0;
padding: 9px;
}

.gsiMaterialButton .gsiMaterialButtonContentWrapper {
-webkit-align-items: center;
align-items: center;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: nowrap;
flex-wrap: nowrap;
height: 100%;
justify-content: space-between;
position: relative;
width: 100%;
}

.gsiMaterialButton .gsiMaterialButtonContents {
-webkit-flex-grow: 1;
flex-grow: 1;
font-family: "Roboto", arial, sans-serif;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
}

.gsiMaterialButton .gsiMaterialButtonState {
-webkit-transition: opacity 0.218s;
transition: opacity 0.218s;
bottom: 0;
left: 0;
opacity: 0;
position: absolute;
right: 0;
top: 0;
}

.gsiMaterialButton:disabled {
cursor: default;
background-color: #ffffff61;
border-color: #1f1f1f1f;
}

.gsiMaterialButton:disabled .gsiMaterialButtonContents {
opacity: 38%;
}

.gsiMaterialButton:disabled .gsiMaterialButtonIcon {
opacity: 38%;
}

.gsiMaterialButton:not(:disabled):active .gsiMaterialButton-State,
.gsiMaterialButton:not(:disabled):focus .gsiMaterialButtonState {
background-color: #303030;
opacity: 12%;
}

.gsiMaterialButton:not(:disabled):hover {
-webkit-box-shadow:
0 1px 2px 0 rgba(60, 64, 67, 0.3),
0 1px 3px 1px rgba(60, 64, 67, 0.15);
box-shadow:
0 1px 2px 0 rgba(60, 64, 67, 0.3),
0 1px 3px 1px rgba(60, 64, 67, 0.15);
}

.gsiMaterialButton:not(:disabled):hover .gsiMaterialButtonState {
background-color: #303030;
opacity: 8%;
}
Loading

0 comments on commit 6f3218f

Please sign in to comment.