Skip to content

Commit

Permalink
ADD: Favorites page, modal for nonauth users, fixed bugs in login and…
Browse files Browse the repository at this point in the history
… register pages
  • Loading branch information
GGalina committed May 13, 2024
1 parent 312769b commit ffe0fbe
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 158 deletions.
98 changes: 29 additions & 69 deletions src/components/Favorites/Favorites.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,82 +2,42 @@ import { useEffect, useState } from 'react';
import { Loader } from '../Loader/Loader';
import { useMediaQuery } from 'react-responsive';
import { useColor } from '../../context/ColorContext';
import { useAuth } from '../../context/AuthContext';
import { TeachersList } from '../TeachersList/TeachersList';
import { getFavoriteTeachersAPI} from '../../services/firebaseAPI';
import {
Container,
LoadMore
} from './Favorites.styled';
import { useFavoriteTeachers } from '../../context/FavoriteTeachersContext';
import { Text, LoadMore, Container } from './Favorites.styled';

export const Favorites = () => {
const { isLoggedIn } = useAuth();
const batchSize = 4;
const [page, setPage] = useState(1);
const { selectedColor } = useColor();
const [teachers, setTeachers] = useState([]);
const [hasMore, setHasMore] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [lastFetched, setLastFetched] = useState(null);
const [allTeachers, setAllTeachers] = useState([]);
const { favoriteTeachers, isLoading } = useFavoriteTeachers();
const isDesktop = useMediaQuery({ query: '(min-width: 1280px)' });

useEffect(() => {
const fetchFavoriteTeachers = async () => {
try {
if (isLoggedIn) {
setIsLoading(true);
const initialTeachers = await getFavoriteTeachersAPI(null);
setTeachers(initialTeachers);
setAllTeachers(favoriteTeachers.slice(0, page * batchSize));
}, [favoriteTeachers, page]);

if (initialTeachers.length > 0) {
const lastFetchedValue = initialTeachers[initialTeachers.length - 1].id;
setLastFetched(lastFetchedValue);
} else {
setHasMore(false);
}
}
} catch (error) {
console.error('Error fetching initial teachers:', error);
} finally {
setIsLoading(false);
}
};

fetchFavoriteTeachers();
}, []);

const loadMoreTeachers = async () => {
try {
setIsLoading(true);

if (lastFetched === null || lastFetched === undefined) {
console.error('Error fetching teachers: lastFetched is null or undefined');
return;
}

const newTeachers = await getFavoriteTeachersAPI(teachers[teachers.length - 1].id);

if (newTeachers.length > 0) {
setTeachers((prevTeachers) => [...prevTeachers, ...newTeachers]);
setLastFetched(newTeachers[newTeachers.length - 1].id);
} else {
// No more teachers to load
setHasMore(false);
}
} catch (error) {
console.error('Error fetching teachers:', error);
} finally {
setIsLoading(false);
}
const loadMoreTeachers = () => {
setPage(prevPage => prevPage + 1);
};

return (
<Container>
<TeachersList teachers={teachers} isDesktop={isDesktop} />
{!isLoading && hasMore && (
<LoadMore $selcolor={selectedColor} type="button" onClick={loadMoreTeachers}>
Load more
</LoadMore>
)}
{isLoading && <Loader />}
</Container>
);
};
return (
<Container>
{isLoading && <Loader />}

{!isLoading && favoriteTeachers.length === 0 ? (
<Text>No favorite teachers found.</Text>
) : (
<>
<TeachersList teachers={allTeachers} isDesktop={isDesktop} />
{favoriteTeachers.length > allTeachers.length && (
<LoadMore $selcolor={selectedColor} type="button" onClick={loadMoreTeachers}>
Load more
</LoadMore>
)}
</>
)}
</Container>
);
};
11 changes: 11 additions & 0 deletions src/components/Favorites/Favorites.styled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import styled from 'styled-components';

export const Container = styled.div`
width: 100%;
min-height: 100vh;
margin-right: auto;
margin-left: auto;
background-color: #EEEEEE;
Expand Down Expand Up @@ -48,4 +49,14 @@ export const LoadMore = styled.button`
&:hover {
transform: scale(1.1);
}
`;

export const Text = styled.p`
font-family: 'Roboto-Medium', sans-serif;
font-size: 28px;
line-height: 48px;
letter-spacing: -0.8px;
align-items: center;
margin-top: 50px;
color: #121417;
`;
2 changes: 1 addition & 1 deletion src/components/Layout/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useModal } from '../../context/ModalContext';
import { ColorProvider } from '../../context/ColorContext';
import { ModalProvider } from '../../context/ModalContext';
import { AuthProvider } from '../../context/AuthContext';
import { FavoriteTeachersProvider } from '../../context/FavoriteTeachersContext'
import { FavoriteTeachersProvider } from '../../context/FavoriteTeachersContext';

const LoginModal = lazy(() => import('../LoginModal/LoginModal').then(module => ({ default: module.LoginModal })));
const RegistrationModal = lazy(() => import('../RegistrationModal/RegistrationModal').then(module => ({ default: module.RegistrationModal })));
Expand Down
2 changes: 1 addition & 1 deletion src/components/LoginModal/LoginModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const LoginModal = () => {
localStorage.setItem('isLoggedIn', 'true');
localStorage.setItem('registeredUserName', userName);

closeModal();
handleClose();
} catch (error) {
throw new Error(error);
}
Expand Down
11 changes: 8 additions & 3 deletions src/components/NonAuthModal/NonAuthModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Btn,
Desc,
Header,
Wrapper,
CloseIcon,
BtnContainer,
ModalContainer
Expand All @@ -26,8 +27,8 @@ export const NonAuthModal = () => {
};

const handleClose = () => {
document.body.classList.remove('no-scroll');
closeModal();
document.body.classList.remove('no-scroll');
};

useEffect(() => {
Expand All @@ -52,8 +53,12 @@ export const NonAuthModal = () => {
<Header>Please register or log in to continue.</Header>
<Desc>Looks like you are not logged in. Please login or register to enjoy all the functionality of LearnLingo.</Desc>
<BtnContainer>
<Btn type="submit" $selcolor={selectedColor} onClick={() => handleModalClick('login')}>Log In</Btn>
<Btn type="submit" $selcolor={selectedColor} onClick={() => handleModalClick('register')}>Registration</Btn>
<Wrapper onClick={() => handleModalClick('login')}>
<Btn $selcolor={selectedColor}>Log In</Btn>
</Wrapper>
<Wrapper onClick={() => handleModalClick('register')}>
<Btn $selcolor={selectedColor} >Registration</Btn>
</Wrapper>
</BtnContainer>
</ModalContainer>
</Backdrop>
Expand Down
4 changes: 3 additions & 1 deletion src/components/NonAuthModal/NonAuthModal.styled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,6 @@ export const Btn = styled.button`
font-family: 'Roboto-Bold',sans-serif;
font-size: 18px;
line-height: 28px;
`;
`;

export const Wrapper = styled.div``;
2 changes: 1 addition & 1 deletion src/components/RegistrationModal/RegistrationModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const RegistrationModal = () => {
localStorage.setItem('isLoggedIn', 'true');
localStorage.setItem('registeredUserName', name);

closeModal();
handleClose();
} catch (error) {
throw new Error(error);
}
Expand Down
5 changes: 2 additions & 3 deletions src/components/TeacherCard/TeacherCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export const TeacherCard = ({ teacher, isDesktop }) => {
try {
if (!isLoggedIn) {
openNonAuthModal();
document.body.classList.add('no-scroll');
} else {
if (isFavorite(teacher.id)) {
await removeFromFavorites(teacher.id);
Expand Down Expand Up @@ -93,15 +92,15 @@ export const TeacherCard = ({ teacher, isDesktop }) => {
<MainInfoContainer>
<TextWrapper>
<GreyAccent>Speaks: </GreyAccent>
<UnderlinedText>{teacher.languages.join(', ')}</UnderlinedText>
<UnderlinedText>{teacher.languages ? teacher.languages.join(', ') : ''}</UnderlinedText>
</TextWrapper>
<TextWrapper>
<GreyAccent>Lesson Info: </GreyAccent>
<Text>{teacher.lesson_info}</Text>
</TextWrapper>
<TextWrapper>
<GreyAccent>Conditions: </GreyAccent>
<Text>{teacher.conditions.join(' ')}</Text>
<Text>{teacher.conditions ? teacher.conditions.join(' ') : ''}</Text>
</TextWrapper>
{showDetails && <TeacherDetails teacher={teacher} />}
<ReadMoreBtn $showdetails={showDetails} onClick={handleShowDetails}>
Expand Down
2 changes: 0 additions & 2 deletions src/components/Teachers/Teachers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ export const Teachers = () => {
useEffect(() => {
const fetchInitialTeachers = async () => {
try {
console.log('we tt')
setIsLoading(true);

const initialTeachers = await fetchTeachersAPI(null);
setTeachers(initialTeachers);
console.log(initialTeachers);

if (initialTeachers.length > 0) {
const lastFetchedValue = initialTeachers[initialTeachers.length - 1].id;
Expand Down
36 changes: 22 additions & 14 deletions src/context/FavoriteTeachersContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,51 @@ export const useFavoriteTeachers = () => useContext(FavoriteTeachersContext);
export const FavoriteTeachersProvider = ({ children }) => {
const [ , setUserId] = useState(null);
const [favoriteTeachers, setFavoriteTeachers] = useState([]);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
const fetchData = async () => {
try {
setIsLoading(true);
const teachers = await getFavoriteTeachersAPI();
setFavoriteTeachers(teachers);

} catch (error) {
console.error('Error fetching favorite teachers:', error);

} finally {
setIsLoading(false);
}
};

const unsubscribe = auth.onAuthStateChanged(user => {
if (user) {
setUserId(user.uid);
fetchFavoriteTeachers();
fetchData();
} else {
setUserId(null);
setFavoriteTeachers([]);
}
});

return unsubscribe;
return () => unsubscribe();
}, []);

const fetchFavoriteTeachers = async () => {
try {
const teachers = await getFavoriteTeachersAPI();
setFavoriteTeachers(teachers);
} catch (error) {
console.error('Error fetching favorite teachers:', error);
}
};

const addToFavorites = async (teacherId) => {
try {
await addToFavoritesAPI(teacherId);
setFavoriteTeachers([...favoriteTeachers, { id: teacherId }]);
const teachers = await getFavoriteTeachersAPI();
setFavoriteTeachers([...teachers]);
} catch (error) {
console.error('Error adding to favorites:', error);
}
};


const removeFromFavorites = async (teacherId) => {
try {
await removeFromFavoritesAPI(teacherId);
setFavoriteTeachers(favoriteTeachers.filter(teacher => teacher.id !== teacherId));
setFavoriteTeachers(prevTeachers => prevTeachers.filter(teacher => teacher.id !== teacherId));
} catch (error) {
console.error('Error removing from favorites:', error);
}
Expand All @@ -66,7 +74,7 @@ export const FavoriteTeachersProvider = ({ children }) => {

return (
<FavoriteTeachersContext.Provider
value={{ favoriteTeachers, addToFavorites, removeFromFavorites, isFavorite }}
value={{ favoriteTeachers, addToFavorites, removeFromFavorites, isFavorite, isLoading }}
>
{children}
</FavoriteTeachersContext.Provider>
Expand Down
4 changes: 0 additions & 4 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ body {
-moz-osx-font-smoothing: grayscale;
}

body.no-scroll {
overflow: hidden;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
Expand Down
Loading

0 comments on commit ffe0fbe

Please sign in to comment.