Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | 6x 6x 22x 22x 22x 21x 6x 79x 79x 22x 22x 43x 43x 43x 2x 41x 2x 43x 3x 43x 2x 43x 8x 2x 43x 20x 2x 18x 19x 18x 3x 43x 38x 38x 5x 43x 8x 8x 8x 2x 43x 41x 41x 1x 43x 9x 9x 2x 43x 9x 9x 2x 43x 4x 4x 2x 43x 43x 43x 43x 43x 2x 43x 2x 2x 2x 43x 2x 2x 3x 2x 1x 1x 43x 43x 2x 43x 7x 7x 7x 2x 43x 2x 43x | const URL_PATH_FORMAT = /^(\/[^/]+){0,}\/?$/;
const URL_ALLOWED_CHARS = /^[A-Za-z0-9\-.*=%()_&?/:+]*$/;
function isValidTargetUrl(rawValue) {
const value = (rawValue || '').trim();
Iif (!value) return true;
if (value === '.*') return true;
return URL_PATH_FORMAT.test(value) && URL_ALLOWED_CHARS.test(value);
}
function invalidUrlMessage(value) {
return `Invalid URL "${value}" — must start with "/" and contain only letters, digits, and - . * = % ( ) _ & ? / : +`;
}
function findInvalidUrl(urlItems) {
Iif (!Array.isArray(urlItems)) return null;
return (
urlItems.find((item) => {
const trimmed = item?.targetUrl?.trim();
return trimmed && !isValidTargetUrl(trimmed);
}) || null
);
}
export default function validateTargetForm(
formData,
{ saveAsTemplate, templateName } = {},
) {
const errors = {};
const trimmedName = formData.name?.trim() || '';
if (!trimmedName) {
errors.name = 'Target name is required';
} else if (trimmedName.length < 3) {
errors.name = 'Name must be at least 3 characters';
}
if (!formData.description?.trim()) {
errors.description = 'Description is required';
}
if (!formData.clients || formData.clients.length === 0) {
errors.clients = 'At least one client type must be selected';
}
if (formData.clients && formData.clients.includes('EMAIL')) {
if (!formData.emailType) {
errors.emailType = 'Email template type is required when Email client is selected';
}
}
if (formData.clients && formData.clients.includes('SITE')) {
if (!formData.targetURLs || formData.targetURLs.length === 0) {
errors.targetURLs = 'At least one Target URL is required when Site client is selected';
} else {
const incompleteURLs = formData.targetURLs.some(
(urlItem) => !urlItem.targetUrl?.trim(),
);
if (incompleteURLs) {
errors.targetURLs = 'All Target URLs must be filled';
}
}
}
if (!errors.targetURLs) {
const invalidUrl = findInvalidUrl(formData.targetURLs);
if (invalidUrl) {
errors.targetURLs = invalidUrlMessage(invalidUrl.targetUrl.trim());
}
}
if (formData.targetUrlsExc && formData.targetUrlsExc.length > 0) {
const incompleteURLsExc = formData.targetUrlsExc.some(
(urlItem) => !urlItem.targetUrl?.trim(),
);
if (incompleteURLsExc) {
errors.targetUrlsExc = 'All Excluded URLs must be filled';
}
}
if (!errors.targetUrlsExc) {
const invalidExcUrl = findInvalidUrl(formData.targetUrlsExc);
if (invalidExcUrl) {
errors.targetUrlsExc = invalidUrlMessage(invalidExcUrl.targetUrl.trim());
}
}
if (formData.latitude !== null && formData.latitude !== '') {
const lat = parseFloat(formData.latitude);
if (Number.isNaN(lat) || lat < -90 || lat > 90) {
errors.latitude = 'Latitude must be between -90 and 90';
}
}
if (formData.longitude !== null && formData.longitude !== '') {
const lon = parseFloat(formData.longitude);
if (Number.isNaN(lon) || lon < -180 || lon > 180) {
errors.longitude = 'Longitude must be between -180 and 180';
}
}
if (formData.dmaValues?.trim()) {
const dmaPattern = /^(([0-9]+)(,(?=[0-9]))?)+$/;
if (!dmaPattern.test(formData.dmaValues.trim())) {
errors.dmaValues = 'DMA codes must be comma-separated numbers (e.g., 501, 524, 803)';
}
}
const hasStates = formData.states?.length > 0;
const hasZip = formData.zipCode?.trim()
|| formData.zipStartRange
|| formData.zipRanges?.length > 0;
const hasDma = formData.dmaValues?.trim();
const filledCount = [hasStates, hasZip, hasDma].filter(Boolean).length;
if (filledCount > 1) {
errors.states = 'Only one of States, Zip Codes, or DMA can be filled at a time';
}
if (formData.zipMode === 'range') {
Eif (formData.zipStartRange && formData.zipEndRange) {
Eif (formData.zipStartRange >= formData.zipEndRange) {
errors.zipStartRange = 'Start zip must be less than end zip';
}
}
}
if (formData.zipMode === 'listRange') {
Eif (formData.zipRanges && Array.isArray(formData.zipRanges)) {
formData.zipRanges.forEach((range, idx) => {
if (!range || !range.start || !range.end) {
errors[`zipRanges[${idx}]`] = 'Both start and end zip are required';
} else Eif (range.start >= range.end) {
errors[`zipRanges[${idx}]`] = 'Start zip must be less than end zip';
}
});
}
}
const urlPattern = /^https?:\/\/.+/;
if (
formData.previousLocation
&& !urlPattern.test(formData.previousLocation)
) {
errors.previousLocation = 'Must be a valid URL starting with http:// or https://';
}
if (
formData.targetCookies
&& Array.isArray(formData.targetCookies)
&& formData.targetCookies.length > 0
) {
const incompleteCookies = formData.targetCookies.some(
(c) => !c || !c.name || !c.value || !c.operator,
);
if (incompleteCookies) {
errors.targetCookies = 'All cookie fields must be filled';
}
}
if (saveAsTemplate && !templateName?.trim()) {
errors.templateName = 'Template name is required';
}
return errors;
}
|