login page added
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
"cra-template": "1.2.0",
|
"cra-template": "1.2.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
|
"react-icons": "^5.4.0",
|
||||||
"react-scripts": "5.0.1"
|
"react-scripts": "5.0.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -31,5 +32,10 @@
|
|||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^10.4.20",
|
||||||
|
"postcss": "^8.5.1",
|
||||||
|
"tailwindcss": "^3.4.17"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
+9
-29
@@ -1,32 +1,8 @@
|
|||||||
.App {
|
/*@media (prefers-reduced-motion: no-preference) {*/
|
||||||
text-align: center;
|
/* .App-logo {*/
|
||||||
}
|
/* animation: App-logo-spin infinite 20s linear;*/
|
||||||
|
/* }*/
|
||||||
.App-logo {
|
/*}*/
|
||||||
height: 40vmin;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
.App-logo {
|
|
||||||
animation: App-logo-spin infinite 20s linear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-header {
|
|
||||||
background-color: #282c34;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: calc(10px + 2vmin);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-link {
|
|
||||||
color: #61dafb;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes App-logo-spin {
|
@keyframes App-logo-spin {
|
||||||
from {
|
from {
|
||||||
@@ -36,3 +12,7 @@
|
|||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button, a {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|||||||
+4
-11
@@ -1,18 +1,11 @@
|
|||||||
import logo from './logo.svg';
|
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
import LoginPage from './pages/LoginPage';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="w-full">
|
||||||
<header className="App-header">
|
<LoginPage />
|
||||||
<img src={logo} className="App-logo" alt="logo" />
|
|
||||||
<p>
|
|
||||||
Edit <code>src/App.js</code> and save to reload.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
DigiFi Office
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 221 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 155 KiB |
@@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default function InputText({id, name, type='text', value, handleChange}) {
|
||||||
|
return (
|
||||||
|
<div className='w-full h-10 round overflow-hidden'>
|
||||||
|
<input id={id} name={name} type={type} value={value} onChange={handleChange} className='p-2 w-full h-full text-black outline-0 ring-0 border border-slate-400 focus:border-purple-600 rounded' />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default function Label({name, htmlfor, error}) {
|
||||||
|
return (
|
||||||
|
<label className='text-black font-semibold flex gap-1 items-center' htmlFor={htmlfor}>{name} {error && <span className='text-red-500 text-sm'>{error}</span>}</label>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { FaCircleNotch } from "react-icons/fa";
|
||||||
|
|
||||||
|
export default function PageLoader() {
|
||||||
|
return (
|
||||||
|
<div className="w-full h-full fixed top-0 left-0 bg-white opacity-75 z-50">
|
||||||
|
<div className="flex justify-center items-center mt-[50vh]">
|
||||||
|
<FaCircleNotch className='text-5xl text-violet-600 animate-spin' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
// import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
|
// import { useMutation } from '@tanstack/react-query'
|
||||||
|
|
||||||
|
// import myLinks from '../../myLinks'
|
||||||
|
import Label from '../Label'
|
||||||
|
import InputText from '../InputText'
|
||||||
|
import PageLoader from '../PageLoader'
|
||||||
|
// import { loginUser } from '../../services/siteServices'
|
||||||
|
|
||||||
|
import GoogleDownload from '../../assets/download/andriod.jpg'
|
||||||
|
import IOSDownload from '../../assets/download/apple.jpg'
|
||||||
|
|
||||||
|
export default function LoginCom() {
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
// const {state} = useLocation()
|
||||||
|
// const navigate = useNavigate()
|
||||||
|
|
||||||
|
const [fields, setFields] = useState({
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleChange = ({target:{name, value}}) => {
|
||||||
|
setFields(prev => ({...prev, [name]:value}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// const login = useMutation({
|
||||||
|
// mutationFn: (fields) => {
|
||||||
|
// if(!fields.username || !fields.password){
|
||||||
|
// throw new Error('Please provide all fields marked *')
|
||||||
|
// }
|
||||||
|
// return loginUser(fields)
|
||||||
|
// },
|
||||||
|
// onError: (error) => {
|
||||||
|
// console.log(error)
|
||||||
|
// },
|
||||||
|
// onSuccess: (res) => {
|
||||||
|
// // const {token, room} = res?.data?.data
|
||||||
|
// // if(token){
|
||||||
|
// // localStorage.setItem('token', token)
|
||||||
|
// // localStorage.setItem('room', room)
|
||||||
|
// // // const data = {token}
|
||||||
|
// // // dispatch(updateUserDetails({ ...data }));
|
||||||
|
// // }
|
||||||
|
// navigate(myLinks.home, {state:{proceed:'true'}}) // later add redux to dispatch state
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
// if(state?.proceed != 'true'){
|
||||||
|
// return navigate(myLinks.getStarted, {replace:true})
|
||||||
|
// }
|
||||||
|
setTimeout(()=>{
|
||||||
|
setLoading(false)
|
||||||
|
},200)
|
||||||
|
},[])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{loading ?
|
||||||
|
<PageLoader />
|
||||||
|
:
|
||||||
|
<div className={`h-screen bg-sky-300 flex flex-col items-center bg-[url('./assets/login-bg.jpg')] bg-cover bg-center bg-no-repeat`}>
|
||||||
|
<div className='flex flex-col gap-3 w-[80%] sm:w-[500px] bg-white rounded-xl mt-8 p-8 shadow'>
|
||||||
|
<div className='w-full mb-8 flex flex-col gap-1'>
|
||||||
|
<h1 className='text-2xl md:text-3xl font-bold'>Digifi BackOffice</h1>
|
||||||
|
<p className='text-sm font-medium text-slate-400'>Welcome back, please login to your account</p>
|
||||||
|
</div>
|
||||||
|
<div className='text-input flex flex-col gap-2'>
|
||||||
|
<Label name='Username' htmlfor='username' />
|
||||||
|
<InputText id='username' name='username' value={fields.username} handleChange={handleChange} />
|
||||||
|
</div>
|
||||||
|
<div className='text-input flex flex-col gap-2'>
|
||||||
|
<Label name='Password' htmlfor='password' />
|
||||||
|
<InputText id='password' name='password' type='password' value={fields.password} handleChange={handleChange} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* {login.error &&
|
||||||
|
<>
|
||||||
|
<div className="w-full text-center p-2">
|
||||||
|
<p className='text-red-500 text-sm'>{login.error.message}</p>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
} */}
|
||||||
|
|
||||||
|
<div className='mt-5 flex justify-end items-center'>
|
||||||
|
{/* <button onClick={()=>{login.mutate(fields)}} disabled={login.isPending} className='px-3 py-2 bg-purple-800 text-white font-bold rounded'>{login.isPending ? 'loading...' : 'Login'}</button> */}
|
||||||
|
<button className='px-4 py-[5px] bg-purple-600 text-white font-bold rounded'>SIGN IN</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-8 grid grid-cols-2 gap-8">
|
||||||
|
<div className="w-full">
|
||||||
|
<a className="icon google"
|
||||||
|
href='#' >
|
||||||
|
<img src={IOSDownload} className='w-100 h-auto' alt='IOS Download' />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full">
|
||||||
|
<a className="icon apple" href='#'>
|
||||||
|
<img src={GoogleDownload} className='w-100 h-auto' alt='IOS Download' />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
html{
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
*{
|
||||||
|
transition: all .3s;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import LoginCom from '../components/auth/LoginCom'
|
||||||
|
|
||||||
|
export default function LoginPage() {
|
||||||
|
return (
|
||||||
|
<LoginCom />
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: ["./src/**/*.{js,jsx,ts,tsx}"],
|
||||||
|
darkMode: "class",
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user