UNPKG

bd-geo-info

Version:

A comprehensive Bangladesh geographical data package with hierarchical selection and address form components

140 lines (139 loc) 9.4 kB
import React, { useState } from 'react'; import DivisionSelect from './DivisionSelect'; import DistrictSelect from './DistrictSelect'; import UpazilaSelect from './UpazilaSelect'; import UnionSelect from './UnionSelect'; import getPostCode from '../utils/getPostCode'; export default function AddressForm({ language = 'en', onChange, className = '', children, theme, validation, showPostCode = true, showLabels = true, customLabels, customErrors, containerClassName = '', labelClassName = '', errorClassName = '', inputContainerClassName = '' }) { const [address, setAddress] = useState({}); const [errors, setErrors] = useState({}); const [selectedDivision, setSelectedDivision] = useState(); const [selectedDistrict, setSelectedDistrict] = useState(); const [selectedUpazila, setSelectedUpazila] = useState(); const [selectedUnion, setSelectedUnion] = useState(); const handleDivisionChange = (division) => { setSelectedDivision(division); handleChange({ division: language === 'bn' ? division.bn_name : division.name }); }; const handleDistrictChange = (district) => { setSelectedDistrict(district); handleChange({ district: language === 'bn' ? district.bn_name : district.name }); }; const handleUpazilaChange = (upazila) => { setSelectedUpazila(upazila); handleChange({ upazila: language === 'bn' ? upazila.bn_name : upazila.name }); }; const handleUnionChange = (union) => { setSelectedUnion(union); handleChange({ union: language === 'bn' ? union.bn_name : union.name }); }; const validateField = (field, value) => { var _a, _b, _c; if (!(validation === null || validation === void 0 ? void 0 : validation[field])) return true; if (((_a = validation[field]) === null || _a === void 0 ? void 0 : _a.required) && !value) { return language === 'bn' ? 'এই ক্ষেত্রটি আবশ্যক' : 'This field is required'; } if ((_b = validation[field]) === null || _b === void 0 ? void 0 : _b.customValidation) { return (_c = validation[field]) === null || _c === void 0 ? void 0 : _c.customValidation(value); } return true; }; const handleChange = (newData) => { var _a, _b, _c, _d; const updatedAddress = Object.assign(Object.assign({}, address), newData); const newErrors = {}; // Reset dependent fields when parent field changes if ('division' in newData) { updatedAddress.district = undefined; updatedAddress.upazila = undefined; updatedAddress.union = undefined; updatedAddress.postCode = undefined; } else if ('district' in newData) { updatedAddress.upazila = undefined; updatedAddress.union = undefined; updatedAddress.postCode = undefined; } else if ('upazila' in newData) { updatedAddress.union = undefined; // Update postcode when upazila changes const postcodes = getPostCode({ division: ((_a = updatedAddress.division) === null || _a === void 0 ? void 0 : _a.toString()) || '', district: ((_b = updatedAddress.district) === null || _b === void 0 ? void 0 : _b.toString()) || '', upazila: ((_c = updatedAddress.upazila) === null || _c === void 0 ? void 0 : _c.toString()) || '', }); updatedAddress.postCode = (_d = postcodes[0]) === null || _d === void 0 ? void 0 : _d.postCode; } // Validate fields Object.keys(updatedAddress).forEach((key) => { const validationResult = validateField(key, updatedAddress[key]); if (typeof validationResult === 'string') { newErrors[key] = validationResult; } }); setErrors(newErrors); setAddress(updatedAddress); onChange === null || onChange === void 0 ? void 0 : onChange(updatedAddress); }; const getStyles = () => { var _a, _b, _c, _d, _e, _f; if (!theme) { return { '--primary-color': '#3b82f6', '--background-color': '#ffffff', '--border-color': '#e5e7eb', '--border-radius': '0.375rem', '--font-size': '0.875rem', '--padding': '0.625rem 0.875rem', '--margin': '0.5rem', '--select-height': '2.5rem', '--transition': 'all 0.2s ease-in-out', '--hover-border-color': '#93c5fd', '--hover-bg-color': '#f8fafc', '--error-color': '#ef4444', '--label-color': '#374151', '--placeholder-color': '#9ca3af', '--mobile-width': '100%', '--desktop-width': '24rem' }; } return { '--primary-color': ((_a = theme.colors) === null || _a === void 0 ? void 0 : _a.primary) || '#3b82f6', '--background-color': ((_b = theme.colors) === null || _b === void 0 ? void 0 : _b.background) || '#ffffff', '--border-color': ((_c = theme.colors) === null || _c === void 0 ? void 0 : _c.border) || '#e5e7eb', '--border-radius': theme.borderRadius || '0.375rem', '--font-size': ((_d = theme.fontSize) === null || _d === void 0 ? void 0 : _d.input) || '0.875rem', '--padding': ((_e = theme.spacing) === null || _e === void 0 ? void 0 : _e.input) || '0.625rem 0.875rem', '--margin': ((_f = theme.spacing) === null || _f === void 0 ? void 0 : _f.label) || '0.5rem', '--select-height': '2.5rem', '--transition': 'all 0.2s ease-in-out', '--hover-border-color': '#93c5fd', '--hover-bg-color': '#f8fafc', '--error-color': '#ef4444', '--label-color': '#374151', '--placeholder-color': '#9ca3af', '--mobile-width': '100%', '--desktop-width': '24rem' }; }; const selectProps = { theme, errorClassName: `${errorClassName} text-[var(--error-color)] text-xs mt-1`, labelClassName: `${labelClassName} block text-[var(--label-color)] text-sm font-medium mb-2`, containerClassName: `${inputContainerClassName} flex flex-col mb-6 w-full md:w-[var(--desktop-width)]`, language, className: `w-full h-[var(--select-height)] px-4 py-2.5 bg-[var(--background-color)] border border-[var(--border-color)] rounded-[var(--border-radius)] text-[var(--font-size)] transition-[var(--transition)] focus:outline-none focus:ring-2 focus:ring-[var(--primary-color)] focus:border-transparent hover:border-[var(--hover-border-color)] hover:bg-[var(--hover-bg-color)] disabled:opacity-50 disabled:cursor-not-allowed shadow-sm` }; return (React.createElement("div", { className: `${containerClassName} bg-white rounded-lg shadow-sm w-full max-w-[1200px] mx-auto p-6`, style: getStyles() }, React.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" }, React.createElement("div", { className: "relative" }, React.createElement(DivisionSelect, Object.assign({}, selectProps, { value: selectedDivision, onChange: handleDivisionChange, placeholder: language === 'bn' ? 'বিভাগ নির্বাচন করুন' : 'Select Division', customLabel: customLabels === null || customLabels === void 0 ? void 0 : customLabels.division, customError: (customErrors === null || customErrors === void 0 ? void 0 : customErrors.division) || errors.division }))), React.createElement("div", { className: "relative" }, React.createElement(DistrictSelect, Object.assign({}, selectProps, { division: selectedDivision, value: selectedDistrict, onChange: handleDistrictChange, placeholder: language === 'bn' ? 'জেলা নির্বাচন করুন' : 'Select District', customLabel: customLabels === null || customLabels === void 0 ? void 0 : customLabels.district, customError: (customErrors === null || customErrors === void 0 ? void 0 : customErrors.district) || errors.district }))), React.createElement("div", { className: "relative" }, React.createElement(UpazilaSelect, Object.assign({}, selectProps, { district: selectedDistrict, value: selectedUpazila, onChange: handleUpazilaChange, placeholder: language === 'bn' ? 'উপজেলা নির্বাচন করুন' : 'Select Upazila', customLabel: customLabels === null || customLabels === void 0 ? void 0 : customLabels.upazila, customError: (customErrors === null || customErrors === void 0 ? void 0 : customErrors.upazila) || errors.upazila }))), React.createElement("div", { className: "relative" }, React.createElement(UnionSelect, Object.assign({}, selectProps, { upazila: selectedUpazila, value: selectedUnion, onChange: handleUnionChange, placeholder: language === 'bn' ? 'ইউনিয়ন নির্বাচন করুন' : 'Select Union', customLabel: customLabels === null || customLabels === void 0 ? void 0 : customLabels.union, customError: (customErrors === null || customErrors === void 0 ? void 0 : customErrors.union) || errors.union })))), children)); }