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

Shaunak Karnik Onboarding Project #20

Open
wants to merge 2 commits into
base: startercode
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Routes, Route } from "react-router-dom";
import axios from "axios";
import { initializeApp } from "firebase/app";
import { setPersistence, getAuth, inMemoryPersistence } from "firebase/auth";
import { useLogin, LoadingScreen, AuthProvider } from "@hex-labs/core";
import { useLogin, LoadingScreen, AuthProvider, Header, Footer } from "@hex-labs/core";

import UserData from './components/UserData';

Expand Down Expand Up @@ -48,12 +48,12 @@ export const App = () => {
// useAuth hook to retrieve the user's login details.
return (
<AuthProvider app={app}>

<Header children={null} />
{/* Setting up our React Router to route to all the different pages we may have */}
<Routes>
<Route path="/" element={<UserData />} />
</Routes>

<Footer />
</AuthProvider>
);
};
Expand Down
99 changes: 98 additions & 1 deletion src/components/UserCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,32 @@ import {
Flex,
HStack,
Text,
Modal,
ModalBody,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalFooter,
Button,
useDisclosure,
UnorderedList,
ListItem
} from "@chakra-ui/react";
import React from "react";
import { apiUrl, Service } from "@hex-labs/core";
import axios from "axios";
import React, { useState, useEffect } from "react";

type Props = {
user: any;
};

type ModalProps = {
isOpen: boolean;
onClose: () => void;
user: any;
};


// TODO: right now, the UserCard only displays the user's name and email. Create a new modal component <UserModal> that
// pops up when the card is clicked. In this modal, list all the user's information including name, email, phoneNumber,
Expand All @@ -23,16 +42,91 @@ type Props = {
// the hexathons that the user has applied to. You can use the /applications endpoint of the registration service to do this
// and the /hexathons endpoint of the hexathons service to get a list of all the hexathons.

const UserModal: React.FC<ModalProps> = (props: ModalProps) => {

// State variable and setter for hexathons
const [hexathons, setHexathons] = useState<any[]>([]);

const getHexathons = async () => {
try {
// fetches all hexathons
const response = await axios.get(apiUrl(Service.HEXATHONS, "/hexathons"));
const allHexathons = response.data;
// fetches all applications for the specific user for each hexathon
// uses Promise for series of async calls
const userApps = await Promise.all(allHexathons.map(async (hexathon: any) => {
const res = await axios.get(apiUrl(Service.REGISTRATION, "/applications"), {
params: {
hexathon: hexathon.id,
userId: props.user.userId
}
});
// returns hexathon if user has applied
return res.data.length > 0 ? hexathon : null;
}));
// filters for non-null hexathons
const filteredHexathons = userApps.filter((hexathon) => hexathon !== null);
setHexathons(filteredHexathons);

} catch (error) {
console.error("Error: " + error);
}

}

useEffect(() => {
if (props.isOpen) {
getHexathons();
}
}, [props.isOpen]);

return (
<Modal isOpen={props.isOpen} onClose={props.onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>User Information</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text><strong>Name:</strong> {`${props.user.name.first} ${props.user.name.last}`}</Text>
<Text><strong>Email:</strong> {props.user.email}</Text>
<Text><strong>Phone Number:</strong> {props.user.phoneNumber || "Not provided"}</Text>
<Text><strong>User ID:</strong> {props.user.userId}</Text>
<Box>
<Text fontWeight="bold" mb={2}>Applied Hexathons:</Text>
{ hexathons.length > 0 ?
(<UnorderedList>
{hexathons.map((hexathon) => (
<ListItem key={hexathon.id}>
{hexathon.name}
</ListItem>
))}
</UnorderedList>) : <Text>No hexathons applied</Text>
}
</Box>
</ModalBody>
<ModalFooter>
<Button onClick={props.onClose}>Close</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
};



const UserCard: React.FC<Props> = (props: Props) => {
const { isOpen, onOpen, onClose } = useDisclosure();

return (
<>
<Box
borderWidth="1px"
rounded="lg"
boxShadow="lg"
height="175px"
fontWeight="bold"
alignItems="center"
onClick={onOpen}
>
<Flex padding="2" flexDirection="column">
<HStack align="flex-end" justify="space-between">
Expand All @@ -48,6 +142,9 @@ const UserCard: React.FC<Props> = (props: Props) => {
</Text>
</Flex>
</Box>

<UserModal isOpen={isOpen} onClose={onClose} user={props.user} />
</>
);
};

Expand Down
27 changes: 22 additions & 5 deletions src/components/UserData.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { apiUrl, Service } from "@hex-labs/core";
import { SimpleGrid, Text } from "@chakra-ui/react";
import { filter, SimpleGrid, Text, Button, HStack } from "@chakra-ui/react";
import axios from "axios";
import UserCard from "./UserCard";

Expand Down Expand Up @@ -39,9 +39,19 @@ const UserData: React.FC = () => {
// this is the endpoint you want to hit, but don't just hit it directly using axios, use the apiUrl() function to make the request
const URL = 'https://users.api.hexlabs.org/users/hexlabs';

try {
// API call
const response = await axios.get(apiUrl(Service.USERS, "/users/hexlabs"));
const users = response.data;
// filters by numbers stating with 470
const filteredUsers = users.filter((user: any) => user.phoneNumber && user.phoneNumber.startsWith("470"));
setUsers(filteredUsers);
} catch (error) {
console.error("Error: " + error);
}
// uncomment the line below to test if you have successfully made the API call and retrieved the data. The below line takes
// the raw request response and extracts the actual data that we need from it.
// setUsers(data?.data?.profiles);

};
document.title = "Hexlabs Users"
getUsers();
Expand All @@ -54,13 +64,20 @@ const UserData: React.FC = () => {

// TODO: Create a function that sorts the users array based on the first name of the users. Then, create a button that
// calls this function and sorts the users alphabetically by first name. You can use the built in sort() function to do this.

function sortByFirstName() {
// makes shallow copy of users and sorts by first name
const sortedUsers = [...users].sort((a, b) => a.name.first.localeCompare(b.name.first));
setUsers(sortedUsers);
}

return (
<>
<Text fontSize="4xl">Hexlabs Users</Text>
<Text fontSize="2xl">This is an example of a page that makes an API call to the Hexlabs API to get a list of users.</Text>
<HStack>
<Text fontSize="4xl">Hexlabs Users</Text>
<Button onClick={sortByFirstName}>Sort by First Name</Button>
</HStack>

<Text fontSize="2xl">This is an example of a page that makes an API call to the Hexlabs API to get a list of users.</Text>

<SimpleGrid columns={[2, 3, 5]} spacing={6} padding={10}>

Expand Down