Skip to content
Merged
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
117 changes: 117 additions & 0 deletions components/SubmitMissingSummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { useState } from 'react';
import styles from '../styles/SubmitMissingSummary.module.css';
import { saveMissingSummary } from '../utils/saveMissingSummaries';

function formatDate(dateString: any) {
const options = { year: 'numeric', month: 'long', day: 'numeric' };
const date = new Date(dateString);
// Manually construct the date string to ensure it's in "DD MMMM YYYY" format
const formattedDate = `${date.getDate()} ${date.toLocaleString('en-US', { month: 'long' })} ${date.getFullYear()}`;
return formattedDate;
}

const SubmitMissingSummary = ({ workgroups, allSummaries }: any) => {
const [selectedWorkgroup, setSelectedWorkgroup] = useState<{ workgroup: string; workgroup_id: string; } | null>(null);
const [meetingDate, setMeetingDate] = useState('');

//console.log("allSummaries", allSummaries)
const handleSubmit = async (e: any) => {
e.preventDefault();
if (selectedWorkgroup && meetingDate) {
const missingSummaryData = {
workgroup: selectedWorkgroup.workgroup,
workgroupId: selectedWorkgroup.workgroup_id,
meetingDate: formatDate(meetingDate), // Assuming you want the formatted date here
status: "Missing",
type: "weekly"
};
const newRow = {
meetingDate: formatDate(meetingDate),
workgroup: selectedWorkgroup.workgroup,
status: "Missing"
};

const conflictSummary = allSummaries.find((summary: any) =>
summary.meetingDate === newRow.meetingDate && summary.workgroup === newRow.workgroup
);

// If a "Done" summary exists for the same meetingDate and workgroup, alert the user
if (conflictSummary && conflictSummary.status === "Done") {
alert("This meeting is already marked as Done.");
return; // Prevent the submission
}

const summariesToUpdate = newRow ? [...allSummaries, newRow] : allSummaries;

try {
// First, save the missing summary through your existing utility function
const saveResponse = await saveMissingSummary(missingSummaryData);
console.log('Save missing summary response:', saveResponse);

// If the save operation is successful, then update the CSV in GitHub
const response = await fetch('/api/updateCSV', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
owner: "SingularityNET-Archive",
repo: "SingularityNET-Archive",
path: "Data/status-of-summaries.csv",
summariesToUpdate
}),
});

if (!response.ok) {
throw new Error('Failed to update CSV');
}

const responseData = await response.json();
console.log('CSV updated successfully:', responseData);

// Reset form state here
setSelectedWorkgroup(null);
setMeetingDate('');
} catch (error) {
console.error('Error:', error);
// Handle error, e.g., showing an error message
}
}
};

return (
<form className={styles.container} onSubmit={handleSubmit}>
<div className={styles.formGroup}>
<label htmlFor="workgroupSelect">Workgroup:</label>
<select
id="workgroupSelect"
value={selectedWorkgroup ? selectedWorkgroup.workgroup : ''}
onChange={(e) => {
const selectedValue = e.target.value;
const workgroupObject = workgroups.find((group: any) => group.workgroup === selectedValue);
setSelectedWorkgroup(workgroupObject || null);
}}
required
>
<option value="">Select a workgroup</option>
{workgroups.map((group: any) => (
<option key={group.workgroup_id} value={group.workgroup}>
{group.workgroup}
</option>
))}
</select>
</div>
<div className={styles.formGroup}>
<label htmlFor="meetingDate">Meeting Date:</label>
<input
type="date"
id="meetingDate"
value={meetingDate}
onChange={(e) => setMeetingDate(e.target.value)}
required
/>
</div>
<button type="submit" className={styles.submitButton}>Submit Missing Summary</button>
</form>
);
};

export default SubmitMissingSummary;
4 changes: 3 additions & 1 deletion components/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ const Nav = () => {
});
})
.catch(error => console.error('Error:', error));

}, [session]);

async function saveUsername() {
Expand All @@ -129,6 +128,9 @@ const Nav = () => {
<Link href='/issues' className="navitems">
Issues
</Link>
{roleData?.appRole == "admin" && (<Link href='/status-of-summaries' className="navitems">
Summaries
</Link>)}
</div>
<div>{latestTag}</div>
<div>
Expand Down
40 changes: 40 additions & 0 deletions pages/api/fetchCsv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// pages/api/fetchCsv.js

export default async function handler(req, res) {
const csvUrl = 'https://raw.githubusercontent.com/SingularityNET-Archive/SingularityNET-Archive/main/Data/status-of-summaries.csv';

try {
const csvResponse = await fetch(csvUrl);
const csvText = await csvResponse.text();

// Convert CSV text to JSON
const json = csvToJson(csvText); // Implement this function based on your CSV structure

res.status(200).json(json);
} catch (error) {
res.status(500).json({ error: "Failed to fetch CSV data" });
}
}

function csvToJson(csv) {
const lines = csv.split('\n');
const result = [];
const headers = lines[0].split(',');

for (let i = 1; i < lines.length; i++) {
const currentline = lines[i].split(',');
// Check if the line is empty or consists of only whitespace
if (currentline.length === 1 && currentline[0].trim() === '') {
continue; // Skip this iteration, effectively ignoring the empty row
}

let obj = {};
for (let j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}

result.push(obj);
}

return result;
}
6 changes: 4 additions & 2 deletions pages/api/issues.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ export default async function handler(req, res) {
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });

try {
const response = await octokit.rest.issues.listForRepo({
const issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
owner: 'SingularityNET-Archive',
repo: 'archive-oracle',
state: 'all',
per_page: 100, // Adjust per_page to your needs
});

res.status(200).json(response.data);
res.status(200).json(issues);
} catch (error) {
console.error("Failed to fetch issues:", error);
res.status(500).json({ error: error.message });
}
}
24 changes: 24 additions & 0 deletions pages/api/updateCSV.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// File: pages/api/updateCSV.js
import { fetchAndUpdateCSV } from '../../utils/updateCSVInGitHub';

export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).send({ message: 'Only POST requests allowed' });
}

const { owner, repo, path, branch, summariesToUpdate } = req.body;

try {
const updateResponse = await fetchAndUpdateCSV({
owner,
repo,
path,
branch,
summariesToUpdate
});
res.status(200).json(updateResponse);
} catch (error) {
console.error('Error updating CSV in GitHub:', error);
res.status(500).json({ message: 'Failed to update CSV', error: error.message });
}
}
112 changes: 112 additions & 0 deletions pages/status-of-summaries.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { useState, useEffect } from "react";
import type { NextPage } from "next";
import styles from '../styles/summariestable.module.css';
import SubmitMissingSummary from '../components/SubmitMissingSummary';
import { getWorkgroups } from '../utils/getWorkgroups';
import { getMissingSummaries } from '../utils/getMissingSummaries';

interface SummaryData {
meetingDate: string;
status: string;
workgroup: string;
workgroupId: string;
}

const StatusOfSummaries: NextPage = () => {
const [loading, setLoading] = useState<boolean>(false);
const [data, setData] = useState<SummaryData[]>([]);
const [workgroups, setWorkgroups] = useState<any[]>([]);
const [allSummaries, setAllSummaries] = useState<any[]>([]);

async function fetchCsvData() {
setLoading(true);
try {
const response = await fetch('/api/fetchCsv');
const data = await response.json();
console.log('Fetched CSV data:', data);
setData(data);
} catch (error) {
console.error("Failed to fetch CSV data:", error);
}
setLoading(false);
}

useEffect(() => {
//fetchCsvData();
fetchWorkgroups(); // Add this line
}, []);

async function fetchWorkgroups() {
try {
const databaseWorkgroups = await getWorkgroups();
const allSummaries = await getMissingSummaries();
setAllSummaries(allSummaries)

// Assuming databaseWorkgroups should be an array, check and handle accordingly
if (Array.isArray(databaseWorkgroups)) {
setWorkgroups(databaseWorkgroups);
} else {
console.error("Expected an array for workgroups, received:", databaseWorkgroups);
// Handle the unexpected format, e.g., set to an empty array or a default value
setWorkgroups([]);
}
} catch (error) {
console.error("Error fetching workgroups:", error);
setWorkgroups([]); // Handle error by setting workgroups to an empty array or another default state
}
}

return (
<div className={styles.container}>
<SubmitMissingSummary workgroups={workgroups} allSummaries={allSummaries}/>
<h1>Status of Summaries</h1>
{loading && <p>Loading...</p>}

<div className={styles.issuesTableContainer}>
{/* Missing Summaries Table */}
<h2 className={styles.missingHeading}>Missing Summaries</h2>
<table className={styles.issuesTable}>
<thead>
<tr className={styles.tableRow}>
<th className={styles.tableHeader}>Meeting Date</th>
<th className={styles.tableHeader}>Workgroup</th>
<th className={styles.tableHeader}>Status</th>
</tr>
</thead>
<tbody>
{allSummaries.filter(row => row.status === "Missing").map((row, index) => (
<tr key={index} className={styles.tableRow}>
<td className={styles.tableData}>{row.meetingDate}</td>
<td className={styles.tableData}>{row.workgroup}</td>
<td className={styles.tableData}>{row.status}</td>
</tr>
))}
</tbody>
</table>

{/* Done Summaries Table */}
<h2 className={styles.doneHeading}>Done Summaries</h2>
<table className={styles.issuesTable}>
<thead>
<tr className={styles.tableRow}>
<th className={styles.tableHeader}>Meeting Date</th>
<th className={styles.tableHeader}>Workgroup</th>
<th className={styles.tableHeader}>Status</th>
</tr>
</thead>
<tbody>
{allSummaries.filter(row => row.status === "Done").map((row, index) => (
<tr key={index} className={styles.tableRow}>
<td className={styles.tableData}>{row.meetingDate}</td>
<td className={styles.tableData}>{row.workgroup}</td>
<td className={styles.tableData}>{row.status}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
};

export default StatusOfSummaries;
17 changes: 17 additions & 0 deletions pages/submit-meeting-summary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,17 @@ useEffect(() => {
});
};

const resetSummary = () => {
setMyVariable(prevMyVariable => ({
...prevMyVariable,
summary: {
...prevMyVariable.summary,
meetingInfo: {},
agendaItems: [],
tags: {}
}
}));
};

return (
<div className={styles.container}>
Expand Down Expand Up @@ -277,6 +288,12 @@ useEffect(() => {
{selectedWorkgroupId && (<>
{myVariable.roles?.isAdmin && (<button className={styles.navButton} onClick={() => setActiveComponent('two')}>Summary</button>)}
{myVariable.roles?.isAdmin && <button className={styles.navButton} onClick={() => setActiveComponent('four')}>Archive Summaries</button>}
<button
className={styles.resetButton}
onClick={resetSummary}
title="All values will be cleared, so please make sure to select all dropdowns and fill in all fields"
>Clear Summary
</button>
</>)}
</div>
{myVariable.isLoggedIn && selectedWorkgroupId && (<div className={styles.mainContent}>
Expand Down
20 changes: 20 additions & 0 deletions styles/SubmitMissingSummary.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.container {
margin-top: 50px;
margin-bottom: 20px;
}

.formGroup {
margin-bottom: 10px;
}

.submitButton {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
}

.submitButton:hover {
background-color: #45a049;
}
Loading