diff --git a/src/v2/api/Controllers/TeamController.cs b/src/v2/api/Controllers/TeamController.cs index b3035365..f5293e69 100644 --- a/src/v2/api/Controllers/TeamController.cs +++ b/src/v2/api/Controllers/TeamController.cs @@ -49,6 +49,22 @@ public async Task>> GetByEventID(long eventId) } } + [HttpGet("event/{eventId}/user/{userid}")] + public async Task>> GetUsersTeamsForEvent(long eventId, int userId) + { + Log.Information("Getting User {userid} Teams by event {eventId}", userId, eventId); + try + { + var teams = mapper.Map>(await teamRepository.GetUsersTeamsByEventIdAsync(eventId, userId)); + return new ActionResult>(teams); + } + catch (NotFoundException> ex) + { + Log.Information(ex.Message, "Event Not Found"); + return NotFound(ex.Message); + } + } + [HttpGet("{teamId}")] public async Task> GetByID(long teamId) { diff --git a/src/v2/api/DataAccess/TeamRepository.cs b/src/v2/api/DataAccess/TeamRepository.cs index 5086e94d..8c530fdf 100644 --- a/src/v2/api/DataAccess/TeamRepository.cs +++ b/src/v2/api/DataAccess/TeamRepository.cs @@ -11,6 +11,7 @@ public interface ITeamRepository Task GetTeamByIdAsync(long id); Task> GetAllAsync(); Task> GetByEventIdAsync(long eventID); + Task> GetUsersTeamsByEventIdAsync(long eventID, int userId); Task ExistsAsync(long id); } @@ -19,7 +20,7 @@ public class TeamRepository : ITeamRepository private readonly AspenContext context; private readonly IMapper mapper; private readonly IPersonTeamAssoicationRepository personTeamAssociationRepository; - + public TeamRepository(AspenContext context, IMapper mapper, IPersonTeamAssoicationRepository personTeamAssociationRepository) { @@ -28,7 +29,7 @@ public TeamRepository(AspenContext context, IMapper mapper, IPersonTeamAssoicati this.personTeamAssociationRepository = personTeamAssociationRepository; } - + public async Task ExistsAsync(long id) { @@ -62,7 +63,7 @@ public async Task AddAsync(Team team) throw new Exception("Person is already on another team in this event"); } } - + await context.Teams.AddAsync(dbTeam); existingEvent.Teams.Add(dbTeam); @@ -76,7 +77,7 @@ public async Task EditTeamAsync(Team team) { var dbTeam = mapper.Map(team); context.Update(dbTeam); - if(team.isArchived == true) + if (team.isArchived == true) { var teamMembers = await personTeamAssociationRepository.GetTeamMembersAsync(team.ID); @@ -89,23 +90,23 @@ public async Task EditTeamAsync(Team team) return team; } - /* public async Task DeleteTeamAsync(Team team) - { - var dbTeam = mapper.Map(team); - context.Update(dbTeam); + /* public async Task DeleteTeamAsync(Team team) + { + var dbTeam = mapper.Map(team); + context.Update(dbTeam); - var teamMembers = await personTeamAssociationRepository.GetTeamMembersAsync(team.ID); + var teamMembers = await personTeamAssociationRepository.GetTeamMembersAsync(team.ID); - foreach (var member in teamMembers) - { - await personTeamAssociationRepository.DeleteAsync(member.ID, team.ID); - } + foreach (var member in teamMembers) + { + await personTeamAssociationRepository.DeleteAsync(member.ID, team.ID); + } - await context.SaveChangesAsync(); - } -*/ + await context.SaveChangesAsync(); + } + */ public async Task> GetByEventIdAsync(long eventID) { @@ -118,4 +119,14 @@ public async Task> GetByEventIdAsync(long eventID) return mapper.Map, IEnumerable>(unArchivedTeams); } + public async Task> GetUsersTeamsByEventIdAsync(long eventID, int userId) + { + var teams = await context.PersonTeamAssociations + .Include(a => a.Team) + .Where(a => a.EventId == eventID && a.PersonId == userId) + .Select(a => a.Team) // Select the Team objects + .ToListAsync(); + + return mapper.Map, IEnumerable>(teams); + } } diff --git a/src/v2/client/package-lock.json b/src/v2/client/package-lock.json index 937f6ee6..ee4d0886 100644 --- a/src/v2/client/package-lock.json +++ b/src/v2/client/package-lock.json @@ -20,6 +20,7 @@ "@types/react-query": "^1.2.9", "axios": "^1.5.0", "bootstrap": "^5.3.1", + "bootstrap-icons": "^1.11.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hot-toast": "^2.4.1", @@ -5576,6 +5577,21 @@ "@popperjs/core": "^2.11.8" } }, + "node_modules/bootstrap-icons": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.1.tgz", + "integrity": "sha512-F0DDp7nKUX+x/QtpfRZ+XHFya60ng9nfdpdS59vDDfs4Uhuxp7zym/QavMsu/xx51txkoM9eVmpE7D08N35blw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ] + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -21745,6 +21761,11 @@ "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==", "requires": {} }, + "bootstrap-icons": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.1.tgz", + "integrity": "sha512-F0DDp7nKUX+x/QtpfRZ+XHFya60ng9nfdpdS59vDDfs4Uhuxp7zym/QavMsu/xx51txkoM9eVmpE7D08N35blw==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", diff --git a/src/v2/client/package.json b/src/v2/client/package.json index a90caf4c..c98e7177 100644 --- a/src/v2/client/package.json +++ b/src/v2/client/package.json @@ -15,6 +15,7 @@ "@types/react-query": "^1.2.9", "axios": "^1.5.0", "bootstrap": "^5.3.1", + "bootstrap-icons": "^1.11.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hot-toast": "^2.4.1", diff --git a/src/v2/client/src/assets/WideContainer.module.scss b/src/v2/client/src/assets/WideContainer.module.scss new file mode 100644 index 00000000..20400f97 --- /dev/null +++ b/src/v2/client/src/assets/WideContainer.module.scss @@ -0,0 +1,14 @@ +@import "./custom.scss"; + +@mixin make-container($padding-x: $container-padding-x) { + width: 100%; + padding-right: $padding-x; + padding-left: $padding-x; + margin-right: auto; + margin-left: auto; + max-width: 100em; +} + +.customContainer { + @include make-container(-x) +} \ No newline at end of file diff --git a/src/v2/client/src/assets/custom.scss b/src/v2/client/src/assets/custom.scss index d8cba774..3b4c27f4 100644 --- a/src/v2/client/src/assets/custom.scss +++ b/src/v2/client/src/assets/custom.scss @@ -1,5 +1,6 @@ $primary: #673AB7; -$secondary: #FFA500; +$secondary: #8AB73A; $info: #0089DB; +$success: #C3DD94; @import "../../node_modules/bootstrap/scss/bootstrap.scss" \ No newline at end of file diff --git a/src/v2/client/src/index.tsx b/src/v2/client/src/index.tsx index 4eb677ba..3d676398 100644 --- a/src/v2/client/src/index.tsx +++ b/src/v2/client/src/index.tsx @@ -5,6 +5,7 @@ import { BrowserRouter } from 'react-router-dom'; import { StrictMode } from 'react'; import "bootstrap" import "./assets/custom.scss" +import "bootstrap-icons/font/bootstrap-icons.css" import { createRoot } from 'react-dom/client' const queryClient = getQueryClient(); diff --git a/src/v2/client/src/models/Team.ts b/src/v2/client/src/models/Team.ts new file mode 100644 index 00000000..55284e2a --- /dev/null +++ b/src/v2/client/src/models/Team.ts @@ -0,0 +1,11 @@ +export interface Team { + id: number; + description: string; + mainImage: string; + ownerId: number; + eventId: number; + name: string; + donationTarget: number; + isArchived: boolean; + welcomeMessage: string; +} \ No newline at end of file diff --git a/src/v2/client/src/pages/home/BenefitsModal.tsx b/src/v2/client/src/pages/home/BenefitsModal.tsx deleted file mode 100644 index e1c429fd..00000000 --- a/src/v2/client/src/pages/home/BenefitsModal.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { useModal, CustomModal, ModalButton } from "../../components/CustomModal" - -export const BenefitsModal = () => { - const eventDetailModalControl = useModal("Benefits", "lg") - - const ModalButton: ModalButton = ({ showModal }) => ( - - ) - return ( - - <> -
-
Benefits of Joining a Charity Event Team
-
-
-
    -
  • Joining a team for a charity event is a powerful way to maximize your impact and make a positive difference in the lives of others.
  • -
  • When you're part of a team, you benefit from the camaraderie and collective motivation, which encourages you to contribute more generously than you might on your own.
  • -
  • The spirit of friendly competition among teams drives each member to push their limits, resulting in a greater overall contribution to the cause.
  • -
  • Being part of a team fosters a sense of belonging, creating a network of passionate individuals united by a common goal.
  • -
  • By working together and leveraging each other's strengths, you not only raise more funds for the charity, but you also forge lasting connections that strengthen your community and promote a culture of giving.
  • -
-
- -
-
- -
- ) -} diff --git a/src/v2/client/src/pages/home/DonationProgess.tsx b/src/v2/client/src/pages/home/DonationProgess.tsx index df3c0e7d..3930c96f 100644 --- a/src/v2/client/src/pages/home/DonationProgess.tsx +++ b/src/v2/client/src/pages/home/DonationProgess.tsx @@ -1,6 +1,6 @@ import { FC } from "react" import { Event } from "../../models/Event" -import { useGetEventDonationQuery } from "./homeHooks"; +import { useGetEventDonationQuery } from "./events/eventHooks"; import { Spinner } from "../../components/Spinner"; export const DonationProgess: FC<{ @@ -15,18 +15,14 @@ export const DonationProgess: FC<{ return ( <> -
{donated}% of our ${event.donationTarget} goal
-
-
-
-
-
-
+
{donated}% of our ${event.donationTarget} goal
+
+
) diff --git a/src/v2/client/src/pages/home/Home.tsx b/src/v2/client/src/pages/home/Home.tsx index d6e71dd1..21d9f94c 100644 --- a/src/v2/client/src/pages/home/Home.tsx +++ b/src/v2/client/src/pages/home/Home.tsx @@ -1,9 +1,8 @@ +import classes from "../../assets/WideContainer.module.scss" import { Spinner } from "../../components/Spinner"; -import { BenefitsModal } from "./BenefitsModal"; -import { UpcomingEventsModal } from "./UpcomingEventsModal"; -import { useGetEventsQuery } from "./homeHooks"; -import { Event } from "../../models/Event"; -import { DonationProgess } from "./DonationProgess"; +import { EventDetails } from "./events/EventDetails"; +import { useGetEventsQuery } from "./events/eventHooks"; +import { CharityTeams } from "./teams/CharityTeams"; export const Home = () => { const getEventsQuery = useGetEventsQuery(); @@ -12,50 +11,45 @@ export const Home = () => { const currentEvent = futureEvents.length > 0 ? futureEvents[0] : undefined if (getEventsQuery.isLoading) return + if (getEventsQuery.isError) return

Error getting events

+ if (!getEventsQuery.data) return

Unable to get events

+ return ( -
-
- {currentEvent ? ( -

Upcoming Event: {currentEvent.title}

- ) : ( -

There are currently no upcoming events

- )} -