Skip to content

Commit

Permalink
Merge pull request #63 from ITPNYU/riho/pausers
Browse files Browse the repository at this point in the history
PA Users
  • Loading branch information
rlho authored Nov 16, 2023
2 parents 3cdfcd5 + 103fa0f commit 07765f2
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Ban } from './Ban';
import { AdminUsers } from './AdminUsers';
import { Liaisons } from './Liaisons';
import { Bookings } from './Bookings';
import { PAUsers } from './PAUsers';

const Admin = () => {
const [tab, setTab] = useState('bookings');
Expand Down Expand Up @@ -51,6 +52,18 @@ const Admin = () => {
Ban
</a>
</li>
<li className="mr-2">
<a
onClick={() => setTab('paUsers')}
className={`${
tab === 'paUsers'
? 'inline-block p-4 text-blue-600 bg-gray-100 rounded-t-lg active dark:bg-gray-800 dark:text-blue-500'
: 'inline-block p-4 rounded-t-lg hover:text-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-300 '
}`}
>
PA users
</a>
</li>
<li className="mr-2">
<a
onClick={() => setTab('adminUsers')}
Expand Down Expand Up @@ -79,6 +92,7 @@ const Admin = () => {
{tab === 'safety_training' && <SafetyTraining />}
{tab === 'ban' && <Ban />}
{tab === 'adminUsers' && <AdminUsers />}
{tab === 'paUsers' && <PAUsers />}
{tab === 'liaesons' && <Liaisons />}
{tab === 'bookings' && <Bookings />}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { useState, useEffect } from 'react';

// This is a wrapper for google.script.run that lets us use promises.

import { SafetyTraining } from './SafetyTraining';
import { Bookings } from './Bookings';

const PAPage = () => {
const [tab, setTab] = useState('bookings');

return (
<div className="m-10">
<ul className="flex flex-wrap text-sm font-medium text-center text-gray-500 border-b border-gray-200 dark:border-gray-700 dark:text-gray-400">
<li className="mr-2">
<a
onClick={() => setTab('bookings')}
aria-current="page"
className={`${
tab === 'bookings'
? 'inline-block p-4 text-blue-600 bg-gray-100 rounded-t-lg active dark:bg-gray-800 dark:text-blue-500'
: 'inline-block p-4 rounded-t-lg hover:text-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-300 '
}`}
>
Bookings
</a>
</li>
<li className="mr-2">
<a
onClick={() => setTab('safety_training')}
className={`${
tab === 'safety_training'
? 'inline-block p-4 text-blue-600 bg-gray-100 rounded-t-lg active dark:bg-gray-800 dark:text-blue-500'
: 'inline-block p-4 rounded-t-lg hover:text-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-300 '
}`}
>
Safety Training
</a>
</li>
</ul>
{tab === 'safety_training' && <SafetyTraining />}
{tab === 'bookings' && <Bookings />}
</div>
);
};

export default PAPage;
157 changes: 157 additions & 0 deletions media_commons_booking_app/src/client/admin-page/components/PAUsers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import React, { useState, useEffect } from 'react';

// This is a wrapper for google.script.run that lets us use promises.
import { serverFunctions } from '../../utils/serverFunctions';
import { formatDate } from '../../utils/date';
import { Loading } from '../../utils/Loading';

const PA_USER_SHEET_NAME = 'pa_users';

type PaUser = {
email: string;
createdAt: string;
};

export const PAUsers = () => {
const [paUsers, setPaUsers] = useState([]);
const [paEmails, setPaEmails] = useState([]);
const [mappingPaUsers, setMappingPaUsers] = useState([]);
const [email, setEmail] = useState('');

useEffect(() => {
fetchPaUsers();
}, []);
useEffect(() => {
const mappings = paUsers
.map((paUser, index) => {
if (index !== 0) {
return mappingPaUserRows(paUser);
}
})
.filter((paUser) => paUser !== undefined);
//TODO: filter out paUsers that are not in the future
setMappingPaUsers(mappings);
const emails = mappings.map((mapping) => {
return mapping.email;
});
setPaEmails(emails);
}, [paUsers]);

const fetchPaUsers = async () => {
serverFunctions.fetchRows(PA_USER_SHEET_NAME).then((rows) => {
setPaUsers(rows);
});
};

const mappingPaUserRows = (values: string[]): PaUser => {
return {
email: values[0],
createdAt: values[1],
};
};

const addPaUser = async () => {
setLoading(true);

if (paEmails.includes(email)) {
alert('This user is already registered');
return;
}

await serverFunctions.appendRow(PA_USER_SHEET_NAME, [
email,
new Date().toString(),
]);

alert('User has been registered successfully!');
setLoading(false);
fetchPaUsers();
};
const [loading, setLoading] = useState(false);
if (loading) {
return <Loading />;
}
return (
<div className="m-10">
<form className="flex items-center">
<div className="mb-6 mr-6">
<label
htmlFor="email"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
>
email
</label>
<input
type="email"
id="email"
onChange={(e) => {
setEmail(e.target.value);
}}
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="name@nyu.edu"
required
/>
</div>
<button
type="button"
onClick={addPaUser}
className="h-[40px] text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
>
Add User
</button>
</form>

<div className="w-[500px relative sm:rounded-lg">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" className="px-2 py-3">
Email
</th>
<th scope="col" className="px-2 py-3">
Created Date
</th>
<th scope="col" className="px-2 py-3">
Action
</th>
</tr>
</thead>
<tbody>
{mappingPaUsers.map((paUser, index) => {
return (
<tr
key={index}
className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600"
>
<td className="px-2 py-4 w-36">{paUser.email}</td>
<td className="px-2 py-4 w-36">
<div className=" flex items-center flex-col">
<div>{formatDate(paUser.createdAt)}</div>{' '}
</div>
</td>
<td className="px-2 py-4 w-36">
<button
className="font-medium text-blue-600 dark:text-blue-500 hover:underline"
onClick={async () => {
setLoading(true);
await serverFunctions.removeFromList(
PA_USER_SHEET_NAME,
paUser.email
);
alert('Successfully removed');
fetchPaUsers();
setLoading(false);
}}
>
Remove
</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
};
14 changes: 14 additions & 0 deletions media_commons_booking_app/src/client/admin-page/pa.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom';
import PAPage from './components/PAPage';
import './styles.css';

const App = () => {
return (
<>
<PAPage />
</>
);
};

ReactDOM.render(<App />, document.getElementById('index'));
4 changes: 0 additions & 4 deletions media_commons_booking_app/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ import {
getSheetRows,
ACTIVE_SHEET_ID,
confirmEvent,
approvedByFirstPerson,
approvedBySecondPerson,
sendTextEmail,
fetchById,
fetchRows_,
Expand All @@ -54,8 +52,6 @@ export {
getEvents,
getSheetRows,
confirmEvent,
approvedByFirstPerson,
approvedBySecondPerson,
sendTextEmail,
fetchById,
approveBooking,
Expand Down
24 changes: 0 additions & 24 deletions media_commons_booking_app/src/server/sheets.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,30 +101,6 @@ export const addEventToCalendar = (
return event.getId();
};

export const approvedByFirstPerson = () => {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const rng = ss.getActiveCell();
const flag = rng.getValue();
console.log('rng', rng);
if (rng.getColumn() == 1 && flag == true) {
sendEmail(
'rh3555@nyu.edu',
'Second Approval',
'Please approve the request'
);
}
};

export const approvedBySecondPerson = () => {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const rng = ss.getActiveCell();
const flag = rng.getValue();
if (rng.getColumn() == 2 && flag == true) {
console.log('rng', rng);
sendEmail('rh3555@nyu.edu', 'Approved!', 'Please approve the request');
}
};

export const confirmEvent = (id) => {
const event = CalendarApp.getEventById(id);
event.setTitle(event.getTitle().replace('[HOLD]', '[CONFIRMED]'));
Expand Down
2 changes: 2 additions & 0 deletions media_commons_booking_app/src/server/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export const doGet = (e) => {
}
if (page === 'admin') {
return HtmlService.createHtmlOutputFromFile('admin-page');
} else if (page === 'pa') {
return HtmlService.createHtmlOutputFromFile('pa-page');
} else {
return HtmlService.createHtmlOutputFromFile('booking');
}
Expand Down
6 changes: 6 additions & 0 deletions media_commons_booking_app/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ const clientEntrypoints = [
filename: 'admin-page',
template: './src/client/admin-page/index.html',
},
{
name: 'CLIENT - PA',
entry: './src/client/admin-page/pa.js',
filename: 'pa-page',
template: './src/client/admin-page/index.html',
},
];

// define certificate locations
Expand Down

0 comments on commit 07765f2

Please sign in to comment.