Skip to content

Commit 7e472af

Browse files
authored
Merge pull request #977 from trycompai/main
[comp] Production Deploy
2 parents befb99e + 96e2771 commit 7e472af

7 files changed

Lines changed: 191 additions & 145 deletions

File tree

Lines changed: 42 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
import { GithubSignIn } from '@/components/github-sign-in';
2-
import { GoogleSignIn } from '@/components/google-sign-in';
3-
import { MagicLinkSignIn } from '@/components/magic-link';
1+
import { LoginForm } from '@/components/login-form';
42
import { env } from '@/env.mjs';
53
import { auth } from '@/utils/auth';
6-
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@comp/ui/accordion';
4+
import {
5+
Card,
6+
CardContent,
7+
CardDescription,
8+
CardFooter,
9+
CardHeader,
10+
CardTitle,
11+
} from '@comp/ui/card';
712
import { Icons } from '@comp/ui/icons';
813
import type { Metadata } from 'next';
914
import { headers } from 'next/headers';
1015
import Link from 'next/link';
1116
import { redirect } from 'next/navigation';
12-
import Balancer from 'react-wrap-balancer';
1317

1418
export const metadata: Metadata = {
1519
title: 'Login | Comp AI',
@@ -25,40 +29,6 @@ export default async function Page({
2529
});
2630
const { inviteCode } = await searchParams;
2731

28-
let preferredSignInOption: React.ReactNode;
29-
30-
if (env.AUTH_GOOGLE_ID && env.AUTH_GOOGLE_SECRET) {
31-
preferredSignInOption = (
32-
<div className="flex flex-col space-y-2">
33-
<GoogleSignIn inviteCode={inviteCode} />
34-
</div>
35-
);
36-
} else {
37-
preferredSignInOption = (
38-
<div className="flex flex-col space-y-2">
39-
<MagicLinkSignIn inviteCode={inviteCode} />
40-
</div>
41-
);
42-
}
43-
44-
let moreSignInOptions: React.ReactNode;
45-
46-
if (
47-
env.AUTH_GOOGLE_ID &&
48-
env.AUTH_GOOGLE_SECRET &&
49-
env.AUTH_GITHUB_ID &&
50-
env.AUTH_GITHUB_SECRET
51-
) {
52-
moreSignInOptions = (
53-
<div className="flex flex-col space-y-2">
54-
<MagicLinkSignIn inviteCode={inviteCode} />
55-
<GithubSignIn inviteCode={inviteCode} />
56-
</div>
57-
);
58-
} else {
59-
moreSignInOptions = null;
60-
}
61-
6232
const orgId = session?.session?.activeOrganizationId;
6333

6434
if (orgId && inviteCode) {
@@ -69,57 +39,46 @@ export default async function Page({
6939
redirect('/');
7040
}
7141

72-
return (
73-
<div>
74-
<header className="fixed right-0 left-0 w-full">
75-
<div className="mt-4 ml-5 md:mt-10 md:ml-10">
76-
<Link href="/">
77-
<Icons.Logo />
78-
</Link>
79-
</div>
80-
</header>
81-
82-
<div className="flex min-h-screen items-center justify-center overflow-hidden p-6 md:p-0">
83-
<div className="relative z-20 m-auto flex w-full max-w-[380px] flex-col py-8">
84-
<div className="relative flex w-full flex-col">
85-
<Balancer>
86-
<h1 className="pb-1 text-3xl font-medium">Get Started with Comp AI</h1>
87-
<h2 className="pb-1 text-xl font-medium">
88-
{'Automate SOC 2, ISO 27001 and GDPR compliance with AI.'}
89-
</h2>
90-
</Balancer>
91-
92-
<div className="pointer-events-auto mt-6 mb-6 flex flex-col">
93-
{preferredSignInOption}
42+
const showGoogle = !!(env.AUTH_GOOGLE_ID && env.AUTH_GOOGLE_SECRET);
43+
const showGithub = !!(env.AUTH_GITHUB_ID && env.AUTH_GITHUB_SECRET);
9444

95-
<Accordion type="single" collapsible className="mt-6 border-t-[1px] pt-2">
96-
{moreSignInOptions && (
97-
<AccordionItem value="item-1" className="border-0">
98-
<AccordionTrigger className="flex justify-center space-x-2 text-sm">
99-
<span>More options</span>
100-
</AccordionTrigger>
101-
<AccordionContent className="mt-4">
102-
<div className="flex flex-col space-y-4">{moreSignInOptions}</div>
103-
</AccordionContent>
104-
</AccordionItem>
105-
)}
106-
</Accordion>
107-
</div>
108-
109-
<p className="text-muted-foreground text-xs">
45+
return (
46+
<div className="flex min-h-screen flex-col text-foreground">
47+
<main className="flex flex-1 items-center justify-center p-6">
48+
<Card className="w-full max-w-lg">
49+
<CardHeader className="text-center space-y-3 pt-10">
50+
<Icons.Logo className="h-10 w-10 mx-auto" />
51+
<CardTitle className="text-2xl tracking-tight text-card-foreground">
52+
Get Started with Comp AI
53+
</CardTitle>
54+
<CardDescription className="text-base text-muted-foreground px-4">
55+
{`Automate SOC 2, ISO 27001 and GDPR compliance with AI.`}
56+
</CardDescription>
57+
</CardHeader>
58+
<CardContent className="space-y-6 pb-6 px-8">
59+
<LoginForm inviteCode={inviteCode} showGoogle={showGoogle} showGithub={showGithub} />
60+
</CardContent>
61+
<CardFooter className="pb-10">
62+
<p className="w-full px-6 text-center text-xs text-muted-foreground">
11063
By clicking continue, you acknowledge that you have read and agree to the{' '}
111-
<a href="https://trycomp.ai/terms-and-conditions" className="underline">
64+
<Link
65+
href="https://trycomp.ai/terms-and-conditions"
66+
className="underline hover:text-primary"
67+
>
11268
Terms and Conditions
113-
</a>{' '}
69+
</Link>{' '}
11470
and{' '}
115-
<a href="https://trycomp.ai/privacy-policy" className="underline">
71+
<Link
72+
href="https://trycomp.ai/privacy-policy"
73+
className="underline hover:text-primary"
74+
>
11675
Privacy Policy
117-
</a>
76+
</Link>
11877
.
11978
</p>
120-
</div>
121-
</div>
122-
</div>
79+
</CardFooter>
80+
</Card>
81+
</main>
12382
</div>
12483
);
12584
}

apps/app/src/components/github-sign-in.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use client';
22

3-
import { ButtonIcon } from '@/components/ui/button-icon';
43
import { authClient } from '@/utils/auth-client';
54
import { Button } from '@comp/ui/button';
65
import { Icons } from '@comp/ui/icons';
@@ -24,16 +23,16 @@ export function GithubSignIn({ inviteCode }: { inviteCode?: string }) {
2423
return (
2524
<Button
2625
onClick={handleSignIn}
27-
className="flex h-[40px] w-full space-x-2 px-6 py-4 font-medium active:scale-[0.98]"
26+
className="w-full h-11 font-medium"
27+
variant="outline"
28+
disabled={isLoading}
2829
>
2930
{isLoading ? (
3031
<Loader2 className="h-4 w-4 animate-spin" />
3132
) : (
3233
<>
33-
<ButtonIcon isLoading={isLoading}>
34-
<Icons.Github />
35-
</ButtonIcon>
36-
<span>{'Continue with GitHub'}</span>
34+
<Icons.Github className="h-4 w-4" />
35+
Continue with GitHub
3736
</>
3837
)}
3938
</Button>

apps/app/src/components/google-sign-in.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use client';
22

3-
import { ButtonIcon } from '@/components/ui/button-icon';
43
import { authClient } from '@/utils/auth-client';
54
import { Button } from '@comp/ui/button';
65
import { Icons } from '@comp/ui/icons';
@@ -27,16 +26,16 @@ export function GoogleSignIn({ inviteCode }: { inviteCode?: string }) {
2726
return (
2827
<Button
2928
onClick={handleSignIn}
30-
className="flex h-[40px] w-full space-x-2 px-6 py-4 font-medium active:scale-[0.98]"
29+
className="w-full h-11 font-medium"
30+
variant="outline"
31+
disabled={isLoading}
3132
>
3233
{isLoading ? (
3334
<Loader2 className="h-4 w-4 animate-spin" />
3435
) : (
3536
<>
36-
<ButtonIcon isLoading={isLoading}>
37-
<Icons.Google />
38-
</ButtonIcon>
39-
<span>{'Continue with Google'}</span>
37+
<Icons.Google className="h-4 w-4" />
38+
Continue with Google
4039
</>
4140
)}
4241
</Button>
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
'use client';
2+
3+
import { GithubSignIn } from '@/components/github-sign-in';
4+
import { GoogleSignIn } from '@/components/google-sign-in';
5+
import { MagicLinkSignIn } from '@/components/magic-link';
6+
import { Button } from '@comp/ui/button';
7+
import { Card, CardContent, CardDescription, CardTitle } from '@comp/ui/card';
8+
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@comp/ui/collapsible';
9+
import { CheckCircle2, ChevronDown, ChevronUp } from 'lucide-react';
10+
import { useState } from 'react';
11+
12+
interface LoginFormProps {
13+
inviteCode?: string;
14+
showGoogle: boolean;
15+
showGithub: boolean;
16+
}
17+
18+
export function LoginForm({ inviteCode, showGoogle, showGithub }: LoginFormProps) {
19+
const [isOptionsOpen, setIsOptionsOpen] = useState(false);
20+
const [magicLinkState, setMagicLinkState] = useState({ sent: false, email: '' });
21+
22+
const handleMagicLinkSent = (email: string) => {
23+
setMagicLinkState({ sent: true, email });
24+
};
25+
26+
if (magicLinkState.sent) {
27+
return (
28+
<Card className="w-full max-w-md">
29+
<CardContent className="flex flex-col items-center justify-center text-center space-y-6 py-16 px-6">
30+
<CheckCircle2 className="h-16 w-16 text-green-500 dark:text-green-400" />
31+
<div className="space-y-2">
32+
<CardTitle className="text-2xl font-semibold text-card-foreground">
33+
Magic link sent
34+
</CardTitle>
35+
<CardDescription className="text-sm text-muted-foreground">
36+
Check your inbox at{' '}
37+
<span className="font-semibold text-foreground">{magicLinkState.email}</span> for a
38+
magic link to sign in.
39+
</CardDescription>
40+
</div>
41+
<Button variant="link" onClick={() => setMagicLinkState({ sent: false, email: '' })}>
42+
Use another method
43+
</Button>
44+
</CardContent>
45+
</Card>
46+
);
47+
}
48+
49+
const preferredSignInOption = showGoogle ? (
50+
<GoogleSignIn inviteCode={inviteCode} />
51+
) : (
52+
<MagicLinkSignIn
53+
key="preferred-magic"
54+
inviteCode={inviteCode}
55+
onMagicLinkSubmit={handleMagicLinkSent}
56+
/>
57+
);
58+
59+
const moreOptionsList = [];
60+
if (showGoogle) {
61+
moreOptionsList.push(
62+
<MagicLinkSignIn
63+
key="secondary-magic"
64+
inviteCode={inviteCode}
65+
onMagicLinkSubmit={handleMagicLinkSent}
66+
/>,
67+
);
68+
}
69+
if (showGithub) {
70+
moreOptionsList.push(<GithubSignIn key="github" inviteCode={inviteCode} />);
71+
}
72+
73+
return (
74+
<div className="space-y-4">
75+
{preferredSignInOption}
76+
77+
{moreOptionsList.length > 0 && (
78+
<Collapsible open={isOptionsOpen} onOpenChange={setIsOptionsOpen} className="w-full">
79+
<div className="relative flex items-center justify-center py-2">
80+
<div className="absolute inset-x-0 top-1/2 flex items-center">
81+
<span className="w-full border-t" />
82+
</div>
83+
<CollapsibleTrigger asChild>
84+
<Button
85+
variant="outline"
86+
size="sm"
87+
className="relative px-4 text-sm text-muted-foreground bg-background hover:bg-muted"
88+
>
89+
More options
90+
{isOptionsOpen ? (
91+
<ChevronUp className="ml-1 h-4 w-4 transition-transform duration-200" />
92+
) : (
93+
<ChevronDown className="ml-1 h-4 w-4 transition-transform duration-200" />
94+
)}
95+
</Button>
96+
</CollapsibleTrigger>
97+
</div>
98+
99+
<CollapsibleContent className="space-y-4 pt-4 data-[state=open]:animate-in data-[state=open]:slide-in-from-top-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95">
100+
{moreOptionsList}
101+
</CollapsibleContent>
102+
</Collapsible>
103+
)}
104+
</div>
105+
);
106+
}

0 commit comments

Comments
 (0)