Skip to content

Commit

Permalink
Feat: improve design of auth pages (#592)
Browse files Browse the repository at this point in the history
  • Loading branch information
vincelwt authored Oct 6, 2024
1 parent ed120ea commit b3800cf
Show file tree
Hide file tree
Showing 11 changed files with 520 additions and 508 deletions.
58 changes: 29 additions & 29 deletions e2e/auth.setup.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
import { test, expect } from "@playwright/test"
import { test, expect } from "@playwright/test";

import { deleteOrg, populateLogs } from "./utils/db"
import { deleteOrg, populateLogs } from "./utils/db";

const authFile = "e2e/.auth/user.json"
const authFile = "e2e/.auth/user.json";

test.beforeAll(async () => {
// Sometimes the teardown isn't called, so we need to clean up the database before running the tests
await deleteOrg()
})
await deleteOrg();
});

test("signup flow", async ({ page }) => {
await page.goto("/")
await page.goto("/");

await page.getByRole("link", { name: "Sign Up" }).click()
await page.getByRole("link", { name: "Sign Up" }).click();

await page.waitForURL("**/signup")
await page.waitForURL("**/signup");

await page.getByPlaceholder("Your email").click()
await page.getByPlaceholder("Your email").fill("test@lunary.ai")
await page.getByPlaceholder("Your email").click();
await page.getByPlaceholder("Your email").fill("test@lunary.ai");

await page.getByPlaceholder("Your full name").click()
await page.getByPlaceholder("Your full name").fill("test test")
await page.getByPlaceholder("Your full name").click();
await page.getByPlaceholder("Your full name").fill("test test");

await page.getByPlaceholder("Your password").click()
await page.getByPlaceholder("Your password").fill("testtest")
await page.getByPlaceholder("Pick a password").click();
await page.getByPlaceholder("Pick a password").fill("testtest");

await page.getByRole("button", { name: "Continue →" }).click()
await page.getByTestId("continue-button").click();

await page.getByPlaceholder("Your project name").click()
await page.getByPlaceholder("Your project name").fill("TESTPROJECT")
await page.getByPlaceholder("Your project name").click();
await page.getByPlaceholder("Your project name").fill("TESTPROJECT");

await page.getByPlaceholder("Organization name").click()
await page.getByPlaceholder("Organization name").fill("TESTORG")
await page.getByPlaceholder("Organization name").click();
await page.getByPlaceholder("Organization name").fill("TESTORG");

await page.getByLabel("6-49").check()
// await page.getByLabel("6-49").check();

await page.getByRole("button", { name: "Create account" }).click()
await page.getByTestId("finish-button").click();

await page.waitForNavigation()
await page.waitForNavigation();

await expect(page.getByText("Are you free in the next days")).toBeVisible()
// await expect(page.getByText("Are you free in the next days")).toBeVisible();

await page.getByRole("button", { name: "Skip to Dashboard" }).click()
await page.getByTestId("open-dashboard-button").click();

await page.waitForURL("**/analytics")
await page.waitForURL("**/analytics");

await expect(
page.getByRole("heading", { name: "Waiting for data..." }),
).toBeVisible()
).toBeVisible();

await page.context().storageState({ path: authFile })
await page.context().storageState({ path: authFile });

await populateLogs()
})
await populateLogs();
});
2 changes: 1 addition & 1 deletion packages/backend/src/jobs/resetUsage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ RETURNING *;`;

// reset playground allowance
async function resetPlaygroundAllowance() {
await sql`UPDATE "public"."org" o SET play_allowance = 3 WHERE o.plan = 'free';`;
await sql`UPDATE "public"."org" o SET play_allowance = 10 WHERE o.plan = 'free';`;
await sql`UPDATE "public"."org" o SET play_allowance = 1000 WHERE o.plan = 'pro' OR o.plan = 'team';`;
await sql`UPDATE "public"."org" o SET play_allowance = 1000 WHERE o.plan = 'unlimited' OR o.plan = 'custom';`;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/components/blocks/SocialProof.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ export default function SocialProof() {
span
fw="bolder"
>
2500+
4500+
</Text>{" "}
AI devs build better apps
GenAI devs build better apps
</Text>
</Stack>
</Group>
Expand Down
4 changes: 3 additions & 1 deletion packages/frontend/components/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export default function Layout({ children }: { children: ReactNode }) {
"/reset-password",
].find((path) => router.pathname.startsWith(path));

const isSignupPage = router.pathname.startsWith("/signup");

const isSignupLastStep =
router.pathname === "/signup" && router.query.step === "3";

Expand Down Expand Up @@ -74,7 +76,7 @@ export default function Layout({ children }: { children: ReactNode }) {

const isPromptPage = router.pathname.startsWith("/prompt");
const isTracePage = router.pathname.startsWith("/traces");
const disablePagePadding = isPromptPage || isTracePage;
const disablePagePadding = isPromptPage || isTracePage || isAuthPage;

useEffect(() => {
if (user) {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/basic-features/typescript for more information.
171 changes: 85 additions & 86 deletions packages/frontend/pages/login.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Anchor,
Box,
Button,
Container,
Paper,
Expand Down Expand Up @@ -143,102 +144,100 @@ function LoginPage() {
const email = router.query.email
? decodeURIComponent(router.query.email as string)
: "";
console.log(form.values.password);
if (email && !form.values.email) {
console.log("here");
form.setFieldValue("email", email);
determineAuthMethod(email);
console.log(step);
}
}, [router.query.email]);

return (
<Container pt="60" size="600">
<NextSeo title="Login" />
<Stack align="center" gap="50">
<Stack align="center">
<IconAnalyze color="#206dce" size="60" />
<Title order={2} fw="700" size="40" ta="center">
Welcome back
</Title>
</Stack>
<Paper radius="md" p="xl" withBorder miw="350">
<Text size="lg" mb="xl" fw="700">
Sign In
</Text>

{step !== "saml" && (
<form
onSubmit={
step === "email"
? (e) => {
determineAuthMethod(form.values.email);
e.preventDefault();
<Box style={{ backgroundColor: "var(--mantine-color-gray-0)" }} h="100vh">
<Container size="600" pt="60">
<NextSeo title="Login" />
<Stack align="center" gap="50">
<Stack align="center">
<IconAnalyze color="#4f87ff" size="60" />
</Stack>
<Paper radius="md" p="xl" miw="350" shadow="md">
<Text size="xl" mb="lg" fw="700" ta="center">
Welcome back!
</Text>

{step !== "saml" && (
<form
onSubmit={
step === "email"
? (e) => {
determineAuthMethod(form.values.email);
e.preventDefault();
}
: form.onSubmit(handleLoginWithPassword)
}
>
<Stack>
<TextInput
leftSection={<IconAt size="16" />}
label="Email"
type="email"
autoComplete="email"
value={form.values.email}
onChange={(event) =>
form.setFieldValue("email", event.currentTarget.value)
}
error={form.errors.email}
placeholder="Your email"
/>
<TextInput
type="password"
opacity={step === "email" ? 0 : 1}
h={step === "email" ? 0 : "auto"}
autoComplete="current-password"
label="Password"
value={form.values.password}
onChange={(event) =>
form.setFieldValue("password", event.currentTarget.value)
}
: form.onSubmit(handleLoginWithPassword)
}
>
<Stack>
<TextInput
leftSection={<IconAt size="16" />}
label="Email"
type="email"
autoComplete="email"
value={form.values.email}
onChange={(event) =>
form.setFieldValue("email", event.currentTarget.value)
}
error={form.errors.email}
placeholder="Your email"
/>
<TextInput
type="password"
opacity={step === "email" ? 0 : 1}
h={step === "email" ? 0 : "auto"}
autoComplete="current-password"
label="Password"
value={form.values.password}
onChange={(event) =>
form.setFieldValue("password", event.currentTarget.value)
}
error={form.errors.password}
placeholder="Your password"
/>
<Button
mt={step === "email" ? 0 : "md"}
type="submit"
fullWidth
loading={loading}
data-testid="continue-button"
>
{step === "email" ? "Continue" : "Login"}
</Button>
</Stack>
</form>
)}

{step === "saml" && (
<p>
Redirecting to your SSO login.
<br />
If you are not redirected in 5s,{" "}
<Anchor href={ssoURI || ""}>click here</Anchor>.
</p>
)}

<Text size="sm" mt="sm" style={{ textAlign: "center" }}>
{`Don't have an account? `}
<Anchor href="/signup">Sign Up</Anchor>
</Text>

{step === "password" && (
error={form.errors.password}
placeholder="Your password"
/>
<Button
mt={step === "email" ? 0 : "md"}
type="submit"
fullWidth
className="CtaBtn"
size="md"
loading={loading}
data-testid="continue-button"
>
{step === "email" ? "Continue" : "Login"}
</Button>
</Stack>
</form>
)}

{step === "saml" && (
<p>
Redirecting to your SSO login.
<br />
If you are not redirected in 5s,{" "}
<Anchor href={ssoURI || ""}>click here</Anchor>.
</p>
)}

<Text size="sm" mt="sm" style={{ textAlign: "center" }}>
<Anchor href="/request-password-reset">Forgot password?</Anchor>
{`Don't have an account? `}
<Anchor href="/signup">Sign Up</Anchor>
</Text>
)}
</Paper>
</Stack>
</Container>

{step === "password" && (
<Text size="sm" mt="sm" style={{ textAlign: "center" }}>
<Anchor href="/request-password-reset">Forgot password?</Anchor>
</Text>
)}
</Paper>
</Stack>
</Container>
</Box>
);
}
export default LoginPage;
Loading

0 comments on commit b3800cf

Please sign in to comment.