From 6173faf290f0e2c921fcec6e08b3e0895d895ccb Mon Sep 17 00:00:00 2001 From: ratankods <90516956+duplixx@users.noreply.github.com> Date: Fri, 24 May 2024 20:34:11 +0530 Subject: [PATCH] advertisement and plugin screen --- public/locales/en.json | 4 +- .../ActionItems/ActionItemsModal.tsx | 8 +- .../core/AddOnEntry/AddOnEntry.module.css | 6 +- .../AddOn/core/AddOnEntry/AddOnEntry.tsx | 15 +- .../core/AddOnStore/AddOnStore.module.css | 45 ++- .../AddOn/core/AddOnStore/AddOnStore.tsx | 360 ++++++++---------- .../support/services/Plugin.helper.test.ts | 13 +- .../AddOn/support/services/Plugin.helper.ts | 32 +- .../Advertisements/Advertisements.module.css | 26 +- .../Advertisements/Advertisements.tsx | 57 ++- .../AdvertisementEntry.module.css | 6 +- .../AdvertisementEntry/AdvertisementEntry.tsx | 27 +- .../AdvertisementRegister.module.css | 3 +- .../AdvertisementRegister.tsx | 8 +- .../EventCalendar/EventCalendar.module.css | 1 + 15 files changed, 353 insertions(+), 258 deletions(-) diff --git a/public/locales/en.json b/public/locales/en.json index 97d63a5073..3d80133f5c 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -745,7 +745,7 @@ "pDesc": "This Plugin enables UI for" }, "addOnStore": { - "title": "Add On Store", + "title": "Plugin Store", "searchName": "Ex: Donations", "enable": "Enabled", "disable": "Disabled", @@ -1028,7 +1028,7 @@ "RstartDate": "Select Start Date", "RendDate": "Select End Date", "RClose": "Close the window", - "addNew": "Create new advertisement", + "addNew": "Create", "EXname": "Ex. Cookie Shop", "EXlink": "Ex. http://yourwebsite.com/photo", "register": "Create Advertisement", diff --git a/src/components/ActionItems/ActionItemsModal.tsx b/src/components/ActionItems/ActionItemsModal.tsx index 8b8cafba4a..315eb1701d 100644 --- a/src/components/ActionItems/ActionItemsModal.tsx +++ b/src/components/ActionItems/ActionItemsModal.tsx @@ -19,8 +19,8 @@ export const ActionItemsModal = (props: InterfaceModalProp): JSX.Element => { return ( <> { diff --git a/src/components/AddOn/core/AddOnEntry/AddOnEntry.module.css b/src/components/AddOn/core/AddOnEntry/AddOnEntry.module.css index 1f1ea89996..c5dd86c8d4 100644 --- a/src/components/AddOn/core/AddOnEntry/AddOnEntry.module.css +++ b/src/components/AddOn/core/AddOnEntry/AddOnEntry.module.css @@ -7,8 +7,12 @@ margin-left: auto; display: flex !important; align-items: center; + background-color: transparent; + color: #31bb6b; +} +.card { + border: 4px solid green; } - .entryaction i { margin-right: 8px; } diff --git a/src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx b/src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx index 6f2cdaf1dc..76207a0a5d 100644 --- a/src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx +++ b/src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx @@ -15,9 +15,9 @@ interface InterfaceAddOnEntryProps { description: string; createdBy: string; component: string; - modified: any; + modified: boolean; uninstalledOrgs: string[]; - getInstalledPlugins: () => any; + getInstalledPlugins: () => void; } function addOnEntry({ @@ -28,9 +28,11 @@ function addOnEntry({ uninstalledOrgs, getInstalledPlugins, }: InterfaceAddOnEntryProps): JSX.Element { + console.log(id); const { t } = useTranslation('translation', { keyPrefix: 'addOnEntry' }); //getting orgId from URL const { orgId: currentOrg } = useParams(); + // console.log(currentOrg); if (!currentOrg) { return ; } @@ -62,7 +64,10 @@ function addOnEntry({ return ( <> - + {/* {uninstalledOrgs.includes(currentOrg) && ( )} */} - {title} + {title} {createdBy} @@ -95,7 +100,7 @@ function addOnEntry({ ) : ( )} {/* {installed ? 'Remove' : configurable ? 'Installed' : 'Install'} */} diff --git a/src/components/AddOn/core/AddOnStore/AddOnStore.module.css b/src/components/AddOn/core/AddOnStore/AddOnStore.module.css index 8a34c03be5..9f5bb6c868 100644 --- a/src/components/AddOn/core/AddOnStore/AddOnStore.module.css +++ b/src/components/AddOn/core/AddOnStore/AddOnStore.module.css @@ -11,8 +11,12 @@ border-bottom: 3px solid #31bb6b; width: 15%; } - -.actioninput { +.input { + display: flex; + position: relative; + width: 560px; +} +/* .actioninput { text-decoration: none; margin-bottom: 50px; border-color: #e8e5e5; @@ -23,9 +27,46 @@ padding-right: 10px; padding-left: 10px; box-shadow: none; +} */ +.actioninput { + margin-top: 10px; + margin-bottom: 10px; + background-color: white; + box-shadow: 0 1px 1px #31bb6b; +} +.inputField > button { + padding-top: 10px; + padding-bottom: 10px; } .actionradio input { width: fit-content; margin: inherit; } +.cardGridItem { + width: 38vw; +} +.justifysp { + display: grid; + width: 100%; + justify-content: space-between; + align-items: baseline; + grid-template-rows: auto; + grid-template-columns: repeat(2, 1fr); + grid-gap: 0.8rem 0.4rem; +} + +@media screen and (max-width: 600px) { + .cardGridItem { + width: 100%; + } + .justifysp { + display: grid; + width: 100%; + justify-content: center; + align-items: start; + grid-template-rows: auto; + grid-template-columns: 1fr; + grid-gap: 0.8rem 0.4rem; + } +} diff --git a/src/components/AddOn/core/AddOnStore/AddOnStore.tsx b/src/components/AddOn/core/AddOnStore/AddOnStore.tsx index 9eb65f9241..2b1e1676eb 100644 --- a/src/components/AddOn/core/AddOnStore/AddOnStore.tsx +++ b/src/components/AddOn/core/AddOnStore/AddOnStore.tsx @@ -1,15 +1,27 @@ import React, { useState } from 'react'; -// import PropTypes from 'react'; import styles from './AddOnStore.module.css'; import AddOnEntry from '../AddOnEntry/AddOnEntry'; -import Action from '../../support/components/Action/Action'; import { useQuery } from '@apollo/client'; import { PLUGIN_GET } from 'GraphQl/Queries/Queries'; // PLUGIN_LIST -import { Col, Form, Row, Tab, Tabs } from 'react-bootstrap'; +import { Col, Dropdown, Form, Row, Tab, Tabs, Button } from 'react-bootstrap'; import PluginHelper from 'components/AddOn/support/services/Plugin.helper'; import { store } from './../../../../state/store'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; +import { Search } from '@mui/icons-material'; + +interface InterfacePluginHelper { + _id: string; + pluginName?: string; + pluginDesc?: string; + pluginCreatedBy: string; + pluginInstallStatus?: boolean; + uninstalledOrgs: string[]; + installed: boolean; + enabled: boolean; + name: string; + component: string; +} function addOnStore(): JSX.Element { const { t } = useTranslation('translation', { keyPrefix: 'addOnStore' }); @@ -18,51 +30,42 @@ function addOnStore(): JSX.Element { const [isStore, setIsStore] = useState(true); const [showEnabled, setShowEnabled] = useState(true); const [searchText, setSearchText] = useState(''); - const [, setDataList] = useState([]); + const [, setDataList] = useState([]); - // type plugData = { pluginName: String, plug }; - const { data, loading } = useQuery(PLUGIN_GET); + const { data, loading } = useQuery<{ getPlugins: InterfacePluginHelper[] }>( + PLUGIN_GET, + ); + console.log(data); - const { orgId } = useParams(); + const { orgId } = useParams<{ orgId: string }>(); /* istanbul ignore next */ const getStorePlugins = async (): Promise => { let plugins = await new PluginHelper().fetchStore(); const installIds = (await new PluginHelper().fetchInstalled()).map( - (plugin: any) => plugin.id, + (plugin: InterfacePluginHelper) => plugin._id, ); - plugins = plugins.map((plugin: any) => { - plugin.installed = installIds.includes(plugin.id); + plugins = plugins.map((plugin: InterfacePluginHelper) => { + plugin.installed = installIds.includes(plugin._id); return plugin; }); store.dispatch({ type: 'UPDATE_STORE', payload: plugins }); }; - /* istanbul ignore next */ - const getInstalledPlugins: () => any = () => { - setDataList(data); - // setRender((current) => !current); - // const { - // data: newData, - // loading: newLoading, - // error: newError, - // } = useQuery(PLUGIN_GET); - // data = newData; - // loading = newLoading; - // error = newError; - // const plugins = await new PluginHelper().fetchInstalled(); - // store.dispatch({ type: 'UPDATE_INSTALLED', payload: plugins }); - // return plugins; + const getInstalledPlugins = (): void => { + if (data) { + setDataList(data.getPlugins); + } }; - const updateSelectedTab = (tab: any): void => { + const updateSelectedTab = (tab: string | null): void => { setIsStore(tab === 'available'); /* istanbul ignore next */ isStore ? getStorePlugins() : getInstalledPlugins(); }; - const filterChange = (ev: any): void => { - setShowEnabled(ev.target.value === 'enabled'); + const filterChange = (eventKey: string): void => { + setShowEnabled(eventKey === 'enabled'); }; /* istanbul ignore next */ @@ -75,9 +78,23 @@ function addOnStore(): JSX.Element { } return ( <> - - - + + +
setSearchText(e.target.value)} /> - + +
{!isStore && ( - -
-
- - -
-
-
+ filterChange(e ? e : '')}> + + {showEnabled ? t('enable') : t('disable')} + + + + {t('enable')} + + + {t('disable')} + + + )} - -
-

{t('pHeading')}

- {searchText ? ( -

- Search results for {searchText} -

- ) : null} - - + + - - {data.getPlugins.filter( - (val: { - _id: string; - pluginName: string | undefined; - pluginDesc: string | undefined; - pluginCreatedBy: string; - pluginInstallStatus: boolean | undefined; - getInstalledPlugins: () => any; - }) => { - if (searchText == '') { - return val; - } else if ( - val.pluginName - ?.toLowerCase() - .includes(searchText.toLowerCase()) - ) { - return val; - } - }, - ).length === 0 ? ( +
+ {data?.getPlugins.filter((val: InterfacePluginHelper) => { + if (searchText == '') { + return val; + } else if ( + val.pluginName + ?.toLowerCase() + .includes(searchText.toLowerCase()) + ) { + return val; + } + }).length === 0 ? (

{t('pMessage')}

) : ( - data.getPlugins - .filter( - (val: { - _id: string; - pluginName: string | undefined; - pluginDesc: string | undefined; - pluginCreatedBy: string; - pluginInstallStatus: boolean | undefined; - getInstalledPlugins: () => any; - }) => { +
+ {data?.getPlugins + .filter((val: InterfacePluginHelper) => { if (searchText == '') { return val; } else if ( @@ -176,51 +165,56 @@ function addOnStore(): JSX.Element { ) { return val; } - }, - ) - .map( - ( - plug: { - _id: string; - pluginName: string | undefined; - pluginDesc: string | undefined; - pluginCreatedBy: string; - uninstalledOrgs: string[]; - getInstalledPlugins: () => any; - }, - i: React.Key | null | undefined, - ): JSX.Element => ( - - ), - ) + }) + .map( + ( + plug: InterfacePluginHelper, + i: React.Key | null | undefined, + ): JSX.Element => ( +
+ +
+ ), + )} +
)} - - - {data.getPlugins +
+
+ +
+ {data?.getPlugins .filter( - (plugin: any) => !plugin.uninstalledOrgs.includes(orgId), + (plugin: InterfacePluginHelper) => + !plugin.uninstalledOrgs.includes(orgId ?? ''), ) - .filter( - (val: { - _id: string; - pluginName: string | undefined; - pluginDesc: string | undefined; - pluginCreatedBy: string; - pluginInstallStatus: boolean | undefined; - getInstalledPlugins: () => any; - }) => { + .filter((val: InterfacePluginHelper) => { + if (searchText === '') { + return val; + } else if ( + val.pluginName + ?.toLowerCase() + .includes(searchText.toLowerCase()) + ) { + return val; + } + }).length === 0 ? ( +

{t('pMessage')}

+ ) : ( + data?.getPlugins + .filter( + (plugin: InterfacePluginHelper) => + !plugin.uninstalledOrgs.includes(orgId ?? ''), + ) + .filter((val: InterfacePluginHelper) => { if (searchText == '') { return val; } else if ( @@ -230,67 +224,31 @@ function addOnStore(): JSX.Element { ) { return val; } - }, - ).length === 0 ? ( -

{t('pMessage')}

- ) : ( - data.getPlugins - .filter( - (plugin: any) => !plugin.uninstalledOrgs.includes(orgId), - ) - .filter( - (val: { - _id: string; - pluginName: string | undefined; - pluginDesc: string | undefined; - pluginCreatedBy: string; - pluginInstallStatus: boolean | undefined; - getInstalledPlugins: () => any; - }) => { - if (searchText == '') { - return val; - } else if ( - val.pluginName - ?.toLowerCase() - .includes(searchText.toLowerCase()) - ) { - return val; - } - }, - ) + }) .map( ( - plug: { - _id: string; - pluginName: string | undefined; - pluginDesc: string | undefined; - pluginCreatedBy: string; - uninstalledOrgs: string[]; - pluginInstallStatus: boolean | undefined; - getInstalledPlugins: () => any; - }, + plug: InterfacePluginHelper, i: React.Key | null | undefined, ): JSX.Element => ( - +
+ +
), ) )} - - -
- +
+ + +
); diff --git a/src/components/AddOn/support/services/Plugin.helper.test.ts b/src/components/AddOn/support/services/Plugin.helper.test.ts index e024734247..39f0a5d12c 100644 --- a/src/components/AddOn/support/services/Plugin.helper.test.ts +++ b/src/components/AddOn/support/services/Plugin.helper.test.ts @@ -9,7 +9,18 @@ describe('Testing src/components/AddOn/support/services/Plugin.helper.ts', () => expect(pluginHelper).toHaveProperty('generateLinks'); }); test('generateLinks should return proper objects', () => { - const obj = { enabled: true, name: 'demo', component: 'samplecomponent' }; + const obj = { + enabled: true, + name: 'demo', + component: 'samplecomponent', + _id: 'someId', + pluginName: 'pluginName', + pluginDesc: 'pluginDesc', + pluginCreatedBy: 'creator', + pluginInstallStatus: true, + uninstalledOrgs: ['org1', 'org2'], + installed: true, + }; const objToMatch = { name: 'demo', url: '/plugin/samplecomponent' }; const pluginHelper = new PluginHelper(); const val = pluginHelper.generateLinks([obj]); diff --git a/src/components/AddOn/support/services/Plugin.helper.ts b/src/components/AddOn/support/services/Plugin.helper.ts index 4730f0c568..1f3ddf8e03 100644 --- a/src/components/AddOn/support/services/Plugin.helper.ts +++ b/src/components/AddOn/support/services/Plugin.helper.ts @@ -1,18 +1,34 @@ +interface InterfacePluginHelper { + _id: string; + pluginName?: string; + pluginDesc?: string; + pluginCreatedBy: string; + pluginInstallStatus?: boolean; + uninstalledOrgs: string[]; + installed: boolean; + enabled: boolean; + name: string; + component: string; +} + class PluginHelper { - fetchStore = async (): Promise => { - const result = await fetch(`http://localhost:${process.env.PORT}/store`); - return await result.json(); + fetchStore = async (): Promise => { + const port = process.env.PORT || '4321'; // Default to 4321 if PORT is not defined + const result = await fetch(`http://localhost:${port}/store`); + return (await result.json()) as InterfacePluginHelper[]; }; - fetchInstalled = async (): Promise => { + fetchInstalled = async (): Promise => { const result = await fetch(`http://localhost:3005/installed`); - return await result.json(); + return (await result.json()) as InterfacePluginHelper[]; }; - generateLinks = (plugins: any[]): { name: string; url: string }[] => { + generateLinks = ( + plugins: InterfacePluginHelper[], + ): { name: string; url: string }[] => { return plugins - .filter((plugin: any) => plugin.enabled) - .map((installedPlugin: any) => { + .filter((plugin) => plugin.enabled) + .map((installedPlugin) => { return { name: installedPlugin.name, url: `/plugin/${installedPlugin.component.toLowerCase()}`, diff --git a/src/components/Advertisements/Advertisements.module.css b/src/components/Advertisements/Advertisements.module.css index 8a34c03be5..6d9eb7f612 100644 --- a/src/components/Advertisements/Advertisements.module.css +++ b/src/components/Advertisements/Advertisements.module.css @@ -1,6 +1,13 @@ .container { display: flex; } +.listBox { + display: grid; + width: 100%; + grid-template-rows: auto; + grid-template-columns: repeat(6, 1fr); + grid-gap: 0.8rem 0.4rem; +} .logintitle { color: #707070; @@ -11,15 +18,24 @@ border-bottom: 3px solid #31bb6b; width: 15%; } - +.input { + display: flex; + position: relative; + width: 560px; +} +.justifysp { + display: grid; + width: 100%; + margin-top: 30px; +} .actioninput { text-decoration: none; - margin-bottom: 50px; + /* margin-bottom: 50px; */ border-color: #e8e5e5; - width: 80%; + background-color: white; border-radius: 7px; - padding-top: 5px; - padding-bottom: 5px; + padding-top: 10px; + padding-bottom: 10px; padding-right: 10px; padding-left: 10px; box-shadow: none; diff --git a/src/components/Advertisements/Advertisements.tsx b/src/components/Advertisements/Advertisements.tsx index 95b95fb936..870ae37263 100644 --- a/src/components/Advertisements/Advertisements.tsx +++ b/src/components/Advertisements/Advertisements.tsx @@ -2,15 +2,17 @@ import React, { useEffect, useState } from 'react'; import styles from './Advertisements.module.css'; import { useQuery } from '@apollo/client'; import { ORGANIZATION_ADVERTISEMENT_LIST } from 'GraphQl/Queries/Queries'; -import { Col, Row, Tab, Tabs } from 'react-bootstrap'; +import { Button, Col, Form, Row, Tab, Tabs } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; import AdvertisementEntry from './core/AdvertisementEntry/AdvertisementEntry'; import AdvertisementRegister from './core/AdvertisementRegister/AdvertisementRegister'; import { useParams } from 'react-router-dom'; import type { InterfaceQueryOrganizationAdvertisementListItem } from 'utils/interfaces'; import InfiniteScroll from 'react-infinite-scroll-component'; +import { Search } from '@mui/icons-material'; export default function advertisements(): JSX.Element { + // const [searchText, setSearchText] = React.useState(); const { orgId: currentOrgId } = useParams(); const { t } = useTranslation('translation', { keyPrefix: 'advertisement' }); document.title = t('title'); @@ -21,8 +23,8 @@ export default function advertisements(): JSX.Element { name: string; type: 'BANNER' | 'MENU' | 'POPUP'; mediaUrl: string; - endDate: string; // Assuming it's a string in the format 'yyyy-MM-dd' - startDate: string; // Assuming it's a string in the format 'yyyy-MM-dd' + endDate: string; + startDate: string; }; const { @@ -32,6 +34,7 @@ export default function advertisements(): JSX.Element { data?: { organizations: InterfaceQueryOrganizationAdvertisementListItem[]; }; + // eslint-disable-next-line refetch: any; } = useQuery(ORGANIZATION_ADVERTISEMENT_LIST, { variables: { @@ -72,15 +75,45 @@ export default function advertisements(): JSX.Element { return ( <> - +
- + +
+ setSearchText("search")} + /> + +
+ + + - + new Date(ad.endDate) > new Date(), ).length !== 0 && (
-
{t('endOfResults')}
+ {/*
{t('endOfResults')}
*/}
) } @@ -155,7 +188,11 @@ export default function advertisements(): JSX.Element { )}
- + new Date(ad.endDate) < new Date(), ).length !== 0 && (
-
{t('endOfResults')}
+ {/*
{t('endOfResults')}
*/}
) } diff --git a/src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.module.css b/src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.module.css index 879d96a0a0..e4f244807f 100644 --- a/src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.module.css +++ b/src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.module.css @@ -20,7 +20,7 @@ .admedia { object-fit: cover; - height: 20rem; + height: 16rem; } .buttons { @@ -28,6 +28,10 @@ justify-content: flex-end; } +.card { + width: 28rem; +} + .dropdownButton { background-color: transparent; color: #000; diff --git a/src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.tsx b/src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.tsx index c6faa21de8..bf534261b8 100644 --- a/src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.tsx +++ b/src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.tsx @@ -10,14 +10,6 @@ import AdvertisementRegister from '../AdvertisementRegister/AdvertisementRegiste import MoreVertIcon from '@mui/icons-material/MoreVert'; import { toast } from 'react-toastify'; -type Ad = { - _id: string; - name: string; - type: 'BANNER' | 'MENU' | 'POPUP'; - mediaUrl: string; - endDate: string; // Assuming it's a string in the format 'yyyy-MM-dd' - startDate: string; // Assuming it's a string in the format 'yyyy-MM-dd' -}; interface InterfaceAddOnEntryProps { id: string; name: string; @@ -26,7 +18,7 @@ interface InterfaceAddOnEntryProps { organizationId: string; startDate: Date; endDate: Date; - setAfter: any; + setAfter: (after: string | null) => void; } function advertisementEntry({ id, @@ -38,6 +30,7 @@ function advertisementEntry({ startDate, setAfter, }: InterfaceAddOnEntryProps): JSX.Element { + console.log(id, type); const { t } = useTranslation('translation', { keyPrefix: 'advertisement' }); const [buttonLoading, setButtonLoading] = useState(false); const [dropdown, setDropdown] = useState(false); @@ -64,9 +57,11 @@ function advertisementEntry({ toast.error('Advertisement Deleted'); setButtonLoading(false); setAfter(null); - } catch (error: any) { - toast.error(error.message); - setButtonLoading(false); + } catch (error: unknown) { + if (error instanceof Error) { + toast.error(error.message); + setButtonLoading(false); + } } }; const handleOptionsClick = (): void => { @@ -77,7 +72,7 @@ function advertisementEntry({ {Array.from({ length: 1 }).map((_, idx) => ( - +