Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded Calendar #138

Merged
merged 11 commits into from
Jan 22, 2021
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* [Project Pairing](membership/project_pairing.md)

* Meetings
* [Calendar](meetings/calendar.md)
* [Semester Outline](meetings/semester_outline.md)
* [Large Group Meetings](meetings/large_group_meetings.md)
* [Small Group Meetings](meetings/small_group_meetings.md)
Expand Down
Binary file added docs/img/lockup-red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 62 additions & 13 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,83 @@
<meta charset="UTF-8">
<title>RCOS Handbook</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description">
<meta name="description" content="Single source of truth for RCOS guidelines, procedures, history, and more.">
<meta name="author" content="RCOS Coordinators & Faculty Advisors">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://handbook.rcos.io/">
<meta property="og:title" content="RCOS Handbook">
<meta property="og:description" content="Single source of truth for RCOS guidelines, procedures, history, and more.">
<meta property="og:image" content="/img/lockup-red.png">

<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://handbook.rcos.io/">
<meta property="twitter:title" content="RCOS Handbook">
<meta property="twitter:description"
content="Single source of truth for RCOS guidelines, procedures, history, and more.">
<meta property="twitter:image" content="/img/lockup-red.png">

<link rel="stylesheet" href="./theme.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/main.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/main.min.js"></script>
<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://unpkg.com/tippy.js@6"></script>
<link rel="stylesheet" href="https://unpkg.com/tippy.js@6/themes/light.css" />
<style>
/* RCOS Calendar styles */
.tippy-box {
min-width: 250px;
}

.tippy-content .meeting-title {
font-size: 1.5em;
}

.tippy-content .meeting-type {
color: #707372;
font-size: 1.2em;
text-transform: capitalize;
margin: 0;
}

.tippy-content .meeting-agenda {
margin-top: 10px;
}

.tippy-content .meeting-agenda ul {
margin-top: 0;
line-height: 1.1;
}
</style>
</head>

<body>
<div id="app"></div>
<script>
window.$docsify = {
name: 'RCOS Handbook',
repo: 'rcos/rcos-handbook',
name: "RCOS Handbook",
repo: "rcos/rcos-handbook",
coverpage: true,
loadSidebar: true,
loadNavbar: false,
maxDepth: 2,
subMaxLevel: 2,
// basePath: '/docs',
executeScript: true,
search: [
'/',
'/mentoring/',
'/grading/',
'/teams/',
'/coordinating/',
'/events/',
'/membership/',
'/resources/',
'/community/'
"/",
"/mentoring/",
"/grading/",
"/meetings/",
"/teams/",
"/coordinating/",
"/events/",
"/membership/",
"/resources/",
"/community/"
]
}
</script>
Expand Down
94 changes: 94 additions & 0 deletions docs/meetings/calendar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<h1>RCOS Calendar</h1>

<div id='calendar'></div>

<script>
const meetingColors = {
'large_group': '#da291c', // RCOS red
'small_group': 'green',
'presentations': 'orange',
'bonus_session': 'gold',
'grading': 'red'
};

/** Maps a meeting object from the API into a Fullcalendar event. */
function meetingToEvent(meeting, index) {
const event = {
title: (meeting.title || 'Meeting'),
start: meeting.start_date_time + 'Z',
end: meeting.end_date_time + 'Z',
backgroundColor: meetingColors[meeting.type],
meeting
};

// TODO: if this is not set, point to RCOS meetings url for auto-generated slides
if (meeting.external_presentation_url) {
event.url = meeting.external_presentation_url;
}

return event;
}

// Points to RCOS Postgrest API
const apiBaseUrl = 'http://198.211.105.73:3000';

const calendarEl = document.getElementById('calendar');
const calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth', // Classic calendar view
timeZone: 'America/New_York',
weekends: false, // Change this to true if RCOS might have weekend events
events: function(info, successCallback, failureCallback) {
fetch(apiBaseUrl + '/public_meetings')
.then(res => res.json())
.then(meetings => successCallback(meetings.map(meetingToEvent)))
.catch(failureCallback)
},
eventDidMount ({ event, el }) {
// For each event, construct the HTML content of a tooltip
try {
// Full meeting object from API is stored in extendedProps
const { meeting } = event.extendedProps;

// Turns 'large_group' into 'large group'
const meetingType = meeting.type.split('_').join(' ');

// Meetings might have a host username
const hostString = meeting.host_username ? ` hosted by ${meeting.host_username}` : '';

const agendaString = meeting.agenda ? `<div class='meeting-agenda'><strong>Agenda</strong><ul>${meeting.agenda.map(item => '<li>' + item + '</li>').join('\n')}</ul></div>` : '';

// Location might be empty, a phsyical location, or a URL
let locationString = '';
if (meeting.location && meeting.location.startsWith('http')) {
locationString = `<a target='_blank' href='${meeting.location}'>${meeting.location}</a><br>`;
} else if (meeting.location) {
locationString = `<span class='meeting-location'>${location}</span><br>`;
}

// External presentation will not always be present
const presentationString = meeting.external_presentation_url ? `<a class='meeting-presentation-url' href='${meeting.external_presentation_url}' target='_blank'>Meeting Slides</a>` : '';

// Recording URL will not always be present
const recordingString = meeting.recording_url ? `<a class='meeting-recording-url' href='${meeting.recording_url}' target='_blank'>Recording</a>` : '';

tippy(el, {
allowHTML: true, // allows content to have HTML
interactive: true, // keeps the tooltip open when mouse hovers over the tooltip
theme: 'light', // closest to RCOS theme
content: `
<strong class='meeting-title'>${meeting.title}</strong><br>
<p class='meeting-type'>${meetingType} Meeting${hostString}</p>
${agendaString}
${locationString}
${presentationString}
${recordingString}
`,
});
} catch (e) {
// By default errors are ignored in this callback for some reason, so we want to make sure they are logged if they occur
console.error(e);
}
},
});
calendar.render();
</script>
Loading