Skip to content
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
151 changes: 127 additions & 24 deletions src/components/UserCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,117 @@ import {
Box,
Flex,
HStack,
Link,
Text,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
useDisclosure,
Button,
ListItem,
UnorderedList,
} from "@chakra-ui/react";
import React from "react";
import {
PhoneIcon,
EmailIcon,
InfoIcon,
EditIcon,
} from "@chakra-ui/icons";
import React, {useState} from "react";
import axios from "axios";
import { apiUrl, Service } from "@hex-labs/core";

type Props = {
user: any;
};

type ModProps = {
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,
// and userId.

const UserModal: React.FC<ModProps> = (props: ModProps) => {
const [hexathons, setHexathons] = useState<any>(null);
const getApplications = async () => {
const data = await axios.get(
apiUrl(
Service.HEXATHONS,
'/hexathons')
);
const allHexathons = data.data;
const applications = await Promise.all(allHexathons.map(async (hexathon: any) => {
const app = await axios.get(
apiUrl(
Service.REGISTRATION,
'/applications'
),
{
params: {
hexathon: hexathon.id,
userId: props.user.userId
}
}
);
return app ? hexathon.name : null;
}));
setHexathons(applications.filter((app: any) => app !== null));
}

return (
<>
<Modal isOpen={props.isOpen} onClose={props.onClose} isCentered>
<ModalOverlay />
<ModalContent>
<ModalHeader>{`${props.user.name.first} ${props.user.name.last}`}</ModalHeader>
<ModalCloseButton />
<ModalBody mt={-3}>
<Text fontSize='md'><EmailIcon/> : <Link href={`mailto:${props.user.email}`}>{`${props.user.email}`}</Link></Text>
<Text fontSize='md'><PhoneIcon/> : {props.user.phoneNumber?.length > 9 && (`${ '+1 (' + props.user.phoneNumber.substring(0,3) + ')'
+ ' ' + props.user.phoneNumber.substring(3,6)
+ '-' + props.user.phoneNumber.substring(6)}`)}</Text>
<Text fontSize='md'><InfoIcon/> : {`${props.user.userId}`}</Text>

{!hexathons && (
<Button onClick={getApplications} colorScheme='gray' size='sm' mt={2} ml={-1}>Load Hexathons</Button>
)}

{ hexathons && (
<Text fontSize='md'><EditIcon/> : Applied Hexathons:
<UnorderedList ml={7}>
{hexathons.map((hexathon : string) => (
<ListItem fontSize='sm' ml={5}>{hexathon}</ListItem>
))}

{hexathons.length == 0 && (
<>No hexathons found.</>
)}

</UnorderedList>
</Text>

)}
</ModalBody>

<ModalFooter>
<Button colorScheme='blue' onClick={props.onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
}

// TODO: Explore if you can display the email as a link to the user's email that will open up the user's
// email client and start a new email to that user. Also explore if you can provide a link to the user's resume.

Expand All @@ -24,30 +122,35 @@ type Props = {
// and the /hexathons endpoint of the hexathons service to get a list of all the hexathons.

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"
>
<Flex padding="2" flexDirection="column">
<HStack align="flex-end" justify="space-between">
<Text fontSize='xl'>{`${props.user.name.first} ${props.user.name.last}`}</Text>
</HStack>
<Text
fontSize="sm"
fontWeight="semibold"
justifyContent="justify"
mt="2"
>
{props.user.email}
</Text>
</Flex>
</Box>
<>
<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">
<Text fontSize='xl'>{`${props.user.name.first} ${props.user.name.last}`}</Text>
</HStack>
<Text
fontSize="sm"
fontWeight="semibold"
justifyContent="justify"
mt="2"
>
{props.user.email}
</Text>
</Flex>
</Box>

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

Expand Down
38 changes: 32 additions & 6 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 { Button, SimpleGrid, Text, Flex } from "@chakra-ui/react";
import axios from "axios";
import UserCard from "./UserCard";

Expand Down Expand Up @@ -30,6 +30,13 @@ const UserData: React.FC = () => {
// TODO: Use the apiUrl() function to make a request to the /users endpoint of our USERS service. The first argument is the URL
// of the request, which is created for the hexlabs api through our custom function apiUrl(), which builds the request URL based on
// the Service enum and the following specific endpoint URL.
const data = await axios.get(
apiUrl(
Service.USERS,
'/users/hexlabs'
)
);


// TODO: Also explore some of the other ways to configure the api call such as filtering and pagination.
// Try to filter all the users with phone numbers starting with 470 or increase the amount of users returned from the default 50 (don't go above 100).
Expand All @@ -39,11 +46,16 @@ 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';

const phoneFilter = data.data.filter((user: any) => {
const phone = user.phoneNumber ?? "";
return phone.startsWith("470")
});

// 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);
setUsers(phoneFilter);
};
document.title = "Hexlabs Users"
document.title = "Hexlabs Users";
getUsers();
}, []);
// ^^ The empty array at the end of the useEffect hook tells React that the
Expand All @@ -55,12 +67,26 @@ 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.

const firstNameSort = () => {
const sorted = [...users].sort((a,b) => {
return a.name.first.localeCompare(b.name.first);
});

setUsers(sorted);

}

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>

<Text fontSize="4xl" justifySelf="center" mt={3}>Hexlabs Users</Text>
<Text fontSize="2xl" justifySelf="center">This is an example of a page that makes an API call to the Hexlabs API to get a list of users.</Text>

<Flex justify="center" mt={3}>
<Button size="md" colorScheme="blue" onClick={firstNameSort}>
Sort by First Name
</Button>
</Flex>


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

Expand Down