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

Add google calender button for meetings #4437

Merged
merged 9 commits into from
Feb 19, 2024
13 changes: 13 additions & 0 deletions app/components/AddToCalendar/AddToCalendar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.calendarToggleButton {
margin-top: 1rem;
margin-bottom: 0.5rem;
}

.calendarImportCard {
margin-top: 0.5rem;
}

.calendarLink {
display: block;
margin-bottom: 1rem;
}
89 changes: 89 additions & 0 deletions app/components/AddToCalendar/AddToCalendar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Button, Card, Icon } from '@webkom/lego-bricks';
import { useState } from 'react';
import {
getIcalUrl,
getIcalUrlGoogle,
} from 'app/routes/events/components/EventFooter';
import styles from './AddToCalendar.css';
import type { DetailedMeeting } from 'app/store/models/Meeting';
import type { PropsWithChildren } from 'react';

type Props = {
icalToken: string;
meeting: DetailedMeeting;
};

const formatTimeForGoogle = (dateTime: string) => {
return dateTime.replace(/-|:/g, '');
};

const getGoogleCalendarLink = (meeting) => {
const baseURL = 'https://calendar.google.com/calendar/event';
const params = new URLSearchParams({
action: 'TEMPLATE',
dates: `${formatTimeForGoogle(meeting.startTime)}/${formatTimeForGoogle(
meeting.endTime
)}`,
text: meeting.title,
details: meeting.description,
location: meeting.location,
sf: 'true',
output: 'xml',
});
return `${baseURL}?${params.toString()}`;
};

const AddToCalendarToggle = ({ icalToken, meeting }: Props) => {
const [calendarIsOpen, setCalendarIsOpen] = useState(false);

return (
<div>
<Button
className={styles.calendarToggleButton}
onClick={() => setCalendarIsOpen(!calendarIsOpen)}
>
<Icon name="calendar-outline" size={19} />
{!calendarIsOpen ? 'Vis kalenderimport' : 'Skjul kalenderimport'}
</Button>

{calendarIsOpen && (
<Card className={styles.calendarImportCard}>
<h3>Google kalender</h3>
<CalendarLink href={getGoogleCalendarLink(meeting)}>
Importer kun dette møtet
</CalendarLink>

<CalendarLink href={getIcalUrlGoogle(icalToken, 'personal')}>
Synkroniser alle dine møter og favorittarrangementer
</CalendarLink>

<h3>iCalendar</h3>

<CalendarLink href={getIcalUrl(icalToken, 'personal')}>
Synkroniser alle dine møter og favorittarrangementer
</CalendarLink>
</Card>
)}
</div>
);
};

export default AddToCalendarToggle;

type CalendarLinkProps = {
href: string;
};

const CalendarLink: React.FC<PropsWithChildren<CalendarLinkProps>> = ({
children,
href,
}) => (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className={styles.calendarLink}
>
{children}
</a>
);
9 changes: 6 additions & 3 deletions app/routes/events/components/EventFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import Circle from 'app/components/Circle';
import config from 'app/config';
import { EventTypeConfig } from '../utils';
import styles from './EventFooter.css';
import type { IcalToken } from 'app/models';

const icalTypes = [
const icalTypes: { name: IcalType; title: string }[] = [
{
name: 'events',
title: 'Alle arrangementer',
Expand All @@ -19,10 +20,12 @@ const icalTypes = [
},
];

const getIcalUrl = (icalToken, icalType) =>
type IcalType = 'events' | 'registrations' | 'personal';

export const getIcalUrl = (icalToken: IcalToken, icalType: IcalType) =>
`${config.serverUrl}/calendar-ical/${icalType}/?token=${icalToken}`;

const getIcalUrlGoogle = (icalToken, icalType) => {
export const getIcalUrlGoogle = (icalToken: IcalToken, icalType: IcalType) => {
const icalUrl = getIcalUrl(icalToken, icalType).replace(/^https/i, 'http');
return `https://www.google.com/calendar/render?cid=${icalUrl}`;
};
Expand Down
5 changes: 5 additions & 0 deletions app/routes/meetings/components/MeetingDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import moment from 'moment-timezone';
import { Helmet } from 'react-helmet-async';
import { Link, useParams } from 'react-router-dom';
import { setInvitationStatus } from 'app/actions/MeetingActions';
import AddToCalendar from 'app/components/AddToCalendar/AddToCalendar';
import AnnouncementInLine from 'app/components/AnnouncementInLine';
import CommentView from 'app/components/Comments/CommentView';
import {
Expand Down Expand Up @@ -49,6 +50,7 @@ const UserLink = ({ user }: { user: PublicUser }) =>
const MeetingDetails = () => {
const { meetingId } = useParams<{ meetingId: string }>();
const { currentUser } = useUserContext();
const icalToken = currentUser?.icalToken;
const meeting = useAppSelector((state) =>
selectMeetingById(state, {
meetingId,
Expand Down Expand Up @@ -208,6 +210,9 @@ const MeetingDetails = () => {
{meeting.mazemapPoi && (
<MazemapEmbed mazemapPoi={meeting.mazemapPoi} />
)}
<li>
<AddToCalendar icalToken={icalToken} meeting={meeting} />
</li>
</ul>

<Flex column gap={7}>
Expand Down