UNPKG

ar-design

Version:

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

159 lines (158 loc) 6.4 kB
import { useContext, useEffect, useRef, useState } from "react"; import { ConfigContext } from "../contexts/Config"; import { NotificationContext } from "../contexts/Notification"; import Utils from "../../../infrastructure/shared/Utils"; import { LanguageContext } from "../contexts/Language"; import { LoadingContext } from "../contexts/Loading"; import { NotificationTR, NotificationEN } from "../locales"; export const useLayout = () => { const context = useContext(ConfigContext); if (!context) throw new Error("useLayout must be used within a LayoutProvider"); return context; }; export const useLoading = () => useContext(LoadingContext); export const useLanguage = () => useContext(LanguageContext); export const useTranslation = function (currentLanguage, translations) { const merged = { tr: { ...translations?.tr, ...NotificationTR }, en: { ...translations?.en, ...NotificationEN }, }; const t = (key, ...args) => { return Utils.StringFormat(merged[currentLanguage ?? "tr"][key], args) ?? ""; }; return { t, currentLanguage }; }; export const useNotification = () => { // contexts const { setTitle, setMessage, setStatus, setTrigger, setIsPopupOpen, setPopupButtons } = useContext(NotificationContext); // methods const notification = ({ title, message, status }) => { setTitle && setTitle(title); setMessage && setMessage(message ?? ""); setStatus && setStatus(status); setTrigger && setTrigger((trigger) => !trigger); }; const popup = ({ title, message, status, }, buttons) => { setTitle && setTitle(title); setMessage && setMessage(message ?? ""); setStatus && setStatus(status); setIsPopupOpen && setIsPopupOpen((trigger) => !trigger); setPopupButtons && setPopupButtons(buttons ?? null); }; return { notification, popup }; }; export 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); setTimeout(() => { 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); }, 0); }; const setError = (key, message, step) => { const _key = step ? `${step}_${key}` : key; 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 { // Subkey sadece bir seviye ise, 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) => { 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); } if (s.type === "minimum" && vLenght < s.value) { setError(key, Utils.StringFormat(s.message, s.value), param.step); } if (s.type === "maximum" && vLenght > s.value) { setError(key, Utils.StringFormat(s.message, s.value), param.step); } if (s.type === "email" && value && !/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)) { setError(key, s.message, param.step); } }; param.shape?.forEach((s) => { const key = getKey(param.subkey); if (param.where) { if (s.type === "required" && !param.where(data)) { Utils.IsNullOrEmpty(value) && setError(param.subkey ? key : param.key, s.message, param.step); } } 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, }; };