diff --git a/UserForm.tsx b/UserForm.tsx
new file mode 100644
index 0000000..9f27a34
--- /dev/null
+++ b/UserForm.tsx
@@ -0,0 +1,97 @@
+import React from 'react';
+
+import { Stack } from '@chakra-ui/react';
+import {
+ isEmail,
+ isMaxLength,
+ isMinLength,
+ isPattern,
+} from '@formiz/validations';
+import { useTranslation } from 'react-i18next';
+
+import { FieldCheckboxes } from '@/components/FieldCheckboxes';
+import { FieldInput } from '@/components/FieldInput';
+import { FieldSelect } from '@/components/FieldSelect';
+import { AVAILABLE_LANGUAGES, DEFAULT_LANGUAGE_KEY } from '@/constants/i18n';
+
+const AUTHORITIES = {
+ ADMIN: 'ROLE_ADMIN',
+ USER: 'ROLE_USER',
+};
+
+export const UserForm = () => {
+ const { t } = useTranslation(['common', 'users']);
+
+ const authorities = Object.values(AUTHORITIES).map((value) => ({ value }));
+ return (
+
+
+
+
+
+
+
+ ({
+ label: t(`common:languages.${key}`),
+ value: key,
+ }))}
+ defaultValue={DEFAULT_LANGUAGE_KEY}
+ />
+
+
+ );
+};
diff --git a/functions/src/index.ts b/functions/src/index.ts
index a538121..f997ae6 100644
--- a/functions/src/index.ts
+++ b/functions/src/index.ts
@@ -1,13 +1,13 @@
-import * as functions from 'firebase-functions';
-import express, { Request, Response } from 'express';
-import cors from 'cors';
-import { Client } from '@hubspot/api-client';
+import {Client} from "@hubspot/api-client";
+import cors from "cors";
+import express, {Request, Response} from "express";
+import * as functions from "firebase-functions";
-const TOKEN = 'pat-eu1-cf82e317-f47b-4cf7-b305-be8371c973cf';
+const TOKEN = "pat-eu1-cf82e317-f47b-4cf7-b305-be8371c973cf";
const app = express();
-app.use(cors({ origin: true }));
+app.use(cors({origin: true}));
// Start writing Firebase Functions
// https://firebase.google.com/docs/functions/typescript
@@ -21,22 +21,33 @@ app.use(cors({ origin: true }));
// functions.logger.info("Hello logs!", {structuredData: true});
// response.send("Hello from Firebase!");
// }
-app.get('/', async (request: Request, response: Response) => {
- const LIMIT = 'limit=100';
- const ASSOCIATIONS = 'associations=contacts';
- const PROPERTIES = 'properties=hs_meeting_title,hs_meeting_start_time,hs_meeting_outcome,hs_internal_meeting_notes';
- const hubspotClient = new Client({ accessToken: TOKEN });
+app.get("/", async (request: Request, response: Response) => {
+ const LIMIT = "limit=100";
+ const ASSOCIATIONS = "associations=contacts";
+ const PROPERTIES = "properties=hs_meeting_title,hs_meeting_start_time,hs_meeting_outcome,hs_internal_meeting_notes";
+ const hubspotClient = new Client({accessToken: TOKEN});
const contacts = await hubspotClient.crm.contacts.getAll();
const meetings = await hubspotClient
- .apiRequest({
- method: 'get',
- path: `/crm/v3/objects/meetings?${LIMIT}&${ASSOCIATIONS}&${PROPERTIES}`,
- })
- .then((data) => data.json());
- // functions.logger.info("Hello logs!", {structuredData: true});
- // response.send("Hello from Fireba);
- // send meetings and contacts as json
- response.send({ meetings: meetings.results, contacts });
+ .apiRequest({
+ method: "get",
+ path: `/crm/v3/objects/meetings?${LIMIT}&${ASSOCIATIONS}&${PROPERTIES}`,
+ })
+ .then((data) => data.json());
+ return response.send({meetings: meetings.results, contacts});
+});
+
+app.delete("/:id", async (request: Request, response: Response) => {
+ const hubspotClient = new Client({accessToken: TOKEN});
+ if (!request.params.id) {
+ return response.status(400).send({error: "No id provided"});
+ }
+ const ids = request.params.id.split(",");
+ const data = await Promise.all(
+ ids.map((id: string) =>
+ hubspotClient.apiRequest({method: "delete", path: `/crm/v3/objects/meetings/${id}`}).then((data) => data.status)
+ )
+ );
+ return response.send({statuses: data});
});
exports.meetings = functions.https.onRequest(app);
diff --git a/package-lock.json b/package-lock.json
index cb78a83..46db1a4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,8 @@
"@emotion/react": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@fontsource/inter": "^4.5.15",
+ "@formiz/core": "^1.8.1",
+ "@formiz/validations": "^1.0.0",
"@formkit/auto-animate": "^1.0.0-beta.6",
"@lukemorales/query-key-factory": "^1.2.0",
"@tanstack/react-query": "^4.29.5",
@@ -3662,6 +3664,49 @@
"resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.5.15.tgz",
"integrity": "sha512-FzleM9AxZQK2nqsTDtBiY0PMEVWvnKnuu2i09+p6DHvrHsuucoV2j0tmw+kAT3L4hvsLdAIDv6MdGehsPIdT+Q=="
},
+ "node_modules/@formiz/core": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@formiz/core/-/core-1.8.1.tgz",
+ "integrity": "sha512-1+hzKqJYqMO1cjnWPo5D85A7oRVdrbPxUzDKFgQZpZcE58z//64lbtkS9yrkrmI3Eor126bt1XM5bq+BieoGug==",
+ "dependencies": {
+ "lodash": "4.17.21",
+ "lodash-es": "4.17.21",
+ "rxjs": "6.6.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/@formiz/core/node_modules/rxjs": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
+ "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
+ "dependencies": {
+ "tslib": "^1.9.0"
+ },
+ "engines": {
+ "npm": ">=2.0.0"
+ }
+ },
+ "node_modules/@formiz/core/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "node_modules/@formiz/validations": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@formiz/validations/-/validations-1.0.0.tgz",
+ "integrity": "sha512-pGTf0IQmSDhK7+4oTYjwtkn5TXqts33URSFXcUBMidDJgd1bSUzTQMNftg7YCeRPY8ROSsaJNWP7bFwtwHQeSA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
"node_modules/@formkit/auto-animate": {
"version": "1.0.0-beta.6",
"resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-1.0.0-beta.6.tgz",
@@ -14439,6 +14484,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
+ "node_modules/lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+ },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
diff --git a/package.json b/package.json
index d79ddb9..3411579 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,8 @@
"@emotion/react": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@fontsource/inter": "^4.5.15",
+ "@formiz/core": "^1.8.1",
+ "@formiz/validations": "^1.0.0",
"@formkit/auto-animate": "^1.0.0-beta.6",
"@lukemorales/query-key-factory": "^1.2.0",
"@tanstack/react-query": "^4.29.5",
diff --git a/src/components/Toast/index.ts b/src/components/Toast/index.ts
new file mode 100644
index 0000000..5eace02
--- /dev/null
+++ b/src/components/Toast/index.ts
@@ -0,0 +1,33 @@
+import { UseToastOptions, useToast } from '@chakra-ui/react';
+
+export const toastDefaultConfig: UseToastOptions = {
+ duration: 3000,
+ isClosable: true,
+ position: 'top-right',
+ variant: 'solid',
+};
+
+export const useToastError = () =>
+ useToast({
+ ...toastDefaultConfig,
+ status: 'error',
+ duration: 5000,
+ });
+
+export const useToastWarning = () =>
+ useToast({
+ ...toastDefaultConfig,
+ status: 'warning',
+ });
+
+export const useToastSuccess = () =>
+ useToast({
+ ...toastDefaultConfig,
+ status: 'success',
+ });
+
+export const useToastInfo = () =>
+ useToast({
+ ...toastDefaultConfig,
+ status: 'info',
+ });
diff --git a/src/containers/ColorModeSwitcher.tsx b/src/containers/ColorModeSwitcher.tsx
deleted file mode 100644
index 4500cc2..0000000
--- a/src/containers/ColorModeSwitcher.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as React from 'react';
-import { useColorMode, useColorModeValue, IconButton, IconButtonProps } from '@chakra-ui/react';
-import { FaMoon, FaSun } from 'react-icons/fa';
-
-type ColorModeSwitcherProps = Omit;
-
-export const ColorModeSwitcher: React.FC = (props) => {
- const { toggleColorMode } = useColorMode();
- const text = useColorModeValue('dark', 'light');
- const SwitchIcon = useColorModeValue(FaMoon, FaSun);
-
- return (
- }
- aria-label={`Switch to ${text} mode`}
- {...props}
- />
- );
-};
diff --git a/src/containers/MeetingCreateView/MeetingCreateView.tsx b/src/containers/MeetingCreateView/MeetingCreateView.tsx
new file mode 100644
index 0000000..5f88b11
--- /dev/null
+++ b/src/containers/MeetingCreateView/MeetingCreateView.tsx
@@ -0,0 +1,84 @@
+import React from 'react';
+
+import { Button, ButtonGroup, Heading } from '@chakra-ui/react';
+import { Formiz, useForm } from '@formiz/core';
+import { useNavigate } from 'react-router-dom';
+
+import { useToastError, useToastSuccess } from '../../components/Toast';
+// import { UserForm } from '@/spa/admin/users/UserForm';
+// import { useUserCreate } from '@/spa/admin/users/users.service';
+import { Page, PageBottomBar, PageContent, PageTopBar } from '../Page/Page';
+
+export const MeetingCreateView = () => {
+ const navigate = useNavigate();
+ const form = useForm({ subscribe: false });
+
+ const toastError = useToastError();
+ const toastSuccess = useToastSuccess();
+
+ // const createUser = useUserCreate({
+ // onError: (error) => {
+ // if (error.response) {
+ // const { title, errorKey } = error.response.data;
+ // toastError({
+ // title: t('users:create.feedbacks.updateError.title'),
+ // description: title,
+ // });
+ // switch (errorKey) {
+ // case 'userexists':
+ // form.invalidateFields({
+ // login: t('users:data.login.alreadyUsed'),
+ // });
+ // break;
+ // case 'emailexists':
+ // form.invalidateFields({
+ // email: t('users:data.email.alreadyUsed'),
+ // });
+ // break;
+ // }
+ // }
+ // },
+ // onSuccess: () => {
+ // toastSuccess({
+ // title: t('users:create.feedbacks.updateSuccess.title'),
+ // });
+ // navigate('/admin/users');
+ // },
+ // });
+
+ // const submitCreateUser = async (values: TODO) => {
+ // const newUser = {
+ // ...values,
+ // };
+ // await createUser.mutate(newUser);
+ // };
+
+ return (
+
+ {
+ console.log('ok');
+ }}
+ connect={form}
+ >
+
+
+
+ );
+};
+
+export default MeetingCreateView;
diff --git a/src/containers/MeetingUpdateView/MeetingUpdateView.tsx b/src/containers/MeetingUpdateView/MeetingUpdateView.tsx
new file mode 100644
index 0000000..b252343
--- /dev/null
+++ b/src/containers/MeetingUpdateView/MeetingUpdateView.tsx
@@ -0,0 +1,103 @@
+import React from 'react';
+
+import { Box, Button, ButtonGroup, HStack, Heading, SkeletonText, Stack, Text } from '@chakra-ui/react';
+import { Formiz, useForm } from '@formiz/core';
+import { useNavigate, useParams } from 'react-router-dom';
+
+import { ErrorPage } from '../../components/ErrorPage';
+import { useToastError, useToastSuccess } from '../../components/Toast';
+// import { useUser, useUserUpdate } from '@/spa/admin/users/users.service';
+import { Page, PageBottomBar, PageContent, PageTopBar } from '../Page/Page';
+import { Loader } from '../Router/Router';
+
+// import { UserForm } from './UserForm';
+
+export const MeetingUpdateView = () => {
+ const { id } = useParams();
+ const navigate = useNavigate();
+ // const user = useUser(id, {
+ // refetchOnWindowFocus: false,
+ // enabled: !!login,
+ // });
+
+ const form = useForm({ subscribe: false });
+
+ const toastSuccess = useToastSuccess();
+ const toastError = useToastError();
+
+ // const { mutate: editUser, isLoading: editUserIsLoading } = useUserUpdate({
+ // onError: (error) => {
+ // if (error.response) {
+ // const { title, errorKey } = error.response.data;
+ // toastError({
+ // title: t('users:update.feedbacks.updateError.title'),
+ // description: title,
+ // });
+ // switch (errorKey) {
+ // case 'userexists':
+ // form.invalidateFields({
+ // login: t('users:data.login.alreadyUsed'),
+ // });
+ // break;
+ // case 'emailexists':
+ // form.invalidateFields({
+ // email: t('users:data.email.alreadyUsed'),
+ // });
+ // break;
+ // }
+ // }
+ // },
+ // onSuccess: () => {
+ // toastSuccess({
+ // title: t('users:update.feedbacks.updateSuccess.title'),
+ // });
+ // navigate(-1);
+ // },
+ // });
+ // const submitEditUser = (values: TODO) => {
+ // const userToSend = {
+ // id: user.data?.id,
+ // ...values,
+ // };
+ // editUser(userToSend);
+ // };
+
+ return (
+
+ navigate(-1)}>
+
+
+ {false || false ? (
+
+ ) : (
+
+ 000
+
+ Meeting ID: 000
+
+
+ )}
+
+
+
+ {/* {user.isFetching && }
+ {user.isError && !user.isFetching && }
+ {!user.isError && !user.isFetching && ( */}
+
+
+
+
+ );
+};
+
+export default MeetingUpdateView;
diff --git a/src/containers/MeetingsActions/MeetingsActions.tsx b/src/containers/MeetingsActions/MeetingsActions.tsx
index 62ca94c..9853dff 100644
--- a/src/containers/MeetingsActions/MeetingsActions.tsx
+++ b/src/containers/MeetingsActions/MeetingsActions.tsx
@@ -7,6 +7,8 @@ import { BiCalendar, BiFilter, BiSort } from 'react-icons/bi';
import { FiChevronDown, FiEdit, FiPlus } from 'react-icons/fi';
import { Link } from 'react-router-dom';
+import { useToastError, useToastSuccess } from '../../components/Toast';
+import { useMeetingRemove } from '../../services/meetings.service';
import { MeetingFilterType, MeetingSortType } from '../../types/meetings.types';
type MeetingsActionsProps = {
@@ -16,6 +18,7 @@ type MeetingsActionsProps = {
setFilter: (filter: MeetingFilterType) => void;
range: DateRange | undefined;
setRange: (range: DateRange | undefined) => void;
+ selected: string[];
selectedAll: boolean;
toggleSelectedAll: () => void;
invertSelected: () => void;
@@ -34,11 +37,12 @@ const ActionsOptions = ({
selectedAll,
toggleSelectedAll,
invertSelected,
-}: Pick) => (
+ removeMeeting,
+}: Pick & { removeMeeting: () => void }) => (
-
+
);
@@ -56,10 +60,25 @@ export const MeetingsActions = ({
setFilter,
range,
setRange,
+ selected,
selectedAll,
toggleSelectedAll,
invertSelected,
}: MeetingsActionsProps) => {
+ const toastSuccess = useToastSuccess();
+ const toastError = useToastError();
+
+ const meetingRemove = useMeetingRemove({
+ onSuccess: (_, { id }) => {
+ toastSuccess({ title: 'Meeting deleted', description: `Meeting ${id} has been deleted.` });
+ },
+ onError: (_, { id }) => {
+ toastError({ title: 'Meeting delete error', description: `Meeting ${id} could not be deleted.` });
+ },
+ });
+ const removeMeeting = () => meetingRemove.mutate({ id: selected.join(',') });
+ const isRemovalLoading = meetingRemove.isLoading;
+
let period = 'Period';
if (range?.from) {
if (!range.to) {
@@ -90,20 +109,43 @@ export const MeetingsActions = ({
@@ -129,14 +171,14 @@ export const MeetingsActions = ({
- }>
+ }>
New Meeting
}
diff --git a/src/containers/MeetingsView/MeetingsView.tsx b/src/containers/MeetingsView/MeetingsView.tsx
index 7aab9a8..0bd309a 100644
--- a/src/containers/MeetingsView/MeetingsView.tsx
+++ b/src/containers/MeetingsView/MeetingsView.tsx
@@ -25,7 +25,7 @@ const MeetingsView = () => {
const filteredMeetings = filterMeetingList(sortedMeetings, filter);
const rangedMeetings = rangeMeetingList(filteredMeetings, range);
const pagedMeetings = rangedMeetings.slice(pageSize * (page - 1), pageSize * page);
- const selectedAll = selected.length === rangedMeetings.length;
+ const selectedAll = !!selected.length && selected.length === rangedMeetings.length;
const toggleSelectedAll = () => (selectedAll ? setSelected([]) : setSelected(rangedMeetings.map((m: Meeting) => m.id)));
const invertSelected = () => setSelected(rangedMeetings.map((m: Meeting) => m.id).filter((id) => !selected.includes(id)));
@@ -44,6 +44,7 @@ const MeetingsView = () => {
setFilter={setFilter}
range={range}
setRange={setRange}
+ selected={selected}
selectedAll={selectedAll}
toggleSelectedAll={toggleSelectedAll}
invertSelected={invertSelected}
diff --git a/src/containers/Router/Router.tsx b/src/containers/Router/Router.tsx
index c5c3b1e..8943bc8 100644
--- a/src/containers/Router/Router.tsx
+++ b/src/containers/Router/Router.tsx
@@ -1,9 +1,11 @@
+import React, { Suspense, useCallback } from 'react';
+
+import { Center, Spinner } from '@chakra-ui/react';
+import { BrowserRouter, Route, Routes, useNavigate, useSearchParams } from 'react-router-dom';
+
import { ErrorBoundary } from '../../components/ErrorBoundary';
import { ErrorPage } from '../../components/ErrorPage';
import { Layout } from '../Layout/Layout';
-import { Center, Spinner } from '@chakra-ui/react';
-import React, { Suspense, useCallback } from 'react';
-import { BrowserRouter, Route, Routes, useSearchParams, useNavigate } from 'react-router-dom';
export const Loader = () => (
@@ -34,13 +36,8 @@ export const useRedirectFromUrl = (defaultTo = '/') => {
};
const MeetingsView = React.lazy(() => import('../MeetingsView/MeetingsView'));
-// const MeetingCreateView = React.lazy(
-// () => import("@/spa/views/MeetingCreateView")
-// );
-// const MeetingUpdateView = React.lazy(
-// () => import("@/spa/views/MeetingUpdateView")
-// );
-// const ApiView = React.lazy(() => import("@/spa/views/ApiView"));
+const MeetingCreateView = React.lazy(() => import('../MeetingCreateView/MeetingCreateView'));
+const MeetingUpdateView = React.lazy(() => import('../MeetingUpdateView/MeetingUpdateView'));
export const Router = () => {
return (
@@ -50,6 +47,8 @@ export const Router = () => {
}>
} />
+ } />
+ } />
} />
diff --git a/src/services/meetings.service.ts b/src/services/meetings.service.ts
index 6d7c39b..70e4e82 100644
--- a/src/services/meetings.service.ts
+++ b/src/services/meetings.service.ts
@@ -1,71 +1,45 @@
-import { Meeting, MeetingList } from '../types/meetings.types';
import { createQueryKeys, inferQueryKeys } from '@lukemorales/query-key-factory';
-import {
- // UseMutationOptions,
- UseQueryOptions, // useMutation,
- useQuery, // useQueryClient,
-} from '@tanstack/react-query';
+import { UseMutationOptions, UseQueryOptions, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import Axios, { AxiosError } from 'axios';
import { DateRange } from 'react-day-picker';
+// import { useToastError, useToastSuccess } from '../../components/Toast';
+import { Meeting, MeetingList } from '../types/meetings.types';
+
+type MeetingWithIdOnly = { id: string };
+
// type UserMutateError = {
// title: string;
// errorKey: "userexists" | "emailexists";
// };
-export const sortMeetingList = (meetings: Meeting[], sort: string) => {
- if (sort === 'NEWEST') {
- return meetings.sort((a, b) => {
- return new Date(b.properties.hs_meeting_start_time).getTime() - new Date(a.properties.hs_meeting_start_time).getTime();
- });
- } else if (sort === 'OLDEST') {
- return meetings.sort((a, b) => {
- return new Date(a.properties.hs_meeting_start_time).getTime() - new Date(b.properties.hs_meeting_start_time).getTime();
- });
- } else {
- return meetings;
- }
-};
+const MEETINGS_API_BASE_URL = 'https://us-central1-epicbrief-c47c8.cloudfunctions.net/meetings';
+// const MEETINGS_API_BASE_URL = 'http://127.0.0.1:5001/epicbrief-c47c8/us-central1/meetings';
-export const filterMeetingList = (meetings: Meeting[], filter: string) => {
- if (filter === 'ALL') {
- return meetings;
- } else {
- return meetings.filter((meeting) => {
- return meeting.properties.hs_meeting_outcome === filter;
- });
- }
-};
-
-export const rangeMeetingList = (meetings: Meeting[], range: DateRange | undefined) => {
- if (!range || !range.from || !range.to) {
- return meetings;
- } else {
- return meetings.filter((meeting) => {
- return (
- range.from &&
- new Date(meeting.properties.hs_meeting_start_time).getTime() >= range.from.getTime() &&
- range.to &&
- new Date(meeting.properties.hs_meeting_start_time).getTime() <= range.to.getTime()
- );
- });
- }
+export const useMeetingRemove = (config: UseMutationOptions = {}) => {
+ const queryClient = useQueryClient();
+ return useMutation((meeting: MeetingWithIdOnly): Promise => Axios.delete(`${MEETINGS_API_BASE_URL}/${meeting.id}`), {
+ ...config,
+ onSuccess: (...args) => {
+ queryClient.invalidateQueries(meetingsKeys.meetings._def);
+ config?.onSuccess?.(...args);
+ },
+ });
};
-const usersKeys = createQueryKeys('usersService', {
+const meetingsKeys = createQueryKeys('usersService', {
meetings: (params: { limit?: number; after?: number }) => [params],
- users: (params: { page?: number; size?: number }) => [params],
- user: (params: { login?: string }) => [params],
});
-type UsersKeys = inferQueryKeys;
+
+type MeetingsKeys = inferQueryKeys;
export const useMeetingList = (
{ page = 0, size = 10, limit = 20 } = {},
- config: UseQueryOptions = {}
+ config: UseQueryOptions = {}
) => {
const result = useQuery(
- usersKeys.meetings({ limit: 20, after: 0 }).queryKey,
- (): Promise => Axios.get('https://us-central1-epicbrief-c47c8.cloudfunctions.net/meetings'),
+ meetingsKeys.meetings({ limit: 20, after: 0 }).queryKey,
+ (): Promise => Axios.get(`${MEETINGS_API_BASE_URL}?limit=${limit}&after=${page}`),
{ keepPreviousData: true, ...config }
);
console.log('result', result.data);
@@ -166,21 +140,41 @@ export const useMeetingList = (
// );
// };
-// type UserWithLoginOnly = Pick;
+export const sortMeetingList = (meetings: Meeting[], sort: string) => {
+ if (sort === 'NEWEST') {
+ return meetings.sort((a, b) => {
+ return new Date(b.properties.hs_meeting_start_time).getTime() - new Date(a.properties.hs_meeting_start_time).getTime();
+ });
+ } else if (sort === 'OLDEST') {
+ return meetings.sort((a, b) => {
+ return new Date(a.properties.hs_meeting_start_time).getTime() - new Date(b.properties.hs_meeting_start_time).getTime();
+ });
+ } else {
+ return meetings;
+ }
+};
+
+export const filterMeetingList = (meetings: Meeting[], filter: string) => {
+ if (filter === 'ALL') {
+ return meetings;
+ } else {
+ return meetings.filter((meeting) => {
+ return meeting.properties.hs_meeting_outcome === filter;
+ });
+ }
+};
-// export const useUserRemove = (
-// config: UseMutationOptions = {}
-// ) => {
-// const queryClient = useQueryClient();
-// return useMutation(
-// (user: UserWithLoginOnly): Promise =>
-// Axios.delete(`/admin/users/${user.login}`),
-// {
-// ...config,
-// onSuccess: (...args) => {
-// queryClient.invalidateQueries(usersKeys.users._def);
-// config?.onSuccess?.(...args);
-// },
-// }
-// );
-// };
+export const rangeMeetingList = (meetings: Meeting[], range: DateRange | undefined) => {
+ if (!range || !range.from || !range.to) {
+ return meetings;
+ } else {
+ return meetings.filter((meeting) => {
+ return (
+ range.from &&
+ new Date(meeting.properties.hs_meeting_start_time).getTime() >= range.from.getTime() &&
+ range.to &&
+ new Date(meeting.properties.hs_meeting_start_time).getTime() <= range.to.getTime()
+ );
+ });
+ }
+};