Skip to content

Commit feac9d0

Browse files
Merge pull request #59 from SingularityNET-Archive:Andre-Diamond/issue52
*Add No =Summary Given option* - [Date: 2024-02-06]
2 parents 111c5fe + 06c8c9b commit feac9d0

File tree

9 files changed

+528
-61
lines changed

9 files changed

+528
-61
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { useState } from 'react';
2+
import styles from '../styles/SubmitMissingSummary.module.css';
3+
import { saveMissingSummary } from '../utils/saveMissingSummaries';
4+
5+
function formatDate(dateString: any) {
6+
const options = { year: 'numeric', month: 'long', day: 'numeric' };
7+
const date = new Date(dateString);
8+
// Manually construct the date string to ensure it's in "DD MMMM YYYY" format
9+
const formattedDate = `${date.getDate()} ${date.toLocaleString('en-US', { month: 'long' })} ${date.getFullYear()}`;
10+
return formattedDate;
11+
}
12+
13+
const SubmitMissingSummary = ({ workgroups, allSummaries }: any) => {
14+
const [selectedWorkgroup, setSelectedWorkgroup] = useState<{ workgroup: string; workgroup_id: string; } | null>(null);
15+
const [meetingDate, setMeetingDate] = useState('');
16+
17+
//console.log("allSummaries", allSummaries)
18+
const handleSubmit = async (e: any) => {
19+
e.preventDefault();
20+
if (selectedWorkgroup && meetingDate) {
21+
const missingSummaryData = {
22+
workgroup: selectedWorkgroup.workgroup,
23+
workgroupId: selectedWorkgroup.workgroup_id,
24+
meetingDate: formatDate(meetingDate), // Assuming you want the formatted date here
25+
status: "Missing",
26+
type: "weekly"
27+
};
28+
const newRow = {
29+
meetingDate: formatDate(meetingDate),
30+
workgroup: selectedWorkgroup.workgroup,
31+
status: "Missing"
32+
};
33+
34+
const conflictSummary = allSummaries.find((summary: any) =>
35+
summary.meetingDate === newRow.meetingDate && summary.workgroup === newRow.workgroup
36+
);
37+
38+
// If a "Done" summary exists for the same meetingDate and workgroup, alert the user
39+
if (conflictSummary && conflictSummary.status === "Done") {
40+
alert("This meeting is already marked as Done.");
41+
return; // Prevent the submission
42+
}
43+
44+
const summariesToUpdate = newRow ? [...allSummaries, newRow] : allSummaries;
45+
46+
try {
47+
// First, save the missing summary through your existing utility function
48+
const saveResponse = await saveMissingSummary(missingSummaryData);
49+
console.log('Save missing summary response:', saveResponse);
50+
51+
// If the save operation is successful, then update the CSV in GitHub
52+
const response = await fetch('/api/updateCSV', {
53+
method: 'POST',
54+
headers: { 'Content-Type': 'application/json' },
55+
body: JSON.stringify({
56+
owner: "SingularityNET-Archive",
57+
repo: "SingularityNET-Archive",
58+
path: "Data/status-of-summaries.csv",
59+
summariesToUpdate
60+
}),
61+
});
62+
63+
if (!response.ok) {
64+
throw new Error('Failed to update CSV');
65+
}
66+
67+
const responseData = await response.json();
68+
console.log('CSV updated successfully:', responseData);
69+
70+
// Reset form state here
71+
setSelectedWorkgroup(null);
72+
setMeetingDate('');
73+
} catch (error) {
74+
console.error('Error:', error);
75+
// Handle error, e.g., showing an error message
76+
}
77+
}
78+
};
79+
80+
return (
81+
<form className={styles.container} onSubmit={handleSubmit}>
82+
<div className={styles.formGroup}>
83+
<label htmlFor="workgroupSelect">Workgroup:</label>
84+
<select
85+
id="workgroupSelect"
86+
value={selectedWorkgroup ? selectedWorkgroup.workgroup : ''}
87+
onChange={(e) => {
88+
const selectedValue = e.target.value;
89+
const workgroupObject = workgroups.find((group: any) => group.workgroup === selectedValue);
90+
setSelectedWorkgroup(workgroupObject || null);
91+
}}
92+
required
93+
>
94+
<option value="">Select a workgroup</option>
95+
{workgroups.map((group: any) => (
96+
<option key={group.workgroup_id} value={group.workgroup}>
97+
{group.workgroup}
98+
</option>
99+
))}
100+
</select>
101+
</div>
102+
<div className={styles.formGroup}>
103+
<label htmlFor="meetingDate">Meeting Date:</label>
104+
<input
105+
type="date"
106+
id="meetingDate"
107+
value={meetingDate}
108+
onChange={(e) => setMeetingDate(e.target.value)}
109+
required
110+
/>
111+
</div>
112+
<button type="submit" className={styles.submitButton}>Submit Missing Summary</button>
113+
</form>
114+
);
115+
};
116+
117+
export default SubmitMissingSummary;

pages/api/fetchCsv.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// pages/api/fetchCsv.js
2+
3+
export default async function handler(req, res) {
4+
const csvUrl = 'https://raw.githubusercontent.com/SingularityNET-Archive/SingularityNET-Archive/main/Data/status-of-summaries.csv';
5+
6+
try {
7+
const csvResponse = await fetch(csvUrl);
8+
const csvText = await csvResponse.text();
9+
10+
// Convert CSV text to JSON
11+
const json = csvToJson(csvText); // Implement this function based on your CSV structure
12+
13+
res.status(200).json(json);
14+
} catch (error) {
15+
res.status(500).json({ error: "Failed to fetch CSV data" });
16+
}
17+
}
18+
19+
function csvToJson(csv) {
20+
const lines = csv.split('\n');
21+
const result = [];
22+
const headers = lines[0].split(',');
23+
24+
for (let i = 1; i < lines.length; i++) {
25+
const currentline = lines[i].split(',');
26+
// Check if the line is empty or consists of only whitespace
27+
if (currentline.length === 1 && currentline[0].trim() === '') {
28+
continue; // Skip this iteration, effectively ignoring the empty row
29+
}
30+
31+
let obj = {};
32+
for (let j = 0; j < headers.length; j++) {
33+
obj[headers[j]] = currentline[j];
34+
}
35+
36+
result.push(obj);
37+
}
38+
39+
return result;
40+
}

pages/api/updateCSV.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// File: pages/api/updateCSV.js
2+
import { fetchAndUpdateCSV } from '../../utils/updateCSVInGitHub';
3+
4+
export default async function handler(req, res) {
5+
if (req.method !== 'POST') {
6+
return res.status(405).send({ message: 'Only POST requests allowed' });
7+
}
8+
9+
const { owner, repo, path, branch, summariesToUpdate } = req.body;
10+
11+
try {
12+
const updateResponse = await fetchAndUpdateCSV({
13+
owner,
14+
repo,
15+
path,
16+
branch,
17+
summariesToUpdate
18+
});
19+
res.status(200).json(updateResponse);
20+
} catch (error) {
21+
console.error('Error updating CSV in GitHub:', error);
22+
res.status(500).json({ message: 'Failed to update CSV', error: error.message });
23+
}
24+
}

pages/status-of-summaries.tsx

Lines changed: 72 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,112 @@
11
import { useState, useEffect } from "react";
22
import type { NextPage } from "next";
3-
import { fetchIssues } from '../utils/fetchIssues';
4-
import styles from '../styles/issues.module.css';
3+
import styles from '../styles/summariestable.module.css';
4+
import SubmitMissingSummary from '../components/SubmitMissingSummary';
5+
import { getWorkgroups } from '../utils/getWorkgroups';
6+
import { getMissingSummaries } from '../utils/getMissingSummaries';
57

6-
interface Issue {
7-
id: number;
8-
title: string;
9-
html_url: string;
10-
state: string;
8+
interface SummaryData {
9+
meetingDate: string;
10+
status: string;
11+
workgroup: string;
12+
workgroupId: string;
1113
}
1214

1315
const StatusOfSummaries: NextPage = () => {
1416
const [loading, setLoading] = useState<boolean>(false);
15-
const [openIssues, setOpenIssues] = useState<Issue[]>([]);
16-
const [closedIssues, setClosedIssues] = useState<Issue[]>([]);
17+
const [data, setData] = useState<SummaryData[]>([]);
18+
const [workgroups, setWorkgroups] = useState<any[]>([]);
19+
const [allSummaries, setAllSummaries] = useState<any[]>([]);
1720

18-
const newIssueUrl = `https://github.com/SingularityNET-Archive/archive-oracle/issues/new?assignees=Andre-Diamond&labels=tool-issue&projects=SingularityNET-Archive%2F3&template=testing_issue.yml&title=%2AEnter+title+here%2A+-+%5BDate%3A+${getCurrentFormattedDate()}%5D`;
19-
20-
async function getIssues() {
21+
async function fetchCsvData() {
2122
setLoading(true);
22-
const issues = await fetchIssues();
23-
console.log(issues)
24-
const open = issues.filter((issue: Issue) => issue.state === 'open');
25-
const closed = issues.filter((issue: Issue) => issue.state === 'closed');
26-
setOpenIssues(open);
27-
setClosedIssues(closed);
23+
try {
24+
const response = await fetch('/api/fetchCsv');
25+
const data = await response.json();
26+
console.log('Fetched CSV data:', data);
27+
setData(data);
28+
} catch (error) {
29+
console.error("Failed to fetch CSV data:", error);
30+
}
2831
setLoading(false);
2932
}
3033

3134
useEffect(() => {
32-
getIssues()
33-
}, []);
35+
//fetchCsvData();
36+
fetchWorkgroups(); // Add this line
37+
}, []);
38+
39+
async function fetchWorkgroups() {
40+
try {
41+
const databaseWorkgroups = await getWorkgroups();
42+
const allSummaries = await getMissingSummaries();
43+
setAllSummaries(allSummaries)
44+
45+
// Assuming databaseWorkgroups should be an array, check and handle accordingly
46+
if (Array.isArray(databaseWorkgroups)) {
47+
setWorkgroups(databaseWorkgroups);
48+
} else {
49+
console.error("Expected an array for workgroups, received:", databaseWorkgroups);
50+
// Handle the unexpected format, e.g., set to an empty array or a default value
51+
setWorkgroups([]);
52+
}
53+
} catch (error) {
54+
console.error("Error fetching workgroups:", error);
55+
setWorkgroups([]); // Handle error by setting workgroups to an empty array or another default state
56+
}
57+
}
3458

35-
function getCurrentFormattedDate() {
36-
const today = new Date();
37-
const yyyy = today.getFullYear().toString();
38-
let mm = (today.getMonth() + 1).toString(); // January is 0!
39-
let dd = today.getDate().toString();
40-
41-
if (dd.length < 2) dd = '0' + dd;
42-
if (mm.length < 2) mm = '0' + mm;
43-
44-
return yyyy + '-' + mm + '-' + dd;
45-
}
46-
4759
return (
4860
<div className={styles.container}>
49-
<h1>Issues</h1>
50-
<a href={newIssueUrl} target="_blank" rel="noopener noreferrer">
51-
<button className={styles.createIssueButton}>Create New Issue</button>
52-
</a>
61+
<SubmitMissingSummary workgroups={workgroups} allSummaries={allSummaries}/>
62+
<h1>Status of Summaries</h1>
63+
{loading && <p>Loading...</p>}
64+
5365
<div className={styles.issuesTableContainer}>
54-
55-
{/* Open Issues Table */}
66+
{/* Missing Summaries Table */}
67+
<h2 className={styles.missingHeading}>Missing Summaries</h2>
5668
<table className={styles.issuesTable}>
5769
<thead>
58-
<tr>
59-
<th colSpan={2}>Open Issues</th>
70+
<tr className={styles.tableRow}>
71+
<th className={styles.tableHeader}>Meeting Date</th>
72+
<th className={styles.tableHeader}>Workgroup</th>
73+
<th className={styles.tableHeader}>Status</th>
6074
</tr>
6175
</thead>
6276
<tbody>
63-
{openIssues.map(issue => (
64-
<tr key={issue.id} className={styles.openIssue}>
65-
<td>
66-
<a className={styles.openIssueLink} href={issue.html_url} target="_blank" rel="noopener noreferrer">
67-
{issue.title}
68-
</a>
69-
</td>
77+
{allSummaries.filter(row => row.status === "Missing").map((row, index) => (
78+
<tr key={index} className={styles.tableRow}>
79+
<td className={styles.tableData}>{row.meetingDate}</td>
80+
<td className={styles.tableData}>{row.workgroup}</td>
81+
<td className={styles.tableData}>{row.status}</td>
7082
</tr>
7183
))}
7284
</tbody>
7385
</table>
74-
75-
{/* Closed Issues Table */}
86+
87+
{/* Done Summaries Table */}
88+
<h2 className={styles.doneHeading}>Done Summaries</h2>
7689
<table className={styles.issuesTable}>
7790
<thead>
78-
<tr>
79-
<th colSpan={2}>Closed Issues</th>
91+
<tr className={styles.tableRow}>
92+
<th className={styles.tableHeader}>Meeting Date</th>
93+
<th className={styles.tableHeader}>Workgroup</th>
94+
<th className={styles.tableHeader}>Status</th>
8095
</tr>
8196
</thead>
8297
<tbody>
83-
{closedIssues.map(issue => (
84-
<tr key={issue.id}>
85-
<td>
86-
<a className={styles.closedIssueLink} href={issue.html_url} target="_blank" rel="noopener noreferrer">
87-
{issue.title}
88-
</a>
89-
</td>
98+
{allSummaries.filter(row => row.status === "Done").map((row, index) => (
99+
<tr key={index} className={styles.tableRow}>
100+
<td className={styles.tableData}>{row.meetingDate}</td>
101+
<td className={styles.tableData}>{row.workgroup}</td>
102+
<td className={styles.tableData}>{row.status}</td>
90103
</tr>
91104
))}
92105
</tbody>
93106
</table>
94-
95107
</div>
96108
</div>
97109
);
98-
99110
};
100111

101-
export default StatusOfSummaries;
112+
export default StatusOfSummaries;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.container {
2+
margin-top: 50px;
3+
margin-bottom: 20px;
4+
}
5+
6+
.formGroup {
7+
margin-bottom: 10px;
8+
}
9+
10+
.submitButton {
11+
background-color: #4CAF50;
12+
color: white;
13+
padding: 10px 20px;
14+
border: none;
15+
cursor: pointer;
16+
}
17+
18+
.submitButton:hover {
19+
background-color: #45a049;
20+
}

0 commit comments

Comments
 (0)