Skip to content

Commit

Permalink
feat: social link validator added
Browse files Browse the repository at this point in the history
  • Loading branch information
mythter committed Sep 20, 2024
1 parent 715aeb1 commit 5299b69
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable import/extensions */

import { doesUrlContainSiteName, isInvalidUrl } from '@/app/common/utils/checkUrl';
import SocialItem from '@/models/social-link/socialItem';

export default function validateSocialLink<T>(
link: string,
socialOptions: SocialItem<T>[],
logoTypes: string[],
sourceLinks: { logoType: T }[],
socialName: string,
): Promise<unknown> {
if (!link || isInvalidUrl(link)) {
return Promise.reject(new Error(
'Недійсний формат посилання',
));
}

const logotype = socialOptions.find((opt) => opt.value === socialName)?.logo;
if (logotype === undefined // we need this explicit check because it can pass when logotype is 0
|| logotype === null
|| (!doesUrlContainSiteName(link, logoTypes[Number(logotype)]))) {
return Promise.reject(new Error(
'Посилання не співпадає з вибраним текстом',
));
}

const doesLinkWithLogoTypeAlreadyExist = sourceLinks.some((obj) => obj.logoType === Number(logotype));
if (doesLinkWithLogoTypeAlreadyExist) {
return Promise.reject(new Error(
'Посилання на таку соціальну мережу вже додано',
));
}

return Promise.resolve();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import TextArea from 'antd/es/input/TextArea';

import FileUploader from '@/app/common/components/FileUploader/FileUploader.component';
import base64ToUrl from '@/app/common/utils/base64ToUrl.utility';
import { doesUrlContainSiteName, isInvalidUrl } from '@/app/common/utils/checkUrl';
import validateSocialLink from '@/app/common/components/modals/validators/socialLinkValidator';
import ImageStore from '@/app/stores/image-store';
import PartnerLink from '@/features/AdminPage/PartnersPage/PartnerLink.component';
import Audio from '@/models/media/audio.model';
Expand Down Expand Up @@ -51,6 +51,7 @@ const PartnerModal: React.FC< {
}) => {
// eslint-disable-next-line max-len,no-useless-escape
const URL_REGEX_VALIDATION_PATTERN = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,256}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/;
const LOGO_TYPES = Object.keys(LogoType).filter((key) => Number.isNaN(Number(key)));
const [form] = Form.useForm();
const [urlTitleEnabled, setUrlTitleEnabled] = useState<string>('');
const [urlTitleValue, setUrlTitleValue] = useState<string>('');
Expand Down Expand Up @@ -508,29 +509,14 @@ const PartnerModal: React.FC< {
},
{
validator: (_, value) => {
if (!value || isInvalidUrl(value)) {
return Promise.reject(new Error(
'Недійсний формат посилання',
));
}

const socialName = partnerLinksForm.getFieldValue('logotype');
const logotype = SOCIAL_OPTIONS.find((opt) => opt.value === socialName)?.logo;
if (logotype === undefined // we need this explicit undefined check because it can pass when logotype is 0
|| (!doesUrlContainSiteName(value, LogoType[logotype]))) {
return Promise.reject(new Error(
'Посилання не співпадає з вибраним текстом',
));
}

const doesLinkWithLogoTypeAlreadyExist = partnerSourceLinks.some((obj) => obj.logoType === Number(logotype));
if (doesLinkWithLogoTypeAlreadyExist) {
return Promise.reject(new Error(
'Посилання на таку соціальну мережу вже додано',
));
}

return Promise.resolve();
return validateSocialLink<LogoType>(
value,
SOCIAL_OPTIONS,
LOGO_TYPES,
partnerSourceLinks,
socialName,
);
},
},
]}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { LogoType } from '@/models/team/team.model';
/* eslint-disable import/extensions */

interface SocialItem {
label: string
value: string
logo: LogoType
}
import { LogoType } from '@/models/partners/partners.model';
import SocialItem from '@/models/social-link/socialItem';

const SOCIAL_OPTIONS: SocialItem[] = [
const SOCIAL_OPTIONS: SocialItem<LogoType>[] = [
{
value: 'x',
label: 'X',
Expand Down
33 changes: 9 additions & 24 deletions src/features/AdminPage/TeamPage/TeamModal/TeamModal.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ import { Option } from 'antd/es/mentions';
import PositionsApi from '@/app/api/team/positions.api';
import FileUploader from '@/app/common/components/FileUploader/FileUploader.component';
import base64ToUrl from '@/app/common/utils/base64ToUrl.utility';
import { doesUrlContainSiteName, isInvalidUrl } from '@/app/common/utils/checkUrl';
import validateSocialLink from '@/app/common/components/modals/validators/socialLinkValidator';
import TeamLink from '@/features/AdminPage/TeamPage/TeamLink.component';
import Audio from '@/models/media/audio.model';
import Image from '@/models/media/image.model';

import POPOVER_CONTENT from '../../JobsPage/JobsModal/constants/popoverContent';
import { constant } from 'lodash';

const TeamModal: React.FC<{
teamMember?: TeamMember, open: boolean,
setIsModalOpen: React.Dispatch<React.SetStateAction<boolean>>, afterSubmit?: (team: TeamCreateUpdate) => void
}> = observer(({ teamMember, open, setIsModalOpen, afterSubmit }) => {
const LOGO_TYPES = Object.keys(LogoType).filter((key) => Number.isNaN(Number(key)));
const [form] = Form.useForm();
const { teamStore } = useMobx();
const [positions, setPositions] = useState<Positions[]>([]);
Expand Down Expand Up @@ -371,29 +371,14 @@ const TeamModal: React.FC<{
{ required: true, message: 'Введіть посилання' },
{
validator: (_, value) => {
if (!value || isInvalidUrl(value)) {
return Promise.reject(new Error(
'Недійсний формат посилання',
));
}

const socialName = teamLinksForm.getFieldValue('logotype');
const logotype = SOCIAL_OPTIONS.find((opt) => opt.value === socialName)?.logo;
if (logotype === undefined // we need this explicit undefined check because it can pass when logotype is 0
|| (logotype !== LogoType.http && !doesUrlContainSiteName(value, LogoType[logotype]))) {
return Promise.reject(new Error(
'Посилання не співпадає з вибраним текстом',
));
}

const doesLinkWithLogoTypeAlreadyExist = teamSourceLinks.some((obj) => obj.logoType === Number(logotype));
if (doesLinkWithLogoTypeAlreadyExist) {
return Promise.reject(new Error(
'Посилання на таку соціальну мережу вже додано',
));
}

return Promise.resolve();
return validateSocialLink<LogoType>(
value,
SOCIAL_OPTIONS,
LOGO_TYPES,
teamSourceLinks,
socialName,
);
},
},
]}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/* eslint-disable import/extensions */

import SocialItem from '@/models/social-link/socialItem';
import { LogoType } from '@/models/team/team.model';

interface SocialItem {
label: string
value: string
logo: LogoType
}
const SOCIAL_OPTIONS: SocialItem[] = [
const SOCIAL_OPTIONS: SocialItem<LogoType>[] = [
{
value: 'x.com',
label: 'X',
Expand Down
5 changes: 5 additions & 0 deletions src/models/social-link/socialItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default interface SocialItem<T> {
label: string
value: string
logo: T
}

0 comments on commit 5299b69

Please sign in to comment.