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
36 changes: 32 additions & 4 deletions src/app/events/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { createMetaData } from '@/util/createMetaData.server';
import DisplayHtml from '@/components/DisplayHtml';
import { dateForDisplay } from '@/util/date';
import Link from 'next/link';
import { Google } from '@/svg/calendar/Google';
import { Outlook } from '@/svg/calendar/Outlook';
import { Ics } from '@/svg/calendar/Ics';

export const metadata = createMetaData({
title: 'Virtual Coffee Community Events',
Expand Down Expand Up @@ -121,10 +124,35 @@ export default async function Page() {
<time dateTime={event.startDateLocalized}>
{`${dateForDisplay(event.startDateLocalized, 'EEEE, LLLL d, yyyy')} - ${dateForDisplay(event.startDateLocalized, 't')} to ${dateForDisplay(event.endDateLocalized, 't ZZZZ')}`}
</time>

<a href={event.eventCalendarLink} download>
<small> Add to Calendar</small>
</a>
<div
className="d-flex flex-row align-items-center"
style={{ gap: '0.5rem' }}
>
<small className="text-muted">Add to Calendar:</small>
<a
href={event.eventCalendarLinks.google}
target="_blank"
rel="noreferrer"
title="Google Calendar"
>
<Google />
</a>
<a
href={event.eventCalendarLinks.outlook}
target="_blank"
rel="noreferrer"
title="Outlook Calendar"
>
<Outlook />
</a>
<a
href={event.eventCalendarLinks.ics}
title="Download ICS"
download
>
<Ics />
</a>
</div>
</div>
<div className="card-body">
<h5 className="card-title">{event.title}</h5>
Expand Down
30 changes: 25 additions & 5 deletions src/data/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { GraphQLClient, gql } from 'graphql-request';
import { DateTime } from 'luxon';
import { sanitizeHtml } from '@/util/sanitizeCmsData';
import { ics } from 'calendar-link';
import { ics, google, outlook } from 'calendar-link';

const calendarsQuery = gql`
query getCalendars {
Expand Down Expand Up @@ -39,7 +39,11 @@ interface SolspaceEventResponse {
eventCalendarDescription: string;
}
export interface EventItem extends SolspaceEventResponse {
eventCalendarLink: string;
eventCalendarLinks: {
google: string;
outlook: string;
ics: string;
};
}
export interface EventsResponse extends Array<EventItem> {}

Expand Down Expand Up @@ -112,16 +116,32 @@ export async function getEvents({
const sanitizedDescription = await sanitizeHtml(
event.eventCalendarDescription,
);
const calendarLink = ics({
const calendarLinkGoogle = google({
title: event.title,
start: event.startDateLocalized,
end: event.endDateLocalized,
description: sanitizedDescription,
});
});
const calendarLinkOutlook = outlook({
title: event.title,
start: event.startDateLocalized,
end: event.endDateLocalized,
description: sanitizedDescription,
});
const calendarLinkIcs = ics({
title: event.title,
start: event.startDateLocalized,
end: event.endDateLocalized,
description: sanitizedDescription,
});
return {
...event,
eventCalendarDescription: sanitizedDescription,
eventCalendarLink: calendarLink,
eventCalendarLinks: {
google: calendarLinkGoogle,
outlook: calendarLinkOutlook,
ics: calendarLinkIcs,
},
};
}),
);
Expand Down
24 changes: 20 additions & 4 deletions src/data/mocks/events.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { faker } from '@faker-js/faker';
import { DateTime } from 'luxon';
import { ics } from 'calendar-link';
import { ics, google, outlook } from 'calendar-link';

export function createEventsData({
limit = 15,
Expand All @@ -19,20 +19,36 @@ export function createEventsData({

return dates.map((date) => {
const startDate = DateTime.fromJSDate(date);
const calendarLink = ics({
const calendarLinkGoogle = google({
title: faker.lorem.sentence(7),
start: startDate.toUTC().toString(),
end: startDate.toUTC().plus({ hours: 1 }).toString(),
description: faker.lorem.paragraph(),
});
});
const calendarLinkOutlook = outlook({
title: faker.lorem.sentence(7),
start: startDate.toUTC().toString(),
end: startDate.toUTC().plus({ hours: 1 }).toString(),
description: faker.lorem.paragraph(),
});
const calendarLinkIcs = ics({
title: faker.lorem.sentence(7),
start: startDate.toUTC().toString(),
end: startDate.toUTC().plus({ hours: 1 }).toString(),
description: faker.lorem.paragraph(),
});

return {
id: faker.string.uuid(),
title: faker.lorem.sentence(7),
startDateLocalized: startDate.toUTC().toString(),
endDateLocalized: startDate.toUTC().plus({ hours: 1 }).toString(),
eventCalendarDescription: `<p>${faker.lorem.paragraph()}</p>`,
eventCalendarLink: calendarLink,
eventCalendarLinks: {
google: calendarLinkGoogle,
outlook: calendarLinkOutlook,
ics: calendarLinkIcs,
},
};
});
}
44 changes: 44 additions & 0 deletions src/svg/calendar/Google.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
export function Google({ title = 'Google Calendar' }: { title?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
x="0px"
y="0px"
width="20"
height="20"
viewBox="0 0 48 48"
style={{
fillRule: 'evenodd',
clipRule: 'evenodd',
strokeLinejoin: 'round',
strokeMiterlimit: 2,
}}
role="img"
aria-labelledby="GoogleSvgTitle"
>
<title id="GoogleSvgTitle">{title}</title>
<rect width="22" height="22" x="13" y="13" fill="#fff" />
<polygon
fill="#1e88e5"
points="25.68,20.92 26.688,22.36 28.272,21.208 28.272,29.56 30,29.56 30,18.616 28.56,18.616"
/>
<path
fill="#1e88e5"
d="M22.943,23.745c0.625-0.574,1.013-1.37,1.013-2.249c0-1.747-1.533-3.168-3.417-3.168
c-1.602,0-2.972,1.009-3.33,2.453l1.657,0.421c0.165-0.664,0.868-1.146,1.673-1.146c0.942,0,1.709,0.646,1.709,1.44
c0,0.794-0.767,1.44-1.709,1.44h-0.997v1.728h0.997c1.081,0,1.993,0.751,1.993,1.64c0,0.904-0.866,1.64-1.931,1.64
c-0.962,0-1.784-0.61-1.914-1.418L17,26.802c0.262,1.636,1.81,2.87,3.6,2.87c2.007,0,3.64-1.511,3.64-3.368
C24.24,25.281,23.736,24.363,22.943,23.745z"
/>
<polygon fill="#fbc02d" points="34,42 14,42 13,38 14,34 34,34 35,38" />
<polygon fill="#4caf50" points="38,35 42,34 42,14 38,13 34,14 34,34" />
<path
fill="#1e88e5"
d="M34,14l1-4l-1-4H9C7.343,6,6,7.343,6,9v25l4,1l4-1V14H34z"
/>
<polygon fill="#e53935" points="34,34 34,42 42,34" />
<path fill="#1565c0" d="M39,6h-5v8h8V9C42,7.343,40.657,6,39,6z" />
<path fill="#1565c0" d="M9,42h5v-8H6v5C6,40.657,7.343,42,9,42z" />
</svg>
);
}
58 changes: 58 additions & 0 deletions src/svg/calendar/Ics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export function Ics({ title = 'Download ICS' }: { title?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
x="0px"
y="0px"
width="20"
height="20"
viewBox="0 0 48 48"
role="img"
aria-labelledby="IcsSvgTitle"
style={{
fillRule: 'evenodd',
clipRule: 'evenodd',
strokeLinejoin: 'round',
strokeMiterlimit: 2,
}}
>
<title id="IcsSvgTitle">{title}</title>
<path
fill="#d6e5e5"
d="M5.291,30.513c0.118-4.478,0.045-8.709-0.136-13.185c-0.078-1.934-0.175-3.888,0.171-5.792 S6.512,7.75,8.008,6.522c2.119-1.739,5.754-2.166,8.485-1.918C20.913,5.006,25.99,5.169,30.42,4.9 C32.789,4.757,35.196,4.493,37.515,5s4.593,1.96,5.346,4.211c0.348,1.04,0.347,2.159,0.344,3.255 c-0.022,6.618-0.045,13.235-0.067,19.853c-0.009,2.766-0.143,5.846-2.108,7.793c-1.707,1.692-4.318,2.02-6.721,2.051 c-5.231,0.066-10.477-0.835-15.676-0.255c-2.35,0.262-4.778,0.819-7.031,0.105c-0.993-0.315-1.894-0.862-2.784-1.405 c-0.787-0.48-1.597-0.981-2.131-1.733c-0.432-0.608-0.651-1.338-0.829-2.062C5.332,34.675,5.233,32.714,5.291,30.513z"
/>
<path
fill="#ef4823"
d="M43.2,12.47c0,1.43-0.01,2.86-0.01,4.29H5.13c-0.07-1.75-0.12-3.51,0.2-5.22 c0.34-1.91,1.18-3.79,2.68-5.02c2.12-1.74,5.75-2.16,8.48-1.92c4.42,0.41,9.5,0.57,13.93,0.3c2.37-0.14,4.78-0.41,7.09,0.1 c2.32,0.51,4.6,1.96,5.35,4.21C43.21,10.25,43.21,11.37,43.2,12.47z"
/>
<path
fill="#010101"
d="M43.488,9.604c-0.427-1.871-1.804-3.341-3.472-4.22c-2.002-1.055-4.279-1.24-6.505-1.166 c-2.44,0.081-4.865,0.301-7.308,0.313c-2.398,0.011-4.797-0.071-7.19-0.23c-2.063-0.137-4.086-0.389-6.15-0.121 c-1.848,0.24-3.746,0.783-5.207,1.988C6.088,7.46,5.203,9.44,4.844,11.403c-0.454,2.482-0.216,5.029-0.129,7.531 c0.089,2.549,0.139,5.1,0.133,7.65c-0.004,1.31-0.023,2.619-0.057,3.928c-0.056,2.352,0.065,4.755,0.743,7.023 c0.3,1.003,0.798,1.871,1.615,2.538c0.81,0.661,1.754,1.204,2.672,1.699c2.191,1.182,4.452,1.193,6.868,0.883 c2.528-0.325,5.015-0.497,7.566-0.415c2.618,0.084,5.229,0.319,7.848,0.398c2.127,0.064,4.362,0.113,6.417-0.526 c1.885-0.586,3.418-1.823,4.212-3.65c0.786-1.806,0.887-3.822,0.904-5.766c0.047-5.255,0.036-10.51,0.054-15.765 c0.004-1.282,0.009-2.564,0.013-3.847C43.706,11.926,43.748,10.744,43.488,9.604z M42.702,13.211 c-0.016,4.881-0.033,9.761-0.049,14.642c-0.007,2.219,0.071,4.459-0.078,6.674c-0.126,1.86-0.52,3.871-1.898,5.232 c-1.391,1.375-3.433,1.761-5.314,1.869c-2.309,0.132-4.636-0.031-6.941-0.169c-2.365-0.142-4.733-0.296-7.104-0.231 c-2.323,0.064-4.604,0.577-6.921,0.631c-1.159,0.027-2.307-0.122-3.373-0.599c-0.97-0.434-1.919-1.012-2.792-1.617 c-0.911-0.63-1.456-1.406-1.762-2.471c-0.316-1.099-0.507-2.238-0.605-3.376c-0.094-1.092-0.1-2.188-0.074-3.284 c0.123-4.804-0.023-9.595-0.183-14.396c-0.074-2.226-0.058-4.541,0.84-6.622c0.778-1.802,2.149-3.086,3.997-3.739 c1.709-0.604,3.56-0.785,5.364-0.7c2.129,0.1,4.249,0.331,6.382,0.408c2.234,0.081,4.473,0.095,6.707,0.01 c2.283-0.087,4.579-0.397,6.864-0.224c1.973,0.149,3.988,0.772,5.416,2.205C42.757,9.042,42.709,11.116,42.702,13.211z"
/>
<path
fill="#010101"
d="M5.466,17.153c2.599-0.219,5.233-0.115,7.838-0.079c2.536,0.035,5.072,0.094,7.608,0.157 c4.916,0.122,9.861,0.364,14.779,0.221c2.342-0.068,4.724-0.284,7.057,0.021c0.636,0.083,0.63-0.918,0-1 c-2.081-0.272-4.204-0.122-6.293-0.047c-2.388,0.086-4.779,0.034-7.167-0.007c-5.011-0.084-10.02-0.251-15.031-0.331 c-2.92-0.047-5.879-0.18-8.792,0.065C4.829,16.207,4.823,17.207,5.466,17.153L5.466,17.153z"
/>
<path
fill="#010101"
d="M19.548,21.837c0.011-0.221-0.164-0.422-0.367-0.482c-0.956-0.281-1.768,0.267-2.49,0.84 c-0.947,0.752-1.877,1.528-2.815,2.292c-0.499,0.407,0.212,1.11,0.707,0.707c0.72-0.587,1.441-1.174,2.161-1.761 c0.468-0.382,1.112-1.06,1.778-1.137c-0.267,5.011-0.633,10.026-0.436,15.047c0.025,0.641,1.025,0.645,1,0 C18.884,32.169,19.28,27.001,19.548,21.837z"
/>
<path
fill="#010101"
d="M33.574,21.289c-0.592-0.121-1.245-0.106-1.848-0.139c-2.617-0.145-5.241-0.103-7.853,0.11 c-0.637,0.052-0.643,1.052,0,1c1.592-0.13,3.187-0.199,4.785-0.197c0.778,0.001,1.556,0.018,2.333,0.051 c0.409,0.017,0.818,0.039,1.226,0.065c0.249,0.016,0.65-0.021,0.959,0.029c-0.09,0.21-0.274,0.496-0.332,0.61 c-0.171,0.334-0.346,0.666-0.522,0.997c-0.34,0.637-0.688,1.269-1.038,1.9c-0.722,1.3-1.457,2.593-2.159,3.904 c-1.296,2.423-2.519,4.938-3.146,7.628c-0.146,0.626,0.818,0.893,0.964,0.266c1.066-4.576,3.763-8.611,5.973-12.693 c0.269-0.496,0.533-0.995,0.791-1.497c0.192-0.375,0.573-0.886,0.547-1.332C34.23,21.585,33.945,21.365,33.574,21.289z"
/>
<path
fill="#d6e5e5"
d="M17.21,12.534c0.175,0.814,0.852,1.364,1.657,1.486c0.78,0.118,1.671-0.022,2.081-0.781 c0.366-0.678,0.24-1.545,0.19-2.281c-0.054-0.81-0.129-1.619-0.16-2.43c-0.024-0.641-1.025-0.645-1,0 c0.025,0.649,0.078,1.297,0.126,1.945c0.045,0.611,0.128,1.249,0.076,1.862c-0.018,0.212-0.068,0.451-0.244,0.589 c-0.17,0.133-0.417,0.147-0.623,0.142c-0.545-0.014-1.017-0.231-1.139-0.797C18.039,11.639,17.075,11.905,17.21,12.534 L17.21,12.534z"
/>
<path
fill="#d6e5e5"
d="M25.982,8.632c-0.044-0.635-1.017-0.65-1,0c0.054,0.784,0.075,1.57,0.058,2.356 c-0.012,0.585-0.012,1.308-0.404,1.786c-0.261,0.318-0.801,0.555-1.108,0.192c-0.341-0.402-0.302-1.102-0.333-1.595 c-0.058-0.91-0.115-1.819-0.173-2.729c-0.017-0.27-0.218-0.5-0.5-0.5c-0.257,0-0.517,0.229-0.5,0.5 c0.061,0.957,0.121,1.915,0.182,2.872c0.047,0.737,0.081,1.55,0.597,2.133c0.539,0.609,1.446,0.624,2.103,0.202 c0.732-0.471,1.007-1.282,1.096-2.11C26.11,10.716,26.052,9.656,25.982,8.632z"
/>
<path
fill="#d6e5e5"
d="M30.626,12.681c-0.801,0-1.597,0.067-2.39,0.168c-0.054-1.37-0.109-2.739-0.163-4.108 c-0.025-0.641-1.026-0.645-1,0c0.062,1.555,0.123,3.109,0.185,4.664c0.014,0.352,0.307,0.533,0.633,0.482 c0.905-0.142,1.819-0.205,2.735-0.205C31.27,13.681,31.271,12.681,30.626,12.681z"
/>
</svg>
);
}
47 changes: 47 additions & 0 deletions src/svg/calendar/Outlook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export function Outlook({ title = 'Outlook Calendar' }: { title?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
x="0px"
y="0px"
width="20"
height="20"
viewBox="0 0 48 48"
role="img"
aria-labelledby="OutlookSvgTitle"
style={{
fillRule: 'evenodd',
clipRule: 'evenodd',
strokeLinejoin: 'round',
strokeMiterlimit: 2,
}}
>
<title id="OutlookSvgTitle">{title}</title>
<path
fill="#1976d2"
d="M28,13h14.533C43.343,13,44,13.657,44,14.467v19.066C44,34.343,43.343,35,42.533,35H28V13z"
/>
<rect width="14" height="15.542" x="28" y="17.958" fill="#fff" />
<polygon fill="#1976d2" points="27,44 4,39.5 4,8.5 27,4" />
<path
fill="#fff"
d="M15.25,16.5c-3.176,0-5.75,3.358-5.75,7.5s2.574,7.5,5.75,7.5S21,28.142,21,24
S18.426,16.5,15.25,16.5z M15,28.5c-1.657,0-3-2.015-3-4.5s1.343-4.5,3-4.5s3,2.015,3,4.5S16.657,28.5,15,28.5z"
/>
<rect width="2.7" height="2.9" x="28.047" y="29.737" fill="#1976d2" />
<rect width="2.7" height="2.9" x="31.448" y="29.737" fill="#1976d2" />
<rect width="2.7" height="2.9" x="34.849" y="29.737" fill="#1976d2" />
<rect width="2.7" height="2.9" x="28.047" y="26.159" fill="#1976d2" />
<rect width="2.7" height="2.9" x="31.448" y="26.159" fill="#1976d2" />
<rect width="2.7" height="2.9" x="34.849" y="26.159" fill="#1976d2" />
<rect width="2.7" height="2.9" x="38.25" y="26.159" fill="#1976d2" />
<rect width="2.7" height="2.9" x="28.047" y="22.706" fill="#1976d2" />
<rect width="2.7" height="2.9" x="31.448" y="22.706" fill="#1976d2" />
<rect width="2.7" height="2.9" x="34.849" y="22.706" fill="#1976d2" />
<rect width="2.7" height="2.9" x="38.25" y="22.706" fill="#1976d2" />
<rect width="2.7" height="2.9" x="31.448" y="19.112" fill="#1976d2" />
<rect width="2.7" height="2.9" x="34.849" y="19.112" fill="#1976d2" />
<rect width="2.7" height="2.9" x="38.25" y="19.112" fill="#1976d2" />
</svg>
);
}