desgin implementation

This commit is contained in:
surajb 2024-07-26 14:35:56 +05:30
parent d83b15b926
commit 7a8a31c482
8 changed files with 123 additions and 173 deletions

22
db.json
View File

@ -165,5 +165,27 @@
"city_id": "", "city_id": "",
"mobile": "07559393995" "mobile": "07559393995"
} }
],
"cities": [
{
"id": "1",
"name": "New York"
},
{
"id": "2",
"name": "Los Angeles"
},
{
"id": "3",
"name": "Chicago"
},
{
"id": "4",
"name": "Houston"
},
{
"id": "5",
"name": "Phoenix"
}
] ]
} }

View File

@ -1,7 +1,8 @@
import axios from 'axios'; import axios from 'axios';
const axiosInstance = axios.create({ const axiosInstance = axios.create({
baseURL: 'http://localhost:5000' baseURL: 'http://localhost:5000',
timeout: 10000,
}); });
export default axiosInstance; export default axiosInstance;

View File

@ -5,10 +5,8 @@ body, html {
padding: 0; padding: 0;
font-family: 'Nunito Sans', sans-serif; font-family: 'Nunito Sans', sans-serif;
background-color: #ffffff; background-color: #ffffff;
/* color: #fff; */
} }
.login-page { .login-page {
display: flex; display: flex;
align-items: center; align-items: center;
@ -16,34 +14,15 @@ body, html {
min-height: 100vh; min-height: 100vh;
padding: 4rem; padding: 4rem;
background-color: #ffffff; background-color: #ffffff;
} position: relative;
.login-container {
/* background-color: #222; */
border-radius: 8px;
padding: 40px;
box-shadow: 0 0 10px #d1d5db;
width: 310.4px;
display: flex;
flex-direction: column;
row-gap: 28px;
column-gap: 28px;
font-size: 14px;
font-weight: 500;
line-height: 14px;
box-sizing: border-box;
}
.form-container {
display: flex;
flex-direction: column;
align-items: center;
} }
.logo { .logo {
display: block; position: absolute;
margin: 0 auto 20px; top: 1rem;
left: 1rem;
width: 100px; width: 100px;
height: auto;
} }
h1 { h1 {
@ -58,44 +37,20 @@ p {
text-align: center; text-align: center;
} }
form { input {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
label {
display: none;
}
/* input[type="email"],
input[type="password"] {
width: 100%; width: 100%;
padding: 12px; padding: 12px;
margin-bottom: 20px; margin-bottom: 20px;
border: 1px solid #B3B3B3; border: 1px solid #B3B3B3;
border-radius: 4px; border-radius: 4px;
font-size: 16px; font-size: 16px;
background-color: #09090B; background-color: #e8e8e8;
color: #fff; color: #4b5563;
box-sizing: border-box; box-sizing: border-box;
} */
.login-page input {
width: 100%;
padding: 12px;
margin-bottom: 20px;
border: 1px solid #B3B3B3; /* Darker border */
border-radius: 4px;
font-size: 16px;
background-color: #e8e8e8; /* Dark background for input fields */
color: #4b5563; /* White text for input fields */
} }
input[type="email"]:focus, input:focus {
input[type="password"]:focus { border-color: #0e355b;
border-color: #4b5563;
outline: none; outline: none;
} }
@ -112,10 +67,6 @@ input[type="password"]:focus {
text-decoration: none; text-decoration: none;
} }
/* .forgot-password-container a:hover {
text-decoration: underline;
} */
.login-button { .login-button {
width: 100%; width: 100%;
padding: 15px 30px; padding: 15px 30px;
@ -130,15 +81,3 @@ input[type="password"]:focus {
.login-button:hover { .login-button:hover {
background-color: #154676; background-color: #154676;
} }
.login-page input:focus {
border-color: #0e355b; /* Orange border on focus */
outline: none;
}
.login-page a {
color: #4b5563;
text-decoration: none;
margin-bottom: 20px;
display: inline-block;
}

View File

@ -1,7 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import axiosInstance from '../../api/axiosConfig'; import axiosInstance from '../../api/axiosConfig';
import './LoginPage.css';
import BrookslogoIcon from '../../assets/thob-data/BrookslogoIcon.svg'; import BrookslogoIcon from '../../assets/thob-data/BrookslogoIcon.svg';
const LoginPage = () => { const LoginPage = () => {
@ -19,7 +18,7 @@ const LoginPage = () => {
const user = response.data.find(user => user.email === email && user.password === password); const user = response.data.find(user => user.email === email && user.password === password);
if (user) { if (user) {
localStorage.setItem("loggedInUser", JSON.stringify(user)) localStorage.setItem("loggedInUser", JSON.stringify(user));
if (user.role === 'admin') { if (user.role === 'admin') {
navigate('/admin'); navigate('/admin');
} else if (user.role === 'employee') { } else if (user.role === 'employee') {
@ -42,15 +41,13 @@ const LoginPage = () => {
}; };
return ( return (
<div className="flex flex-row min-h-screen justify-center items-center"> <div className="flex flex-col min-h-screen bg-secondary p-4 relative">
<div className="login-page flex items-center justify-center min-h-screen w-full md:w-1/2 lg:w-1/3 p-4"> <img src={BrookslogoIcon} alt="Logo" className="absolute top-6 left-6 w-24" />
<div className="w-full"> <div className="flex flex-col items-center justify-center flex-1 px-4 py-6">
<img src={BrookslogoIcon} alt="Logo" className="logo" /> <h1 className="text-primary-text text-2xl font-bold mb-4">welcome back</h1>
<h1>welcome back</h1> <p className="text-secondary-text text-center mb-6">be among the first to experience 3D magic! Register for private alpha.</p>
<p>be among the first to experience 3D magic! register for private alpha.</p> {error && <p className="text-red-500 text-center mb-4">{error}</p>}
{error && <p className="error-message">{error}</p>} <div className="flex flex-col space-y-4 w-full max-w-sm">
<form onSubmit={handleLogin} className="space-y-4">
<label htmlFor="email" className="block"></label>
<input <input
type="email" type="email"
id="email" id="email"
@ -59,9 +56,8 @@ const LoginPage = () => {
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
placeholder="john123@domain.com" placeholder="john123@domain.com"
required required
className="input-field" className="w-full p-3 border border-gray-300 rounded-md text-gray-700 focus:border-primary focus:outline-none"
/> />
<label htmlFor="password" className="block"></label>
<input <input
type="password" type="password"
id="password" id="password"
@ -70,15 +66,17 @@ const LoginPage = () => {
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
placeholder="Enter your password" placeholder="Enter your password"
required required
className="input-field" className="w-full p-3 border border-gray-300 rounded-md text-gray-700 focus:border-primary focus:outline-none"
/> />
<div className="forgot-password-container"> <div className="flex justify-end">
<a href="/reset-password">forgot password?</a> <a href="/reset-password" className="text-primary-text">forgot password?</a>
</div> </div>
<button type="submit" className="login-button"> <button
onClick={handleLogin}
className="w-full py-3 bg-primary text-button-text rounded-md text-lg font-semibold hover:bg-primary-dark"
>
login login
</button> </button>
</form>
</div> </div>
</div> </div>
</div> </div>

View File

@ -21,13 +21,12 @@ const CLASSES = {
imagePreview: 'bg-gray-300 w-24 h-24 rounded-full mx-auto overflow-hidden', imagePreview: 'bg-gray-300 w-24 h-24 rounded-full mx-auto overflow-hidden',
noImage: 'w-full h-full flex items-center justify-center text-gray-500', noImage: 'w-full h-full flex items-center justify-center text-gray-500',
hiddenInput: 'hidden', hiddenInput: 'hidden',
uploadButton: uploadButton: 'absolute bottom-0 left-1/2 transform -translate-x-1/2 bg-gray-700 text-white text-xs px-2 py-1 rounded-full',
'absolute bottom-0 left-1/2 transform -translate-x-1/2 bg-gray-700 text-white text-xs px-2 py-1 rounded-full',
linkTitle: 'text-lg font-semibold', linkTitle: 'text-lg font-semibold',
formSection: 'md:col-span-2 space-y-4', formSection: 'md:col-span-2 space-y-4',
formGroup: 'block text-gray-800 font-medium', formGroup: ' text-gray-800 font-medium',
formInput: 'w-full p-2 border-b border-gray-400 focus:border-gray-700', formInput: ' p-2 border-b border-gray-400 focus:border-gray-700',
formSelect: 'w-full p-2 border-b border-gray-400 focus:border-gray-700', formSelect: ' p-2 border-b border-gray-400 focus:border-gray-700',
submitButton: 'bg-[#0e355b] text-white py-2 px-4 rounded-md', submitButton: 'bg-[#0e355b] text-white py-2 px-4 rounded-md',
}; };
@ -40,7 +39,6 @@ const AddCustomer = () => {
gender: '', gender: '',
email: '', email: '',
mobile: '', mobile: '',
image: null,
address: { address: {
address_line_1: '', address_line_1: '',
address_line_2: '', address_line_2: '',
@ -48,6 +46,7 @@ const AddCustomer = () => {
pincode: '', pincode: '',
city_id: '', city_id: '',
}, },
image: null,
}); });
const [cities, setCities] = useState([]); const [cities, setCities] = useState([]);
@ -63,7 +62,7 @@ const AddCustomer = () => {
console.error('Error: Data is not an array', response.data); console.error('Error: Data is not an array', response.data);
} }
} catch (error) { } catch (error) {
console.error('Error fetching cities:', error.response || error.message); console.error('Error fetching cities:', error.response ? error.response.data : error.message);
} }
}; };
@ -78,17 +77,6 @@ const AddCustomer = () => {
})); }));
}; };
const handleAddressChange = (e) => {
const { name, value } = e.target;
setCustomerData((prevData) => ({
...prevData,
address: {
...prevData.address,
[name]: value,
},
}));
};
const handleImageChange = (e) => { const handleImageChange = (e) => {
const file = e.target.files[0]; const file = e.target.files[0];
if (file) { if (file) {
@ -104,18 +92,12 @@ const AddCustomer = () => {
e.preventDefault(); e.preventDefault();
const formData = new FormData(); const formData = new FormData();
Object.keys(customerData).forEach((key) => { Object.keys(customerData).forEach((key) => {
if (key === 'address') {
Object.keys(customerData.address).forEach((addrKey) => {
formData.append(`address[${addrKey}]`, customerData.address[addrKey]);
});
} else {
formData.append(key, customerData[key]); formData.append(key, customerData[key]);
}
}); });
try { try {
const response = await axiosInstance.post( const response = await axiosInstance.post(
'http://localhost:5000/customers', '/customers',
formData, formData,
{ {
headers: { headers: {
@ -123,7 +105,6 @@ const AddCustomer = () => {
}, },
} }
); );
console.log('Raw response:', response);
console.log('Customer added successfully:', response.data); console.log('Customer added successfully:', response.data);
navigate('/customers'); navigate('/customers');
} catch (error) { } catch (error) {
@ -176,7 +157,7 @@ const AddCustomer = () => {
} }
className={CLASSES.uploadButton} className={CLASSES.uploadButton}
> >
Upload upload
</button> </button>
</div> </div>
</div> </div>
@ -229,9 +210,7 @@ const AddCustomer = () => {
onChange={handleInputChange} onChange={handleInputChange}
className={CLASSES.formSelect} className={CLASSES.formSelect}
> >
<option value="" disabled> <option value="" disabled>Select Gender</option>
Select Gender
</option>
<option value="male">Male</option> <option value="male">Male</option>
<option value="female">Female</option> <option value="female">Female</option>
<option value="other">Other</option> <option value="other">Other</option>
@ -252,8 +231,8 @@ const AddCustomer = () => {
<input <input
type="text" type="text"
name="address_line_1" name="address_line_1"
value={customerData.address.address_line_1} value={customerData.address_line_1}
onChange={handleAddressChange} onChange={handleInputChange}
className={CLASSES.formInput} className={CLASSES.formInput}
/> />
</div> </div>
@ -262,8 +241,8 @@ const AddCustomer = () => {
<input <input
type="text" type="text"
name="address_line_2" name="address_line_2"
value={customerData.address.address_line_2} value={customerData.address_line_2}
onChange={handleAddressChange} onChange={handleInputChange}
className={CLASSES.formInput} className={CLASSES.formInput}
/> />
</div> </div>
@ -272,8 +251,8 @@ const AddCustomer = () => {
<input <input
type="text" type="text"
name="nearby_landmark" name="nearby_landmark"
value={customerData.address.nearby_landmark} value={customerData.nearby_landmark}
onChange={handleAddressChange} onChange={handleInputChange}
className={CLASSES.formInput} className={CLASSES.formInput}
/> />
</div> </div>
@ -282,8 +261,8 @@ const AddCustomer = () => {
<input <input
type="text" type="text"
name="pincode" name="pincode"
value={customerData.address.pincode} value={customerData.pincode}
onChange={handleAddressChange} onChange={handleInputChange}
className={CLASSES.formInput} className={CLASSES.formInput}
/> />
</div> </div>
@ -291,15 +270,12 @@ const AddCustomer = () => {
<label className={CLASSES.formGroup}>City:</label> <label className={CLASSES.formGroup}>City:</label>
<select <select
name="city_id" name="city_id"
value={customerData.address.city_id} value={customerData.city_id}
onChange={handleAddressChange} onChange={handleInputChange}
className={CLASSES.formSelect} className={CLASSES.formSelect}
> >
<option value="" disabled> <option value="" disabled>Select City</option>
Select City {cities.map((city) => (
</option>
{Array.isArray(cities) &&
cities.map((city) => (
<option key={city.id} value={city.id}> <option key={city.id} value={city.id}>
{city.name} {city.name}
</option> </option>
@ -309,18 +285,16 @@ const AddCustomer = () => {
<div> <div>
<label className={CLASSES.formGroup}>Mobile:</label> <label className={CLASSES.formGroup}>Mobile:</label>
<input <input
type="tel" type="text"
name="mobile" name="mobile"
value={customerData.mobile} value={customerData.mobile}
onChange={handleInputChange} onChange={handleInputChange}
className={CLASSES.formInput} className={CLASSES.formInput}
/> />
</div> </div>
<div className="flex justify-end">
<button type="submit" className={CLASSES.submitButton}> <button type="submit" className={CLASSES.submitButton}>
Add Customer Add Customer
</button> </button>
</div>
</form> </form>
</div> </div>
</div> </div>

View File

@ -36,7 +36,7 @@ const EmployeeDashboard = () => {
<div className={classNames.content}> <div className={classNames.content}>
<header className={classNames.header}> <header className={classNames.header}>
<div className="flex items-center"> <div className="flex items-center">
<h1 className={classNames.headerTitle}>Home</h1> <h1 className={classNames.headerTitle}>employee dashboard</h1>
</div> </div>
<div> <div>
<p className={classNames.welcomeText}>welcome back, {userName}</p> <p className={classNames.welcomeText}>welcome back, {userName}</p>

View File

@ -1,4 +1,3 @@
// server.js
const express = require('express'); const express = require('express');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
@ -10,11 +9,26 @@ const port = 5000;
app.use(bodyParser.json()); app.use(bodyParser.json());
let users = [ let users = [
// Example users
{ email: 'admin@example.com', password: 'admin123', role: 'admin' }, { email: 'admin@example.com', password: 'admin123', role: 'admin' },
{ email: 'employee@example.com', password: 'employee123', role: 'employee' }, { email: 'employee@example.com', password: 'employee123', role: 'employee' },
]; ];
// Endpoint to handle login requests
app.post('/auth/login', (req, res) => {
const { email, password } = req.body;
const user = users.find(user => user.email === email && user.password === password);
if (!user) {
return res.status(401).json({ success: false, message: 'Invalid email or password' });
}
res.status(200).json({
success: true,
message: 'Login successful',
role: user.role,
});
});
// Endpoint to handle password reset requests // Endpoint to handle password reset requests
app.post('/auth/forgot-password', (req, res) => { app.post('/auth/forgot-password', (req, res) => {
const { email } = req.body; const { email } = req.body;

View File

@ -1,4 +1,5 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: [ content: [
'./src/**/*.{html,js,jsx}', './src/**/*.{html,js,jsx}',
@ -13,6 +14,7 @@ module.exports = {
'secondary-text': '#4b5563', 'secondary-text': '#4b5563',
'button-text': '#d1d5db', 'button-text': '#d1d5db',
}, },
fontFamily: { fontFamily: {
sans: ['"Nunito Sans"', 'sans-serif'], sans: ['"Nunito Sans"', 'sans-serif'],
}, },