Preview: gravity-form.ts
Size: 7.24 KB
/var/www/nea-dev-frontend.wpress.dk/httpdocs/src/utils/gravity-form.ts
export const getGravityAuthHeader = () => {
const consumerKey = process.env.GF_ACCESS_KEY;
const consumerSecret = process.env.GF_ACCESS_SECRET;
if (!consumerKey || !consumerSecret) {
throw new Error(
'GF_ACCESS_KEY and GF_ACCESS_SECRET must be set in .env.local for Gravity Forms API authentication.'
);
}
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString('base64');
return auth;
};
export const getGravityBaseUrl = () => {
const baseUrl = process.env.GRAVITY_FORMS_BASE_URL;
if (!baseUrl) {
throw new Error(
'GRAVITY_FORMS_BASE_URL is not set. Add it to your .env.local (e.g. GRAVITY_FORMS_BASE_URL=https://your-wordpress-site.com) and restart the dev server.'
);
}
return `${baseUrl}/wp-json/gf/v2`;
};
export type GravityFormData = {
fields: any[];
button?: {
text?: string;
layoutGridColumnSpan?: string;
};
[key: string]: unknown;
};
export async function fetchFormFields(
formId: string,
): Promise<{ data: GravityFormData | null; error: string | null }> {
try {
if (!formId) {
throw new Error('Form ID is required');
}
const url = getGravityBaseUrl();
const form_url = `${url}/forms/${formId}`;
const auth = getGravityAuthHeader();
const revalidateTime = process.env.NODE_ENV === 'development' ? 0 : 36000;
const response = await fetch(form_url, {
method: 'GET',
headers: {
Authorization: `Basic ${auth}`,
'Content-Type': 'application/json',
},
next: {
revalidate: revalidateTime,
tags: ['global', 'form', `form-${formId}`],
},
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.message || `Failed to fetch fields: ${response.status}`);
}
const data = await response.json();
if (!data.fields) {
throw new Error('No fields found in response');
}
return {
data: {
fields: data.fields || [],
button: data.button || null,
...data,
},
error: null,
};
} catch (error) {
console.error('Error fetching form fields:', error);
return {
data: null,
error: error instanceof Error ? error.message : 'Failed to fetch form fields',
};
}
}
type ConditionalRule = {
fieldId: string;
operator: string;
value: string;
}
export const evaluateConditionalLogic = (field: any, fieldValues: any): boolean => {
if (!field.conditionalLogic || !field.conditionalLogic.enabled) {
return true;
}
const { actionType, logicType, rules } = field.conditionalLogic;
const ruleResults = rules.map((rule: ConditionalRule) => {
const fieldValue = fieldValues[rule.fieldId];
// console.log("fieldValue", fieldValue);
// console.log("rule", rule);
const isEmpty =
fieldValue === undefined ||
fieldValue === null ||
fieldValue === '' ||
(Array.isArray(fieldValue) && fieldValue.length === 0);
if (rule.value === '') {
if (rule.operator === 'is') {
return isEmpty;
}
if (rule.operator === 'isnot') {
return !isEmpty;
}
}
// Skip further evaluation if the field is empty and we're not explicitly checking for emptiness
if (isEmpty && rule.value !== '') {
// When field is empty, only "is empty" should be true, all other conditions are false
return false;
}
switch (rule.operator) {
case 'is':
if (Array.isArray(fieldValue)) {
return fieldValue.includes(rule.value);
}
if (fieldValue == "true") {
return "1" === rule.value
};
return fieldValue === rule.value;
case 'isnot':
if (Array.isArray(fieldValue)) {
return !fieldValue.includes(rule.value);
}
if (fieldValue == "false") {
return "1" !== rule.value
};
return fieldValue !== rule.value;
case 'contains':
return typeof fieldValue === 'string' && fieldValue.includes(rule.value);
case 'greater_than':
return Number(fieldValue) > Number(rule.value);
case 'less_than':
return Number(fieldValue) < Number(rule.value);
case 'starts_with':
return typeof fieldValue === 'string' && fieldValue.startsWith(rule.value);
case 'ends_with':
return typeof fieldValue === 'string' && fieldValue.endsWith(rule.value);
default:
return false;
}
});
let shouldShow: boolean;
if (logicType === 'all') {
shouldShow = ruleResults.every((result: any) => result);
} else {
shouldShow = ruleResults.some((result: any) => result);
}
// Invert the result if the action type is 'hide'
return actionType === 'show' ? shouldShow : !shouldShow;
};
// Helper function to determine file type based on extension
// utils/fileUtils.ts
// Core MIME type mapper
function getMimeTypeByExtension(ext: string): string {
ext = ext.trim().toLowerCase();
if (!ext.startsWith('.')) ext = '.' + ext;
switch (ext) {
case '.pdf': return 'application/pdf';
case '.doc': return 'application/msword';
case '.docx': return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
case '.odt': return 'application/vnd.oasis.opendocument.text';
case '.rtf': return 'application/rtf';
case '.txt': return 'text/plain';
case '.csv': return 'text/csv';
case '.tsv': return 'text/tab-separated-values';
case '.xls': return 'application/vnd.ms-excel';
case '.xlsx': return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
case '.ods': return 'application/vnd.oasis.opendocument.spreadsheet';
case '.ppt': return 'application/vnd.ms-powerpoint';
case '.pptx': return 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
case '.odp': return 'application/vnd.oasis.opendocument.presentation';
case '.jpg': return 'image/jpg';
case '.jpeg': return 'image/jpeg';
case '.png': return 'image/png';
case '.gif': return 'image/gif';
case '.bmp': return 'image/bmp';
case '.tiff':
case '.tif': return 'image/tiff';
case '.svg': return 'image/svg+xml';
case '.webp': return 'image/webp';
case '.ico': return 'image/x-icon';
case '.mp3': return 'audio/mpeg';
case '.wav': return 'audio/wav';
case '.ogg': return 'audio/ogg';
case '.mp4': return 'video/mp4';
case '.mov': return 'video/quicktime';
case '.avi': return 'video/x-msvideo';
case '.wmv': return 'video/x-ms-wmv';
case '.mkv': return 'video/x-matroska';
case '.zip': return 'application/zip';
case '.rar': return 'application/vnd.rar';
case '.7z': return 'application/x-7z-compressed';
case '.tar': return 'application/x-tar';
case '.gz': return 'application/gzip';
case '.json': return 'application/json';
case '.xml': return 'application/xml';
case '.html':
case '.htm': return 'text/html';
case '.md': return 'text/markdown';
default: return ext; // fallback: return original ext as `.ext` string
}
}
// Exposed function: accepts filename or extension (your original version)
export function getFileType(filename: string = "", extension: string = ""): string {
let ext = extension ? extension : (filename.includes('.') ? filename.split('.').pop() || '' : '');
return getMimeTypeByExtension(ext);
}
Directory Contents
Dirs: 0 × Files: 2