Skip to content
This repository has been archived by the owner on Apr 12, 2023. It is now read-only.

GitHub API CRUD #6

Open
wants to merge 2 commits into
base: master
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
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@patternfly/react-core": "^3.129.3",
"@patternfly/react-table": "^2.24.64",
"apollo-boost": "^0.4.7",
"bootstrap": "^4.4.1",
"graphql": "^14.5.8",
"graphql-tag": "^2.10.1",
"react": "^16.12.0",
"react-bootstrap": "^1.0.0-beta.16",
"react-dom": "^16.12.0",
"react-scripts": "3.2.0"
},
Expand Down
24 changes: 14 additions & 10 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
.App {
text-align: center;
}

.App-logo {
height: 40vmin;
height: 100px;
}

.App-header {
background-color: #282c34;
min-height: 100vh;
background-color: white;
height: 120px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
flex: 1;
color: white;
flex-direction: row;
}

.App-link {
color: #09d3ac;
.dashHead{
color: lightseagreen;
font-size: xx-large;
}

.head{
text-align: center;
color: lightseagreen;
font-size: xx-large;
}
19 changes: 9 additions & 10 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';
import MainPage from './components/MainPage'

function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
<p className="dashHead">
<b> git </b>
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<hr/>
<br/>
<p className="head">
<b style={{textAlign:"center"}}>Repo: {localStorage.getItem('repoName')}</b>
</p>
<MainPage/>
</div>
);
}
Expand Down
46 changes: 46 additions & 0 deletions src/components/HeaderTabs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { Tabs, Tab } from '@patternfly/react-core';
import '@patternfly/react-core/dist/styles/base.css';
import Repos from './sets/Repos'
import Issues from './sets/Issues'
import Comments from './sets/Comments'


class HeaderTabs extends React.Component {
tabNumber = localStorage.getItem('tabNumber');
constructor(props) {
super(props);
this.state = {
activeTabKey: Number.parseInt(localStorage.getItem('tabNumber'))
};
// Toggle currently active tab
this.handleTabClick = (event, tabIndex) => {
this.setState({
activeTabKey: tabIndex
});
if(tabIndex==0){
localStorage.clear();
window.location.reload();
}

localStorage.setItem('tabNumber', tabIndex);
};
}

render() {
return (
<Tabs style={{padding:32}} isFilled activeKey={this.state.activeTabKey} onSelect={this.handleTabClick}>
<Tab eventKey={0} title="Repositories">
<Repos/>
</Tab>
<Tab eventKey={1} title="Issues">
<Issues/>
</Tab>
<Tab eventKey={2} title="Comments">
<Comments/>
</Tab>
</Tabs>
);
}
}
export default HeaderTabs;
12 changes: 12 additions & 0 deletions src/components/MainPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import '@patternfly/react-core/dist/styles/base.css';
import HeaderTabs from './HeaderTabs';

const MainPage = () => {
const tabNumber = localStorage.getItem('tabNumber');
if(tabNumber==null){
localStorage.setItem('tabNumber', 0);
}
return <HeaderTabs/>;
};
export default MainPage;
30 changes: 30 additions & 0 deletions src/components/Pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

const Pagination = ({active, perPage, total, paginate}) => {
const pageNumbers=[];
for(let i=1; i<= Math.ceil(total/perPage);i++){
pageNumbers.push(i);
}
return(
<nav className="pagination">
{pageNumbers.map(number=>{
if(number==active){
return (<li key={number} className="page-item active">
<a onClick={()=>paginate(number)} href='!#' className='page-link'>
{number}
</a>
</li>);
} else {
return(<li key={number} className="page-item">
<a onClick={()=>paginate(number)} href='!#' className='page-link'>
{number}
</a>
</li>
);
}
})}
</nav>
)
}
export default Pagination;
185 changes: 185 additions & 0 deletions src/components/sets/Comments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import React, {useState, useEffect} from 'react';
import ApolloClient from 'apollo-boost'
import gql from 'graphql-tag'
import {TextInput} from '@patternfly/react-core'
import {TableHeader, TableBody, Table} from '@patternfly/react-table';
import Button from 'react-bootstrap/Button';
import '@patternfly/react-core/dist/styles/base.css';

const Comments = () => {
const [comments, setComments] = useState([]);
const [loading, setLoading] = useState(false);
const [body, setBody] = useState("")
const [mode, setMode] = useState("")
let token = '';
const client = new ApolloClient({
uri: 'https://api.github.com/graphql',

request: (operation) => {
operation.setContext({
headers: {
authorization: token? `bearer ${token}` : ''
}
})
}
})
useEffect(() => {
const fetchRepos = async () => {
setMode("Create")
setLoading(true)
let isn = localStorage.getItem('issueTitle')
if(localStorage.getItem(isn+'Comments')!=null){
let is = localStorage.getItem(isn+'Comments')
console.log(is)
setComments(JSON.parse(is))
setLoading(false)
}
};
fetchRepos();
}, []);
const columns = [
'Author Username',
'Comment',
'Edit Comment',
'Delete Comment',
];
const rows = comments.map(cmt => {
let login = localStorage.getItem('viewer-login')
if(cmt.node.author.login==login){
return ({cells: [
cmt.node.author.login,
cmt.node.bodyText,
(
<div>
<Button onClick={()=>{
setMode("Edit")
localStorage.setItem('commentId', cmt.node.id)
setBody(cmt.node.bodyText)
}} variant="success">Edit</Button>
</div>
),
(
<div>
<Button onClick={()=>{
deleteCommentSubmit(cmt.node.id)
}} variant="danger">Delete</Button>
</div>
),
]});
} else {
return ({cells: [
cmt.node.author.login,
cmt.node.bodyText,
'N/A',
'N/A'
]});
}
});

const handleBodyChange = (e) =>{
setBody(e)
}

const creatCommentSubmit = async(event, id, body) =>{
event.preventDefault();
let nId = '"'+id+'"';
let nBody = '"'+body+'"'
await client.mutate({
mutation: gql`
mutation{
addComment(input:{subjectId:${nId}, body:${nBody}}){
clientMutationId
}
}
`
}).then(result => {
console.log(result)
localStorage.clear();
window.location.reload();
alert("Created Comment");
})
}

const deleteCommentSubmit = async (id) =>{
let nId = '"'+id+'"';
await client.mutate({
mutation: gql`
mutation{
deleteIssueComment(input:{id:${nId}}){
clientMutationId
}
}
`
}).then(result => {
alert("Successfully Deleted")
localStorage.setItem('tabNumber', 0)
localStorage.setItem('repoName', '')
window.location.reload();
})
}

const updateCommentSubmit = async (event,id, body) =>{
event.preventDefault();
let nId = '"' + id + '"'
let nTitle = '"' + body + '"'

await client.mutate({
mutation: gql`
mutation{
updateIssueComment(input:{id:${nId}, body:${nTitle}}){
issueComment{
id
}
}
}
`
}).then(result => {
alert("Successfully Updated")
localStorage.setItem('tabNumber', 0)
localStorage.setItem('repoName', '')
window.location.reload();
})
}

if((loading)&&(localStorage.getItem('issueTitle')!=null)) {
return(
<div>
<h1>Comment</h1>
<TextInput style={{margin: 8}} value={body} onChange={(event)=>handleBodyChange(event)} placeholder="Message"/>
<Button type="submit" style={{margin: 8}} onClick={(event)=>{
if(mode=="Create")
creatCommentSubmit(event, localStorage.getItem('issueTitle'), body)
else
updateCommentSubmit(event, localStorage.getItem('commentId'), body)
}}>{mode}</Button>

</div>
)
}


if(loading){
return ( <h2>No Comments Available</h2>);
}

return(
<div style={{margin: 16, padding: 16}}>
<div>
<h1>Comment</h1>
<TextInput style={{margin: 8}} value={body} onChange={(event)=>handleBodyChange(event)} placeholder="Message"/>
<Button type="submit" style={{margin: 8}} onClick={(event)=>{
if(mode=="Create")
creatCommentSubmit(event, localStorage.getItem('issueTitle'), body)
else
updateCommentSubmit(event, localStorage.getItem('commentId'), body)
}}>{mode}</Button>
</div>
<Table cells={columns} rows={rows}>
<TableHeader/>
<TableBody />
</Table>
<br/>
</div>
);
}
export default Comments;
Loading