Skip to content

Commit

Permalink
Merge pull request #208 from melnikga/feat/Implement-Login-and-Signup…
Browse files Browse the repository at this point in the history
…-pages-on-landing-page

Implement Login and Signup pages on landing page
  • Loading branch information
Solomonsolomonsolomon authored Dec 2, 2024
2 parents 2711754 + b3c820b commit dc34012
Show file tree
Hide file tree
Showing 10 changed files with 1,074 additions and 15 deletions.
726 changes: 721 additions & 5 deletions landing_page/package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion landing_page/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
"lint": "next lint"
},
"dependencies": {
"@radix-ui/react-select": "^2.1.2",
"clsx": "^2.1.1",
"lucide-react": "^0.453.0",
"next": "14.2.15",
"next-themes": "^0.3.0",
"react": "^18",
"react-dom": "^18",
"react-icons": "^5.3.0"
"react-icons": "^5.3.0",
"tailwind-merge": "^2.5.5"
},
"devDependencies": {
"@types/node": "^20",
Expand Down
6 changes: 3 additions & 3 deletions landing_page/src/app/components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import Button from "./Button/Button";
import P from './P/P'
import Link from "next/link";
const Hero = () => {
return (
<div className="grid place-items-center gap-6 p-6">
Expand All @@ -9,8 +9,8 @@ const Hero = () => {
<P size="h4" classname="font-bold text-[#282828]">Track, Verify, Transfer</P>
</div>
<div className="flex gap-4">
<Button size="full">Sign In</Button>
<Button variant="gray" size="full">Sign Up</Button>
<Link href='/signin' className="px-12 py-[0.65rem] text-white rounded text-xs bg-[#6364d5]">Sign In</Link>
<Link href='/signup' className="bg-[#828282] px-12 py-[0.65rem] text-white rounded text-xs" >Sign Up</Link>
</div>
</div>
);
Expand Down
38 changes: 38 additions & 0 deletions landing_page/src/app/components/Input/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';

interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
rightElement?: React.ReactNode;
}

export const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ label, error, rightElement, className = '', ...props }, ref) => {
return (
<div className="w-full">
{label && (
<label className="block text-sm font-medium mb-1">
{label}
</label>
)}
<div className="relative">
<input
ref={ref}
className={`w-full pl-6 pr-[30px] py-4 rounded-lg border border-[#5D5D5D] placeholder:text-[#797979] placeholder:text-[16px] leading-[21.86px] focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent ${
error ? 'border-red-500' : ''
} ${className}`}
{...props}
/>
{rightElement && (
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
{rightElement}
</div>
)}
</div>
{error && <p className="mt-1 text-sm text-red-500">{error}</p>}
</div>
);
}
);

Input.displayName = 'Input';
9 changes: 4 additions & 5 deletions landing_page/src/app/components/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React, { useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { Menu, X } from "lucide-react";
import Button from "./Button/Button";

const NavBar = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
Expand Down Expand Up @@ -33,12 +32,12 @@ const NavBar = () => {
<div className="hidden md:flex items-center gap-8">
<div className="flex items-center gap-4 text-sm">
<Link
href="/"
href="/signin"
className="text-[#6364d5] hover:text-[#4e4fb8] transition-colors text-xs"
>
Login
</Link>
<Button>Sign Up</Button>
<Link className="text-white rounded text-xs py-3 px-6 bg-[#6364d5]" href='/signup'>Sign Up</Link>
</div>
</div>

Expand Down Expand Up @@ -78,14 +77,14 @@ const NavBar = () => {
</Link>
<div className="flex flex-col gap-2 pt-2 border-t">
<Link
href="/"
href="/signin"
className="p-2 text-[#6364d5] hover:bg-gray-50 rounded-lg transition-colors"
onClick={() => setIsMenuOpen(false)}
>
Login
</Link>
<div className="px-2">
<Button classname="w-full justify-center">Sign Up</Button>
<Link className="text-white rounded text-xs py-3 px-6 bg-[#6364d5]" href='/signup'>Sign Up</Link>
</div>
</div>
</nav>
Expand Down
159 changes: 159 additions & 0 deletions landing_page/src/app/components/Select/Select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
"use client"

import * as React from "react"
import * as SelectPrimitive from "@radix-ui/react-select"
import { Check, ChevronDown, ChevronUp } from "lucide-react"

import { cn } from "../../lib/utils"

const Select = SelectPrimitive.Root

const SelectGroup = SelectPrimitive.Group

const SelectValue = SelectPrimitive.Value

const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex w-full items-center justify-between whitespace-nowrap rounded-lg border border-[#5D5D5D] bg-transparent px-4 py-3 text-base font-[400] focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent [&>span]:line-clamp-1 disabled:cursor-not-allowed disabled:opacity-50 bg-white data-[placeholder]:text-[#797979]",
className
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
))
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName

const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
))
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName

const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
))
SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName

const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 bg-white",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
))
SelectContent.displayName = SelectPrimitive.Content.displayName

const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold", className)}
{...props}
/>
))
SelectLabel.displayName = SelectPrimitive.Label.displayName

const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-[#F0EFFC] focus:text-[#6E62E5] transition-none",
className
)}
{...props}
>
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))
SelectItem.displayName = SelectPrimitive.Item.displayName

const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
))
SelectSeparator.displayName = SelectPrimitive.Separator.displayName

export {
Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent,
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
}
3 changes: 2 additions & 1 deletion landing_page/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ body {
}
*{
@apply transition-colors duration-200
}
}

6 changes: 6 additions & 0 deletions landing_page/src/app/lib/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
53 changes: 53 additions & 0 deletions landing_page/src/app/signin/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use client';

import { useState } from 'react';
import Button from '../components/Button/Button';
import { Input } from '../components/Input/Input';

export default function LoginPage() {
const [showPassword, setShowPassword] = useState(false);

return (
<div className="min-h-screen flex items-center justify-center bg-[#f5f5f5] text-[#1f1f1f] px-4">
<div className="max-w-md w-full space-y-8">
<div className="text-center">
<h1 className="text-[40px] font-bold">Sign in</h1>
<p className="mt-2 text-[22px] font-[300] text-gray-600">
Hey, Enter your details to login to your account
</p>
</div>

<form className="mt-8 space-y-6">
<Input
type="text"
placeholder="Enter Email / Phone No"
/>

<Input
type={showPassword ? 'text' : 'password'}
placeholder="Passcode"
rightElement={
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className=""
>
{showPassword? 'Hide' : 'Show'}
</button>
}
/>
<div className="text-xs font-[500]">
<span className="text-[#797979]">Don&apos;t have an account yet? </span>
<a href="/signup" className="text-[#000000]">
Register now!
</a>
</div>

<Button classname='w-full !text-lg !font-[600]'>
Sign in
</Button>
</form>
</div>
</div>
)
}
Loading

0 comments on commit dc34012

Please sign in to comment.