diff --git a/public/locales/en.json b/public/locales/en.json index 0f7e0ce3b9..d2d3c1366d 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -701,6 +701,8 @@ "archievedAds": "Completed Campaigns", "pMessage": "Ads not present for this campaign.", "delete": "Delete", + "validLink": "Link is valid", + "invalidLink": "Link is invalid", "Rname": "Enter name of Advertisement", "Rtype": "Select type of Advertisement", "Rlink": "Provide a link for content to be displayed", diff --git a/public/locales/fr.json b/public/locales/fr.json index 1dc6d9246a..ba5f9537c4 100644 --- a/public/locales/fr.json +++ b/public/locales/fr.json @@ -696,6 +696,8 @@ "archievedAds": "Campagnes terminées", "pMessage": "Aucune publicité n'est présente pour cette campagne.", "delete": "Supprimer", + "validLink": "Le lien est valide", + "invalidLink": "Le lien n'est pas valide", "close": "Fermer", "deleteAdvertisement": "Supprimer l'annonce", "deleteAdvertisementMsg": "Voulez-vous supprimer cette annonce ?", diff --git a/public/locales/hi.json b/public/locales/hi.json index 985853ad07..a4828051a3 100644 --- a/public/locales/hi.json +++ b/public/locales/hi.json @@ -697,6 +697,8 @@ "archievedAds": "संपन्न अभियान", "pMessage": "इस अभियान के लिए कोई विज्ञापन नहीं हैं।", "delete": "हटाएँ", + "validLink": "लिंक मान्य है", + "invalidLink": "लिंक अमान्य है", "close": "बंद करें", "deleteAdvertisement": "विज्ञापन हटाएं", "deleteAdvertisementMsg": "क्या आप इस विज्ञापन को हटाना चाहते हैं?", diff --git a/public/locales/sp.json b/public/locales/sp.json index 3a1bfce741..97661fc8b7 100644 --- a/public/locales/sp.json +++ b/public/locales/sp.json @@ -696,6 +696,8 @@ "archievedAds": "Campañas completadas", "pMessage": "No hay anuncios disponibles para esta campaña.", "delete": "Eliminar", + "validLink": "El enlace es válido.", + "invalidLink": "El enlace no es válido.", "close": "Cerrar", "deleteAdvertisement": "Eliminar anuncio", "deleteAdvertisementMsg": "¿Desea eliminar este anuncio?", diff --git a/public/locales/zh.json b/public/locales/zh.json index ab2c51ba2e..026d6364a8 100644 --- a/public/locales/zh.json +++ b/public/locales/zh.json @@ -697,6 +697,8 @@ "archievedAds": "已完成的广告活动", "pMessage": "此广告活动没有相关广告。", "delete": "删除", + "validLink": "链接有效", + "invalidLink": "链接无效", "close": "关闭", "deleteAdvertisement": "删除广告", "deleteAdvertisementMsg": "您是否要删除此广告?", diff --git a/src/components/Advertisements/Advertisements.test.tsx b/src/components/Advertisements/Advertisements.test.tsx index 337b335e3b..9f0778c0f6 100644 --- a/src/components/Advertisements/Advertisements.test.tsx +++ b/src/components/Advertisements/Advertisements.test.tsx @@ -213,10 +213,14 @@ describe('Testing Advertisement Component', () => { screen.getByLabelText('Enter name of Advertisement'), 'Cookie Shop' ); + userEvent.click( + screen.getByLabelText('Provide a link for content to be displayed') + ); userEvent.type( screen.getByLabelText('Provide a link for content to be displayed'), 'http://yourwebsite.com/photo' ); + userEvent.click(screen.getByLabelText('Select type of Advertisement')); userEvent.selectOptions( screen.getByLabelText('Select type of Advertisement'), 'POPUP' diff --git a/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.module.css b/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.module.css index 646311041a..164cdf757e 100644 --- a/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.module.css +++ b/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.module.css @@ -17,3 +17,9 @@ background-color: #31bb6b; color: white; } + +.link_check { + display: flex; + justify-content: center; + align-items: flex-start; +} diff --git a/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.test.tsx b/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.test.tsx index 31445780a0..da0c80c1b1 100644 --- a/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.test.tsx +++ b/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.test.tsx @@ -30,6 +30,7 @@ const { getItem } = useLocalStorage(); jest.mock('react-toastify', () => ({ toast: { success: jest.fn(), + warn: jest.fn(), error: jest.fn(), }, })); @@ -110,7 +111,7 @@ describe('Testing Advertisement Register Component', () => { type="BANNER" name="Advert1" orgId="1" - link="google.com" + link="https://google.com" /> } @@ -136,7 +137,7 @@ describe('Testing Advertisement Register Component', () => { type="BANNER" name="Advert1" orgId="1" - link="google.com" + link="https://google.com" formStatus="edit" /> } @@ -163,7 +164,7 @@ describe('Testing Advertisement Register Component', () => { type="BANNER" name="Advert1" orgId="1" - link="google.com" + link="https://google.com" /> } @@ -195,7 +196,7 @@ describe('Testing Advertisement Register Component', () => { type="BANNER" name="Advert1" orgId="1" - link="google.com" + link="https://google.com" /> } @@ -275,8 +276,8 @@ describe('Testing Advertisement Register Component', () => { fireEvent.click(getByText(translations.register)); await waitFor(() => { - expect(toast.error).toBeCalledWith( - 'An error occured, could not create new advertisement' + expect(toast.warn).toBeCalledWith( + 'Link is invalid. Please enter a valid link' ); }); }); diff --git a/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.tsx b/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.tsx index 85c13119fc..b1b5b28b0c 100644 --- a/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.tsx +++ b/src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.tsx @@ -11,6 +11,8 @@ import { useTranslation } from 'react-i18next'; import { toast } from 'react-toastify'; import dayjs from 'dayjs'; import { ADVERTISEMENTS_GET } from 'GraphQl/Queries/Queries'; +import { Check, Clear } from '@mui/icons-material'; +import { isValidLink } from 'utils/linkValidator'; interface InterfaceAddOnRegisterProps { id?: string; // OrgId @@ -50,7 +52,7 @@ function advertisementRegister({ const { t } = useTranslation('translation', { keyPrefix: 'advertisement' }); const [show, setShow] = useState(false); - + const [isInputFocused, setIsInputFocused] = useState(false); const handleClose = (): void => setShow(false); const handleShow = (): void => setShow(true); const [create] = useMutation(ADD_ADVERTISEMENT_MUTATION); @@ -93,6 +95,10 @@ function advertisementRegister({ const handleRegister = async (): Promise => { try { + if (!isValidLink(formState.link)) { + toast.warn('Link is invalid. Please enter a valid link'); + return; + } console.log('At handle register', formState); if (formState.endDate < formState.startDate) { toast.error('End date must be greater than or equal to start date'); @@ -240,6 +246,8 @@ function advertisementRegister({ placeholder={t('EXlink')} autoComplete="off" required + onFocus={(): void => setIsInputFocused(true)} + onBlur={(): void => setIsInputFocused(false)} value={formState.link} onChange={(e): void => { setFormState({ @@ -248,6 +256,21 @@ function advertisementRegister({ }); }} /> +
+ {isInputFocused && ( +

+ {isValidLink(formState.link) ? ( + + {t('validLink')} + + ) : ( + + {t('invalidLink')} + + )} +

+ )} +
{t('Rtype')} diff --git a/src/utils/linkValid.test.tsx b/src/utils/linkValid.test.tsx new file mode 100644 index 0000000000..0cf8a9785b --- /dev/null +++ b/src/utils/linkValid.test.tsx @@ -0,0 +1,15 @@ +import { isValidLink } from './linkValidator'; + +describe('Testing link validator', () => { + it('returns true for a valid link', () => { + const validLink = 'https://www.example.com'; + const result = isValidLink(validLink); + expect(result).toBe(true); + }); + + it('returns false for an invalid link', () => { + const invalidLink = 'not a valid link'; + const result = isValidLink(invalidLink); + expect(result).toBe(false); + }); +}); diff --git a/src/utils/linkValidator.ts b/src/utils/linkValidator.ts new file mode 100644 index 0000000000..fac4766a3b --- /dev/null +++ b/src/utils/linkValidator.ts @@ -0,0 +1,8 @@ +export const isValidLink = (link: string): boolean => { + try { + new URL(link); + return true; + } catch (error) { + return false; + } +};