feat: add component form-login
add component form-login
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
import type { JSX, SVGProps } from 'react'
|
||||
|
||||
export const LeftArrow = (
|
||||
properties: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>,
|
||||
) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width={100}
|
||||
height={100}
|
||||
viewBox="0 0 70 70"
|
||||
fill="currentColor"
|
||||
{...properties}
|
||||
>
|
||||
<path
|
||||
d="M1.60494 17.938C1.05815 18.4849 0.750977 19.2266 0.750977 20C0.750977 20.7734 1.05815 21.5152 1.60494 22.0621L18.1045 38.5617C18.6546 39.093 19.3914 39.387 20.1561 39.3803C20.9208 39.3737 21.6524 39.0669 22.1932 38.5262C22.7339 37.9854 23.0407 37.2539 23.0473 36.4891C23.054 35.7244 22.76 34.9876 22.2287 34.4375L10.7079 22.9167H49.3333C50.1068 22.9167 50.8487 22.6094 51.3957 22.0624C51.9426 21.5154 52.2499 20.7736 52.2499 20C52.2499 19.2265 51.9426 18.4846 51.3957 17.9376C50.8487 17.3907 50.1068 17.0834 49.3333 17.0834H10.7079L22.2287 5.56254C22.76 5.01245 23.054 4.27569 23.0473 3.51095C23.0407 2.74621 22.7339 2.01467 22.1932 1.4739C21.6524 0.933127 20.9208 0.626385 20.1561 0.619739C19.3914 0.613094 18.6546 0.907077 18.1045 1.43837L1.60494 17.938Z"
|
||||
fill="#2E2F7C"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export const LinkIcon = (
|
||||
height={95}
|
||||
stroke="currentColor"
|
||||
fill="currentColor"
|
||||
stroke-width="0"
|
||||
strokeWidth="0"
|
||||
viewBox="0 0 1024 1024"
|
||||
{...properties}
|
||||
>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { APP } from '~/data/meta'
|
||||
|
||||
export const Banner = () => {
|
||||
return (
|
||||
<div className="min-h-[65px] bg-amber-400 sm:mx-10">
|
||||
<div className="min-h-[65px] sm:mx-10">
|
||||
<div className="relative">
|
||||
<Link
|
||||
to="/#"
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Button } from './button'
|
||||
|
||||
export const Carousel = (properties: TNews) => {
|
||||
const location = useLocation()
|
||||
const hasCategory = location.pathname.includes('/categories/')
|
||||
const hasCategory = location.pathname.includes('/category/')
|
||||
|
||||
const { title, description, items, type } = properties
|
||||
return (
|
||||
@@ -71,8 +71,11 @@ export const Carousel = (properties: TNews) => {
|
||||
)}
|
||||
>
|
||||
<div className={`${type === 'hero' ? 'hidden' : ''} `}>
|
||||
{tags?.map((item) => (
|
||||
<span className="my-3 mr-2 inline-block rounded bg-gray-200 px-3 py-1">
|
||||
{tags?.map((item, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="my-3 mr-2 inline-block rounded bg-gray-200 px-3 py-1"
|
||||
>
|
||||
{item}
|
||||
</span>
|
||||
))}
|
||||
@@ -97,7 +100,7 @@ export const Carousel = (properties: TNews) => {
|
||||
size="block"
|
||||
as={Link}
|
||||
to={`detail/${slug}`}
|
||||
className={twMerge('', type === 'hero' ? '' : 'mb-5 sm:mb-0')}
|
||||
className={twMerge('', type === 'hero' ? '' : 'mb-5')}
|
||||
>
|
||||
View More
|
||||
</Button>
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// import { EyeIcon, EyeOffIcon } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { Link } from 'react-router'
|
||||
|
||||
import { LeftArrow } from '~/components/icons/left-arrow'
|
||||
import { APP } from '~/data/meta'
|
||||
|
||||
const FormLogin = () => {
|
||||
const [showPassword, setShowPassword] = useState(false)
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center">
|
||||
<div className="w-full max-w-md p-6">
|
||||
<div className="absolute top-[80px] left-[50px]">
|
||||
<Link
|
||||
to="/#"
|
||||
className="mt-2 h-full py-2"
|
||||
>
|
||||
<LeftArrow
|
||||
width={'70px'}
|
||||
height={'70px'}
|
||||
></LeftArrow>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="mb-6 flex justify-center">
|
||||
<Link to="/news">
|
||||
<img
|
||||
src={APP.logo}
|
||||
alt={APP.title}
|
||||
className="h-[100px]"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="mb-4 p-4 text-center">
|
||||
<p className="text-[#565658]">
|
||||
Selamat Datang, silakan daftarkan akun Anda untuk melanjutkan!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form>
|
||||
{/* Input Email / No Telepon */}
|
||||
<div className="mb-4">
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="mb-1 block text-gray-700"
|
||||
>
|
||||
Email/No. Telepon
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Contoh: legal@legalgo.id"
|
||||
className="focus:inheriten w-full rounded-md border border-[#DFDFDF] p-2"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Input Password */}
|
||||
<div className="relative mb-4">
|
||||
<label
|
||||
htmlFor="password"
|
||||
className="mb-1 block text-gray-700 focus:outline-[#2E2F7C]"
|
||||
>
|
||||
Kata Sandi
|
||||
</label>
|
||||
<input
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
placeholder="Masukkan Kata Sandi"
|
||||
className="w-full rounded-md border border-[#DFDFDF] p-2 pr-10 focus:outline-[#2E2F7C]"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="absolute top-9 right-3 text-gray-500"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
>
|
||||
{/* {showPassword ? <EyeOffIcon size={18} /> : <EyeIcon size={18} />} */}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Lupa Kata Sandi */}
|
||||
<div className="mb-4 flex justify-between">
|
||||
<span className="text-gray-600">Lupa Kata Sandi?</span>
|
||||
<Link
|
||||
to="/reset-password"
|
||||
className="font-semibold text-[#2E2F7C]"
|
||||
>
|
||||
Reset Kata Sandi
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Tombol Masuk */}
|
||||
<button className="w-full rounded-md bg-[#2E2F7C] py-2 text-white transition hover:bg-blue-800">
|
||||
Masuk
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{/* Link Daftar */}
|
||||
<div className="mt-4 text-center text-sm">
|
||||
Belum punya akun?{' '}
|
||||
<Link
|
||||
to="/register"
|
||||
className="font-semibold text-[#2E2F7C]"
|
||||
>
|
||||
Daftar Disini
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormLogin
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
interface ModalProperties {
|
||||
isOpen: boolean
|
||||
onClose: () => void
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const Modal = ({ isOpen, onClose, children }: ModalProperties) => {
|
||||
if (!isOpen) return
|
||||
|
||||
return (
|
||||
<div className="bg-opacity-50 fixed inset-0 z-50 flex items-center justify-center bg-black">
|
||||
{/* Modal Container */}
|
||||
<div className="animate-fade-in relative rounded-lg bg-white p-6 shadow-lg">
|
||||
{/* Tombol Close */}
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="absolute top-2 right-2 text-gray-500 hover:text-gray-800"
|
||||
>
|
||||
✖
|
||||
</button>
|
||||
<h1>test</h1>
|
||||
{/* Modal Content */}
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Modal
|
||||
Reference in New Issue
Block a user