Skip to content

Commit

Permalink
feat: Create SignUp form
Browse files Browse the repository at this point in the history
  • Loading branch information
shivarm committed Sep 26, 2024
1 parent e5082ed commit b0d51ea
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 2 deletions.
2 changes: 1 addition & 1 deletion client/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default [
'warn',
{ allowConstantExport: true },
],
'react-prop-types': 'off',
'react/prop-types': 'off',
},
},
];
3 changes: 3 additions & 0 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import {
TransactionPage,
NotFound,
} from './pages/constant.js';
import { Header } from './components/Header.jsx';

function App() {
const authUser = true; // TODO: remove hardcode data
return (
<>
{authUser === true ? <Header /> : <NotFound />}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<LoginPage />} />
Expand Down
18 changes: 18 additions & 0 deletions client/src/components/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Link } from 'react-router-dom';

export const Header = () => {
return (
<div className="mb-10">
<h1 className="md:text-6xl text-4xl lg:text-7xl font-bold text-center relative z-50 text-white pt-10">
Expensify <Link to="/">Execution</Link>
</h1>
<div className="relative mb-10 w-1/2 mx-auto hidden md:block">
{/* Gradients effect */}
<div className="absolute inset-x-20 top-0 bg-gradient-to-r from-transparent via-indigo-500 to-transparent h-[2px] w-3/4 blur-sm" />
<div className="absolute inset-x-20 top-0 bg-gradient-to-r from-transparent via-indigo-500 to-transparent h-px w-3/4" />
<div className="absolute inset-x-60 top-0 bg-gradient-to-r from-transparent via-sky-500 to-transparent h-[5px] w-1/4 blur-sm" />
<div className="absolute inset-x-60 top-0 bg-gradient-to-r from-transparent via-sky-500 to-transparent h-px w-1/4" />
</div>
</div>
);
};
19 changes: 19 additions & 0 deletions client/src/components/input/InputField.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const InputField = ({ label, id, name, type = 'text', onChange, value }) => {
return (
<div>
<label htmlFor={id} className="block text-sm font-medium text-gray-700">
{label}
</label>
<input
className="mt-1 p-2 w-full border rounded-md text-black focus:border-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-300 transition-colors duration-300"
id={id}
type={type}
name={name}
value={value}
onChange={onChange}
/>
</div>
);
};

export default InputField;
38 changes: 38 additions & 0 deletions client/src/components/input/RadioButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const RadioButton = ({ id, label, onChange, value, checked }) => {
return (
<div className="inline-flex items-center">
<label
className="relative flex items-center p-3 rounded-full cursor-pointer"
htmlFor={id}
>
<input
name="type"
type="radio"
className="before:content[''] peer relative h-5 w-5 cursor-pointer appearance-none rounded-full border border-black text-gray-900 transition-all before:absolute before:top-2/4 before:left-2/4 before:block before:h-12 before:w-12 before:-translate-y-2/4 before:-translate-x-2/4 before:rounded-full before:bg-blue-gray-500 before:opacity-0 before:transition-opacity checked:border-gray-900 checked:before:bg-gray-900 hover:before:opacity-10"
id={id}
value={value}
onChange={onChange}
checked={checked}
/>
<span className="absolute text-gray-900 transition-opacity opacity-0 pointer-events-none top-2/4 left-2/4 -translate-y-2/4 -translate-x-2/4 peer-checked:opacity-100">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-3.5 w-3.5"
viewBox="0 0 16 16"
fill="currentColor"
>
<circle data-name="ellipse" cx="8" cy="8" r="8"></circle>
</svg>
</span>
</label>
<label
className="mt-px font-light text-gray-700 cursor-pointer select-none"
htmlFor={id}
>
{label}
</label>
</div>
);
};

export default RadioButton;
110 changes: 109 additions & 1 deletion client/src/pages/Signup.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,113 @@
import { useState } from 'react';
import { Link } from 'react-router-dom';
import RadioButton from '../components/input/RadioButton';
import InputField from '../components/input/InputField';

const Signup = () => {
return <div>Signup</div>;
const [signUpData, setSignUpData] = useState({
name: '',
username: '',
password: '',
gender: '',
});

const handleChange = (e) => {
const { name, value, type } = e.target;

if (type === 'radio') {
setSignUpData((prevData) => ({
...prevData,
gender: value,
}));
} else {
setSignUpData((prevData) => ({
...prevData,
[name]: value,
}));
}
};

const handleSubmit = async (e) => {
e.preventDefault();
console.log(signUpData);
};

return (
<div className="h-screen flex justify-center items-center">
<div className="flex rounded-lg overflow-hidden z-50 bg-gray-300">
<div className="w-full bg-gray-100 min-w-80 sm:min-w-96 flex items-center justify-center">
<div className="max-w-md w-full p-6">
<h1 className="text-3xl font-semibold mb-6 text-black text-center">
Sign Up
</h1>
<h1 className="text-sm font-semibold mb-6 text-gray-500 text-center">
Join to keep track of your expenses
</h1>
<form className="space-y-4" onSubmit={handleSubmit}>
<InputField
label="Full Name"
id="name"
name="name"
value={signUpData.name}
onChange={handleChange}
/>
<InputField
label="Username"
id="username"
name="username"
value={signUpData.username}
onChange={handleChange}
/>

<InputField
label="Password"
id="password"
name="password"
type="password"
value={signUpData.password}
onChange={handleChange}
/>
<div className="flex gap-10">
<RadioButton
id="male"
label="Male"
name="gender"
value="male"
onChange={handleChange}
checked={signUpData.gender === 'male'}
/>
<RadioButton
id="female"
label="Female"
name="gender"
value="female"
onChange={handleChange}
checked={signUpData.gender === 'female'}
/>
</div>

<div>
<button
type="submit"
className="w-full bg-black text-white p-2 rounded-md hover:bg-gray-800 focus:outline-none focus:bg-black focus:ring-2 focus:ring-offset-2 focus:ring-gray-900 transition-colors duration-300 disabled:opacity-50 disabled:cursor-not-allowed"
>
Sign Up
</button>
</div>
</form>
<div className="mt-4 text-sm text-gray-600 text-center">
<p>
Already have an account?{' '}
<Link to="/login" className="text-black hover:underline">
Login here
</Link>
</p>
</div>
</div>
</div>
</div>
</div>
);
};

export default Signup;

0 comments on commit b0d51ea

Please sign in to comment.