Skip to content

Commit

Permalink
Merge pull request #43 from hcp-uw/settings-again
Browse files Browse the repository at this point in the history
Settings again
  • Loading branch information
zth12301 authored Sep 3, 2024
2 parents 123f8ef + c7203b0 commit 2a043b4
Show file tree
Hide file tree
Showing 11 changed files with 412 additions and 51 deletions.
5 changes: 4 additions & 1 deletion starter-backend/src/config/firebase-config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { initializeApp, cert } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";
import { getFirestore } from "firebase-admin/firestore";
import { getStorage } from "firebase-admin/storage";

const app = initializeApp({
credential: cert("./serviceAccountKey.json"),
Expand All @@ -12,4 +13,6 @@ const auth = getAuth(app);
// db variable used for firestore db purposes
const db = getFirestore();

export { auth, db };
const storage = getStorage();

export { auth, db, storage };
1 change: 1 addition & 0 deletions starter-frontend/src/components/navbar/Navbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,5 @@ nav {

#profile-icon {
display: block;
border-radius: 50%;
}
27 changes: 23 additions & 4 deletions starter-frontend/src/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Link } from 'react-router-dom';
import Logout from '../auth/Logout';
import { auth } from '../../config/firebase';
import { useAuth } from '../../contexts/AuthContext';
import { useRef } from "react";


/* Home logo with binary tree and Green Notes title. (Upper right corner of navigation bar) */
Expand Down Expand Up @@ -48,19 +49,37 @@ function Profile(): JSX.Element {
setIsModal(!isModal);
}

/* dropdown disappears if you click anywhere on the screen outside of it */
const dropdownRef = useRef<HTMLDivElement>(null);
const handleClickOutside = (e: any) => {
if (open && !dropdownRef.current?.contains(e.target)) {
setOpen(false);
}
}
window.addEventListener("click", handleClickOutside);

const user = useAuth();
if (user === null) {
throw new Error();
}
const currentUser = user.currentUser;
if (currentUser === null) {
throw new Error();
}

return (
<div>
<div ref={dropdownRef}>
<Logout isModal={isModal} setIsModal={setIsModal}/>
<a onClick={handleOpen}><img id="profile-icon" src={profile} /></a>
<a onClick={handleOpen}><img id="profile-icon" src={currentUser.photoURL || profile} /></a>
{open ? (
<ul className="menu">
<li className="menu-item">
{/* TODO: figure out how to give ddown-option more height and convert other things to links */}
<Link to={`profile`} className='ddown-option' onClick={handleOpen}>Your Profile</Link>
</li>
<li className="menu-item">
{/* <li className="menu-item">
<button onClick={handleOpen}>Shared Files</button>
</li>
</li> */}
<li className="menu-item">
<Link to={`settings`} className='ddown-option' onClick={handleOpen}>Settings</Link>
</li>
Expand Down
10 changes: 10 additions & 0 deletions starter-frontend/src/components/navbar/ProfileDropdown.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,14 @@
margin-left: 5px;
text-decoration: none;
color: black;
/* vertically center: */
position: absolute;
top: 50%;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}

.menu-item {
height: 28px;
position: relative;
}
5 changes: 4 additions & 1 deletion starter-frontend/src/config/firebase.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";


/** All sensitive data is in .env file that isn't part of
Expand All @@ -24,6 +25,8 @@ const auth = getAuth(app);

// Starts and exports the database part of firebase
const db = getFirestore(app);

const storage = getStorage(app);


export { auth, db };
export { auth, db, storage };
7 changes: 6 additions & 1 deletion starter-frontend/src/pages/edit-profile/EditProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { useNavigate } from "react-router-dom";

import { useAuth } from "../../contexts/AuthContext";
import smile from '../../assets/profile-button.png';
import { ref, getDownloadURL } from 'firebase/storage';
import { storage } from '../../config/firebase';

// edit profile page


/** New Profile page */
export default function NewProfile() {
const navigate = useNavigate();
Expand Down Expand Up @@ -37,9 +40,11 @@ export default function NewProfile() {
setError("");
setLoading(true);
const user = currentUser;
const fileRef = ref(storage, 'profile-button.png')
const photo = await getDownloadURL(fileRef);
const profile = {
displayName: username,
// photoURL: avatars[selectedAvatar],
photoURL: photo,
};
await updateUserProfile(user, profile);
navigate("/notes");
Expand Down
66 changes: 66 additions & 0 deletions starter-frontend/src/pages/settings/EditBio.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// import { db } from '../../../../starter-backend/src/config/firebase-config';
// import { doc, updateDoc } from "firebase/firestore";

// export async function EditBioField(): Promise<void> {
// const userRef = doc(db, "users", "frank");

// await updateDoc(userRef, {
// "favorites.color": "Red"
// });

// db.collection("users").doc("frank").update({
// "favorites.firebase": "Help")};
// }

import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from '../../contexts/AuthContext';
import './settings.css';

/* Allows the user to edit their bio */

type EditBioProps = {isModal: boolean, setIsModal: React.Dispatch<React.SetStateAction<boolean>>}

export default function EditBio({ isModal, setIsModal }: EditBioProps) {
const navigate = useNavigate();
const user = useAuth();

if (user === null) {
throw new Error("Not logged in");
}
const currentUser = user.currentUser;
if (currentUser === null) {
throw new Error("Not logged in");
}

const [bio, setBio] = useState("");
const setError = user.setError;

const handleEditBio = async (e: any) => {
// e.preventDefault();

// try {
// setError("");
// await user.updateUserProfile(currentUser, { displayName: name });

// setIsModal(false);
// navigate("/settings");
// } catch (e) {
// setError("failed to update display name");
// }
}

if (!isModal) {
return null;
} else {
return (
<div className="edit-name-popup">
<form>
<div><input id="new-name" type="text" placeholder="Enter your bio" onChange={(e) => setBio(e.target.value)}></input></div>
<button onClick={handleEditBio}>Save</button>
<button onClick={() => setIsModal(false)}>Cancel</button>
</form>
</div>
);
}
}
52 changes: 52 additions & 0 deletions starter-frontend/src/pages/settings/EditName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from '../../contexts/AuthContext';
import './settings.css';

/* Allows the user to edit their display name */

type EditDisplayNameProps = {isModal: boolean, setIsModal: React.Dispatch<React.SetStateAction<boolean>>}

export default function EditName({ isModal, setIsModal }: EditDisplayNameProps) {
const navigate = useNavigate();
const user = useAuth();

if (user === null) {
throw new Error("Not logged in");
}
const currentUser = user.currentUser;
if (currentUser === null) {
throw new Error("Not logged in");
}

const [name, setName] = useState("");
const setError = user.setError;

const handleEditDisplayName = async (e: any) => {
e.preventDefault();

try {
setError("");
await user.updateUserProfile(currentUser, { displayName: name });

setIsModal(false);
navigate("/settings");
} catch (e) {
setError("failed to update display name");
}
}

if (!isModal) {
return null;
} else {
return (
<div className="edit-name-popup">
<form>
<div><input id="new-name" type="text" placeholder="Enter new display name" onChange={(e) => setName(e.target.value)}></input></div>
<button onClick={handleEditDisplayName}>Save</button>
<button onClick={() => setIsModal(false)}>Cancel</button>
</form>
</div>
);
}
}
67 changes: 67 additions & 0 deletions starter-frontend/src/pages/settings/UploadProfilePic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from "react";
import { useEffect, useState } from "react";
import { useAuth } from '../../contexts/AuthContext';
import { storage } from '../../config/firebase';
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
import profile from '../../assets/profile-button.png';

/* Allows the user to change their profile photo by uploading an image from their device */

export default function UploadProfilePic(): JSX.Element {
const user = useAuth();
if (user === null) {
throw new Error('error');
}
const currentUser = user.currentUser;
if (currentUser === null) {
throw new Error('error');
}

async function upload(file: any, user: any, setLoading: any) {
if (user === null) {
throw new Error('error');
}
const currentUser = user.currentUser;
const fileRef = ref(storage, currentUser.uid + '.png');

setLoading(true);
const snapshot = await uploadBytes(fileRef, file);
const photoURL = await getDownloadURL(fileRef);

setPhotoUrl(photoURL);
user.updateUserProfile(currentUser, {photoURL: photoURL});
setLoading(false);
}

const [photo, setPhoto] = useState(null);
const [loading, setLoading] = useState(false);
const [photoUrl, setPhotoUrl] = useState('');

function handleChange(e: any) {
if (e.target.files[0]) {
setPhoto(e.target.files[0]);
}
}

function handleClick() {
upload(photo, user, setLoading);
}

useEffect(() => {
if (currentUser?.photoURL) {
setPhotoUrl(currentUser.photoURL);
}
}, [currentUser]);

return (
<div className='profile-text'>
<div className='container'>
<div id='image-cropper'><img src={photoUrl || profile} alt='profile' id='img'></img></div>
</div>
<p></p>
<p id='edit-profile-text'>Edit profile photo:</p>
<input type="file" onChange={handleChange}></input>
<button disabled={loading || !photo} onClick={handleClick}>Upload</button>
</div>
)
}
Loading

0 comments on commit 2a043b4

Please sign in to comment.