Skip to content

Commit

Permalink
Merge pull request #12 from Gin-n-Tonicc/Final-Bugfixes
Browse files Browse the repository at this point in the history
Final bugfixes
  • Loading branch information
stefan-petrov1 committed Apr 21, 2024
2 parents 8e22d17 + 7e38cc3 commit 37e8bac
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 85 deletions.
6 changes: 5 additions & 1 deletion client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AuthProvider } from './contexts/AuthContext';
import { ErrorProvider } from './contexts/ErrorContext';
import Admin from './pages/admin/Admin';
import AdminTableDefault from './pages/admin/admin-tables/AdminTableDefault';
import AdminTableEvents from './pages/admin/admin-tables/AdminTableEvents';
import AdminTableSkills from './pages/admin/admin-tables/AdminTableSkills';
import AdminTableUsers from './pages/admin/admin-tables/AdminTableUsers';
import FinishRegister from './pages/auth/finish-register/FinishRegister';
Expand Down Expand Up @@ -98,7 +99,10 @@ function App() {
path={AdminPageEnum.SKILLS}
element={<AdminTableSkills />}
/>

<Route
path={AdminPageEnum.EVENTS}
element={<AdminTableEvents />}
/>
<Route
path="*"
element={<Navigate to={PageEnum.NotFound} />}
Expand Down
12 changes: 6 additions & 6 deletions client/src/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ function AdminNav() {
<ul className="navbar-nav align-items-center">
<NavItem text="Users" to={`${PageEnum.Admin}/${AdminPageEnum.USERS}`} />
<NavItem text="Skills" to={`${PageEnum.Admin}/${AdminPageEnum.SKILLS}`} />
<NavItem text="Events" to={`${PageEnum.Admin}/${AdminPageEnum.EVENTS}`} />
</ul>
);
}
Expand Down Expand Up @@ -68,12 +69,11 @@ function UserNav(props: {
<Link to={PageEnum.Events} className="dropdown-item">
All Events
</Link>
{props.isOrganisation ||
(props.isAdmin && (
<Link to={PageEnum.EventsCreate} className="dropdown-item">
Create Event
</Link>
))}
{(props.isOrganisation || props.isAdmin) && (
<Link to={PageEnum.EventsCreate} className="dropdown-item">
Create Event
</Link>
)}
</div>
</div>
{props.isAuthenticated ? <LoggedNav {...props} /> : <GuestNav />}
Expand Down
14 changes: 14 additions & 0 deletions client/src/pages/admin/admin-tables/AdminTableEvents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import AdminTableApi from '../admin-table-api/AdminTableApi';

// The component that displays the admin users table
export default function AdminTableEvents() {
return (
<AdminTableApi
tableName="Events"
apiPathname="/events"
create={false}
delete={true}
update={true}
/>
);
}
109 changes: 60 additions & 49 deletions client/src/pages/events-details/EventsDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { useEffect, useMemo, useState } from 'react';
import { useParams } from 'react-router-dom';
import { Link, useParams } from 'react-router-dom';
import { useFetch } from 'use-http';
import {
eventsPaths,
filesPaths,
userEventStatusesPaths,
} from '../../config/api';
import { useAuthContext } from '../../contexts/AuthContext';
import { PageEnum } from '../../types/enums/PageEnum';
import { IUser } from '../../types/interfaces/auth/IUser';
import { IEvent } from '../../types/interfaces/events/IEvent';

const CHARACTER_DESCRIPTION_THRESHOLD = 60;

function EventsDetails() {
const { id } = useParams();
const [reduced1, setReduced] = useState<string[]>([]);
const { user } = useAuthContext();
const { user, isAuthenticated, hasFinishedOAuth2 } = useAuthContext();
const [participatingUsers, setParticipatingUsers] = useState<IUser[]>([]);

const eventId = Number(id || -1);
Expand All @@ -41,45 +39,6 @@ function EventsDetails() {
setParticipatingUsers(participatingUsersFetch);
}, [participatingUsersFetch]);

useEffect(() => {
if (!event) {
return;
}

const separator = event.description.includes(' ') ? ' ' : '';
const descWords = event.description.split(separator);

const reduced = descWords.reduce<{
count: number;
previousIndex: number;
newArr: string[];
}>(
(acc, x, i, arr) => {
acc.count += x.length;

if (acc.count > CHARACTER_DESCRIPTION_THRESHOLD) {
const wordsMatchThreshold = arr
.slice(acc.previousIndex, i)
.join(separator);
acc.previousIndex = i;
acc.newArr.push(wordsMatchThreshold);
acc.count = 0;
}

return acc;
},
{ count: 0, previousIndex: 0, newArr: [] }
);

reduced.newArr.push(
descWords
.slice(reduced.previousIndex, descWords.length - 1)
.join(separator)
);

setReduced(reduced.newArr);
}, [event]);

const handleParticipation = async () => {
const body = {
id: 0,
Expand All @@ -93,8 +52,6 @@ function EventsDetails() {
}
};

console.log(participatingUsers);

const participating = useMemo(
() => participatingUsers.some((x) => x.id === user.id),
[participatingUsers, user]
Expand Down Expand Up @@ -145,18 +102,22 @@ function EventsDetails() {
</span>
<span className="text-truncate me-0">
<i className="fas fa-user text-primary me-2" />
People Going: {participatingUsers.length}
People Participating: {participatingUsers.length}
</span>
</div>
</div>
<div className="d-flex flex-column align-items-center justify-content-center gap-3 mb-3">
<h4>Event description</h4>
<p style={{ textAlign: 'center' }}>{reduced1.join('\n')}</p>
<p style={{ textAlign: 'center' }}>{event?.description}</p>
<div style={{ width: '60%' }}>
<button
className="btn btn-primary w-100"
disabled={
loadingEvent || loadingStatuses || participating
loadingEvent ||
loadingStatuses ||
participating ||
!isAuthenticated ||
!hasFinishedOAuth2
}
onClick={handleParticipation}>
{!participating
Expand All @@ -167,6 +128,52 @@ function EventsDetails() {
</div>
</div>
</div>
<div
className="col-sm-12 ps-0 wow slideInUp"
style={{
maxWidth: '150%',
maxHeight: '60vh',
overflowY: 'scroll',
}}>
<div>
<div className="card-body">
<h5 className="d-flex align-items-center mb-3">
People Participating: {participatingUsers.length}
</h5>
<div>
<div className="card d-flex row">
{participatingUsers.map((x) => (
<div
className="p-4 d-flex align-items-center gap-3"
key={x.id}>
<img
src="https://bootdey.com/img/Content/avatar/avatar2.png"
alt=""
className="rounded-circle"
width="40"
height="40"
/>
<div>
<Link
to={PageEnum.Profile.replace(
':userId',
x.id.toString()
)}
className="fw-semibold mb-0">
<h5>{x.firstname}</h5>
</Link>
<span className="fs-7 d-flex align-items-center">
<i className="ti ti-map-pin text-dark fs-3 me-1"></i>
{x.whatCanHelpWith}
</span>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
<div className="d-flex justify-content-center align-items-center gap-5">
<div
style={{ width: '50%', height: '100%' }}
Expand Down Expand Up @@ -198,8 +205,12 @@ function EventsDetails() {
<p className="m-0">
What can we help with? {user.whatCanHelpWith}
</p>
<p className="m-0 text-blue te text-decoration-underline">
Connect with us through our profile page!
</p>
</div>
</div>
<div></div>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions client/src/pages/events/events-item/EventsItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { IEvent } from '../../../types/interfaces/events/IEvent';
export interface EventsItemProps extends IEvent {}

function EventsItem(props: EventsItemProps) {
const { isAuthenticated, user } = useAuthContext();
const { isAuthenticated, user, hasFinishedOAuth2 } = useAuthContext();

const [hasLiked, setHasLiked] = useState(
props.liked_users.some((x) => x.id === user.id)
Expand Down Expand Up @@ -65,7 +65,7 @@ function EventsItem(props: EventsItemProps) {
</div>
<div className="col-sm-12 col-md-4 d-flex flex-column align-items-start align-items-md-end justify-content-center">
<div className="d-flex mb-3">
{isAuthenticated && (
{isAuthenticated && hasFinishedOAuth2 && (
<a
className="btn btn-light btn-square me-3"
onClick={likeHandler}>
Expand Down
1 change: 1 addition & 0 deletions client/src/types/enums/AdminPageEnum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
export enum AdminPageEnum {
USERS = 'users',
SKILLS = 'skills',
EVENTS = 'events',
}
1 change: 1 addition & 0 deletions server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.15.2</version>
</dependency>

</dependencies>
<dependencyManagement>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.ginAndTonic.LudogorieHackEnter2024.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ginAndTonic.LudogorieHackEnter2024.enums.Role;
import com.ginAndTonic.LudogorieHackEnter2024.exceptions.handlers.JwtAuthenticationEntryPoint;
import com.ginAndTonic.LudogorieHackEnter2024.filters.JwtAuthenticationFilter;
import com.ginAndTonic.LudogorieHackEnter2024.security.OAuth2LoginSuccessHandler;
Expand Down Expand Up @@ -70,10 +71,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
"/swagger-ui.html",
"/oauth/**",
"/api/v1/skills/all",
"/api/v1/messages/**"
"/api/v1/messages/**",
"/api/v1/userEventStatuses/**"
)
.permitAll()

.anyRequest()
.authenticated()
.and()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ginAndTonic.LudogorieHackEnter2024.controllers;

import com.ginAndTonic.LudogorieHackEnter2024.exceptions.AccessDeniedException;
import com.ginAndTonic.LudogorieHackEnter2024.filters.JwtAuthenticationFilter;
import com.ginAndTonic.LudogorieHackEnter2024.model.dto.auth.PublicUserDTO;
import com.ginAndTonic.LudogorieHackEnter2024.model.dto.common.UserEventStatusDTO;
Expand Down Expand Up @@ -34,7 +35,13 @@ public ResponseEntity<UserEventStatusDTO> getUserEventStatusById(@PathVariable(n

@PostMapping("/create")
public ResponseEntity<UserEventStatusDTO> createUserEventStatus(@Valid @RequestBody UserEventStatusDTO userEventStatusDTO, HttpServletRequest httpServletRequest) {
UserEventStatusDTO cratedUserEventStatus = userEventStatusService.createUserEventStatus(userEventStatusDTO, (PublicUserDTO) httpServletRequest.getAttribute(JwtAuthenticationFilter.userKey));
PublicUserDTO currentUser = (PublicUserDTO) httpServletRequest.getAttribute(JwtAuthenticationFilter.userKey);

if (currentUser == null) {
throw new AccessDeniedException();
}

UserEventStatusDTO cratedUserEventStatus = userEventStatusService.createUserEventStatus(userEventStatusDTO, currentUser);
return new ResponseEntity<>(cratedUserEventStatus, HttpStatus.CREATED);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ protected void doFilterInternal(
final String userEmail = jwtService.extractUsername(jwt);

if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userService.findByEmail(userEmail);
UserDetails userDetails;
try {
userDetails = userService.findByEmail(userEmail);
} catch (Exception e) {
return;
}

// Check if token is valid and not revoked or expired
boolean isTokenValid = tokenRepository.findByToken(jwt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,36 +156,39 @@ public EventResponseDTO addLike(Long eventId, PublicUserDTO loggedUser) {

@Override
public List<EventResponseDTO> filterEventsByCriteria(boolean hasGoneTo, String filterType, PublicUserDTO publicUserDTO, int n) throws ChangeSetPersister.NotFoundException {
User user = userRepository.findById(publicUserDTO.getId()).orElseThrow(UserNotFoundException::new);
List<Event> resultEvents = new ArrayList<>();
if (!hasGoneTo) {
if (filterType.equalsIgnoreCase("All")) {
resultEvents = eventRepository.findByDeletedFalseOrderByIdDesc();
} else if (filterType.equalsIgnoreCase("Will happen")) {
resultEvents = eventRepository.findByStartTimeAfterAndDeletedIsFalseOrderByIdDesc(LocalDateTime.now());
} else if (filterType.equalsIgnoreCase("Favourited")) {
resultEvents = eventRepository.findEventsLikedByUser(user);
}
if(publicUserDTO == null){
resultEvents = eventRepository.findByDeletedFalseOrderByIdDesc();
} else {
List<UserEventStatus> userEventStatusList = userEventStatusRepository.findByUserIdId(user.getId());

if (filterType.equalsIgnoreCase("All")) {
for (UserEventStatus userEvent : userEventStatusList) {
Event event = eventRepository.findById(userEvent.getEventId().getId()).orElseThrow(NoSuchElementException::new);
resultEvents.add(event);
User user = userRepository.findById(publicUserDTO.getId()).orElseThrow(UserNotFoundException::new);
if (!hasGoneTo) {
if (filterType.equalsIgnoreCase("All")) {
resultEvents = eventRepository.findByDeletedFalseOrderByIdDesc();
} else if (filterType.equalsIgnoreCase("Will happen")) {
resultEvents = eventRepository.findByStartTimeAfterAndDeletedIsFalseOrderByIdDesc(LocalDateTime.now());
} else if (filterType.equalsIgnoreCase("Favourited")) {
resultEvents = eventRepository.findEventsLikedByUser(user);
}
} else if (filterType.equalsIgnoreCase("Favourited")) {
List<Event> likedEvents = eventRepository.findEventsLikedByUser(user);
for (UserEventStatus userEventStatus : userEventStatusList) {
for (Event likedEvent : likedEvents) {
if (Objects.equals(userEventStatus.getEventId().getId(), likedEvent.getId())) {
resultEvents.add(likedEvent);
} else {
List<UserEventStatus> userEventStatusList = userEventStatusRepository.findByUserIdId(user.getId());

if (filterType.equalsIgnoreCase("All")) {
for (UserEventStatus userEvent : userEventStatusList) {
Event event = eventRepository.findById(userEvent.getEventId().getId()).orElseThrow(NoSuchElementException::new);
resultEvents.add(event);
}
} else if (filterType.equalsIgnoreCase("Favourited")) {
List<Event> likedEvents = eventRepository.findEventsLikedByUser(user);
for (UserEventStatus userEventStatus : userEventStatusList) {
for (Event likedEvent : likedEvents) {
if (Objects.equals(userEventStatus.getEventId().getId(), likedEvent.getId())) {
resultEvents.add(likedEvent);
}
}
}
}
resultEvents = resultEvents.stream().sorted((a, b) -> b.getId().compareTo(a.getId())).toList();
}

resultEvents = resultEvents.stream().sorted((a, b) -> b.getId().compareTo(a.getId())).toList();
}

return resultEvents.stream()
Expand Down

0 comments on commit 37e8bac

Please sign in to comment.