.
This commit is contained in:
52
README.md
52
README.md
@@ -1,46 +1,14 @@
|
|||||||
# Getting Started with Create React App
|
# Starting
|
||||||
|
1. `git clone https://git.stani.se/stani/telenor-test.git`
|
||||||
|
2. `cd telenor-test`
|
||||||
|
3. `yarn`
|
||||||
|
4. `yarn start`
|
||||||
|
5. done :)
|
||||||
|
|
||||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
For questions contact Stanislav Pintjuk
|
||||||
|
|
||||||
## Available Scripts
|
stani@shiftkey.se
|
||||||
|
|
||||||
In the project directory, you can run:
|
or stani@stani.se
|
||||||
|
|
||||||
### `yarn start`
|
or 0736843130
|
||||||
|
|
||||||
Runs the app in the development mode.\
|
|
||||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
|
||||||
|
|
||||||
The page will reload if you make edits.\
|
|
||||||
You will also see any lint errors in the console.
|
|
||||||
|
|
||||||
### `yarn test`
|
|
||||||
|
|
||||||
Launches the test runner in the interactive watch mode.\
|
|
||||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
|
||||||
|
|
||||||
### `yarn build`
|
|
||||||
|
|
||||||
Builds the app for production to the `build` folder.\
|
|
||||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
|
||||||
|
|
||||||
The build is minified and the filenames include the hashes.\
|
|
||||||
Your app is ready to be deployed!
|
|
||||||
|
|
||||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
|
||||||
|
|
||||||
### `yarn eject`
|
|
||||||
|
|
||||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
|
||||||
|
|
||||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
|
||||||
|
|
||||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
|
||||||
|
|
||||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
|
||||||
|
|
||||||
## Learn More
|
|
||||||
|
|
||||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
|
||||||
|
|
||||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
|
||||||
|
|||||||
15
package.json
15
package.json
@@ -10,9 +10,17 @@
|
|||||||
"@types/node": "^12.0.0",
|
"@types/node": "^12.0.0",
|
||||||
"@types/react": "^17.0.0",
|
"@types/react": "^17.0.0",
|
||||||
"@types/react-dom": "^17.0.0",
|
"@types/react-dom": "^17.0.0",
|
||||||
|
"@types/react-modal": "^3.12.0",
|
||||||
|
"@types/react-time-picker": "^4.0.1",
|
||||||
|
"formik": "^2.2.6",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
"react-datepicker": "^3.8.0",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
"react-loader-spinner": "^4.0.0",
|
||||||
|
"react-modal": "^3.13.1",
|
||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
|
"react-time-picker": "^4.2.1",
|
||||||
|
"styled-components": "^5.2.3",
|
||||||
"typescript": "^4.1.2",
|
"typescript": "^4.1.2",
|
||||||
"web-vitals": "^1.0.1"
|
"web-vitals": "^1.0.1"
|
||||||
},
|
},
|
||||||
@@ -39,5 +47,10 @@
|
|||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react-datepicker": "^3.1.8",
|
||||||
|
"@types/styled-components": "^5.1.9"
|
||||||
|
},
|
||||||
|
"proxy": "https://6oen8x7qoj.execute-api.eu-north-1.amazonaws.com"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { render, screen } from '@testing-library/react';
|
|
||||||
import App from './App';
|
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
|
||||||
render(<App />);
|
|
||||||
const linkElement = screen.getByText(/learn react/i);
|
|
||||||
expect(linkElement).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
20
src/App.tsx
20
src/App.tsx
@@ -1,25 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import logo from './logo.svg';
|
import {AppointmentsPage} from './components/appointments-page';
|
||||||
import './App.css';
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<AppointmentsPage/>
|
||||||
<header className="App-header">
|
|
||||||
<img src={logo} className="App-logo" alt="logo" />
|
|
||||||
<p>
|
|
||||||
Edit <code>src/App.tsx</code> and save to reload.
|
|
||||||
</p>
|
|
||||||
<a
|
|
||||||
className="App-link"
|
|
||||||
href="https://reactjs.org"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Learn React
|
|
||||||
</a>
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
108
src/apis/appointment-client/check-conflicts.test.ts
Normal file
108
src/apis/appointment-client/check-conflicts.test.ts
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import { AppointmentEdit } from ".";
|
||||||
|
import { checkConflict } from "./check-conflicts";
|
||||||
|
|
||||||
|
describe("checkConflict", () => {
|
||||||
|
it("should detect SamePeriod", () => {
|
||||||
|
// arrange
|
||||||
|
const appointmentNew: AppointmentEdit = {
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1, 12),
|
||||||
|
endTime: new Date(2020, 1, 1, 13),
|
||||||
|
date: new Date(2020, 1, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
const result = checkConflict(appointmentNew, [
|
||||||
|
{ id: "0", ...appointmentNew },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result!.status).toEqual("SamePeriod");
|
||||||
|
expect(result!.appointment.id).toEqual("0");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should detect Overlap", () => {
|
||||||
|
// arrange
|
||||||
|
const appointmentNew = {
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1, 12),
|
||||||
|
endTime: new Date(2020, 1, 1, 13),
|
||||||
|
date: new Date(2020, 1, 1),
|
||||||
|
};
|
||||||
|
const appointmentOld = {
|
||||||
|
id: "0",
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1, 12),
|
||||||
|
endTime: new Date(2020, 1, 1, 14),
|
||||||
|
date: new Date(2020, 1, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
const result = checkConflict(appointmentNew, [appointmentOld]);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result!.status).toEqual("OverlapsWith");
|
||||||
|
expect(result!.appointment.id).toEqual("0");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should detect Intersect", () => {
|
||||||
|
// arrange
|
||||||
|
const appointmentNew = {
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1, 12, 0),
|
||||||
|
endTime: new Date(2020, 1, 1, 14, 0),
|
||||||
|
date: new Date(2020, 1, 1)
|
||||||
|
};
|
||||||
|
const appointmentOld = {
|
||||||
|
id: "0",
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1, 13, 0),
|
||||||
|
endTime: new Date(2020, 1, 1, 15, 0),
|
||||||
|
date: new Date(2020, 1, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
const result = checkConflict(appointmentNew, [appointmentOld]);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result!.status).toEqual("IntersectsWith");
|
||||||
|
expect(result!.appointment.id).toEqual("0");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not detect conflict if dates have same time but different dates", () => {
|
||||||
|
// arrange
|
||||||
|
const appointmentNew = {
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1, 12),
|
||||||
|
endTime: new Date(2020, 1, 1, 14),
|
||||||
|
date: new Date(2020, 1, 1),
|
||||||
|
};
|
||||||
|
const appointmentOld = {
|
||||||
|
id: "0",
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1, 12),
|
||||||
|
endTime: new Date(2020, 1, 1, 14),
|
||||||
|
date: new Date(2020, 1, 2),
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
const result = checkConflict(appointmentNew, [appointmentOld]);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
66
src/apis/appointment-client/check-conflicts.ts
Normal file
66
src/apis/appointment-client/check-conflicts.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { Appointment, AppointmentEdit, ConflictResult } from ".";
|
||||||
|
import { normalizeAppointmentTime } from "../../helpers/date-helpers";
|
||||||
|
|
||||||
|
export const checkConflict = (
|
||||||
|
newAppointment: AppointmentEdit,
|
||||||
|
appointmentStore: Appointment[]
|
||||||
|
): ConflictResult | undefined => {
|
||||||
|
const newNormalApt = normalizeAppointmentTime(newAppointment);
|
||||||
|
for (const apt of appointmentStore) {
|
||||||
|
const normalAptOld = normalizeAppointmentTime(apt);
|
||||||
|
if (isSamePeriod(newNormalApt, normalAptOld)) {
|
||||||
|
return {
|
||||||
|
status: "SamePeriod",
|
||||||
|
appointment: apt,
|
||||||
|
};
|
||||||
|
} else if (isOverlapping(newNormalApt, normalAptOld)) {
|
||||||
|
return {
|
||||||
|
status: "OverlapsWith",
|
||||||
|
appointment: apt,
|
||||||
|
};
|
||||||
|
} else if (isIntersecting(newNormalApt, normalAptOld)) {
|
||||||
|
return {
|
||||||
|
status: "IntersectsWith",
|
||||||
|
appointment: apt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSamePeriod = (
|
||||||
|
newAppointment: AppointmentEdit,
|
||||||
|
oldAppointment: AppointmentEdit
|
||||||
|
): boolean => {
|
||||||
|
return (
|
||||||
|
newAppointment.date.getTime() === oldAppointment.date.getTime() &&
|
||||||
|
newAppointment.startTime.getTime() === oldAppointment.startTime.getTime() &&
|
||||||
|
newAppointment.endTime.getTime() === oldAppointment.endTime.getTime()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isOverlapping = (
|
||||||
|
newAppointment: AppointmentEdit,
|
||||||
|
oldAppointment: AppointmentEdit
|
||||||
|
): boolean => {
|
||||||
|
return (
|
||||||
|
newAppointment.date.getTime() === oldAppointment.date.getTime() &&
|
||||||
|
((newAppointment.startTime >= oldAppointment.startTime &&
|
||||||
|
newAppointment.endTime <= oldAppointment.endTime) ||
|
||||||
|
(oldAppointment.startTime >= newAppointment.startTime &&
|
||||||
|
oldAppointment.endTime <= newAppointment.endTime))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isIntersecting = (
|
||||||
|
newAppointment: AppointmentEdit,
|
||||||
|
oldAppointment: AppointmentEdit
|
||||||
|
): boolean => {
|
||||||
|
return (
|
||||||
|
newAppointment.date.getTime() === oldAppointment.date.getTime() &&
|
||||||
|
((newAppointment.startTime > oldAppointment.startTime &&
|
||||||
|
newAppointment.startTime < oldAppointment.endTime) ||
|
||||||
|
(newAppointment.endTime > oldAppointment.startTime &&
|
||||||
|
newAppointment.endTime < oldAppointment.endTime))
|
||||||
|
);
|
||||||
|
};
|
||||||
11
src/apis/appointment-client/index.tsx
Normal file
11
src/apis/appointment-client/index.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import React, { useContext } from "react";
|
||||||
|
import { MemoryAppointmentClient } from "./memory-appointment-client";
|
||||||
|
import { IAppointmentClient } from "./types";
|
||||||
|
export * from "./types";
|
||||||
|
export * from "./memory-appointment-client";
|
||||||
|
|
||||||
|
export const AppointmentClientContext = React.createContext<IAppointmentClient>(
|
||||||
|
new MemoryAppointmentClient()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useAppointmentClient = () => useContext(AppointmentClientContext);
|
||||||
117
src/apis/appointment-client/memory-appointment-client.test.ts
Normal file
117
src/apis/appointment-client/memory-appointment-client.test.ts
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import {
|
||||||
|
MemoryAppointmentClient,
|
||||||
|
AppointmentEdit,
|
||||||
|
} from "../../apis/appointment-client";
|
||||||
|
|
||||||
|
describe("MemoryAppointmentClient", () => {
|
||||||
|
describe("addAppoinment", () => {
|
||||||
|
it("should add an appointment", async () => {
|
||||||
|
// Arrange
|
||||||
|
const appointment: AppointmentEdit = {
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1),
|
||||||
|
endTime: new Date(2020, 1, 2),
|
||||||
|
date: new Date(2020, 1, 1),
|
||||||
|
};
|
||||||
|
const client = new MemoryAppointmentClient();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const { id } = await client.addAppointment(appointment);
|
||||||
|
const result = await client.getAppointment(id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result!.name).toStrictEqual(appointment.name);
|
||||||
|
expect(result!.email).toStrictEqual(appointment.email);
|
||||||
|
expect(result!.phoneNumber).toStrictEqual(appointment.phoneNumber);
|
||||||
|
expect(result!.startTime).toStrictEqual(appointment.startTime);
|
||||||
|
expect(result!.endTime).toStrictEqual(appointment.endTime);
|
||||||
|
expect(result!.date).toStrictEqual(appointment.date);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw if appointment is overlapping with another appointment", async () => {
|
||||||
|
// Arrange
|
||||||
|
const client = new MemoryAppointmentClient();
|
||||||
|
const appointment: AppointmentEdit = {
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1),
|
||||||
|
endTime: new Date(2020, 1, 2),
|
||||||
|
date: new Date(2020, 1, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await client.addAppointment(appointment);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await expect(client.addAppointment(appointment)).rejects.toThrowError();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("updateAppointment", () => {
|
||||||
|
it("should update the appointment with new values", async () => {
|
||||||
|
// Arrange
|
||||||
|
const client = new MemoryAppointmentClient();
|
||||||
|
const appointmentNew: AppointmentEdit = {
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1),
|
||||||
|
endTime: new Date(2020, 1, 2),
|
||||||
|
date: new Date(2020, 1, 1),
|
||||||
|
};
|
||||||
|
const appointmentUpdate: AppointmentEdit = {
|
||||||
|
name: "updated",
|
||||||
|
email: "updated@test.se",
|
||||||
|
phoneNumber: "12345",
|
||||||
|
startTime: new Date(2020, 2, 1),
|
||||||
|
endTime: new Date(2020, 2, 2),
|
||||||
|
date: new Date(2020, 2, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const { id } = await client.addAppointment(appointmentNew);
|
||||||
|
await client.updateAppointment(id, appointmentUpdate);
|
||||||
|
const result = await client.getAppointment(id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result!.name).toStrictEqual(appointmentUpdate.name);
|
||||||
|
expect(result!.email).toStrictEqual(appointmentUpdate.email);
|
||||||
|
expect(result!.phoneNumber).toStrictEqual(appointmentUpdate.phoneNumber);
|
||||||
|
expect(result!.startTime).toStrictEqual(appointmentUpdate.startTime);
|
||||||
|
expect(result!.endTime).toStrictEqual(appointmentUpdate.endTime);
|
||||||
|
expect(result!.date).toStrictEqual(appointmentUpdate.date);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw if appointment is overlapping with another appointment", async () => {
|
||||||
|
// Arrange
|
||||||
|
const client = new MemoryAppointmentClient();
|
||||||
|
const appointmentNew: AppointmentEdit = {
|
||||||
|
name: "test",
|
||||||
|
email: "test@test.se",
|
||||||
|
phoneNumber: "123",
|
||||||
|
startTime: new Date(2020, 1, 1),
|
||||||
|
endTime: new Date(2020, 1, 2),
|
||||||
|
date: new Date(2020, 1, 1),
|
||||||
|
};
|
||||||
|
const appointmentUpdate: AppointmentEdit = {
|
||||||
|
name: "updated",
|
||||||
|
email: "updated@test.se",
|
||||||
|
phoneNumber: "12345",
|
||||||
|
startTime: new Date(2020, 2, 1),
|
||||||
|
endTime: new Date(2020, 2, 2),
|
||||||
|
date: new Date(2020, 2, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const { id } = await client.addAppointment(appointmentNew);
|
||||||
|
await client.addAppointment(appointmentUpdate);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await expect(client.updateAppointment(id, appointmentUpdate)).rejects.toThrowError();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
86
src/apis/appointment-client/memory-appointment-client.ts
Normal file
86
src/apis/appointment-client/memory-appointment-client.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import { checkConflict } from "./check-conflicts";
|
||||||
|
import {
|
||||||
|
IAppointmentClient,
|
||||||
|
AppointmentEdit,
|
||||||
|
Appointment,
|
||||||
|
ConflictResult,
|
||||||
|
ConflictError,
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
export class MemoryAppointmentClient implements IAppointmentClient {
|
||||||
|
private AppointmentStore: Appointment[] = [];
|
||||||
|
private idCounter = 0;
|
||||||
|
|
||||||
|
getAppointments = () => {
|
||||||
|
const promise = new Promise<Appointment[]>((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(Promise.resolve(this.AppointmentStore));
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
getAppointment = (id: string) => {
|
||||||
|
return Promise.resolve(
|
||||||
|
this.AppointmentStore.filter((apt) => apt.id === id)[0]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
updateAppointment = (id: string, appointment: AppointmentEdit) => {
|
||||||
|
const otherAppointments = this.AppointmentStore.filter((apt) => apt.id !== id)
|
||||||
|
const conflict = checkConflict(
|
||||||
|
appointment,
|
||||||
|
otherAppointments
|
||||||
|
);
|
||||||
|
if (conflict) {
|
||||||
|
return Promise.reject(new ConflictError({ type: "single", conflict }));
|
||||||
|
}
|
||||||
|
for (let i = 0; i < this.AppointmentStore.length; i++) {
|
||||||
|
const apt = this.AppointmentStore[i];
|
||||||
|
if (apt.id === id) {
|
||||||
|
this.AppointmentStore[i] = { id, ...appointment };
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
addAppointment = (appointment: AppointmentEdit) => {
|
||||||
|
const conflict = checkConflict(appointment, this.AppointmentStore);
|
||||||
|
if (conflict) {
|
||||||
|
return Promise.reject(new ConflictError({ type: "single", conflict }));
|
||||||
|
}
|
||||||
|
this.idCounter++;
|
||||||
|
const newAppointment = {
|
||||||
|
...appointment,
|
||||||
|
id: this.idCounter.toString(),
|
||||||
|
};
|
||||||
|
this.AppointmentStore.push(newAppointment);
|
||||||
|
return Promise.resolve(newAppointment);
|
||||||
|
};
|
||||||
|
|
||||||
|
importAppointments = (importApts: AppointmentEdit[]) => {
|
||||||
|
const promise = new Promise<void>((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const conflicts = importApts
|
||||||
|
.map((apt) => checkConflict(apt, this.AppointmentStore))
|
||||||
|
.filter((c) => c !== undefined) as ConflictResult[];
|
||||||
|
if (conflicts.length > 0) {
|
||||||
|
return reject(
|
||||||
|
new ConflictError({ type: "multiple", conflicts })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const newAppointments = importApts.map((apt) => {
|
||||||
|
this.idCounter++;
|
||||||
|
return {
|
||||||
|
...apt,
|
||||||
|
id: this.idCounter.toString(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
this.AppointmentStore = this.AppointmentStore.concat(newAppointments);
|
||||||
|
return resolve();
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
}
|
||||||
58
src/apis/appointment-client/types.ts
Normal file
58
src/apis/appointment-client/types.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
export interface Appointment {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
phoneNumber: string;
|
||||||
|
startTime: Date;
|
||||||
|
endTime: Date;
|
||||||
|
date: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AppointmentEdit = Omit<Appointment, "id">;
|
||||||
|
|
||||||
|
export interface IAppointmentClient {
|
||||||
|
getAppointments: () => Promise<Appointment[]>;
|
||||||
|
getAppointment: (id: string) => Promise<Appointment | undefined>;
|
||||||
|
updateAppointment: (
|
||||||
|
id: string,
|
||||||
|
appointment: AppointmentEdit
|
||||||
|
) => Promise<void>;
|
||||||
|
addAppointment: (appointment: AppointmentEdit) => Promise<Appointment>;
|
||||||
|
importAppointments: (appointment: AppointmentEdit[]) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConflictResult {
|
||||||
|
status: "SamePeriod" | "OverlapsWith" | "IntersectsWith";
|
||||||
|
appointment: Appointment;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Conflicts =
|
||||||
|
| {
|
||||||
|
type: "multiple";
|
||||||
|
conflicts: ConflictResult[];
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: "single";
|
||||||
|
conflict: ConflictResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class ConflictError extends Error {
|
||||||
|
public conflicts: Conflicts;
|
||||||
|
constructor(conflicts: Conflicts) {
|
||||||
|
if (conflicts.type === "single") {
|
||||||
|
super(
|
||||||
|
`Conflict of type ${
|
||||||
|
conflicts.conflict.status
|
||||||
|
} with appointment ${JSON.stringify(
|
||||||
|
conflicts.conflict.appointment,
|
||||||
|
undefined,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
super("Multiple conflicts detected. See ConflictError.conflicts");
|
||||||
|
}
|
||||||
|
this.name = "ConflictError";
|
||||||
|
this.conflicts = conflicts;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/apis/telenor-client/index.tsx
Normal file
12
src/apis/telenor-client/index.tsx
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import React, { useContext } from "react";
|
||||||
|
import { AppConfig } from "../../app-config";
|
||||||
|
import { TelenorClient } from "./telenor-client";
|
||||||
|
import { ITelenorClient } from "./types";
|
||||||
|
export * from "./types";
|
||||||
|
export * from "./telenor-client";
|
||||||
|
|
||||||
|
export const TelenorClientContext = React.createContext<ITelenorClient>(
|
||||||
|
new TelenorClient(AppConfig)
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useTelenorClient = () => useContext(TelenorClientContext);
|
||||||
27
src/apis/telenor-client/telenor-client.ts
Normal file
27
src/apis/telenor-client/telenor-client.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { IAppConfig } from "../../app-config";
|
||||||
|
import { ITelenorClient } from "./types";
|
||||||
|
|
||||||
|
export class TelenorClient implements ITelenorClient {
|
||||||
|
constructor(private appConfig: IAppConfig) {}
|
||||||
|
|
||||||
|
getAppointments = async () => {
|
||||||
|
const response = await fetch(
|
||||||
|
`${this.appConfig.telenorApiUrl}/api/Appointments`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
accept: "application/json",
|
||||||
|
key: this.appConfig.telenorApiKey,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const json = await response.json();
|
||||||
|
const mapped = json.map((apt: any) => ({
|
||||||
|
...apt,
|
||||||
|
endTime: new Date(apt.endTime),
|
||||||
|
startTime: new Date(apt.startTime),
|
||||||
|
date: new Date(apt.date),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return mapped;
|
||||||
|
};
|
||||||
|
}
|
||||||
5
src/apis/telenor-client/types.ts
Normal file
5
src/apis/telenor-client/types.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import {AppointmentEdit} from "../appointment-client";
|
||||||
|
|
||||||
|
export interface ITelenorClient {
|
||||||
|
getAppointments: () => Promise<AppointmentEdit[]>;
|
||||||
|
};
|
||||||
9
src/app-config.ts
Normal file
9
src/app-config.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export interface IAppConfig {
|
||||||
|
telenorApiUrl: string,
|
||||||
|
telenorApiKey: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppConfig: IAppConfig = {
|
||||||
|
telenorApiUrl: '/Prod',
|
||||||
|
telenorApiKey: 'E9658970-8A7E-4821-9335-6DCEAA3AC061'
|
||||||
|
}
|
||||||
95
src/components/appointment-form.tsx
Normal file
95
src/components/appointment-form.tsx
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Formik, Form, Field, ErrorMessage } from "formik";
|
||||||
|
import { Appointment } from "../apis/appointment-client";
|
||||||
|
import { Heading } from "./styled-components/heading";
|
||||||
|
import { Button } from "./styled-components/button";
|
||||||
|
import { Stack } from "./styled-components/page-grid";
|
||||||
|
import { Label } from "./styled-components/label";
|
||||||
|
import { TimePickerField } from "./time-picker-field";
|
||||||
|
|
||||||
|
export interface AppointmentFormProps {
|
||||||
|
onSubmit: (appointment: Appointment) => Promise<void>;
|
||||||
|
initialValues: Partial<Appointment>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppointmentForm = (props: AppointmentFormProps) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Heading>Add a new appointment</Heading>
|
||||||
|
|
||||||
|
<Formik<Appointment>
|
||||||
|
initialValues={props.initialValues as Appointment}
|
||||||
|
validate={validationFunction}
|
||||||
|
onSubmit={props.onSubmit}
|
||||||
|
>
|
||||||
|
{({ isSubmitting, values, isValid }) => (
|
||||||
|
<Form>
|
||||||
|
<Stack>
|
||||||
|
<Label>
|
||||||
|
Date:{" "}
|
||||||
|
<pre>
|
||||||
|
{values.date.getFullYear()}-{values.date.getMonth()}-
|
||||||
|
{values.date.getDate()}
|
||||||
|
</pre>
|
||||||
|
</Label>
|
||||||
|
<Label>
|
||||||
|
Start time:
|
||||||
|
<TimePickerField name="startTime" />
|
||||||
|
<ErrorMessage name="startTime" component="div" />
|
||||||
|
</Label>
|
||||||
|
<Label>
|
||||||
|
End time:
|
||||||
|
<TimePickerField name="endTime" />
|
||||||
|
<ErrorMessage name="endTime" component="div" />
|
||||||
|
</Label>
|
||||||
|
<Label>
|
||||||
|
Name:
|
||||||
|
<Field type="text" name="name" />
|
||||||
|
</Label>
|
||||||
|
<ErrorMessage name="name" component="div" />
|
||||||
|
<Label>
|
||||||
|
Email:
|
||||||
|
<Field type="email" name="email" />
|
||||||
|
</Label>
|
||||||
|
<ErrorMessage name="email" component="div" />
|
||||||
|
<Button
|
||||||
|
className="primary"
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting || !isValid}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const validationFunction = (values: Appointment) => {
|
||||||
|
const errors: any = {};
|
||||||
|
if (!values.email) {
|
||||||
|
errors.email = "Required";
|
||||||
|
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {
|
||||||
|
errors.email = "Invalid email address";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!values.date) {
|
||||||
|
errors.date = "Required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!values.startTime) {
|
||||||
|
errors.startTime = "Required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!values.endTime) {
|
||||||
|
errors.endTime = "Required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!values.date) {
|
||||||
|
errors.date = "Required";
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
};
|
||||||
92
src/components/appointments-overview.tsx
Normal file
92
src/components/appointments-overview.tsx
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import React, { useMemo } from "react";
|
||||||
|
import { Appointment } from "../apis/appointment-client";
|
||||||
|
import { useMonthSelection } from "../hooks/use-month-selection";
|
||||||
|
import {
|
||||||
|
CalendarHeader,
|
||||||
|
CalendarWrapper,
|
||||||
|
Day,
|
||||||
|
} from "./styled-components/calendar";
|
||||||
|
import { Button } from "./styled-components/button";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
export interface AppointmentsOverviewProps {
|
||||||
|
appointments: Appointment[];
|
||||||
|
addAppointment: (date: Date) => void;
|
||||||
|
updateAppointment: (appointment: Appointment) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppointmentsOverview = (props: AppointmentsOverviewProps) => {
|
||||||
|
const { year, month, days, nextMonth, prevMonth } = useMonthSelection(
|
||||||
|
new Date()
|
||||||
|
);
|
||||||
|
|
||||||
|
const monthName = useMemo(() => monthNames[month], [month]);
|
||||||
|
const daysWithAppointments = useMemo(
|
||||||
|
() => days.map((d) => mapToAppointments(d, props.appointments)),
|
||||||
|
[days, props.appointments]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<CalendarHeader>
|
||||||
|
<Button className="thin" onClick={prevMonth}>
|
||||||
|
{"<"}
|
||||||
|
</Button>
|
||||||
|
<div>
|
||||||
|
{monthName} - {year}
|
||||||
|
</div>
|
||||||
|
<Button className="thin" onClick={nextMonth}>
|
||||||
|
{">"}
|
||||||
|
</Button>
|
||||||
|
</CalendarHeader>
|
||||||
|
<CalendarWrapper>
|
||||||
|
{daysWithAppointments.map(({ day, appointments }, i) => (
|
||||||
|
<Day
|
||||||
|
key={i}
|
||||||
|
day={day}
|
||||||
|
onClick={() => props.addAppointment(day)}
|
||||||
|
appointments={appointments}
|
||||||
|
updateAppointment={props.updateAppointment}
|
||||||
|
></Day>
|
||||||
|
))}
|
||||||
|
</CalendarWrapper>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
max-width: max-content;
|
||||||
|
min-width: min-content;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const mapToAppointments = (
|
||||||
|
day: Date,
|
||||||
|
appointments: Appointment[]
|
||||||
|
): { day: Date; appointments: Appointment[] } => {
|
||||||
|
const appointmentsForDay = appointments.filter((apt) => {
|
||||||
|
return (
|
||||||
|
apt.date.getDate() === day.getDate() &&
|
||||||
|
apt.date.getMonth() === day.getMonth() &&
|
||||||
|
apt.date.getFullYear() === day.getFullYear()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
day,
|
||||||
|
appointments: appointmentsForDay,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const monthNames = [
|
||||||
|
"January",
|
||||||
|
"February",
|
||||||
|
"March",
|
||||||
|
"April",
|
||||||
|
"May",
|
||||||
|
"June",
|
||||||
|
"July",
|
||||||
|
"August",
|
||||||
|
"September",
|
||||||
|
"October",
|
||||||
|
"November",
|
||||||
|
"December",
|
||||||
|
];
|
||||||
169
src/components/appointments-page.tsx
Normal file
169
src/components/appointments-page.tsx
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
import React, { useEffect, useCallback, useState, useMemo } from "react";
|
||||||
|
import {
|
||||||
|
Appointment,
|
||||||
|
useAppointmentClient,
|
||||||
|
} from "../apis/appointment-client";
|
||||||
|
import { useTelenorClient } from "../apis/telenor-client";
|
||||||
|
import { useEndpoint } from "../hooks/use-endpoint";
|
||||||
|
import { AppointmentsOverview } from "./appointments-overview";
|
||||||
|
import { Spinner } from "./spinner";
|
||||||
|
import { Button } from "./styled-components/button";
|
||||||
|
import { Heading } from "./styled-components/heading";
|
||||||
|
import { AppointmentForm } from "./appointment-form";
|
||||||
|
import {
|
||||||
|
Header,
|
||||||
|
Main,
|
||||||
|
PageGrid,
|
||||||
|
Sidebar,
|
||||||
|
Stack,
|
||||||
|
} from "./styled-components/page-grid";
|
||||||
|
import Modal from "react-modal";
|
||||||
|
import { useBoolean } from "../hooks/use-boolean";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To anyeone reading: This file is what I am least proud of in the project.
|
||||||
|
* I should have gone with redux from the start.
|
||||||
|
* */
|
||||||
|
export const AppointmentsPage = () => {
|
||||||
|
///
|
||||||
|
// Initiate clients
|
||||||
|
const telenorClient = useTelenorClient();
|
||||||
|
const client = useAppointmentClient();
|
||||||
|
const {
|
||||||
|
endpoint: getAppointmentsEp,
|
||||||
|
loading: loadingAppointments,
|
||||||
|
result: appointments,
|
||||||
|
} = useEndpoint(client.getAppointments, []);
|
||||||
|
|
||||||
|
const {
|
||||||
|
endpoint: addAppointmentEp,
|
||||||
|
error: addAppointmentError,
|
||||||
|
} = useEndpoint(client.addAppointment, undefined);
|
||||||
|
|
||||||
|
const {
|
||||||
|
endpoint: updateAppointmentEp,
|
||||||
|
error: updateAppointmentError,
|
||||||
|
} = useEndpoint(client.updateAppointment, undefined);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Init import logic
|
||||||
|
const [importing, setImporting] = useState(false);
|
||||||
|
const [importError, setImportError] = useState<undefined|Error>();
|
||||||
|
const handleImport = useCallback(async () => {
|
||||||
|
setImporting(true);
|
||||||
|
try {
|
||||||
|
const telenorApts = await telenorClient.getAppointments();
|
||||||
|
await client.importAppointments(telenorApts);
|
||||||
|
await getAppointmentsEp();
|
||||||
|
} catch (err) {
|
||||||
|
setImportError(err);
|
||||||
|
}
|
||||||
|
setImporting(false);
|
||||||
|
}, [setImportError, setImporting, client, telenorClient, getAppointmentsEp]);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Init modal variables and functions
|
||||||
|
const [modalIsOpen, openModal, closeModal] = useBoolean();
|
||||||
|
const [isAddIntent, setAddIntent, setUpdateIntent] = useBoolean();
|
||||||
|
const [presetAppointment, setPresetAppointment] = useState({});
|
||||||
|
|
||||||
|
const handleSubmitAppointment = useCallback(
|
||||||
|
async (appointment: Appointment) => {
|
||||||
|
closeModal();
|
||||||
|
await addAppointmentEp(appointment);
|
||||||
|
await getAppointmentsEp();
|
||||||
|
},
|
||||||
|
[getAppointmentsEp, addAppointmentEp, closeModal]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSubmitAppointmentUpdate = useCallback(
|
||||||
|
async (appointment: Appointment) => {
|
||||||
|
closeModal();
|
||||||
|
await updateAppointmentEp(appointment.id, appointment);
|
||||||
|
await getAppointmentsEp();
|
||||||
|
},
|
||||||
|
[getAppointmentsEp, updateAppointmentEp, closeModal]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOpenAddAppointmentForm = useCallback(
|
||||||
|
(date: Date) => {
|
||||||
|
setPresetAppointment({ date: date });
|
||||||
|
setAddIntent();
|
||||||
|
openModal();
|
||||||
|
},
|
||||||
|
[setPresetAppointment, openModal, setAddIntent]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOpenEditAppointmentForm = useCallback(
|
||||||
|
(appointment: Appointment) => {
|
||||||
|
setPresetAppointment(appointment);
|
||||||
|
setUpdateIntent();
|
||||||
|
openModal();
|
||||||
|
},
|
||||||
|
[setPresetAppointment, openModal, setUpdateIntent]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getAppointmentsEp();
|
||||||
|
}, [getAppointmentsEp]);
|
||||||
|
|
||||||
|
// Init variables for simpler rendering
|
||||||
|
const showSpinner = useMemo(() => importing || loadingAppointments, [
|
||||||
|
importing,
|
||||||
|
loadingAppointments,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageGrid>
|
||||||
|
<Header>
|
||||||
|
<Heading>Appointments</Heading>
|
||||||
|
</Header>
|
||||||
|
<Main>
|
||||||
|
{!showSpinner && (
|
||||||
|
<AppointmentsOverview
|
||||||
|
appointments={appointments}
|
||||||
|
addAppointment={handleOpenAddAppointmentForm}
|
||||||
|
updateAppointment={handleOpenEditAppointmentForm}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Spinner visible={showSpinner} />
|
||||||
|
</Main>
|
||||||
|
<Sidebar>
|
||||||
|
<Stack>
|
||||||
|
<Button className="primary" onClick={handleImport}>
|
||||||
|
Import appointments
|
||||||
|
</Button>
|
||||||
|
<Button onClick={getAppointmentsEp}>Refresh</Button>
|
||||||
|
{importing && "Importing ..."}
|
||||||
|
{addAppointmentError && addAppointmentError.toString()}
|
||||||
|
{updateAppointmentError && updateAppointmentError.toString()}
|
||||||
|
{importError && importError.toString()}
|
||||||
|
</Stack>
|
||||||
|
</Sidebar>
|
||||||
|
<Modal
|
||||||
|
isOpen={modalIsOpen}
|
||||||
|
onRequestClose={closeModal}
|
||||||
|
style={customStyles}
|
||||||
|
ariaHideApp={false}
|
||||||
|
>
|
||||||
|
<AppointmentForm
|
||||||
|
initialValues={presetAppointment}
|
||||||
|
onSubmit={isAddIntent ? handleSubmitAppointment : handleSubmitAppointmentUpdate}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
</PageGrid>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const customStyles = {
|
||||||
|
content: {
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
right: "auto",
|
||||||
|
bottom: "auto",
|
||||||
|
marginRight: "-50%",
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
width: "30rem",
|
||||||
|
overflow: "inherit",
|
||||||
|
},
|
||||||
|
};
|
||||||
18
src/components/date-picker-field.tsx
Normal file
18
src/components/date-picker-field.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useField, useFormikContext } from "formik";
|
||||||
|
import DatePicker from "react-datepicker";
|
||||||
|
|
||||||
|
export const DatePickerField = ({ ...props }) => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const [field] = useField(props as any);
|
||||||
|
return (
|
||||||
|
<DatePicker
|
||||||
|
{...field}
|
||||||
|
{...props}
|
||||||
|
selected={(field.value && new Date(field.value)) || null}
|
||||||
|
onChange={(val) => {
|
||||||
|
setFieldValue(field.name, val);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
19
src/components/spinner.tsx
Normal file
19
src/components/spinner.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import Loader from "react-loader-spinner";
|
||||||
|
import React from "react";
|
||||||
|
import styled, {useTheme} from "styled-components";
|
||||||
|
|
||||||
|
export const Spinner = (props: { visible: boolean }) => {
|
||||||
|
const theme = useTheme() as any;
|
||||||
|
return (
|
||||||
|
<StyledSpinner
|
||||||
|
visible={props.visible}
|
||||||
|
type="Puff"
|
||||||
|
color={theme.colors.primary}
|
||||||
|
height={100}
|
||||||
|
width={100}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledSpinner = styled(Loader)`
|
||||||
|
`;
|
||||||
35
src/components/styled-components/button.tsx
Normal file
35
src/components/styled-components/button.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
export const Button = styled.button`
|
||||||
|
padding: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 2px solid ${({theme, disabled}) => !disabled ? theme.colors.primary : theme.colors.lightGray};
|
||||||
|
color: ${({theme, disabled}) => !disabled ? theme.colors.primary : theme.colors.lightGray};
|
||||||
|
font-size: 1rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${({ theme }) => theme.colors.secondary};
|
||||||
|
}
|
||||||
|
&.small {
|
||||||
|
width: inherit;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.primary {
|
||||||
|
color: ${({theme}) => theme.colors.white};
|
||||||
|
background-color: ${({theme, disabled}) => !disabled ? theme.colors.primary : theme.colors.lightGray};
|
||||||
|
&:hover {
|
||||||
|
background-color: ${({ theme }) => theme.colors.secondary};
|
||||||
|
color: ${({theme}) => theme.colors.primary};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.thin {
|
||||||
|
padding: 1px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`;
|
||||||
90
src/components/styled-components/calendar.tsx
Normal file
90
src/components/styled-components/calendar.tsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import React, { useCallback, useMemo } from "react";
|
||||||
|
import { Appointment } from "../../apis/appointment-client";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
export interface DayProps {
|
||||||
|
day: Date;
|
||||||
|
appointments: Appointment[];
|
||||||
|
onClick: () => void;
|
||||||
|
updateAppointment: (appointment: Appointment) => void;
|
||||||
|
}
|
||||||
|
export const Day = (props: DayProps) => {
|
||||||
|
return (
|
||||||
|
<StyledDay onClick={props.onClick}>
|
||||||
|
<DayNumber>{props.day.getDate()}</DayNumber>
|
||||||
|
{props.appointments.map((apt, i) => (
|
||||||
|
<AptLine key={i} appointment={apt} onClick={props.updateAppointment}/>
|
||||||
|
))}
|
||||||
|
</StyledDay>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const AptLine = (props: { appointment: Appointment, onClick: (appointment: Appointment) => void}) => {
|
||||||
|
const startTime = props.appointment.startTime;
|
||||||
|
const endTime = props.appointment.endTime;
|
||||||
|
const startTimeStr = useMemo(
|
||||||
|
() => `${startTime.getHours()}:${startTime.getMinutes()}`,
|
||||||
|
[startTime]
|
||||||
|
);
|
||||||
|
const endTimeStr = useMemo(
|
||||||
|
() => `${endTime.getHours()}:${endTime.getMinutes()}`,
|
||||||
|
[endTime]
|
||||||
|
);
|
||||||
|
const handleClick = useCallback((e: any) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
props.onClick(props.appointment);
|
||||||
|
}, [props]);
|
||||||
|
return (
|
||||||
|
<AptLineWrapper onClick={handleClick}>
|
||||||
|
{props.appointment.name} {startTimeStr} - {endTimeStr}
|
||||||
|
</AptLineWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cellWidth = 7;
|
||||||
|
const cellHeight = 8;
|
||||||
|
|
||||||
|
const AptLineWrapper = styled.div`
|
||||||
|
background-color: ${({ theme }) => theme.colors.blue2};
|
||||||
|
font-size: ${({ theme }) => theme.fonts.tiny};
|
||||||
|
color: ${({ theme }) => theme.colors.white};
|
||||||
|
margin-top: 2px;
|
||||||
|
padding: 1px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${({ theme }) => theme.colors.primary};
|
||||||
|
color: ${({ theme }) => theme.colors.white};
|
||||||
|
outline: 1px solid ${({ theme }) => theme.colors.blue1};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DayNumber = styled.div`
|
||||||
|
color: ${({ theme }) => theme.colors.blue1};
|
||||||
|
`;
|
||||||
|
const StyledDay = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: ${({ theme }) => theme.colors.lightGray};
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${({ theme }) => theme.colors.secondary};
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CalendarHeader = styled.div`
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 5rem auto 5rem;
|
||||||
|
justify-items: center;
|
||||||
|
margin-bottom: ${({ theme }) => theme.gaps.tiny};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CalendarWrapper = styled.div`
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(7, ${cellWidth}rem);
|
||||||
|
grid-template-rows: repeat(5, ${cellHeight}rem);
|
||||||
|
margin: 0 auto;
|
||||||
|
grid-gap: 2px;
|
||||||
|
column-gap: 2px;
|
||||||
|
`;
|
||||||
6
src/components/styled-components/heading.ts
Normal file
6
src/components/styled-components/heading.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
export const Heading = styled.h1`
|
||||||
|
font-size: ${({theme}) => theme.fonts.header1};
|
||||||
|
margin-bottom: ${({theme}) => theme.gaps.tiny};
|
||||||
|
`;
|
||||||
6
src/components/styled-components/label.ts
Normal file
6
src/components/styled-components/label.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
export const Label = styled.label`
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
`;
|
||||||
38
src/components/styled-components/page-grid.tsx
Normal file
38
src/components/styled-components/page-grid.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
export const PageGrid = styled.div`
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto auto auto;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
grid-template-areas: "header header header header" "main main main sidebar" "footer footer footer footer";
|
||||||
|
row-gap: ${({theme}) => theme.gaps.small};
|
||||||
|
column-gap: ${({theme}) => theme.gaps.small};
|
||||||
|
padding: ${({theme}) => theme.gaps.small};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Header = styled.div`
|
||||||
|
grid-area: header;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Main = styled.div`
|
||||||
|
min-width: 675px;
|
||||||
|
grid-area: main;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Sidebar = styled.div`
|
||||||
|
grid-area: sidebar;
|
||||||
|
max-width: 260px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Stack = styled.div`
|
||||||
|
grid-template-columns: auto;
|
||||||
|
row-gap: ${({theme}) => theme.gaps.small};
|
||||||
|
display: grid;
|
||||||
|
align-items: start;
|
||||||
|
grid-template-rows: auto auto 1fr;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Footer = styled.div`
|
||||||
|
grid-area: footer;
|
||||||
|
`;
|
||||||
|
|
||||||
29
src/components/time-picker-field.tsx
Normal file
29
src/components/time-picker-field.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useField, useFormikContext } from "formik";
|
||||||
|
import TimePicker, { TimePickerValue } from "react-time-picker";
|
||||||
|
|
||||||
|
export const TimePickerField = ({ ...props }) => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const [field] = useField(props as any);
|
||||||
|
return (
|
||||||
|
<TimePicker
|
||||||
|
{...field}
|
||||||
|
{...props}
|
||||||
|
value={asTimeStr(field.value)}
|
||||||
|
onChange={(val) => {
|
||||||
|
setFieldValue(field.name, asDate(val));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const asTimeStr = (date: Date | undefined): TimePickerValue | "" => {
|
||||||
|
if (date === undefined)
|
||||||
|
return "";
|
||||||
|
return `${date.getHours()}:${date.getMinutes()}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const asDate = (time: TimePickerValue): Date => {
|
||||||
|
const [hours, minutes] = time.toString().split(":");
|
||||||
|
return new Date(0, 0, 0, Number(hours), Number(minutes));
|
||||||
|
};
|
||||||
39
src/context/appointments-page-context.tsx
Normal file
39
src/context/appointments-page-context.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// I should have gone with redux from the start
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { Appointment } from "../apis/appointment-client";
|
||||||
|
|
||||||
|
interface IAppointmentPageContext {
|
||||||
|
store: {
|
||||||
|
appointmentForm: AppointmentFormState;
|
||||||
|
};
|
||||||
|
updateAppointment: (appointment: Appointment) => void;
|
||||||
|
addAppointment: (day: Date) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type AppointmentFormState =
|
||||||
|
| {
|
||||||
|
intent: "update";
|
||||||
|
appointment: Appointment;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
intent: "add";
|
||||||
|
date: Date;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
intent: "closed";
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AppointmentPageContext = React.createContext<IAppointmentPageContext>(
|
||||||
|
{
|
||||||
|
store: {
|
||||||
|
appointmentForm: {
|
||||||
|
intent: "closed",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updateAppointment: () => {},
|
||||||
|
addAppointment: () => {},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useAppointmentPageContext = () => React.useContext(AppointmentPageContext);
|
||||||
8
src/globalStyle.ts
Normal file
8
src/globalStyle.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { createGlobalStyle } from "styled-components";
|
||||||
|
|
||||||
|
export const GlobalStyle = createGlobalStyle<any>`
|
||||||
|
body {
|
||||||
|
font-family: Open-Sans, Helvetica, Sans-Serif;
|
||||||
|
color: ${({theme}) => theme.colors.primary};
|
||||||
|
}
|
||||||
|
`;
|
||||||
20
src/helpers/date-helpers.ts
Normal file
20
src/helpers/date-helpers.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { AppointmentEdit } from "../apis/appointment-client";
|
||||||
|
|
||||||
|
export const normalizeTime = (time: Date): Date => {
|
||||||
|
return new Date(0, 0, 0, time.getHours(), time.getMinutes());
|
||||||
|
};
|
||||||
|
|
||||||
|
export const normalizeDate = (date: Date): Date => {
|
||||||
|
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||||
|
};
|
||||||
|
|
||||||
|
export const normalizeAppointmentTime = (
|
||||||
|
apt: AppointmentEdit
|
||||||
|
): AppointmentEdit => {
|
||||||
|
return {
|
||||||
|
...apt,
|
||||||
|
startTime: normalizeTime(apt.startTime),
|
||||||
|
endTime: normalizeTime(apt.endTime),
|
||||||
|
date: normalizeDate(apt.date),
|
||||||
|
};
|
||||||
|
};
|
||||||
8
src/hooks/use-boolean.ts
Normal file
8
src/hooks/use-boolean.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import {useCallback, useState} from "react";
|
||||||
|
|
||||||
|
export const useBoolean = (initialValue: boolean = false): [boolean, () => void, () => void] => {
|
||||||
|
const [value, setValue] = useState(initialValue);
|
||||||
|
const setTrue = useCallback(() => setValue(true), [setValue]);
|
||||||
|
const setFalse = useCallback(() => setValue(false), [setValue]);
|
||||||
|
return [value, setTrue, setFalse];
|
||||||
|
}
|
||||||
37
src/hooks/use-endpoint.ts
Normal file
37
src/hooks/use-endpoint.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { useState, useCallback } from "react";
|
||||||
|
|
||||||
|
export const useEndpoint = <T extends unknown>(
|
||||||
|
endpoint: (...args: any) => Promise<T>,
|
||||||
|
defaultValue: T
|
||||||
|
): {
|
||||||
|
endpoint: (...args: any) => void;
|
||||||
|
loading: boolean;
|
||||||
|
result: T;
|
||||||
|
error: Error | undefined;
|
||||||
|
} => {
|
||||||
|
const [result, setResult] = useState<T>(defaultValue);
|
||||||
|
const [error, setError] = useState<Error | undefined>(undefined);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const callEndpoint = useCallback(
|
||||||
|
async (...args) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const result = await endpoint(...args);
|
||||||
|
setResult(result);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Endpoint threw error', err);
|
||||||
|
setError(err);
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
},
|
||||||
|
[endpoint, setResult, setLoading]
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
endpoint: callEndpoint,
|
||||||
|
loading,
|
||||||
|
result,
|
||||||
|
error
|
||||||
|
};
|
||||||
|
};
|
||||||
51
src/hooks/use-month-selection.ts
Normal file
51
src/hooks/use-month-selection.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { useCallback, useMemo, useState } from "react";
|
||||||
|
|
||||||
|
export const useMonthSelection = (
|
||||||
|
initialDate: Date
|
||||||
|
): {
|
||||||
|
year: number;
|
||||||
|
month: number;
|
||||||
|
days: Date[];
|
||||||
|
nextMonth: () => void;
|
||||||
|
prevMonth: () => void;
|
||||||
|
} => {
|
||||||
|
const [month, setMonth] = useState(initialDate.getMonth());
|
||||||
|
const [year, setYear] = useState(initialDate.getFullYear());
|
||||||
|
const days = useMemo(() => getDaysInMonthUTC(month, year), [month, year]);
|
||||||
|
|
||||||
|
const nextMonth = useCallback(() => {
|
||||||
|
if (month === 11) {
|
||||||
|
setYear(year + 1);
|
||||||
|
setMonth(0);
|
||||||
|
} else {
|
||||||
|
setMonth(month + 1);
|
||||||
|
}
|
||||||
|
}, [setYear, setMonth, month, year]);
|
||||||
|
|
||||||
|
const prevMonth = useCallback(() => {
|
||||||
|
if (month === 0) {
|
||||||
|
setYear(year - 1);
|
||||||
|
setMonth(11);
|
||||||
|
} else {
|
||||||
|
setMonth(month - 1);
|
||||||
|
}
|
||||||
|
}, [setYear, setMonth, month, year]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
year,
|
||||||
|
month,
|
||||||
|
days,
|
||||||
|
nextMonth,
|
||||||
|
prevMonth,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDaysInMonthUTC = (month: number, year: number): Date[] => {
|
||||||
|
var date = new Date(Date.UTC(year, month, 1));
|
||||||
|
var days = [];
|
||||||
|
while (date.getUTCMonth() === month) {
|
||||||
|
days.push(new Date(date));
|
||||||
|
date.setUTCDate(date.getUTCDate() + 1);
|
||||||
|
}
|
||||||
|
return days;
|
||||||
|
};
|
||||||
@@ -1,14 +1,32 @@
|
|||||||
import React from 'react';
|
import React from "react";
|
||||||
import ReactDOM from 'react-dom';
|
import "react-loader-spinner/dist/loader/css/react-spinner-loader.css";
|
||||||
import './index.css';
|
import "react-datepicker/dist/react-datepicker.css";
|
||||||
import App from './App';
|
import ReactDOM from "react-dom";
|
||||||
import reportWebVitals from './reportWebVitals';
|
import "./reset.css";
|
||||||
|
import App from "./App";
|
||||||
|
import reportWebVitals from "./reportWebVitals";
|
||||||
|
import {
|
||||||
|
AppointmentClientContext,
|
||||||
|
MemoryAppointmentClient,
|
||||||
|
} from "./apis/appointment-client";
|
||||||
|
import { TelenorClient, TelenorClientContext } from "./apis/telenor-client";
|
||||||
|
import { AppConfig } from "./app-config";
|
||||||
|
import { GlobalStyle } from "./globalStyle";
|
||||||
|
import { ThemeProvider } from "styled-components";
|
||||||
|
import theme from "./theme";
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<AppointmentClientContext.Provider value={new MemoryAppointmentClient()}>
|
||||||
|
<TelenorClientContext.Provider value={new TelenorClient(AppConfig)}>
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
|
<GlobalStyle />
|
||||||
|
<App />
|
||||||
|
</ThemeProvider>
|
||||||
|
</TelenorClientContext.Provider>
|
||||||
|
</AppointmentClientContext.Provider>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById("root")
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
// If you want to start measuring performance in your app, pass a function
|
||||||
|
|||||||
48
src/reset.css
Normal file
48
src/reset.css
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* http://meyerweb.com/eric/tools/css/reset/
|
||||||
|
v2.0 | 20110126
|
||||||
|
License: none (public domain)
|
||||||
|
*/
|
||||||
|
|
||||||
|
html, body, div, span, applet, object, iframe,
|
||||||
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||||
|
a, abbr, acronym, address, big, cite, code,
|
||||||
|
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||||
|
small, strike, strong, sub, sup, tt, var,
|
||||||
|
b, u, i, center,
|
||||||
|
dl, dt, dd, ol, ul, li,
|
||||||
|
fieldset, form, label, legend,
|
||||||
|
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||||
|
article, aside, canvas, details, embed,
|
||||||
|
figure, figcaption, footer, header, hgroup,
|
||||||
|
menu, nav, output, ruby, section, summary,
|
||||||
|
time, mark, audio, video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
article, aside, details, figcaption, figure,
|
||||||
|
footer, header, hgroup, menu, nav, section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
blockquote, q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
blockquote:before, blockquote:after,
|
||||||
|
q:before, q:after {
|
||||||
|
content: '';
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
22
src/theme.ts
Normal file
22
src/theme.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const theme = {
|
||||||
|
colors: {
|
||||||
|
primary: "#2B3A67",
|
||||||
|
secondary: "#FFC482",
|
||||||
|
blue1: "#496A81",
|
||||||
|
blue2: "#66999B",
|
||||||
|
sage: "#B3AF8F",
|
||||||
|
white: "#FFF",
|
||||||
|
lightGray: "lightgray",
|
||||||
|
},
|
||||||
|
gaps: {
|
||||||
|
small: "1rem",
|
||||||
|
tiny: "0.5rem",
|
||||||
|
},
|
||||||
|
fonts: {
|
||||||
|
header1: "2rem",
|
||||||
|
normal: "1rem",
|
||||||
|
tiny: "0.6rem",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default theme;
|
||||||
390
yarn.lock
390
yarn.lock
@@ -80,7 +80,16 @@
|
|||||||
jsesc "^2.5.1"
|
jsesc "^2.5.1"
|
||||||
source-map "^0.5.0"
|
source-map "^0.5.0"
|
||||||
|
|
||||||
"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13":
|
"@babel/generator@^7.13.16":
|
||||||
|
version "7.13.16"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.16.tgz#0befc287031a201d84cdfc173b46b320ae472d14"
|
||||||
|
integrity sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.13.16"
|
||||||
|
jsesc "^2.5.1"
|
||||||
|
source-map "^0.5.0"
|
||||||
|
|
||||||
|
"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13":
|
||||||
version "7.12.13"
|
version "7.12.13"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab"
|
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab"
|
||||||
integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==
|
integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==
|
||||||
@@ -278,6 +287,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.17.tgz#bc85d2d47db38094e5bb268fc761716e7d693848"
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.17.tgz#bc85d2d47db38094e5bb268fc761716e7d693848"
|
||||||
integrity sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==
|
integrity sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==
|
||||||
|
|
||||||
|
"@babel/parser@^7.13.16":
|
||||||
|
version "7.13.16"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.16.tgz#0f18179b0448e6939b1f3f5c4c355a3a9bcdfd37"
|
||||||
|
integrity sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==
|
||||||
|
|
||||||
"@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.12.13":
|
"@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.12.13":
|
||||||
version "7.12.13"
|
version "7.12.13"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz#d1c6d841802ffb88c64a2413e311f7345b9e66b5"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz#d1c6d841802ffb88c64a2413e311f7345b9e66b5"
|
||||||
@@ -1091,6 +1105,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.13.4"
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
|
"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.9.2":
|
||||||
|
version "7.13.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec"
|
||||||
|
integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
|
"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
|
||||||
version "7.12.18"
|
version "7.12.18"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.18.tgz#af137bd7e7d9705a412b3caaf991fe6aaa97831b"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.18.tgz#af137bd7e7d9705a412b3caaf991fe6aaa97831b"
|
||||||
@@ -1098,13 +1119,6 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.13.4"
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@babel/runtime@^7.12.5", "@babel/runtime@^7.9.2":
|
|
||||||
version "7.13.17"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec"
|
|
||||||
integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==
|
|
||||||
dependencies:
|
|
||||||
regenerator-runtime "^0.13.4"
|
|
||||||
|
|
||||||
"@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3":
|
"@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3":
|
||||||
version "7.12.13"
|
version "7.12.13"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
|
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
|
||||||
@@ -1129,6 +1143,20 @@
|
|||||||
globals "^11.1.0"
|
globals "^11.1.0"
|
||||||
lodash "^4.17.19"
|
lodash "^4.17.19"
|
||||||
|
|
||||||
|
"@babel/traverse@^7.4.5":
|
||||||
|
version "7.13.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.17.tgz#c85415e0c7d50ac053d758baec98b28b2ecfeea3"
|
||||||
|
integrity sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.12.13"
|
||||||
|
"@babel/generator" "^7.13.16"
|
||||||
|
"@babel/helper-function-name" "^7.12.13"
|
||||||
|
"@babel/helper-split-export-declaration" "^7.12.13"
|
||||||
|
"@babel/parser" "^7.13.16"
|
||||||
|
"@babel/types" "^7.13.17"
|
||||||
|
debug "^4.1.0"
|
||||||
|
globals "^11.1.0"
|
||||||
|
|
||||||
"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.17", "@babel/types@^7.12.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
|
"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.17", "@babel/types@^7.12.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
|
||||||
version "7.12.17"
|
version "7.12.17"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.17.tgz#9d711eb807e0934c90b8b1ca0eb1f7230d150963"
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.17.tgz#9d711eb807e0934c90b8b1ca0eb1f7230d150963"
|
||||||
@@ -1138,6 +1166,14 @@
|
|||||||
lodash "^4.17.19"
|
lodash "^4.17.19"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@babel/types@^7.13.16", "@babel/types@^7.13.17":
|
||||||
|
version "7.13.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.17.tgz#48010a115c9fba7588b4437dd68c9469012b38b4"
|
||||||
|
integrity sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-validator-identifier" "^7.12.11"
|
||||||
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@bcoe/v8-coverage@^0.2.3":
|
"@bcoe/v8-coverage@^0.2.3":
|
||||||
version "0.2.3"
|
version "0.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
@@ -1161,6 +1197,28 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
|
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
|
||||||
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
|
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
|
||||||
|
|
||||||
|
"@emotion/is-prop-valid@^0.8.8":
|
||||||
|
version "0.8.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
|
||||||
|
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/memoize" "0.7.4"
|
||||||
|
|
||||||
|
"@emotion/memoize@0.7.4":
|
||||||
|
version "0.7.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
|
||||||
|
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
|
||||||
|
|
||||||
|
"@emotion/stylis@^0.8.4":
|
||||||
|
version "0.8.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
|
||||||
|
integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
|
||||||
|
|
||||||
|
"@emotion/unitless@^0.7.4":
|
||||||
|
version "0.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
|
||||||
|
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
|
||||||
|
|
||||||
"@eslint/eslintrc@^0.3.0":
|
"@eslint/eslintrc@^0.3.0":
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318"
|
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318"
|
||||||
@@ -1209,6 +1267,14 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@hapi/hoek" "^8.3.0"
|
"@hapi/hoek" "^8.3.0"
|
||||||
|
|
||||||
|
"@hypnosphi/create-react-context@^0.3.1":
|
||||||
|
version "0.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6"
|
||||||
|
integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==
|
||||||
|
dependencies:
|
||||||
|
gud "^1.0.0"
|
||||||
|
warning "^4.0.3"
|
||||||
|
|
||||||
"@istanbuljs/load-nyc-config@^1.0.0":
|
"@istanbuljs/load-nyc-config@^1.0.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
||||||
@@ -1709,6 +1775,14 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/hoist-non-react-statics@*":
|
||||||
|
version "3.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||||
|
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
hoist-non-react-statics "^3.3.0"
|
||||||
|
|
||||||
"@types/html-minifier-terser@^5.0.0":
|
"@types/html-minifier-terser@^5.0.0":
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50"
|
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50"
|
||||||
@@ -1791,6 +1865,20 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
|
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
|
||||||
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
|
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
|
||||||
|
|
||||||
|
"@types/react-clock@*":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-clock/-/react-clock-3.0.0.tgz#43226ae01da98788f7a30a435b7522aba76eaade"
|
||||||
|
integrity sha512-I6zNSVOmzwcofYgBEtjLZq7T8RFD1QGJg3YPeqDrDUPxmuVTwOzBXU5DaeUN1SgNjQ7uUMeyUqTH/2lnxIkS2Q==
|
||||||
|
|
||||||
|
"@types/react-datepicker@^3.1.8":
|
||||||
|
version "3.1.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-datepicker/-/react-datepicker-3.1.8.tgz#642b0d5f2c30f53d7940b1771d5fb11b646bb7fb"
|
||||||
|
integrity sha512-RFEg7++xhosMq02i2lsuaUPEbZGn66U3dxtvw9LU/ZRqLkBGr9Ft2LTz6vbeYYVtaBdOr0NcQatOLnlfUaS8kw==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
date-fns "^2.0.1"
|
||||||
|
popper.js "^1.14.1"
|
||||||
|
|
||||||
"@types/react-dom@^17.0.0":
|
"@types/react-dom@^17.0.0":
|
||||||
version "17.0.3"
|
version "17.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.3.tgz#7fdf37b8af9d6d40127137865bb3fff8871d7ee1"
|
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.3.tgz#7fdf37b8af9d6d40127137865bb3fff8871d7ee1"
|
||||||
@@ -1798,6 +1886,20 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-modal@^3.12.0":
|
||||||
|
version "3.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-modal/-/react-modal-3.12.0.tgz#91fa86a76fd7fc57e36d2cf9b76efe5735a855a1"
|
||||||
|
integrity sha512-UnHu/YO73NZLwqFpju/c0tqiswR0UHIfeO16rkfLVJUIMfQsl7X0CBm99H5XXgBMe/PgtQ/Rkud72iuRBr1TeA==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-time-picker@^4.0.1":
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-time-picker/-/react-time-picker-4.0.1.tgz#e0c7afda295205cfe12971b28b2d910c5a31a020"
|
||||||
|
integrity sha512-9CKWwJTtQe8jwlpyfHcxpE0lJKa25zRkYyIee1LSuhyxghlRC9Lipcw861gd7o4IXmNDtvVyGZ6lZ1soEQT7tA==
|
||||||
|
dependencies:
|
||||||
|
"@types/react-clock" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@^17.0.0":
|
"@types/react@*", "@types/react@^17.0.0":
|
||||||
version "17.0.3"
|
version "17.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79"
|
||||||
@@ -1829,6 +1931,15 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff"
|
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff"
|
||||||
integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==
|
integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==
|
||||||
|
|
||||||
|
"@types/styled-components@^5.1.9":
|
||||||
|
version "5.1.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.9.tgz#00d3d84b501420521c4db727e3c195459f87a6cf"
|
||||||
|
integrity sha512-kbEG6YlwK8rucITpKEr6pA4Ho9KSQHUUOzZ9lY3va1mtcjvS3D0wDciFyHEiNHKLL/npZCKDQJqm0x44sPO9oA==
|
||||||
|
dependencies:
|
||||||
|
"@types/hoist-non-react-statics" "*"
|
||||||
|
"@types/react" "*"
|
||||||
|
csstype "^3.0.2"
|
||||||
|
|
||||||
"@types/tapable@*", "@types/tapable@^1.0.5":
|
"@types/tapable@*", "@types/tapable@^1.0.5":
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74"
|
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74"
|
||||||
@@ -2133,6 +2244,11 @@
|
|||||||
"@webassemblyjs/wast-parser" "1.9.0"
|
"@webassemblyjs/wast-parser" "1.9.0"
|
||||||
"@xtuc/long" "4.2.2"
|
"@xtuc/long" "4.2.2"
|
||||||
|
|
||||||
|
"@wojtekmaj/date-utils@^1.0.0":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@wojtekmaj/date-utils/-/date-utils-1.0.3.tgz#2dcfd92881425c5923e429c2aec86fb3609032a1"
|
||||||
|
integrity sha512-1VPkkTBk07gMR1fjpBtse4G+oJqpmE+0gUFB0dg3VIL7qJmUVaBoD/vlzMm/jNeOPfvlmerl1lpnsZyBUFIRuw==
|
||||||
|
|
||||||
"@xtuc/ieee754@^1.2.0":
|
"@xtuc/ieee754@^1.2.0":
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||||
@@ -2615,6 +2731,21 @@ babel-plugin-named-asset-import@^0.3.7:
|
|||||||
resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz#156cd55d3f1228a5765774340937afc8398067dd"
|
resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz#156cd55d3f1228a5765774340937afc8398067dd"
|
||||||
integrity sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==
|
integrity sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==
|
||||||
|
|
||||||
|
"babel-plugin-styled-components@>= 1.12.0":
|
||||||
|
version "1.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz#1dec1676512177de6b827211e9eda5a30db4f9b9"
|
||||||
|
integrity sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-annotate-as-pure" "^7.0.0"
|
||||||
|
"@babel/helper-module-imports" "^7.0.0"
|
||||||
|
babel-plugin-syntax-jsx "^6.18.0"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
|
||||||
|
babel-plugin-syntax-jsx@^6.18.0:
|
||||||
|
version "6.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
||||||
|
integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
|
||||||
|
|
||||||
babel-plugin-syntax-object-rest-spread@^6.8.0:
|
babel-plugin-syntax-object-rest-spread@^6.8.0:
|
||||||
version "6.13.0"
|
version "6.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
|
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
|
||||||
@@ -3091,6 +3222,11 @@ camelcase@^6.0.0, camelcase@^6.1.0, camelcase@^6.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
|
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
|
||||||
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
||||||
|
|
||||||
|
camelize@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
|
||||||
|
integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
|
||||||
|
|
||||||
caniuse-api@^3.0.0:
|
caniuse-api@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
|
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
|
||||||
@@ -3245,6 +3381,11 @@ class-utils@^0.3.5:
|
|||||||
isobject "^3.0.0"
|
isobject "^3.0.0"
|
||||||
static-extend "^0.1.1"
|
static-extend "^0.1.1"
|
||||||
|
|
||||||
|
classnames@^2.2.6:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
|
||||||
|
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
|
||||||
|
|
||||||
clean-css@^4.2.3:
|
clean-css@^4.2.3:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
|
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
|
||||||
@@ -3637,6 +3778,11 @@ css-blank-pseudo@^0.1.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
postcss "^7.0.5"
|
postcss "^7.0.5"
|
||||||
|
|
||||||
|
css-color-keywords@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
|
||||||
|
integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
|
||||||
|
|
||||||
css-color-names@0.0.4, css-color-names@^0.0.4:
|
css-color-names@0.0.4, css-color-names@^0.0.4:
|
||||||
version "0.0.4"
|
version "0.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
|
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
|
||||||
@@ -3698,6 +3844,15 @@ css-select@^2.0.0, css-select@^2.0.2:
|
|||||||
domutils "^1.7.0"
|
domutils "^1.7.0"
|
||||||
nth-check "^1.0.2"
|
nth-check "^1.0.2"
|
||||||
|
|
||||||
|
css-to-react-native@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
|
||||||
|
integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
|
||||||
|
dependencies:
|
||||||
|
camelize "^1.0.0"
|
||||||
|
css-color-keywords "^1.0.0"
|
||||||
|
postcss-value-parser "^4.0.2"
|
||||||
|
|
||||||
css-tree@1.0.0-alpha.37:
|
css-tree@1.0.0-alpha.37:
|
||||||
version "1.0.0-alpha.37"
|
version "1.0.0-alpha.37"
|
||||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22"
|
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22"
|
||||||
@@ -3889,6 +4044,11 @@ data-urls@^2.0.0:
|
|||||||
whatwg-mimetype "^2.3.0"
|
whatwg-mimetype "^2.3.0"
|
||||||
whatwg-url "^8.0.0"
|
whatwg-url "^8.0.0"
|
||||||
|
|
||||||
|
date-fns@^2.0.1:
|
||||||
|
version "2.21.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.21.1.tgz#679a4ccaa584c0706ea70b3fa92262ac3009d2b0"
|
||||||
|
integrity sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==
|
||||||
|
|
||||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
|
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
|
||||||
version "2.6.9"
|
version "2.6.9"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
@@ -3930,7 +4090,7 @@ dedent@^0.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
|
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
|
||||||
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
|
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
|
||||||
|
|
||||||
deep-equal@^1.0.1:
|
deep-equal@^1.0.1, deep-equal@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
|
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
|
||||||
integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
|
integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
|
||||||
@@ -3947,6 +4107,11 @@ deep-is@^0.1.3, deep-is@~0.1.3:
|
|||||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||||
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||||
|
|
||||||
|
deepmerge@^2.1.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
|
||||||
|
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
|
||||||
|
|
||||||
deepmerge@^4.2.2:
|
deepmerge@^4.2.2:
|
||||||
version "4.2.2"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||||
@@ -4025,6 +4190,11 @@ destroy@~1.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||||
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
|
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
|
||||||
|
|
||||||
|
detect-element-overflow@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/detect-element-overflow/-/detect-element-overflow-1.2.0.tgz#86e504292ffedc3aef813395fbdf0261aaf6afa9"
|
||||||
|
integrity sha512-Jtr9ivYPhpd9OJux+hjL0QjUKiS1Ghgy8tvIufUjFslQgIWvgGr4mn57H190APbKkiOmXnmtMI6ytaKzMusecg==
|
||||||
|
|
||||||
detect-newline@^3.0.0:
|
detect-newline@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
|
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
|
||||||
@@ -4738,6 +4908,11 @@ execa@^4.0.0:
|
|||||||
signal-exit "^3.0.2"
|
signal-exit "^3.0.2"
|
||||||
strip-final-newline "^2.0.0"
|
strip-final-newline "^2.0.0"
|
||||||
|
|
||||||
|
exenv@^1.2.0:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||||
|
integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=
|
||||||
|
|
||||||
exit@^0.1.2:
|
exit@^0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
||||||
@@ -5066,6 +5241,19 @@ form-data@~2.3.2:
|
|||||||
combined-stream "^1.0.6"
|
combined-stream "^1.0.6"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
|
formik@^2.2.6:
|
||||||
|
version "2.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/formik/-/formik-2.2.6.tgz#378a4bafe4b95caf6acf6db01f81f3fe5147559d"
|
||||||
|
integrity sha512-Kxk2zQRafy56zhLmrzcbryUpMBvT0tal5IvcifK5+4YNGelKsnrODFJ0sZQRMQboblWNym4lAW3bt+tf2vApSA==
|
||||||
|
dependencies:
|
||||||
|
deepmerge "^2.1.1"
|
||||||
|
hoist-non-react-statics "^3.3.0"
|
||||||
|
lodash "^4.17.14"
|
||||||
|
lodash-es "^4.17.14"
|
||||||
|
react-fast-compare "^2.0.1"
|
||||||
|
tiny-warning "^1.0.2"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
forwarded@~0.1.2:
|
forwarded@~0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
||||||
@@ -5207,6 +5395,13 @@ get-stream@^5.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
pump "^3.0.0"
|
pump "^3.0.0"
|
||||||
|
|
||||||
|
get-user-locale@^1.2.0:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-user-locale/-/get-user-locale-1.4.0.tgz#a2c4b5da46feec9f03c9b07d197b1620490a5370"
|
||||||
|
integrity sha512-gQo03lP1OArHLKlnoglqrGGl7b04u2EP9Xutmp72cMdtrrSD7ZgIsCsUKZynYWLDkVJW33Cj3pliP7uP0UonHQ==
|
||||||
|
dependencies:
|
||||||
|
lodash.once "^4.1.1"
|
||||||
|
|
||||||
get-value@^2.0.3, get-value@^2.0.6:
|
get-value@^2.0.3, get-value@^2.0.6:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
||||||
@@ -5319,6 +5514,11 @@ growly@^1.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||||
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
|
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
|
||||||
|
|
||||||
|
gud@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0"
|
||||||
|
integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==
|
||||||
|
|
||||||
gzip-size@5.1.1:
|
gzip-size@5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"
|
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"
|
||||||
@@ -5439,6 +5639,13 @@ hmac-drbg@^1.0.1:
|
|||||||
minimalistic-assert "^1.0.0"
|
minimalistic-assert "^1.0.0"
|
||||||
minimalistic-crypto-utils "^1.0.1"
|
minimalistic-crypto-utils "^1.0.1"
|
||||||
|
|
||||||
|
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0:
|
||||||
|
version "3.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||||
|
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||||
|
dependencies:
|
||||||
|
react-is "^16.7.0"
|
||||||
|
|
||||||
hoopy@^0.1.4:
|
hoopy@^0.1.4:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d"
|
resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d"
|
||||||
@@ -6910,6 +7117,11 @@ locate-path@^5.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
p-locate "^4.1.0"
|
p-locate "^4.1.0"
|
||||||
|
|
||||||
|
lodash-es@^4.17.14:
|
||||||
|
version "4.17.21"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||||
|
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
|
||||||
|
|
||||||
lodash._reinterpolate@^3.0.0:
|
lodash._reinterpolate@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||||
@@ -6920,6 +7132,11 @@ lodash.memoize@^4.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||||
|
|
||||||
|
lodash.once@^4.1.1:
|
||||||
|
version "4.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
|
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
||||||
|
|
||||||
lodash.sortby@^4.7.0:
|
lodash.sortby@^4.7.0:
|
||||||
version "4.7.0"
|
version "4.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||||
@@ -6955,7 +7172,7 @@ loglevel@^1.6.8:
|
|||||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
|
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
|
||||||
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
|
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
|
||||||
|
|
||||||
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||||
@@ -7010,6 +7227,11 @@ make-dir@^3.0.0, make-dir@^3.0.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
semver "^6.0.0"
|
semver "^6.0.0"
|
||||||
|
|
||||||
|
make-event-props@^1.1.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/make-event-props/-/make-event-props-1.2.0.tgz#96b87d88919533b8f8934b58b4c3d5679459a0cf"
|
||||||
|
integrity sha512-BmWFkm/jZzVH9A0tEBdkjAARUz/eha+5IRyfOndeSMKRadkgR5DawoBHoRwLxkYmjJOI5bHkXKpaZocxj+dKgg==
|
||||||
|
|
||||||
makeerror@1.0.x:
|
makeerror@1.0.x:
|
||||||
version "1.0.11"
|
version "1.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
|
resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
|
||||||
@@ -7069,6 +7291,11 @@ memory-fs@^0.5.0:
|
|||||||
errno "^0.1.3"
|
errno "^0.1.3"
|
||||||
readable-stream "^2.0.1"
|
readable-stream "^2.0.1"
|
||||||
|
|
||||||
|
merge-class-names@^1.1.1:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/merge-class-names/-/merge-class-names-1.4.0.tgz#02edcdd5ff677fbb03b47ecd4586df89d697b81b"
|
||||||
|
integrity sha512-xNdBM7s+6uD+vNZJEymqrFbMBCDGzoA8clZTcj2F1XIy1QQKF+wjFVv7iDZFfdCBnViTdt54A4Ye2lmBsXrBjQ==
|
||||||
|
|
||||||
merge-descriptors@1.0.1:
|
merge-descriptors@1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||||
@@ -8017,6 +8244,11 @@ pnp-webpack-plugin@1.6.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ts-pnp "^1.1.6"
|
ts-pnp "^1.1.6"
|
||||||
|
|
||||||
|
popper.js@^1.14.1, popper.js@^1.14.4:
|
||||||
|
version "1.16.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
||||||
|
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
|
||||||
|
|
||||||
portfinder@^1.0.26:
|
portfinder@^1.0.26:
|
||||||
version "1.0.28"
|
version "1.0.28"
|
||||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
|
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
|
||||||
@@ -8775,7 +9007,7 @@ prompts@2.4.0, prompts@^2.0.1:
|
|||||||
kleur "^3.0.3"
|
kleur "^3.0.3"
|
||||||
sisteransi "^1.0.5"
|
sisteransi "^1.0.5"
|
||||||
|
|
||||||
prop-types@^15.7.2:
|
prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.7.2:
|
||||||
version "15.7.2"
|
version "15.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||||
@@ -8951,6 +9183,26 @@ react-app-polyfill@^2.0.0:
|
|||||||
regenerator-runtime "^0.13.7"
|
regenerator-runtime "^0.13.7"
|
||||||
whatwg-fetch "^3.4.1"
|
whatwg-fetch "^3.4.1"
|
||||||
|
|
||||||
|
react-clock@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-clock/-/react-clock-3.0.0.tgz#0d29f8e682ef516574061d1d24b1a286cb2da89b"
|
||||||
|
integrity sha512-D3K82D3YGcDtzxZCfiACLcDTL8cJXSgpdrzTY9ff3H5vflxlLzTSLF8apZRo6JZzOFrZQvw5mrS7TkQzj9nG0A==
|
||||||
|
dependencies:
|
||||||
|
"@wojtekmaj/date-utils" "^1.0.0"
|
||||||
|
merge-class-names "^1.1.1"
|
||||||
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
|
react-datepicker@^3.8.0:
|
||||||
|
version "3.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-3.8.0.tgz#c3bccd3e3f47aa66864a2fa75651be097414430b"
|
||||||
|
integrity sha512-iFVNEp8DJoX5yEvEiciM7sJKmLGrvE70U38KhpG13XrulNSijeHw1RZkhd/0UmuXR71dcZB/kdfjiidifstZjw==
|
||||||
|
dependencies:
|
||||||
|
classnames "^2.2.6"
|
||||||
|
date-fns "^2.0.1"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
react-onclickoutside "^6.10.0"
|
||||||
|
react-popper "^1.3.8"
|
||||||
|
|
||||||
react-dev-utils@^11.0.3:
|
react-dev-utils@^11.0.3:
|
||||||
version "11.0.4"
|
version "11.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
|
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
|
||||||
@@ -8995,7 +9247,20 @@ react-error-overlay@^6.0.9:
|
|||||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
|
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
|
||||||
integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==
|
integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==
|
||||||
|
|
||||||
react-is@^16.8.1:
|
react-fast-compare@^2.0.1:
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
||||||
|
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
||||||
|
|
||||||
|
react-fit@^1.0.3:
|
||||||
|
version "1.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-fit/-/react-fit-1.3.1.tgz#850cb5d554fdfa4b27891f62a9d290d3e7eda57b"
|
||||||
|
integrity sha512-MmVk/SXyVbxiz9peAeD7fWxFdGLoy/sCxte01M3w74regPIVkLqc2yT0wUAGRd1MNP1fQ40MqYKNBLpbK/aI1w==
|
||||||
|
dependencies:
|
||||||
|
detect-element-overflow "^1.2.0"
|
||||||
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
|
react-is@^16.7.0, react-is@^16.8.1:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
@@ -9005,6 +9270,46 @@ react-is@^17.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339"
|
||||||
integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==
|
integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==
|
||||||
|
|
||||||
|
react-lifecycles-compat@^3.0.0:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||||
|
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||||
|
|
||||||
|
react-loader-spinner@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-loader-spinner/-/react-loader-spinner-4.0.0.tgz#43d9e71b0574219f64216933c28ef5faa12262f6"
|
||||||
|
integrity sha512-RU2vpEej6G4ECei0h3q6bgLU10of9Lw5O+4AwF/mtkrX5oY20Sh/AxoPJ7etbrs/7Q3u4jN5qwCwGLRKCHpk6g==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
|
react-modal@^3.13.1:
|
||||||
|
version "3.13.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.13.1.tgz#a02dce63bbfee7582936f1e9835d518ef8f56453"
|
||||||
|
integrity sha512-m6yXK7I4YKssQnsjHK7xITSXy2O81BSOHOsg0/uWAsdKtuT9HF2tdoYhRuxNNQg2V+LgepsoHUPJKS8m6no+eg==
|
||||||
|
dependencies:
|
||||||
|
exenv "^1.2.0"
|
||||||
|
prop-types "^15.5.10"
|
||||||
|
react-lifecycles-compat "^3.0.0"
|
||||||
|
warning "^4.0.3"
|
||||||
|
|
||||||
|
react-onclickoutside@^6.10.0:
|
||||||
|
version "6.10.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.10.0.tgz#05abb592575b08b4d129003494056b9dff46eeeb"
|
||||||
|
integrity sha512-7i2L3ef+0ILXpL6P+Hg304eCQswh4jl3ynwR71BSlMU49PE2uk31k8B2GkP6yE9s2D4jTGKnzuSpzWxu4YxfQQ==
|
||||||
|
|
||||||
|
react-popper@^1.3.8:
|
||||||
|
version "1.3.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd"
|
||||||
|
integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.1.2"
|
||||||
|
"@hypnosphi/create-react-context" "^0.3.1"
|
||||||
|
deep-equal "^1.1.1"
|
||||||
|
popper.js "^1.14.4"
|
||||||
|
prop-types "^15.6.1"
|
||||||
|
typed-styles "^0.0.7"
|
||||||
|
warning "^4.0.2"
|
||||||
|
|
||||||
react-refresh@^0.8.3:
|
react-refresh@^0.8.3:
|
||||||
version "0.8.3"
|
version "0.8.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
||||||
@@ -9076,6 +9381,20 @@ react-scripts@4.0.3:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "^2.1.3"
|
fsevents "^2.1.3"
|
||||||
|
|
||||||
|
react-time-picker@^4.2.1:
|
||||||
|
version "4.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-time-picker/-/react-time-picker-4.2.1.tgz#b27f0bbc2e58534f20dbf10b14d0b8f3334fcb07"
|
||||||
|
integrity sha512-T0aEabJ3bz54l8LV3pdpB5lOZuO3pRIbry5STcUV58UndlrWLcHpdpvS1IC8JLNXhbLxzGs1MmpASb5k1ddlsg==
|
||||||
|
dependencies:
|
||||||
|
"@wojtekmaj/date-utils" "^1.0.0"
|
||||||
|
get-user-locale "^1.2.0"
|
||||||
|
make-event-props "^1.1.0"
|
||||||
|
merge-class-names "^1.1.1"
|
||||||
|
prop-types "^15.6.0"
|
||||||
|
react-clock "^3.0.0"
|
||||||
|
react-fit "^1.0.3"
|
||||||
|
update-input-width "^1.1.1"
|
||||||
|
|
||||||
react@^17.0.2:
|
react@^17.0.2:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||||
@@ -9758,6 +10077,11 @@ sha.js@^2.4.0, sha.js@^2.4.8:
|
|||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
shallowequal@^1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
||||||
|
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
||||||
|
|
||||||
shebang-command@^1.2.0:
|
shebang-command@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||||
@@ -10261,6 +10585,22 @@ style-loader@1.3.0:
|
|||||||
loader-utils "^2.0.0"
|
loader-utils "^2.0.0"
|
||||||
schema-utils "^2.7.0"
|
schema-utils "^2.7.0"
|
||||||
|
|
||||||
|
styled-components@^5.2.3:
|
||||||
|
version "5.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.2.3.tgz#752669fd694aac10de814d96efc287dde0d11385"
|
||||||
|
integrity sha512-BlR+KrLW3NL1yhvEB+9Nu9Dt51CuOnHoxd+Hj+rYPdtyR8X11uIW9rvhpy3Dk4dXXBsiW1u5U78f00Lf/afGoA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-module-imports" "^7.0.0"
|
||||||
|
"@babel/traverse" "^7.4.5"
|
||||||
|
"@emotion/is-prop-valid" "^0.8.8"
|
||||||
|
"@emotion/stylis" "^0.8.4"
|
||||||
|
"@emotion/unitless" "^0.7.4"
|
||||||
|
babel-plugin-styled-components ">= 1.12.0"
|
||||||
|
css-to-react-native "^3.0.0"
|
||||||
|
hoist-non-react-statics "^3.0.0"
|
||||||
|
shallowequal "^1.1.0"
|
||||||
|
supports-color "^5.5.0"
|
||||||
|
|
||||||
stylehacks@^4.0.0:
|
stylehacks@^4.0.0:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
|
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
|
||||||
@@ -10270,7 +10610,7 @@ stylehacks@^4.0.0:
|
|||||||
postcss "^7.0.0"
|
postcss "^7.0.0"
|
||||||
postcss-selector-parser "^3.0.0"
|
postcss-selector-parser "^3.0.0"
|
||||||
|
|
||||||
supports-color@^5.3.0:
|
supports-color@^5.3.0, supports-color@^5.5.0:
|
||||||
version "5.5.0"
|
version "5.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||||
@@ -10469,6 +10809,11 @@ timsort@^0.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
||||||
|
|
||||||
|
tiny-warning@^1.0.2:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
||||||
|
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
|
||||||
|
|
||||||
tmpl@1.0.x:
|
tmpl@1.0.x:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
|
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
|
||||||
@@ -10565,7 +10910,7 @@ tsconfig-paths@^3.9.0:
|
|||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
strip-bom "^3.0.0"
|
strip-bom "^3.0.0"
|
||||||
|
|
||||||
tslib@^1.8.1, tslib@^1.9.0:
|
tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0:
|
||||||
version "1.14.1"
|
version "1.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
@@ -10656,6 +11001,11 @@ type@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/type/-/type-2.3.0.tgz#ada7c045f07ead08abf9e2edd29be1a0c0661132"
|
resolved "https://registry.yarnpkg.com/type/-/type-2.3.0.tgz#ada7c045f07ead08abf9e2edd29be1a0c0661132"
|
||||||
integrity sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==
|
integrity sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==
|
||||||
|
|
||||||
|
typed-styles@^0.0.7:
|
||||||
|
version "0.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9"
|
||||||
|
integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==
|
||||||
|
|
||||||
typedarray-to-buffer@^3.1.5:
|
typedarray-to-buffer@^3.1.5:
|
||||||
version "3.1.5"
|
version "3.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
||||||
@@ -10770,6 +11120,11 @@ upath@^1.1.1, upath@^1.1.2, upath@^1.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
|
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
|
||||||
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
|
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
|
||||||
|
|
||||||
|
update-input-width@^1.1.1:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/update-input-width/-/update-input-width-1.2.1.tgz#769d6182413590c3b50b52ffa9c65d79e2c17f95"
|
||||||
|
integrity sha512-zygDshqDb2C2/kgfoD423n5htv/3OBF7aTaz2u2zZy998EJki8njOHOeZjKEd8XSYeDziIX1JXfMsKaIRJeJ/Q==
|
||||||
|
|
||||||
uri-js@^4.2.2:
|
uri-js@^4.2.2:
|
||||||
version "4.4.1"
|
version "4.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||||
@@ -10936,6 +11291,13 @@ walker@^1.0.7, walker@~1.0.5:
|
|||||||
dependencies:
|
dependencies:
|
||||||
makeerror "1.0.x"
|
makeerror "1.0.x"
|
||||||
|
|
||||||
|
warning@^4.0.2, warning@^4.0.3:
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
|
||||||
|
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.0.0"
|
||||||
|
|
||||||
watchpack-chokidar2@^2.0.1:
|
watchpack-chokidar2@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"
|
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"
|
||||||
|
|||||||
Reference in New Issue
Block a user