Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VOL 249/dashboard link up dashboard community page to users #266

Merged
merged 7 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added web/public/assets/profile_placeholder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 59 additions & 51 deletions web/src/components/Dashboard/DashboardCommunity/CommunityGallery.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,69 @@
import axios from 'axios';
import { useState, useEffect } from 'react';
import CommunityGalleryCard from '../dashboardCommunity/CommunityGalleryCard';
import { useState, useEffect, useContext } from 'react';
import CommunityGalleryCard from '../DashboardCommunity/CommunityGalleryCard';
import CommunitySearchContext from '../../../context/CommunitySearchContext';

interface GalleryData {
title: string;
image: string;
type userData = {
profile_picture: string;
firstName: string;
lastName: string;
email: string;
mobile: string;
upi: string;
birthdate: string;
gender: string;
yearLevel: string;
dietaryRequirements: string;
driversLicense: string;
hours: number;
otherRequirements: string;
emergencyContactFirstName: string;
emergencyContactLastName: string;
emergencyContactMobile: string;
emergencyContactRelationship: string;
}

const CommunityGallery = ({event, location}: {event: string, location: string}) => {

// TEMPORARY DATA, we should be getting the profile data from somewhere
const name = 'John Doe';
const hours = '14';
const [data, setData] = useState<GalleryData[]>([
{
title: "Relay For Life",
image: "/assets/EventHighlights/Events/RelayForLife/imgB.png"
},
{
title:"Volunteers Day",
image: "/assets/EventHighlights/Events/VolunteersDay/imgB.png"
},
{
title:"Blind Low Vision",
image: "/assets/EventHighlights/Events/BlindLowVision/imgB.png"
},
{
title: "Pub Quiz",
image: "/assets/EventHighlights/Events/PubQuiz/imgB.png"
}
]);

useEffect(() => {
// Fetch gallery data
axios.get('http://localhost:3000/api/homepage/gallery')
.then((res) => {
setData(res.data);
})
.catch((err) => {
console.log(err);
});
}
const CommunityGallery = () => {

const [data, setData] = useState<userData[]>([]);
const [filteredData, setFilteredData] = useState<userData[]>([]);

const context = useContext(CommunitySearchContext);

const filterUsers = (users: userData[]) => {
return users.filter((user) => {
const fullName = user.firstName + ' ' + user.lastName;
return fullName.toLowerCase().includes(context.searchTerm.toLowerCase());
});
};

useEffect(() => {
// Fetch gallery data
axios.get('http://localhost:3000/api/users')
.then((res) => {
setData(res.data);
})
.catch((err) => {
console.log(err);
});
}
, []);

useEffect(() => {
setFilteredData(filterUsers(data));
}, [context.searchTerm, data]);


return (
<div className='bg-white rounded-3xl py-10 px-[4%] w-full text-subheading text-black shadow-lg max-[1887px]:px-[6%] max-[1770px]:px-[3%] max-[1510px]:px-[8%]'>
<p>People you may know from {event} at {location}</p>
<div className='flex gap-x-[5px] justify-between gap-y-2 flex-wrap '>
{/* hardcoded 4 people, this shoulded be mapped with however many people in the event?? */}
<CommunityGalleryCard name={name} hours={hours} profileImgLink={data[0].image}/>
<CommunityGalleryCard name={name} hours={hours} profileImgLink={data[1].image}/>
<CommunityGalleryCard name={name} hours={hours} profileImgLink={data[2].image}/>
<CommunityGalleryCard name={name} hours={hours} profileImgLink={data[3].image}/>
</div>
</div>
);
return (
<div className='bg-white rounded-3xl py-10 px-[4%] w-full text-subheading text-black shadow-lg max-[1887px]:px-[6%] max-[1770px]:px-[3%] max-[1510px]:px-[8%]'>
<p>People you may know: </p>
<div className='flex gap-x-[1%] justify-start gap-y-2 flex-wrap'>
{filteredData.map((user: userData, index: number) => (
<CommunityGalleryCard key={index} user={user} />
))}
</div>
</div>
);
}

export default CommunityGallery;
Original file line number Diff line number Diff line change
@@ -1,34 +1,57 @@
import { BsFillPersonPlusFill } from "react-icons/bs";

type userData = {
profile_picture: string;
firstName: string;
lastName: string;
email: string;
mobile: string;
upi: string;
birthdate: string;
gender: string;
yearLevel: string;
dietaryRequirements: string;
driversLicense: string;
hours: number;
otherRequirements: string;
emergencyContactFirstName: string;
emergencyContactLastName: string;
emergencyContactMobile: string;
emergencyContactRelationship: string;
}

interface CommunityGalleryCardProps {
name: string;
hours: string;
profileImgLink: string;
user: userData;
}

const CommunityGalleryCard = ({name, hours, profileImgLink}: CommunityGalleryCardProps) => {
const CommunityGalleryCard = ({user}: CommunityGalleryCardProps) => {

const handleAddFriend = () => {
console.log('add friend');
};

if (user.profile_picture === "" || user.profile_picture === null || user.profile_picture === undefined) {
console.log(user.profile_picture);
user.profile_picture = "assets/profile_placeholder.png";
}

return (
<div className="w-[300px] h-[540px] rounded-2xl relative max-[1887px]:w-[270px] max-[1887px]:h-[510px] max-[1755px]:w-[300px]">
<div className="bg-primary h-[23%] rounded-t-2xl">
</div>

<div className="bg-lightGrey absolute w-[150px] top-[7%] right-[25%] rounded-full max-[1887px]:w-[125px] max-[1887px]:right-[26%] max-[1755px]:right-[28%]">
<img src={profileImgLink} alt="" className="w-[100%] object-cover aspect-square rounded-full"/>
<img src={user.profile_picture} alt="profile" className="w-[100%] object-cover aspect-square rounded-full"/>
</div>

<div className="border-b-[1px] border-x-[1px] rounded-b-2xl border-lightGrey2 h-[70%] flex flex-col items-center">
<p className="text-[25px] mt-[5.8rem] mb-0 text-black max-[1887px]:mt-[4rem]">{name}</p>
<p className="text-[40px] my-1 text-black">{hours}</p>
<p className="text-[25px] mt-[5.8rem] mb-0 text-black max-[1887px]:mt-[4rem]">{user.firstName + " " + user.lastName}</p>
<p className="text-[40px] my-1 text-black">{user.hours}</p>
<p className="text-body text-m text-lightGrey2 mb-6">hours</p>

<div className="flex items-center w-[70%] justify-between">
<div className="bg-lightGrey w-[40px] rounded-full flex-shrink-0">
<img src={profileImgLink} alt="" className="aspect-square rounded-full"/>
<img src={user.profile_picture} alt="" className="aspect-square rounded-full object-cover"/> {/* this should be the profile picture of the mutual, but for now just uses the user's img */}
</div>
{/* THIS DOES NOT HANDLE MUTUALS, IDK HOW WE ARE GONNA DO THAT SO I HAVENT MADE PROPS FOR THE BELOW STUFF */}
<p className="text-body text-sm text-lightGrey2 ml-4 mb-0 mr-0">jaquallelina and 12 other mutual friends</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,20 @@
/*
* So like the purpose of this file is to have a container for every event, then for every event it will have x amount of profile cards shown
* For now, we don't separate the events, we just show all the profile cards in one container
*/

import axios from "axios";
import { useState, useEffect } from "react";
import CommunityGallery from "../dashboardCommunity/CommunityGallery";
import CommunityGallery from "./CommunityGallery";

interface EventData {
title: string;
location: string;
}

const CommunityGalleryWhole = () => {
// TEMPORARY DATA passing down events into community gallery vvvvvvvvvvvvvvvvvvvvvvvvvvvvv
const [data, setData] = useState<EventData[]>([
{
title: "Quiz Night",
location: "Uni"
},
{
title:"Launch Night",
location: "Somewhere"
},
{
title:"C",
location: "Somewhere"
},
{
title: "Beach Cleanup",
location: "Beach"
}
]);

useEffect(() => {
// Fetch gallery data
axios.get('http://localhost:3000/api/homepage/highlights')
.then((res) => {
setData(res.data);
})
.catch((err) => {
console.log(err);
});
}
, []);
// TEMPORARY ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

return (
<div>
{/* passing event data into community gallery*/}
{data.map(( event ) => (
<div className="mb-5">
<CommunityGallery event={event.title} location={event.location}/>
</div>
))}
<CommunityGallery />
</div>
);
}
Expand Down
9 changes: 5 additions & 4 deletions web/src/components/Dashboard/DashboardCommunity/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import React, { useState } from 'react';
import React, { useContext, useState } from 'react';
import { FiSearch } from 'react-icons/fi'; // magnifying glass icon
import CommunitySearchContext from '../../../context/CommunitySearchContext';

interface SearchBarProps {
placeholder?: string; // Optional placeholder for the search input
}

const SearchBar: React.FC<SearchBarProps> = ({ placeholder = "Search by name" }) => {
const [searchTerm, setSearchTerm] = useState<string>('');
const context = useContext(CommunitySearchContext);

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
setSearchTerm(value);
context.setSearchTerm(value);
};

return (
Expand All @@ -20,7 +21,7 @@ const SearchBar: React.FC<SearchBarProps> = ({ placeholder = "Search by name" })
<input
type="text"
placeholder={placeholder}
value={searchTerm}
value={context.searchTerm}
onChange={handleInputChange}
className="w-full p-2 pl-10 border border-gray-300 rounded-md" // Adjust padding for the icon
/>
Expand Down
5 changes: 5 additions & 0 deletions web/src/context/CommunitySearchContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createContext } from "react";

const CommunitySearchContext = createContext<any>(null);

export default CommunitySearchContext;
18 changes: 18 additions & 0 deletions web/src/context/CommunitySearchContextProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useState } from "react";
import CommunitySearchContext from "./CommunitySearchContext";


export function CommunitySearchContextProvider({ children }: { children: React.ReactNode }) {
const [searchTerm, setSearchTerm] = useState<string>('');

const contextValue = {
searchTerm,
setSearchTerm,
};

return (
<CommunitySearchContext.Provider value={contextValue as any}>
{children}
</CommunitySearchContext.Provider>
);
}
9 changes: 7 additions & 2 deletions web/src/pages/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SearchBar from "@components/Dashboard/dashboardCommunity/SearchBar";
import ProfileEditModalContextProvider from "../context/ProfileEditModalContextProvider";
import DashboardHeader from "@components/Dashboard/DashboardHeader";
import SideBar from "@components/Dashboard/SideBar";
import { CommunitySearchContextProvider } from "../context/CommunitySearchContextProvider";

function Dashboard() {
const [tab, setTab] = useState(1);
Expand All @@ -33,6 +34,7 @@ function Dashboard() {
};

return (
<CommunitySearchContextProvider>
<div className="bg-[#F7F7FB] primary-background overflow-hidden flex flex-row">
{/* width of the left nav bar */}
{/* place thing component here and remove bg-primary */}
Expand All @@ -47,7 +49,7 @@ function Dashboard() {
{tab === 5 &&(
<>
<h1>other thig</h1>
<SearchBar />
<SearchBar />
</>
)}
<DashboardHeader/>
Expand All @@ -65,11 +67,14 @@ function Dashboard() {
</ProfileEditModalContextProvider>
</>}
{tab === 4 && <DashboardCalendar />}
{tab === 5 && <DashboardCommunity />}
{tab === 5 &&
<DashboardCommunity />
}
</div>
</div>

</div>
</CommunitySearchContextProvider>
);
}

Expand Down
Loading