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

More styling changes, better error handling and mailer bug fixes #75

Merged
merged 3 commits into from
Feb 2, 2021
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
37 changes: 19 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,19 @@

## Table of contents

* [features](#features)
* [Community](#community)
* [API Documentation](#api-documentation)
* [Getting Started](#getting-started)
* [Prerequisites](#prerequisites)
* [Installation](#installation)
* [Setup](#setup)
* [Development](#development)
* [Testing](#test)
* [Production](#production)
* [Deployment](#deployment)
* [Deploy with vercel](#vercel)
* [Contributing](#contributing)
* [License](#license)
- [Community](#community)
- [API Documentation](#api-documentation)
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Setup](#setup)
- [Development](#development)
- [Testing](#test)
- [Production](#production)
- [Deployment](#deployment)
- [Deploy with vercel](#vercel)
- [Contributing](#contributing)
- [License](#license)

## Community

Expand Down Expand Up @@ -52,27 +51,30 @@ $ npm i

### Setup

- Make a copy of the `.env.development.example` and `.env.production.example` files to `.env.development` and `.env.production` files respectively.
- Make a copy of the `.env.development.example` and `.env.production.example` files to `.env.development` and `.env.production` files respectively.
- Create a firebase account , setup firebase authentication for google sign-in (firebase-console > Authentication > Sign-in methods > Google ), whitelist the client domain in the `Authorised domains` section. Set firebase config variables in `.env` files.
- Set the encryption variables and domain URLs in the `.env` files

### Development
### Development

```bash
$ npm run dev
```

Linting

```bash
$ npx eslint . --ext .tsx,.ts
```

> Note: Or simply setup automatic linting in `vscode`

Testing

```bash
$ npm run test
```

### Production

```bash
Expand All @@ -87,7 +89,7 @@ Make a copy of the `.env.production.example` file to `.env.production` and set t

## Deploy with vercel

> Note: You need to have the [RocketMeet-server](https://github.com/RocketMeet/RocketMeet-server) and [RocketMeet-mailer](https://github.com/RocketMeet/RocketMeet-mailer) setup before using this one-click deployment. Make sure to create a firebase account and setup `firebase-auth` for google signin.
> Note: You need to have the [RocketMeet-server](https://github.com/RocketMeet/RocketMeet-server) and [RocketMeet-mailer](https://github.com/RocketMeet/RocketMeet-mailer) setup before using this one-click deployment. Make sure to create a firebase account and setup `firebase-auth` for google signin.

Set the environment variables in `.env.production.example` to vercel in the next step.

Expand All @@ -100,4 +102,3 @@ Check out our [contributing guide](https://github.com/RocketMeet/RocketMeet-clie
## License

RocketMeet-client is distributed under the [MIT License](https://github.com/RocketMeet/RocketMeet-client/blob/main/LICENSE).

4 changes: 2 additions & 2 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ const Home = (): JSX.Element => {
<h1 className="hero-title">
<span className="hero-line">
Scheduling meetings{" "}
<span className="hero-strikethrough">is boring</span>
<span className="hero-strikethrough">is boring</span>{" "}
</span>
<span className="hero-line">has never been faster</span>
</h1>
<h3 className="hero-desc">
<span className="hero-line">
Quickly find the best time for team meetings and one-on-ones
with
with{" "}
</span>
<span className="hero-line">
RocketMeet — a free and open source meeting scheduling app
Expand Down
34 changes: 19 additions & 15 deletions pages/poll/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { useState } from "react";
import { GetServerSideProps } from "next";
import { Row, Container, Jumbotron } from "react-bootstrap";
import { ChevronDown } from "react-bootstrap-icons";
import { useSelector } from "react-redux";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { serverAPI } from "../../src/api/server";
import Layout from "../../src/components/Layout";
import PollInfo from "../../src/components/PollInfo";
import PollTable from "../../src/components/PollTable";
import InviteMail from "../../src/components/InviteMail";
import {
Choice,
ChoiceFromDB,
Expand All @@ -23,9 +23,9 @@ dayjs.extend(localizedFormat);

const Poll = (props: {
pollFromDB: RocketMeetPollFromDB;
pollid: string;
pollID: string;
}): JSX.Element => {
const { pollFromDB, pollid } = props;
const { pollFromDB, pollID } = props;
const pollCreatorEmailID = decrypt(pollFromDB.encryptedEmailID);
const loggedInUserEmailID = useSelector(
(state: RootState) => state.authReducer.username
Expand All @@ -49,26 +49,30 @@ const Poll = (props: {
{pollFromDB.open &&
loggedInUserEmailID === pollCreatorEmailID && (
<ShareInvite
polltitle={pollFromDB.title}
pollid={pollid}
pollTitle={pollFromDB.title}
pollID={pollID}
finalChoice={undefined}
/>
)}
{!pollFromDB.open &&
loggedInUserEmailID === pollCreatorEmailID && (
{!pollFromDB.open && loggedInUserEmailID === pollCreatorEmailID && (
<>
<ShareInvite
polltitle={pollFromDB.title}
pollid={pollid}
pollTitle={pollFromDB.title}
pollID={pollID}
finalChoice={pollFromDB.finalChoice}
/>
)}
<div className="rm-chevron-down-div">
<ChevronDown className="rm-chevron-down" />
</div>
</>
)}
</Jumbotron>
</div>
<div className="col-sm-8">
<Jumbotron className="poll-table-jumbo">
<PollTable
pollFromDB={pollFromDB}
pollid={pollid}
pollID={pollID}
sortedChoices={sortedChoices}
newVote={newVote}
setNewVote={setNewVote}
Expand All @@ -86,11 +90,11 @@ const Poll = (props: {
};

export const getServerSideProps: GetServerSideProps = async (context) => {
let pollid = null;
let pollID = null;
if (context.params) {
pollid = context.params.id;
pollID = context.params.id;
}
const getPollResponse = await serverAPI.getPoll(pollid);
const getPollResponse = await serverAPI.getPoll(pollID);
const pollFromDB = getPollResponse.data;

if (getPollResponse.statusCode === 404) {
Expand All @@ -102,7 +106,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
};
}
return {
props: { pollFromDB, pollid }, // will be passed to the page component as props
props: { pollFromDB, pollID }, // will be passed to the page component as props
};
};

Expand Down
22 changes: 15 additions & 7 deletions pages/poll/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ const Create = (): JSX.Element => {
msg: "Poll creation failed, check your connection.",
});
}
} else if (!pollTitle) {
setResponse({
status: true,
type: "error",
msg: "Please provide a title.",
});
} else {
setResponse({
status: true,
type: "error",
msg: "Please select at least two time slots to choose from.",
});
}
};

Expand Down Expand Up @@ -151,17 +163,12 @@ const Create = (): JSX.Element => {
<AvailableTimes
weekStartsOn="monday"
onChange={onChoicesChange}
height="28rem"
height="65vh"
/>
<Button
className="rm-primary-button create-poll-btn"
onClick={handleSubmit}
disabled={
!pollTitle ||
!pollChoices ||
pollChoices?.length < 2 ||
disabled
}
disabled={disabled}
>
{!disabled ? (
`Create Poll`
Expand All @@ -173,6 +180,7 @@ const Create = (): JSX.Element => {
size="sm"
role="status"
aria-hidden="true"
className="rm-button-spinner"
/>
</>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/api/mailer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class MailerAPI {
token: string
): Promise<MailerResponse> => {
const payload = JSON.stringify(mailerArgs);
const endpoint = `${this.URL}/meetInfo`;
const endpoint = `${this.URL}/invite`;
return this.httpPost(payload, endpoint, token);
};

Expand All @@ -62,7 +62,7 @@ class MailerAPI {
token: string
): Promise<MailerResponse> => {
const payload = JSON.stringify(mailerArgs);
const endpoint = `${this.URL}/finalOption`;
const endpoint = `${this.URL}/finalChoice`;
return this.httpPost(payload, endpoint, token);
};
}
Expand Down
28 changes: 14 additions & 14 deletions src/api/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ class ServerAPI {
};

getPoll = (
pollid: string | string[] | null | undefined
pollID: string | string[] | null | undefined
): Promise<HttpResponse> => {
const endpoint = `${this.URL}/poll/${pollid}`;
const endpoint = `${this.URL}/poll/${pollID}`;
this.headers = {
"Content-Type": "application/json",
};
Expand All @@ -48,11 +48,11 @@ class ServerAPI {
};

getPolls = (pollArgs: {
userID: string;
encryptedEmailID: string;
token: string;
}): Promise<HttpResponse> => {
const { userID, token } = pollArgs;
const endpoint = `${this.URL}/user/${userID}`;
const { encryptedEmailID, token } = pollArgs;
const endpoint = `${this.URL}/user/${encryptedEmailID}`;
this.headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
Expand Down Expand Up @@ -88,10 +88,10 @@ class ServerAPI {

markChoices = (voteArgs: {
newVote: Vote;
pollid: string;
pollID: string;
}): Promise<HttpResponse> => {
const { newVote, pollid } = voteArgs;
const endpoint = `${this.URL}/poll/${pollid}`;
const { newVote, pollID } = voteArgs;
const endpoint = `${this.URL}/poll/${pollID}`;
this.headers = {
"Content-Type": "application/json",
};
Expand All @@ -107,11 +107,11 @@ class ServerAPI {

markFinalChoice = (voteArgs: {
finalChoice: { finalChoice: Choice | undefined; open: boolean };
pollid: string;
pollID: string;
token: string;
}): Promise<HttpResponse> => {
const { finalChoice, pollid, token } = voteArgs;
const endpoint = `${this.URL}/user/poll/${pollid}`;
const { finalChoice, pollID, token } = voteArgs;
const endpoint = `${this.URL}/user/poll/${pollID}`;
this.headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
Expand All @@ -127,11 +127,11 @@ class ServerAPI {
};

deletePoll = (voteArgs: {
pollid: string;
pollID: string;
token: string;
}): Promise<HttpResponse> => {
const { pollid, token } = voteArgs;
const endpoint = `${this.URL}/user/poll/${pollid}`;
const { pollID, token } = voteArgs;
const endpoint = `${this.URL}/user/poll/${pollID}`;
this.headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
Expand Down
37 changes: 31 additions & 6 deletions src/components/CopyLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,37 @@ import {
Popover,
OverlayTrigger,
} from "react-bootstrap";
import { Clipboard } from "react-bootstrap-icons";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import copy from "copy-to-clipboard";
import { Choice } from "../models/poll";

dayjs.extend(localizedFormat);

const CopyLink = (props: {
pollURL: string;
pollTitle: string;
finalChoice: Choice | undefined;
}): JSX.Element => {
const { pollURL, pollTitle, finalChoice } = props;

let textToCopy: string;

if (finalChoice) {
textToCopy = `${pollTitle} would be held on ${dayjs(
finalChoice?.start
).format("ddd")}, ${dayjs(finalChoice?.start).format("MMM")} ${dayjs(
finalChoice?.start
).format("DD")}, ${dayjs(finalChoice?.start).format("LT")} - ${dayjs(
finalChoice?.end
).format("LT")}.`;
} else {
textToCopy = pollURL;
}

const CopyLink = (props: { pollurl: string; final: boolean }): JSX.Element => {
const { pollurl, final } = props;
const handleCopy = (): void => {
copy(pollurl);
copy(textToCopy);
};

const popover = (
Expand All @@ -23,19 +48,19 @@ const CopyLink = (props: { pollurl: string; final: boolean }): JSX.Element => {
<div>
<Form.Group>
<Form.Label className="font-weight-bold">
{final ? "Copy final time info" : "Share link"}
{finalChoice ? "Copy final time" : "Share link"}
</Form.Label>
<InputGroup className="mb-3">
<Form.Control
type="text"
readOnly
defaultValue={pollurl}
defaultValue={textToCopy}
className="share-textbox"
/>
<InputGroup.Append>
<OverlayTrigger trigger="click" placement="top" overlay={popover}>
<Button variant="light" onClick={handleCopy}>
Copy
<Clipboard />
</Button>
</OverlayTrigger>
</InputGroup.Append>
Expand Down
Loading