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

feat(consent): added register page #3505

Merged
merged 2 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 apps/consent/app/components/input-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const InputComponent: React.FC<InputProps> = ({ label, id, ...inputProps }) => {
border-1
border-solid
border-gray-300
rounded-sm
rounded-md
mb-
w-full
bg-[var(--inputBackground)]
Expand Down
25 changes: 25 additions & 0 deletions apps/consent/app/components/login-link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react"
import Link from "next/link"

type LoginLinkProp = {
href: string
}

const LoginLink: React.FC<LoginLinkProp> = ({ href }) => {
return (
<div className="flex justify-center mt-6">
<div className="text-center text-sm ">
<Link href={href} replace>
<p className="font-medium text-sm">
Already have an Account?{" "}
<span className="font-semibold text-[var(--primaryButtonBackground)] dark:text-[var(--primaryButtonBackground)] hover:underline">
Login Here.
</span>
</p>
</Link>
</div>
</div>
)
}

export default LoginLink
65 changes: 65 additions & 0 deletions apps/consent/app/components/phone-auth/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { redirect } from "next/navigation"
import React from "react"

import PhoneAuthForm from "./phone-auth-form"

import { getSupportedCountryCodes } from "@/app/graphql/queries/get-supported-countries"

import { hydraClient } from "@/services/hydra"
import Card from "@/app/components/card"
import MainContent from "@/app/components/main-container"
import Logo from "@/app/components/logo"
import Heading from "@/app/components/heading"
import SubHeading from "@/app/components/sub-heading"

interface PhoneAuth {
login_challenge: string
authAction: "Register" | "Login"
}

const PhoneAuth = async ({ login_challenge, authAction }: PhoneAuth) => {
if (!login_challenge) {
throw new Error("Invalid Request")
}

const { data: body } = await hydraClient.getOAuth2LoginRequest({
loginChallenge: login_challenge,
})

if (body.skip) {
const { data: response } = await hydraClient.acceptOAuth2LoginRequest({
loginChallenge: login_challenge,
acceptOAuth2LoginRequest: {
subject: String(body.subject),
},
})
redirect(String(response.redirect_to))
}

const countries = await getSupportedCountryCodes()
if (!countries) {
throw new Error("Unable to get Countries")
}

const countryCodes = countries.map((country) => country.id)
const subHeadingMessage =
authAction === "Register"
? "Enter your phone number to register with Blink and log in to this application."
: "Enter your phone number to log in to this application."

return (
<MainContent>
<Card>
<Logo />
<Heading>{authAction} In with Blink</Heading>
<SubHeading>{subHeadingMessage}</SubHeading>
<PhoneAuthForm
authAction={authAction}
countryCodes={countryCodes}
login_challenge={login_challenge}
/>
</Card>
</MainContent>
)
}
export default PhoneAuth
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import { E164Number } from "libphonenumber-js/types"
// @ts-ignore-next-line error
import { experimental_useFormState as useFormState } from "react-dom"

import { getCaptchaChallenge } from "./server-actions"
import LoginLink from "../login-link"

import { GetCaptchaChallengeResponse } from "./phone-login.types"
import { getCaptchaChallenge } from "@/app/login/phone/server-actions"

import { GetCaptchaChallengeResponse } from "@/app/types/phone-auth.types"

import PrimaryButton from "@/app/components/button/primary-button-component"
import SecondaryButton from "@/app/components/button/secondary-button-component"
Expand All @@ -23,22 +25,29 @@ import { CaptchaChallenge } from "@/app/components/captcha-challenge"
import FormComponent from "@/app/components/form-component"
import Separator from "@/app/components/separator"

import { SubmitValue } from "@/app/index.types"
import { SubmitValue } from "@/app/types/index.types"
// eslint-disable-next-line import/no-unassigned-import
import "react-phone-number-input/style.css"
// eslint-disable-next-line import/no-unassigned-import
import "./phone-input-styles.css"

import SelectComponent from "@/app/components/select"

interface LoginFormProps {
import RegisterLink from "@/app/components/register-link"

interface AuthFormProps {
authAction: "Register" | "Login"
login_challenge: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
countryCodes: any
}

// TODO need to add country call codes
const LoginForm: React.FC<LoginFormProps> = ({ login_challenge, countryCodes }) => {
const PhoneAuthForm: React.FC<AuthFormProps> = ({
login_challenge,
countryCodes,
authAction,
}) => {
const [phoneNumber, setPhoneNumber] = useState<string>("")
//TODO useFormState is not giving type suggestions/errors i.e: not typed
const [state, formAction] = useFormState<GetCaptchaChallengeResponse>(
Expand Down Expand Up @@ -121,15 +130,19 @@ const LoginForm: React.FC<LoginFormProps> = ({ login_challenge, countryCodes })
Remember me
</label>
</div>
<Separator>or</Separator>

<div className="flex justify-center mb-4">
<div className="text-center text-sm w-60">
<Link href={`/login?login_challenge=${login_challenge}`} replace>
<p className="font-semibold text-sm">Sign in with Email</p>
</Link>
</div>
</div>

{authAction === "Register" ? null : (
<>
<Separator>or</Separator>
<div className="flex justify-center mb-4">
<div className="text-center text-sm w-60">
<Link href={`/login?login_challenge=${login_challenge}`} replace>
<p className="font-semibold text-sm">Sign in with Email</p>
</Link>
</div>
</div>
</>
)}

<div className="flex flex-col md:flex-row-reverse w-full gap-2">
<PrimaryButton
Expand All @@ -152,8 +165,13 @@ const LoginForm: React.FC<LoginFormProps> = ({ login_challenge, countryCodes })
</SecondaryButton>
</div>
</FormComponent>
{authAction === "Register" ? (
<LoginLink href={`/login/phone?login_challenge=${login_challenge}`} />
) : (
<RegisterLink href={`/register?login_challenge=${login_challenge}`} />
)}
</>
)
}

export default LoginForm
export default PhoneAuthForm
25 changes: 25 additions & 0 deletions apps/consent/app/components/register-link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react"
import Link from "next/link"

type RegisterLinkProp = {
href: string
}

const RegisterLink: React.FC<RegisterLinkProp> = ({ href }) => {
return (
<div className="flex justify-center mt-6">
<div className="text-center text-sm ">
<Link href={href} replace>
<p className="font-medium text-sm">
Don&apos;t have an Account?{" "}
<span className="font-semibold text-[var(--primaryButtonBackground)] dark:text-[var(--primaryButtonBackground)] hover:underline">
Register Here.
</span>
</p>
</Link>
</div>
</div>
)
}

export default RegisterLink
2 changes: 1 addition & 1 deletion apps/consent/app/components/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const SelectComponent: React.FC<SelectProps> = ({
border-1
border-solid
border-gray-300
rounded-sm
rounded-md
w-full
bg-[var(--inputBackground)]
focus:border-blue-500 "
Expand Down
2 changes: 1 addition & 1 deletion apps/consent/app/consent/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import ScopeItem from "../components/scope-item/scope-item"
import PrimaryButton from "../components/button/primary-button-component"
import SecondaryButton from "../components/button/secondary-button-component"
import Heading from "../components/heading"
import { SubmitValue } from "../index.types"
import { SubmitValue } from "../types/index.types"

interface ConsentProps {
consent_challenge: string
Expand Down
2 changes: 1 addition & 1 deletion apps/consent/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
--primaryButtonFont: var(--black);
--inputBackground: var(--darkGrey);
--inputColor: var(--white);
--inputSecondary: var(--grey4);
--inputSecondary: var(--grey3);
--shadow:
rgba(255, 255, 255, 0.144) 0px 1px 3px 0px,
rgba(227, 231, 235, 0.144) 0px 0px 0px 1px;
Expand Down
119 changes: 63 additions & 56 deletions apps/consent/app/login/email-login-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ import FormComponent from "../components/form-component"
import Separator from "../components/separator"
import PrimaryButton from "../components/button/primary-button-component"
import SecondaryButton from "../components/button/secondary-button-component"
import { SubmitValue } from "../index.types"
import RegisterLink from "../components/register-link"

import { SubmitValue } from "../types/index.types"

import { submitForm } from "./email-login-server-action"

interface LoginProps {
login_challenge: string
}
Expand All @@ -30,63 +33,67 @@ const EmailLoginForm = ({ login_challenge }: LoginProps) => {
}

return (
<FormComponent action={formAction}>
<input type="hidden" name="login_challenge" value={login_challenge} />
<InputComponent
data-testid="email_id_input"
label="Email"
type="email"
id="email"
name="email"
required
placeholder="Email Id"
/>
<div className="flex items-center mb-4">
<label className="text-[var(--inputColor)] text-sm flex items-center">
<input
type="checkbox"
id="remember"
name="remember"
value="1"
className="mr-2"
style={{ width: "14px", height: "14px" }}
/>
Remember me
</label>
</div>
<Separator>or</Separator>
<div className="flex justify-center mb-4">
<div className="text-center text-sm w-60">
<Link
data-testid="sign_in_with_phone_text"
href={`/login/phone?login_challenge=${login_challenge}`}
replace
<>
<FormComponent action={formAction}>
<input type="hidden" name="login_challenge" value={login_challenge} />
<InputComponent
data-testid="email_id_input"
label="Email"
type="email"
id="email"
name="email"
required
placeholder="Email Id"
/>
<div className="flex items-center mb-4">
<label className="text-[var(--inputColor)] text-sm flex items-center">
<input
type="checkbox"
id="remember"
name="remember"
value="1"
className="mr-2"
style={{ width: "14px", height: "14px" }}
/>
Remember me
</label>
</div>
<Separator>or</Separator>
<div className="flex justify-center mb-4">
<div className="text-center text-sm w-60">
<Link
data-testid="sign_in_with_phone_text"
href={`/login/phone?login_challenge=${login_challenge}`}
replace
>
<p className="font-semibold text-sm">Sign in with phone</p>
</Link>
</div>
</div>

<div className="flex flex-col md:flex-row-reverse w-full gap-2">
<PrimaryButton
type="submit"
id="accept"
name="submit"
value="Log in"
data-testid="email_login_next_btn"
>
Next
</PrimaryButton>
<SecondaryButton
type="submit"
id="reject"
name="submit"
value={SubmitValue.denyAccess}
formNoValidate
>
<p className="font-semibold text-sm">Sign in with phone</p>
</Link>
Cancel
</SecondaryButton>
</div>
</div>
<div className="flex flex-col md:flex-row-reverse w-full gap-2">
<PrimaryButton
type="submit"
id="accept"
name="submit"
value="Log in"
data-testid="email_login_next_btn"
>
Next
</PrimaryButton>
<SecondaryButton
type="button"
id="reject"
name="submit"
value={SubmitValue.denyAccess}
formNoValidate
>
Cancel
</SecondaryButton>
</div>
</FormComponent>
</FormComponent>
<RegisterLink href={`/login/phone?login_challenge=${login_challenge}`} />
</>
)
}
export default EmailLoginForm
2 changes: 1 addition & 1 deletion apps/consent/app/login/email-login-server-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { redirect } from "next/navigation"
import { cookies, headers } from "next/headers"

import { hydraClient } from "../../services/hydra"
import { LoginType, SubmitValue } from "../index.types"
import { LoginType, SubmitValue } from "../types/index.types"

import { LoginEmailResponse } from "./email-login.types"

Expand Down
2 changes: 1 addition & 1 deletion apps/consent/app/login/email-login.types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { ServerActionResponse } from "../index.types"
import { ServerActionResponse } from "../types/index.types"
type LoginEmailBody = null
export interface LoginEmailResponse extends ServerActionResponse<LoginEmailBody> {}
Loading
Loading