diff --git a/README.md b/README.md index 7753f17..14417b7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,21 @@ -# react-google-calendar +# reactjs-google-calendar ======================================== +
+ + desktop version number + + + LICENSE + +
+ React Google Calendar is a functional and easy way - Easy to use @@ -10,29 +25,32 @@ React Google Calendar is a functional and easy way - Light on dependencies: relies on axios, he, and react - Native strong typing - no need to install @types/ definition - Includes TypeScript support +- Supports 'Offline' calendars (events not created from the Google Calendar API) +- Default is client side, supports SSR Install ------- -react-google-calendar is available on [npm](https://www.npmjs.com/package/react-google-calendar). It +reactjs-google-calendar is available on [npm](https://www.npmjs.com/package/react-google-calendar). It can be installed with the following command: npm install react-google-calendar -If you don't want to use npm, [clone this respository](https://github.com/theLAZYmd/react-google-calendar.git) to your project source. +If you don't want to use npm, [clone this respository](https://github.com/theLAZYmd/reactjs-google-calendar.git) to your project source. -Homepage & Demo +Live Demos ---------------- -- [Demo](https://oxfordunichess.github.io/oucc-frontend/termcard) +- [Online calendar (uses Google APIs, full settings)](http://users.ox.ac.uk/~chess/termcard/ht20) +- [Offline Calendar, SSR](https://results.scorchapp.co.uk/calendar) To learn how to use React Google Calendar: - [Examples](https://github.com/theLAZYmd/react-google-calendar/blob/master/examples) -React Google Calendar in your React projects +React Google Calendar in your client-side (react-scripts) projects -------------------- Simply import the package into your component with @@ -47,71 +65,226 @@ And use as a React component, specifying three settings of: - Styles: a module.css component ```html - + ``` -Register for an API key at https://developers.google.com/calendar - -The settings config should be of the following format: +This library is easier to use with typescript, since type definitions are included for the configuration. +For JavaScript users, see below: CalendarProps should be of the following format. -```js -{ +## Online CalendarProps -// Register for an API key - "APIkey": "", +```ts +interface CalendarProps { -/** - * Calendar IDs should be an object of key-value pairs. - * Each key should be a calendar link of the format - * {random string of 26-letters}@group.calendar.google.com - * Example: f8r5s6amq4momsc2s7nrt8vees@group.calendar.google.com - * Alternatively personal user calendars will appear as - * oxfordunichess@gmail.com - * Get this calendar ID by going to - * Settings and Sharing > Integrate Calendar > CalendarID - * Make your calendar publically visible in Access Permissions - * The value fields of this object should be html colours - */ - "calendarIDs": { - [calendarID: string]: [colour: string] + //--- Online props -// If you want your locations to be rendered as a link to a map. Leave blank for none. Use Google Maps (below) as default + /** + * @required + * A map of Google Calendar IDs to the color you'd like that calendar to be displayed. + * + * A google calendar ID (in v3) is of the format: {hash of 26-letters}@group.calendar.google.com + * Alternatively, personal user calendars will appear as your email, ex: oxfordunichess@gmail.com + * Generate a calendar ID by going to: + * - Settings and Sharing > Integrate Calendar > CalendarID + * - Make your calendar publically visible in Access Permissions + * + * Colors are applied directly as a CSS property so use MDN specification + * - https://developer.mozilla.org/en-US/docs/Web/CSS/color_value + * @example + * ``` + * { + * [f8r5s6amq4momsc2s7nrt8vees@group.calendar.google.com]: red + * } + * ``` + */ + calendars: { + [calendarId: string]: string }, - "mapsLink": "https://www.google.com/maps/search/", - -/** - * The renderer takes the first line of a location - * in the Google Calendar entry and renders it - * Use this to 'adjust' any locations - */ - "locationReplacers": { - "Christ Church Cathedral": "Christ Church" + + settings: { + + /** + * Register for an API key at https://developers.google.com/calendar + * NOTE: This will be insecure client-side + */ + APIkey: string + + /** + * Google Calendars have a 'location' field. + * If you want your cell to contain a link to a map, + * include a baseURL for the mapsLink, ex: + * "mapsLink": "https://www.google.com/maps/search/" + */ + mapsLink?: string + + /** + * Special use case property + * Sometimes, the Google Maps 'location' field requires + * you to put in address incorrectly + * ex: will say address rather than landmark + * or: will get placename wrong + * You can use a string dictionary to replace those strings found in locations with your preferences + * ex: "locationReplacers": { + * Christ Church Cathedral": "Christ Church" + * } + */ + locationReplacers: { + [key: string]: string + }, + + /** + * If the google API link is updated and for some reason this package is not updated, replace the default temporarily here + * @default 'https://clients6.google.com/calendar/v3/calendars/' + */ + baseURL?: string + }, -// When should the calendar start date be? (a Sunday) - "start": "6 October 2019", - -// When should the calendar finish date be? - "finish": "8 December 2019", - -// What should the calendar title be? - "title": "MT'19", - -// How should the days of the week be displayed on the top row? -// (Must start with a Sunday) - "days": [ - "SUN", - "MON", - "TUES", - "WED", - "THURS", - "FRI", - "SAT" - ] + //--- Universal props + + // Fetch events from Google calendars starting from what date + start: Date + + /** + * Fetch events from Google calendars ending at what date + * @default Date.now() + */ + finish?: Date + + // The title of your calendar. Goes in the top left cell of the table generated. + title?: string + + /** + * What timezone should this calendar be displayed in? + * You can set this client-side to make it adapt to users' browsers + */ + timeZone?: string + + /** + * An object assigning classnames to each element of the table. + * You can also just plug in a .module.css file, ex: + * + * import styles from myCalendar.module.css + * + * + * See below for the list of available classNames + */ + classNames?: {[key: string]: string} + + /** + * How many weeks should be displayed? + * @default 4 + */ + weeks?: number + + /** + * A custom list of days to display in the header of the table + * First day of the week should be a monday + * Submit a pull request for support with weeks starting on Sundays or other + * @default ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'] + */ + dayLabels?: string[] + + /** + * If you want to use a custom link component, + * ex: next/link to route components + * then add it hears as prop. ex: + * + * import Link from 'next/link'; + * + */ + customLinkComponent?: () => ReactElement + + /** + * How many events should be rendered per cell? + * Any more and a 'more' sign will be displayed + * which can be clicked to be expanded + * @default 5 + */ + maxEvents?: number + + /** + * By default, reactjs-google-calendar will update + * the hash router of your webpage to today's timestamp + * to allow users to 'jump-to' the right cell. + * Set this property to false to disable this feature. + * @default true + */ + noUpdateHash?: boolean + + /** + * By default, reactjs-google-calendar highlights today's cell. + * Set this property to false to disable this feature. + * @default true + */ + noHighlightToday?: boolean +} +``` + +## Offline CalendarProps + +You can use this package client-side and fetch the data server-side too if you so desire. +Alternatively, you can use this package to just generate a calendar, without interacting with the google API. + +To do this, simply modify the structure of the props. +The whole section above marked 'OnlineProps' should be replaced with the following: + +```ts +interface OfflineProps { + + /** + * @required + * Structure your events as an array of CalendarEvents + * for each possible datestamp + * You can get CalendarEvent[] as a class from the package. + * Use the CalendarEvent.fromGeneric() static function + * to construct new events, not new CalendarEvent() as this constructor + * is used for forming new Events from GoogleEvent objects. + * + * We recommend you use the getEventDate() function from the package + * to construct your timestamps, as this gives a unique timestamp + * for each day. + events: { + [timestamp: string]: CalendarEvent[] + } + + /** + * @required + * A dictionary of colors to the name of the category of event. + * Which ordinarily would be populated by the calendarName field + * from a Google Event. + * NOTE: we do not create this dictionary by calendarId anymore + * since we are not fetching any Google calendars. + */ + calendars: { + [color: string]: string //calendarName + } + + /** + * Note that the settings dictionary is not a thing anymore + * for these OfflineProps, and the interface for the + * calendars prop has changed. + * See examples for help/ + */ } + +type CalendarProps = (OfflineProps | OnlineProps) & GenericProps + +## List of classNames + +```css +table +today +firstColumn +cell +dateNumber +key +status ``` +Make a pull request if you need more. + Contributing ------------- +-------------------- -To discuss a new feature or ask a question, open an issue. To fix a bug, submit a pull request to be credited with the [contributors](https://github.com/theLAZYmd/react-google-calendar/graphs/contributors)! Remember, a pull request, *with test*, is best. \ No newline at end of file +To discuss a new feature or ask a question, open an [issue](https://github.com/theLAZYmd/react-google-calendar/issues). To fix a bug, submit a pull request to be credited with the [contributors](https://github.com/theLAZYmd/react-google-calendar/graphs/contributors)! Remember, a pull request, *with test*, is best. \ No newline at end of file diff --git a/examples/nextjs-offline-calendar.tsx b/examples/nextjs-offline-calendar.tsx new file mode 100644 index 0000000..5e7023a --- /dev/null +++ b/examples/nextjs-offline-calendar.tsx @@ -0,0 +1,48 @@ +import { useMemo } from 'react'; +import GoogleCalendar, { CalendarEvent, getEventDate } from 'reactjs-google-calendar'; +import { GetStaticProps } from 'next'; +import Link from 'next/link'; + +import styles from 'myStyles.module.css'; + +export default function CalendarPage({ events }: { events: CalendarEvent[] }) { + + const formed = useMemo(() => events.map(e => CalendarEvent.fromGeneric(e, e.calendarName, e.color, {})), [events]); + const start = useMemo(() => { + let today = new Date(); + return new Date(today.setDate(today.getDate() - today.getDay())); + }, []); + + const [calendars, timestamped] = useMemo(() => { + let colors = {} as {[key: string]: string}; + let dict = {} as {[timestamp: number]: CalendarEvent[]}; + formed.forEach((e) => { + let start = getEventDate(e.start); + if (!dict[start]) dict[start] = []; + dict[start].push(e); + if (!colors[e.color]) colors[e.color] = e.calendarName; + }); + return [colors, dict]; + }, [formed]); + + return ; + +} + +export const getStaticProps: GetStaticProps = async () => { + + const res = await fetch('https://{mybackEnd}.com/events' ); + const events = res.json(); + return { + props: { events }, + revalidate: 10 + }; +}; \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js index 3c92894..31ad9f2 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -30,8 +30,8 @@ export default { rollupCommonJSResolveHack: true, exclude: '**/__tests__/**', clean: true - }), - json(), + }), + json(), commonjs({ include: ['node_modules/**'], namedExports: { diff --git a/src/hooks/useEvents.ts b/src/hooks/useEvents.ts index 4975e5a..e3d36d5 100644 --- a/src/hooks/useEvents.ts +++ b/src/hooks/useEvents.ts @@ -65,7 +65,6 @@ export default function useEvents(props: EventHookProps) { if (!c[e.color]) c[e.color] = e.calendarName; } } - console.log(c); setColors(c); props.setColorStatuses(Object.keys(c)); }, [setColors, props.setColorStatuses]); diff --git a/src/index.tsx b/src/index.tsx index c956dd7..30e9a6d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -34,7 +34,6 @@ export interface CalendarProps { timeZone?: string classNames?: {[key: string]: string} - days?: string[] noUpdateHash?: boolean customLinkComponent?: ((...args: any[]) => JSX.Element) }