Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the sign in / account creation experiences #1008

Merged
merged 32 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
eb1b21b
Add a new sign in modal that is triggered from the login prompt scree…
sabaimran Nov 23, 2024
530b44c
Merge branch 'master' of github.com:khoj-ai/khoj into features/new-si…
sabaimran Dec 11, 2024
d35db99
Initial version of a carousel working for sign in with steps for emai…
sabaimran Dec 12, 2024
de6ed23
Break up the parts of the login dialog into smaller modules to extend…
sabaimran Dec 12, 2024
142239d
Add mobile friendliness and replace the login page redirects
sabaimran Dec 12, 2024
0f8b055
Improve padding for space, esp in mobile
sabaimran Dec 12, 2024
b60b750
Update the styling to align with Google branding via the sign in button
sabaimran Dec 12, 2024
41bb1e6
Use the LoginPrompt in the chat history side panel
sabaimran Dec 12, 2024
943065b
Remove dead dependencies and improve the google sign in button
sabaimran Dec 12, 2024
a7d0ed8
Add carousel for navigating images in the sign up modal
sabaimran Dec 12, 2024
ad3f8a3
Add a static login footer that prompts login, disable input box witho…
sabaimran Dec 12, 2024
dfc150c
Merge branch 'master' of github.com:khoj-ai/khoj into features/new-si…
sabaimran Dec 12, 2024
4697dae
Improve opengraph metadata across front-end pages
sabaimran Dec 12, 2024
144f283
Maintain old login page for posterity and associated API
sabaimran Dec 13, 2024
e74e922
Update file path of python installation
sabaimran Dec 13, 2024
62545a9
Update package path for pypi ci export
sabaimran Dec 13, 2024
d5681ad
Update image assets to sign up prompt
sabaimran Dec 13, 2024
f1fb452
Remove old images
sabaimran Dec 13, 2024
73c1fe6
Add text overlay to caption the different assets
sabaimran Dec 13, 2024
c25174e
Apply more finished styling to login features, make the pop-up mobile…
sabaimran Dec 14, 2024
6a56140
Allow users to directly enter their unique code when logging in
sabaimran Dec 14, 2024
8e33131
Simplify the magic link email a little bit
sabaimran Dec 14, 2024
5d3da33
Include email in verification API
sabaimran Dec 15, 2024
b778335
Decrease timeout limit for verification codes to 5 minutes
sabaimran Dec 16, 2024
ae9750e
Add rate limiting to OTP login attempts and update email template for…
sabaimran Dec 16, 2024
28b8f91
Remove parenthetical from email template
sabaimran Dec 16, 2024
064f7e4
Update various copy texts for OG metadata and such
sabaimran Dec 17, 2024
efb0b9f
Gracefully handle error when user login code is expired
sabaimran Dec 17, 2024
d17a9ba
Fix return data for expired code user
sabaimran Dec 17, 2024
13e7455
Use lowercase c in click
sabaimran Dec 17, 2024
20888d3
Clarify some of the language in the sign in email
sabaimran Dec 17, 2024
753859f
Make the docs and github buttons on the sign in email less prominent
sabaimran Dec 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
sabaimran marked this conversation as resolved.
Show resolved Hide resolved
</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
Loading