Skip to content

Commit

Permalink
Merge pull request #285 from ayush-848/main
Browse files Browse the repository at this point in the history
Added profile
  • Loading branch information
AbhiDiva96 authored Jul 13, 2024
2 parents c6bedb1 + 1a6a536 commit 366ec87
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Trdyear from "./components/page3/3Year";
import Fothyear from "./components/page3/4Year";
import LoginSignup from './components/login/LoginSignup.jsx';
import ReviewPage from './components/review/review.jsx';
import ProfilePage from './components/ProfilePage/ProfilePage.jsx'
import About from './components/about/About.jsx';
import ScrollToTop from './Content/ScrollToTop.jsx';

Expand Down Expand Up @@ -66,6 +67,7 @@ function App() {
<Route path="/login" element={<LoginSignup />} />
<Route path="/Review" element={<ReviewPage />} />
<Route path="/about" element={<About />} />
<Route path="/ProfilePage" element={<ProfilePage />} />
</Routes>
</Router>
</ThemeProvider>
Expand Down
129 changes: 129 additions & 0 deletions src/components/ProfilePage/ProfilePage.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
.profile-page {
padding: 20px;
}

.profile-container {
max-width: 600px;
margin: 0 auto;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
padding: 20px;
}

.profile-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}

.profile-header h1 {
margin: 0;
}

.edit-button {
background-color: #007bff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}

.edit-button:hover {
background-color: #0056b3;
}

.avatar-container {
text-align: center;
margin-bottom: 20px;
margin-left: 40%;
margin-right: 30%;
}

.avatar {
width: 150px;
height: 150px;
border-radius: 50%;
object-fit: cover;
border: 2px solid #007bff;
}

.avatar-placeholder {
width: 150px;
height: 150px;
border-radius: 50%;
background-color: #007bff;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 48px;
font-weight: bold;
}

.avatar-input {
opacity: 0;
position: absolute;
width: 100%;
height: 100%;
cursor: pointer;
}

/* New styles for the Change Avatar button */
.change-avatar-button {
background-color: #34b808;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
transition: background-color 0.3s ease;
}

.change-avatar-button:hover {
background-color: #206b1d;
}

.profile-form {
display: flex;
flex-direction: column;
}

.form-group {
margin-bottom: 15px;
margin-right: 15px;
}

.form-group label {
margin-bottom: 5px;
font-weight: bold;
}

.form-group input, .form-group textarea {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}

.form-group textarea {
resize: vertical;
min-height: 100px;
}

.save-button {
background-color: #28a745;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}

.save-button:hover {
background-color: #218838;
}
156 changes: 156 additions & 0 deletions src/components/ProfilePage/ProfilePage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React, { useState, useContext, useEffect, useRef } from "react";
import { ToastContainer, toast } from 'react-toastify';
import { Link } from "react-router-dom";
import 'react-toastify/dist/ReactToastify.css';
import './ProfilePage.css';
import { ThemeContext } from "../../Content/context";
import MyChatbot from "../ChatBot/chatbot";

const ProfilePage = () => {
const { theme } = useContext(ThemeContext);
const fileInputRef = useRef(null);

const [formData, setFormData] = useState(() => {
const savedData = localStorage.getItem('profileData');
return savedData ? JSON.parse(savedData) : {
name: 'John Doe',
email: 'john.doe@example.com',
bio: 'I love coding and exploring new technologies!',
avatar: null
};
});

const [isEditing, setIsEditing] = useState(false);

useEffect(() => {
localStorage.setItem('profileData', JSON.stringify(formData));
}, [formData]);

const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};

const handleSubmit = (e) => {
e.preventDefault();
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
let errors = [];

if (!formData.name) errors.push('Name is required.');
if (!emailRegex.test(formData.email)) errors.push('Invalid Email Address.');
if (!formData.bio) errors.push('Bio is required.');

if (errors.length > 0) {
errors.forEach(error => toast.error(error));
return;
}

toast.success("Profile updated successfully!");
setIsEditing(false);
};

const handleAvatarChange = (e) => {
if (isEditing) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onloadend = () => {
setFormData({ ...formData, avatar: reader.result });
};
reader.readAsDataURL(file);
}
}
};

const triggerFileInput = () => {
if (isEditing) {
fileInputRef.current.click();
}
};

return (
<div className={`profile-page ${theme === 'dark' ? "dark-theme" : "light-theme"}`}>
<Link to="/" className="back-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" fill="currentColor" viewBox="0 0 16 16" style={{ fontWeight: 'bold', position: 'fixed', top: '20px', left: '20px' }}>
<path fillRule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8m15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-4.5-.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5z"></path>
</svg>
</Link>

<div className="profile-container">
<div className="profile-header">
<h1>Your Profile</h1>
<button onClick={() => setIsEditing(!isEditing)} className="edit-button">
{isEditing ? 'Cancel' : 'Edit Profile'}
</button>
</div>

<div className="avatar-container">
{formData.avatar ? (
<img src={formData.avatar} alt="Profile Avatar" className="avatar" />
) : (
<div className="avatar-placeholder">
<span>{formData.name.charAt(0)}</span>
</div>
)}
{isEditing && (
<button onClick={triggerFileInput} className="change-avatar-button">
Change Avatar
</button>
)}
<input
type="file"
ref={fileInputRef}
accept="image/*"
onChange={handleAvatarChange}
className="avatar-input"
style={{ display: 'none' }}
/>
</div>

<form onSubmit={handleSubmit} className="profile-form">
<div className="form-group">
<label htmlFor="name">Name</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
disabled={!isEditing}
required
/>
</div>
<div className="form-group">
<label htmlFor="email">Email Address</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
disabled={!isEditing}
required
/>
</div>
<div className="form-group">
<label htmlFor="bio">Bio</label>
<textarea
id="bio"
name="bio"
value={formData.bio}
onChange={handleChange}
disabled={!isEditing}
required
/>
</div>
{isEditing && (
<button type="submit" className="save-button">Save Profile</button>
)}
</form>
</div>
<ToastContainer />
<MyChatbot />
</div>
);
};

export default ProfilePage;
4 changes: 2 additions & 2 deletions src/components/review/review.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const ReviewPage = () => {
};

return (
<section className={`${theme=='dark'?"active":""} `}>
<section className={`${theme==='dark'?"active":""} `}>

<Link to="/" className="back-icon" style={{ position: 'absolute', top: '15px', left: '35px', fontSize: '42px' }}>
<svg
Expand All @@ -87,7 +87,7 @@ const ReviewPage = () => {
</svg>
</Link>

<div className={`${theme=='dark'?"active":""} review-container`}>
<div className={`${theme==='dark'?"active":""} review-container`}>
<div className="reviewInfo">
<div>
{/* Review info section */}
Expand Down
7 changes: 5 additions & 2 deletions src/pages/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function Header() {
}

function handleClick(e){
if(theme=="dark"){
if(theme==="dark"){
toggleTheme('light')
}else{
toggleTheme('dark')
Expand All @@ -42,14 +42,17 @@ isOpen?setIsOpen(false): setIsOpen(true)
</a>
<a href="/about" className="logo link1" style={{ padding: 10, margin: 5, height: 30, width: 80 }}>
<b>About Us</b>
</a>
<a href="/ProfilePage" className="logo link1" style={{ padding: 10, margin: 5, height: 30, width: 80 }}>
<b>Profile</b>
</a>
{
theme === 'dark' ? <HiSun size={"3rem"} onClick={handleClick} style={{ paddingRight: '20px' }} /> : <HiMoon size={"3rem"} onClick={handleClick} style={{ paddingRight: '30px' }} />
}
</div>
{

theme=='dark'? <HiSun className='mode' size={"3rem"} onClick={handleClick}/>:<HiMoon className='mode' size={"3rem"} onClick={handleClick}/>
theme==='dark'? <HiSun className='mode' size={"3rem"} onClick={handleClick}/>:<HiMoon className='mode' size={"3rem"} onClick={handleClick}/>
}
<div class="hamburger" id="hamburger" onClick={handleHamClick}>
<div></div>
Expand Down

0 comments on commit 366ec87

Please sign in to comment.