Skip to content

Commit

Permalink
Edit profile page
Browse files Browse the repository at this point in the history
  • Loading branch information
echelonka committed Jun 6, 2024
1 parent 696d6a2 commit ec8e794
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Routes, Route } from 'react-router-dom';

import AuthPage from './components/AuthPage.tsx';
import DashboardPage from './components/DashboardPage.tsx';
import EditProfilePage from './components/EditProfilePage.tsx';
import InitialPage from './components/InitialPage.tsx';
import MatchesPage from './components/MatchesPage.tsx';

Expand All @@ -13,6 +14,7 @@ export const App = () => {
<Route path="/auth" element={<AuthPage />} />
<Route path="/dashboard" element={<DashboardPage />} />
<Route path="/matches" element={<MatchesPage />} />
<Route path="/edit-profile" element={<EditProfilePage />} />
</Routes>
);
};
192 changes: 192 additions & 0 deletions src/components/EditProfilePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { Box, Spinner, Input, Select, Stack, Button, useToast, Text, FormControl, FormLabel } from '@chakra-ui/react';
import { getAuth } from 'firebase/auth';
import { doc, updateDoc } from 'firebase/firestore';
import { FormEvent, ChangeEvent, useEffect, useState } from 'react';
import { useAuthState } from 'react-firebase-hooks/auth';
import { useDocument } from 'react-firebase-hooks/firestore';
import { Navigate } from 'react-router-dom';

import { db } from '../../firebase.config';
import countries from '../components/countries.json';

const auth = getAuth();

function EditProfilePage() {
const [user, userLoading] = useAuthState(auth);
const toast = useToast();

// Get the current user from Firebase
const [currentUser, currentUserLoading] = useDocument(doc(db, 'users', user?.uid || 'asd'));

const [userLoaded, setUserLoaded] = useState(false);

const [age, setAge] = useState('');
const [countryOfLiving, setCountryOfLiving] = useState('');
const [gender, setGender] = useState('');
const [name, setName] = useState('');
const [preference, setPreference] = useState('');
const [contactInfo, setContactInfo] = useState('');
const [comment, setComment] = useState('');

useEffect(() => {
// Set initial values for the form fields after user is loaded
if (!userLoaded && !currentUserLoading) {
const currentUserData = currentUser?.data() || {};

setAge(currentUserData.age);
setCountryOfLiving(currentUserData.countryOfLiving);
setGender(currentUserData.gender);
setName(currentUserData.name);
setPreference(currentUserData.preference);
setContactInfo(currentUserData.contactInfo);
setComment(currentUserData.comment);

setUserLoaded(true);
}
}, [userLoaded, currentUserLoading, currentUser]);

const updateProfile = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (!currentUser) return;

try {
await updateDoc(currentUser.ref, {
age,
countryOfLiving,
gender,
name,
preference,
contactInfo,
comment,
});

toast({
status: 'success',
description: 'Successfully updated user.',
});
} catch (e) {
toast({ status: 'error', description: 'Failed to update user.' });
}
};

const handleNameChange = (e: ChangeEvent<HTMLInputElement>) => {
setName(e.target.value);
};

const handleAgeChange = (e: ChangeEvent<HTMLInputElement>) => {
setAge(e.target.value);
};

const handleGenderChange = (e: ChangeEvent<HTMLSelectElement>) => {
setGender(e.target.value);
};

const handleCountryChange = (e: ChangeEvent<HTMLSelectElement>) => {
setCountryOfLiving(e.target.value);
};

const handleContactChange = (e: ChangeEvent<HTMLInputElement>) => {
setContactInfo(e.target.value);
};

const handlePreferenceChange = (e: ChangeEvent<HTMLSelectElement>) => {
setPreference(e.target.value);
};

const handleCommentChange = (e: ChangeEvent<HTMLInputElement>) => {
setComment(e.target.value);
};

// Do not show page content until auth state is fetched.
if (userLoading || currentUserLoading) {
return <Spinner />;
}

// If user isn't signed in, redirect to auth page.
if (!user) {
return <Navigate to="/auth" replace />;
}

return (
<Box padding="24px">
<Text fontSize="xl" marginBottom="16px">
Profile settings
</Text>
<form onSubmit={updateProfile}>
<Stack spacing={4}>
<FormControl>
<FormLabel>Name</FormLabel>
<Input placeholder="Name" type="text" onChange={handleNameChange} value={name} required />
</FormControl>

<FormControl>
<FormLabel>Age</FormLabel>
<Input placeholder="Age" type="number" onChange={handleAgeChange} value={age} required />
</FormControl>

<FormControl>
<FormLabel>Gender</FormLabel>
<Select
placeholder="Gender"
onChange={handleGenderChange}
value={gender}
required
style={{ color: gender ? 'black' : 'grey' }}
>
<option value="male">Male</option>
<option value="female">Female</option>
<option value="non-binary">Non-binary</option>
</Select>
</FormControl>

<FormControl>
<FormLabel>Country of living</FormLabel>
<Select
placeholder="Country of living"
onChange={handleCountryChange}
value={countryOfLiving}
required
style={{ color: countryOfLiving ? 'black' : 'grey' }}
>
{countries.map((country) => (
<option key={country.value} value={country.value}>
{country.name}
</option>
))}
</Select>
</FormControl>

<FormControl>
<FormLabel>Contact Information</FormLabel>
<Input
placeholder="Contact Information"
type="text"
onChange={handleContactChange}
value={contactInfo}
required
/>
</FormControl>

<FormControl>
<FormLabel>Preference</FormLabel>
<Select placeholder="Preference" onChange={handlePreferenceChange} value={preference} required>
<option value="friends">Friends</option>
<option value="date">Date</option>
<option value="dont-know">Don't know</option>
</Select>
</FormControl>

<FormControl>
<FormLabel>Comment</FormLabel>
<Input placeholder="Comment" type="text" onChange={handleCommentChange} value={comment} required />
</FormControl>

<Button type="submit">Update</Button>
</Stack>
</form>
</Box>
);
}

export default EditProfilePage;

0 comments on commit ec8e794

Please sign in to comment.