Skip to content

Commit

Permalink
Added GithubEventList Component (#156)
Browse files Browse the repository at this point in the history
# PR Summary

**Highlights:**
- Handled key GitHub events: Push, Pull, Fork, Create, Issues.
- Formatted card to match global post.

**Demo:**
- Check sc for all tested events.

**TODO:**
- Add header/logo/picture for GitHubEventList grid item on ProfilePage +
enhance cards UI

![Screenshot 2023-11-28
084312](https://github.com/uofa-cmput404/404f23project-404-team-not-found/assets/19487622/e6aa5330-c807-497f-87bc-2329345cc166)



![Screenshot 2023-11-28
084352](https://github.com/uofa-cmput404/404f23project-404-team-not-found/assets/19487622/08d7e41e-898f-4942-85bf-035a8e4c918a)
  • Loading branch information
rmgutierrez authored Nov 29, 2023
2 parents cee762e + 371fb85 commit 5cbe38d
Show file tree
Hide file tree
Showing 3 changed files with 286 additions and 1 deletion.
15 changes: 14 additions & 1 deletion client/src/components/Profilepage/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { useParams, useLocation } from "react-router-dom";
import MakePostModal from "../post/MakePostModal";
import LeftNavBar from "../template/LeftNavBar";


import GitHubEventList from "../post/GitHubEventList";
import CloseIcon from "@mui/icons-material/Close";
import FavoriteRoundedIcon from "@mui/icons-material/FavoriteRounded";
import FollowAuthorButton from "./FollowAuthorButton";
Expand Down Expand Up @@ -126,6 +128,7 @@ const ProfilePage = () => {
github: response.data.github,
profileImage: response.data.profileImage,
});

}
} catch (error) {
console.error("Error fetching author", error);
Expand All @@ -136,6 +139,8 @@ const ProfilePage = () => {
setIsMakePostModalOpen(true);
};



const fetchPosts = useCallback(async () => {
const url = (isLocal()) ?
`${APP_URI}authors/${authorId}/posts/` :
Expand Down Expand Up @@ -337,6 +342,7 @@ const ProfilePage = () => {
paddingTop: 2,
paddingBottom: 5,
borderBottom: "1px solid #dbd9d9",

}}
>
<Box
Expand Down Expand Up @@ -435,7 +441,14 @@ const ProfilePage = () => {
fetchPosts={fetchPosts}
posts={posts}
/>
</Grid>
</Grid >
<Grid item xs={3.6} style={{ paddingLeft: '4px' }}>
{authorData && authorData.github && (
<GitHubEventList
githubUrl={authorData.github}
/>
)}
</Grid>
<div>
<Modal
open={open}
Expand Down
250 changes: 250 additions & 0 deletions client/src/components/post/GitHubEventList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
import { GitHubEvent } from "../../interfaces/interfaces";
import {
Avatar,
Card,
CardContent,
CardHeader,
Typography,
Grid,
Paper,
Box
} from "@mui/material";

import { makeStyles } from "@mui/styles";

import { formatDateTime } from "../../utils/dateUtils";

import { useState, useEffect } from "react";

import axios from "axios";

import GitHubIcon from '@mui/icons-material/GitHub';

const extractUsernameFromUrl = (url: string): string | null => {
try {
const urlObject = new URL(url);

if (
urlObject.hostname === "github.com" &&
urlObject.pathname.split("/").length >= 2
) {
return urlObject.pathname.split("/")[1];
} else {
return null;
}
} catch (error) {
return null;
}
};

const useStyles = makeStyles((theme) => ({
root: {
"&::-webkit-scrollbar": {
width: 0,
},
},
}));

const GitHubEventsList = ({ githubUrl }: { githubUrl: string }) => {
const [githubEvents, setGitHubEvents] = useState<GitHubEvent[]>([]);
const username = extractUsernameFromUrl(githubUrl);
const gitehubUrl = `https://api.github.com/users/${username}/events`;
const classes = useStyles();

useEffect(() => {
const fetchGitHubEvents = async (): Promise<void> => {
try {
const response = await axios.get(gitehubUrl);
const eventsData = response.data as Array<any>;

const filteredEvents = eventsData
.map((event: any) => ({
id: event.id,
type: event.type,
created_at: event.created_at,
username: username,
repoName: event.repo.name,
repoUrl: event.repo.url,
actor: {
display_login: event.actor.display_login,
avatar_url: event.actor.avatar_url,
},
payload: {
size: event.payload?.size,
action: event.payload?.action,
title: event.payload?.title,
issue: {
title: event.payload?.issue?.title,
},
},
}))
.filter((event: any): event is GitHubEvent => {
return (
event.type === "PushEvent" ||
event.type === "PullRequestEvent" ||
event.type === "ForkEvent" ||
event.type === "CreateEvent" ||
event.type === "IssuesEvent"
);
});

setGitHubEvents(
filteredEvents.map((event: any) => ({
...event,
}))
);
} catch (error) {
console.error("Error fetching GitHub events:", error);
setGitHubEvents([]);
}
};

fetchGitHubEvents();
}, [githubUrl, username, gitehubUrl]);

const renderEventContent = (event: GitHubEvent) => {
switch (event.type) {
case "PushEvent":
console.log(event.payload.size);
return (
<>
<Typography>
{event.actor.display_login} <strong> pushed </strong>{" "}
{event.payload.size} commit/s to <strong>{event.repoName}</strong>
</Typography>
</>
);
case "PullRequestEvent":
return (
<>
<Typography>
{event.actor.display_login}{" "}
<strong>{event.payload.action}</strong> a Pull Request in{" "}
<strong>{event.repoName}</strong>
</Typography>
</>
);
case "ForkEvent":
return (
<>
<Typography>
{event.actor.display_login} <strong> forked </strong> a repository
from <strong>{event.repoName}</strong>
</Typography>
</>
);
case "CreateEvent":
return (
<>
<Typography>
{event.actor.display_login} <strong> created </strong> a
repository at <strong>{event.repoName}</strong>
</Typography>
</>
);
case "IssuesEvent":
return (
<>
<Typography>
{event.actor.display_login}{" "}
<strong>{event.payload.action}</strong> "
<strong> {event.payload?.issue?.title} </strong>" issue in{" "}
<strong>{event.repoName}</strong>
</Typography>
</>
);
default:
return null;
}
};

if (username !== null) {
return (
<Grid container spacing={2}>
<Grid
item
xs={12}
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
</Grid>
<Grid
item
container
direction="column"
xs={12}
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "25vw",
backgroundColor: "white",
position: "fixed",
right: "2.5vw",
top: 60
}}
>
<Grid container
direction="row"
alignItems="center"
justifyContent="center"
sx={{
marginBottom: 1
}}
>
<GitHubIcon fontSize="medium"/>
<Typography variant="h6">
Github
</Typography>
</Grid>
<Paper
elevation={0}
sx={{
borderRadius: 4,
overflow: "auto",
maxHeight: "85vh",
width: "100%"
}}
className={classes.root}
>
{githubEvents.length > 0 ? (
githubEvents.map((event) => (
<Card
key={event.id}
sx={{
boxShadow: "none",
borderBottom: "2px solid white",
backgroundColor: "#f7f8fa"
}}
>
<CardHeader
avatar={<Avatar src={event.actor.avatar_url} />}
title={<strong>{event.actor.display_login}</strong>}
subheader={formatDateTime(event.created_at)}
sx={{ margin: 0 }}
/>
<CardContent sx={{paddingTop: 0}}>{renderEventContent(event)}</CardContent>
</Card>
))
) : (
<Typography
variant="subtitle1"
align="center"
sx={{ fontWeight: "bold" }}
>
GitHub activity unavailable, please check username
</Typography>
)}
</Paper>
</Grid>
</Grid>
);
} else {
return <Typography variant="h6" align="center"></Typography>;
}
};

export default GitHubEventsList;
22 changes: 22 additions & 0 deletions client/src/interfaces/interfaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,28 @@ export interface Post {
comments: string;
}

export interface GitHubEvent {
id: string;
type: string;
created_at: string;
repoUrl: string;
repoName: string;
actor: {
display_login: string;
avatar_url: string;
};
payload: {
size?: number;
action?: string;
title?: string;
issue? : {
title?: string;

}
};
}


export interface Comment {
id: string;
author: Author;
Expand Down

0 comments on commit 5cbe38d

Please sign in to comment.