UNPKG

ar-design

Version:

AR Design is a (react | nextjs) ui library.

148 lines (147 loc) 6.29 kB
"use client"; import { useEffect, useRef, useState } from "react"; import Utils from "../../../infrastructure/shared/Utils"; const useValidation = function (data, params, step) { // refs const _errors = useRef({}); // states const [errors, setErrors] = useState({}); const [submit, setSubmit] = useState(false); // methods const onSubmit = (callback) => { setSubmit(true); queueMicrotask(() => { let result = true; if (!data || Object.keys(data).length === 0 || params.length === 0) result = false; if (step) { const filteredErrors = Object.fromEntries(Object.entries(_errors.current) .filter(([key]) => key.startsWith(`${step}_`)) .map(([key, value]) => [key.replace(/^\d+_/, ""), String(value)])); if (Object.keys(filteredErrors).length > 0) result = false; } else { if (Object.keys(_errors.current).length > 0) result = false; } callback(result); }); }; const setError = (key, message, step, trackByValue) => { let _key = step ? `${step}_${key}` : key; if (trackByValue !== undefined) _key = `${_key}_${trackByValue}`; setErrors((prev) => ({ ...prev, [_key]: message })); _errors.current = { ..._errors.current, [_key]: message }; }; const handleParams = (param) => { const value = data[param.key]; // Eğer subkey varsa, onunla işlem yapılacak. if (param.subkey) { if (param.subkey.includes(".")) { // Subkey içinde birden fazla seviye varsa, her seviyeye inerek değer alınacak. const levels = param.subkey.split("."); let currentData = value; for (const key of levels) { // Eğer currentData null ya da undefined ise, işlem sonlandırılır. if (!currentData) { paramsShape(param, currentData); return; } // Seviye bazında ilerleyerek veriye ulaşılır. currentData = currentData[key]; } // Son seviyedeki veriyi paramsShape fonksiyonuna gönder. paramsShape(param, currentData); } else { if (Array.isArray(value)) { // Eğer value bir dizi ise ve subkey sadece bir seviye ise, // dizinin her bir elemanına subkey uygulanabilir. const extractedValues = value.map((item) => ({ value: item?.[param.subkey], trackByValue: item?.trackByValue, })); // Elde edilen değerler topluca paramsShape'e gönderilebilir ya da başka bir şekilde işlenebilir. extractedValues.map((extractedValue) => paramsShape(param, extractedValue.value, extractedValue.trackByValue)); } else { // Value bir obje ise, subkey doğrudan kullanılır. paramsShape(param, value?.[param.subkey]); } } } else { // Eğer subkey yoksa, doğrudan param.key üzerinden işlem yapılır. paramsShape(param, value); } }; const paramsShape = (param, value, trackByValue) => { const vLenght = value ? value.length : 0; const getKey = (subkey) => { if (!subkey) return param.key; const levels = subkey.split("."); return levels[levels.length - 1]; }; const handleValidation = (key, s) => { if (s.type === "required" && Utils.IsNullOrEmpty(value)) { setError(key, s.message, param.step, trackByValue); } if (s.type === "minimum" && vLenght < s.value) { setError(key, Utils.StringFormat(s.message, s.value), param.step, trackByValue); } if (s.type === "maximum" && vLenght > s.value) { setError(key, Utils.StringFormat(s.message, s.value), param.step, trackByValue); } // Regexes // const phoneRegex = /^((\+90|0)?([2-5]\d{2})\d{7}|\+[1-9]\d{7,14})$/; const phoneRegex = /^\d{7,14}$/; const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; const ibanRegex = /^TR\d{24}$/; const accountNumberRegex = /^\d{6,16}$/; if (s.type === "phone" && value && !phoneRegex.test(value.replace(/\D/g, ""))) { setError(key, s.message, param.step, trackByValue); } if (s.type === "email" && value && !emailRegex.test(value)) { setError(key, s.message, param.step, trackByValue); } if (s.type === "iban" && value && !ibanRegex.test(value.replace(/\s/g, ""))) { setError(key, s.message, param.step, trackByValue); } if (s.type === "account-number" && value && !accountNumberRegex.test(value)) { setError(key, s.message, param.step, trackByValue); } }; param.shape?.forEach((s) => { const key = getKey(param.subkey); if (param.where) { if (param.where(data)) { setError(param.subkey ? key : param.key, s.message, param.step, trackByValue); } } else { handleValidation(key, s); } }); }; // useEffects useEffect(() => { setErrors({}); _errors.current = {}; if (!submit) return; params.forEach((param) => handleParams(param)); }, [submit, data]); return { onSubmit, setSubmit, errors: step ? Object.fromEntries(Object.entries(errors) .filter(([key]) => key.startsWith(`${step}_`)) .map(([key, value]) => [key.replace(/^\d+_/, ""), String(value)])) : errors, }; }; export default useValidation;