THN
Trường Huy Nguyễn

User Modify Modal - Copy this React, Tailwind Component to your project

Use this code to generate UI import { useState, useEffect } from "react"; import { IoMdClose } from "react icons/io"; import { FiMail, FiUser } from "react icons/fi"; import { MdMessage } from "react icons/md"; import axios from "axios"; import { currentHost } from "../../../configs/serverConfigs"; import ApiHelper from "../../utils/ApiHelper"; const UserModifyModal = ({ isOpen, onClose, actionType, user, isDisabled }) => { console.log("🚀 ~ UserModifyModal ~ user:", user) const [formData, setFormData] = useState({ fullName: "", email: "", socialAccountLimit: "" }); const [permissions, setPermissions] = useState([]); const [selectedPermissions, setSelectedPermissions] = useState([]); const [errors, setErrors] = useState({}); const [emailSuggestions, setEmailSuggestions] = useState([]); const [showSuggestions, setShowSuggestions] = useState(false); const emailDomains = ["@gmail.com", "@yahoo.com", "@outlook.com", "@hotmail.com"]; useEffect(() => { const fetchPermissions = async () => { try { const formData = new FormData(); formData.append("PageIndex", 1); formData.append("PageSize", 100); formData.append("Keyword", ""); const response = await axios.post(currentHost + "/api/permission/list", formData, { headers: { 'Content Type': 'multipart/form data' } }); setPermissions(response.data.data.items); } catch (error) { console.error("Error fetching permissions:", error); } }; if (isOpen) { if (user) { const api = new ApiHelper(currentHost); let response = api.getUserDetail(user.userId); response.then(res => { console.log("🚀 ~ response.then ~ res:", res) setFormData({ fullName: res.data.fullName, email: res.data.email, socialAccountLimit: res.data.socialAccountLimit }); console.log("res.data", res.data); setSelectedPermissions(res.data.permissions.map((permission) => permission.permissionId)); }); if (isDisabled) { setFormData(prevState => ({ ...prevState, fullName: prevState.fullName, email: prevState.email, socialAccountLimit: prevState.socialAccountLimit })); document.querySelectorAll('input, textarea, select').forEach(element => { element.setAttribute('readonly', ''); }); document.querySelector('button[type="submit"]').style.display = 'none'; } } else { setFormData({ fullName: "", email: "", socialAccountLimit: "" }); setSelectedPermissions([]); } fetchPermissions(); console.log("🚀 ~ useEffect ~ user:", user) document.body.style.overflow = "hidden"; } else { document.body.style.overflow = "unset"; } return () => { document.body.style.overflow = "unset"; }; }, [isOpen]); const validateEmail = (email) => { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email); }; const handleInputChange = (e) => { const { name, value } = e.target; setFormData({ ...formData, [name]: value }); if (name === "email" && !value.includes("@")) { const suggestions = emailDomains.map(domain => value + domain); setEmailSuggestions(suggestions); setShowSuggestions(true); } else { setShowSuggestions(false); } if (errors[name]) { setErrors({ ...errors, [name]: "" }); } }; const handlePermissionChange = (permissionId) => { setSelectedPermissions(prev => prev.includes(permissionId) ? prev.filter(id => id !== permissionId) : [...prev, permissionId] ); }; const handleSubmit = (e) => { e.preventDefault(); const newErrors = {}; if (!formData.fullName.trim()) { newErrors.name = "Name is required"; } if (!formData.email.trim()) { newErrors.email = "Email is required"; } else if (!validateEmail(formData.email)) { newErrors.email = "Please enter a valid email"; } if (!formData.socialAccountLimit) { newErrors.socialAccountLimit = "Social account limit is required"; } if (Object.keys(newErrors).length > 0) { setErrors(newErrors); return; } const api = new ApiHelper(currentHost); if (actionType === "CREATE") { const jsonData = { ...formData, permissions: selectedPermissions }; console.log("🚀 ~ handleSubmit ~ jsonData:", jsonData) api.addUser(jsonData); } else if (actionType === "UPDATE") { const userData = { ...formData, userId: user.userId }; console.log("🚀 ~ handleSubmit ~ jsonData:", userData) api.updateUser(userData); const permissionData = { userId: user.userId, permissions: selectedPermissions }; api.updatePermission(permissionData); console.log("🚀 ~ handleSubmit ~ permissionData:", permissionData) } onClose(); setFormData({ fullName: "", email: "", socialAccountLimit: "" }); setSelectedPermissions([]); }; const selectEmailSuggestion = (suggestion) => { setFormData({ ...formData, email: suggestion }); setShowSuggestions(false); }; if (!isOpen) return null; return ( <div style={{ marginLeft: '280px' }} className="fixed inset 0 z 50 flex items center justify center p 4 bg black bg opacity 50 animate fadeIn"> <div className="bg white rounded xl shadow 2xl w full max w 4xl relative overflow hidden animate slideIn"> <div className="flex justify between items center p 6 border b"> <h2 className="text 2xl font semibold text gray 800">User Information & Permissions</h2> <button onClick={onClose} className="text gray 500 hover:text gray 700 transition colors duration 300" aria label="Close modal" > <IoMdClose size={24} /> </button> </div> <div className="grid grid cols 1 md:grid cols 2 gap 6 p 6"> <div className="md:col span 1 space y 4"> <form onSubmit={handleSubmit}> <div> <label className="block text sm font medium text gray 700 mb 1"> Họ tên </label> <div className="relative"> <FiUser className="absolute left 3 top 1/2 transform translate y 1/2 text gray 400" /> <input type="text" name="fullName" value={formData.fullName} onChange={handleInputChange} className={`w full pl 10 pr 4 py 2 border rounded lg focus:ring 2 focus:ring blue 500 outline none transition all duration 300 ${errors.name ? "border red 500" : "border gray 300"}`} placeholder="Tên người dùng" aria label="Name" /> </div> {errors.name && ( <p className="text red 500 text sm mt 1">{errors.name}</p> )} </div> <div className="mt 4"> <label className="block text sm font medium text gray 700 mb 1"> Email </label> <div className="relative"> <FiMail className="absolute left 3 top 1/2 transform translate y 1/2 text gray 400" /> <input type="email" name="email" value={formData.email} onChange={handleInputChange} className={`w full pl 10 pr 4 py 2 border rounded lg focus:ring 2 focus:ring blue 500 outline none transition all duration 300 ${errors.email ? "border red 500" : "border gray 300"}`} placeholder="Email" aria label="Email" /> {showSuggestions && ( <div className="absolute z 10 w full mt 1 bg white border rounded lg shadow lg"> {emailSuggestions.map((suggestion, index) => ( <div key={index} onClick={() => selectEmailSuggestion(suggestion)} className="px 4 py 2 hover:bg gray 100 cursor pointer" > {suggestion} </div> ))} </div> )} </div> {errors.email && ( <p className="text red 500 text sm mt 1">{errors.email}</p> )} </div> <div className="mt 4"> <label className="block text sm font medium text gray 700 mb 1"> Số lượng account giới hạn </label> <div className="relative"> <MdMessage className="absolute left 3 top 3 text gray 400" /> <input type="number" name="socialAccountLimit" value={formData.socialAccountLimit} onChange={handleInputChange} rows="4" className={`w full pl 10 pr 4 py 2 border rounded lg focus:ring 2 focus:ring blue 500 outline none transition all duration 300 ${errors.message ? "border red 500" : "border gray 300"}`} placeholder="Số lượng account giới hạn" aria label="socialAccountLimit" ></input> </div> {errors.message && ( <p className="text red 500 text sm mt 1">{errors.message}</p> )} </div> </form> </div> <div className="md:col span 1 bg gray 50 p 6 rounded lg"> <h3 className="text lg font semibold text gray 800 mb 4">User Permissions</h3> <div className="space y 3 max h [400px] overflow y auto"> {permissions && permissions.length > 0 ? ( <div> {/* Ô checkbox "Chọn tất cả" */} <div className="flex items center mb 6"> <input type="checkbox" id="select all" checked={selectedPermissions.length === permissions.length} onChange={() => { if (selectedPermissions.length === permissions.length) { // Bỏ chọn tất cả nếu đã chọn hết setSelectedPermissions([]); } else { // Chọn tất cả các quyền setSelectedPermissions(permissions.map((permission) => permission.permissionId)); } }} className="w 4 h 4 text blue 600 border gray 300 rounded focus:ring blue 500" /> <label htmlFor="select all" className="ml 3 text sm font medium text gray 700"> <b>Chọn tất cả</b> </label> </div> {/* Danh sách các quyền */} {permissions.map((permission) => ( <div key={permission.permissionId} className="flex items center"> <input type="checkbox" id={`permission ${permission.permissionId}`} checked={selectedPermissions.includes(permission.permissionId)} onChange={() => handlePermissionChange(permission.permissionId)} className="w 4 h 4 text blue 600 border gray 300 rounded focus:ring blue 500" /> <label htmlFor={`permission ${permission.permissionId}`} className="ml 3 text sm font medium text gray 700" > {permission.permissionName} </label> </div> ))} </div> ) : ( <p>Loading...</p> )} </div> </div> </div> <div className="p 6 border t bg gray 50 flex justify center items center"> <button onClick={handleSubmit} className="w full bg blue 600 text white py 2 rounded lg hover:bg blue 700 transition colors duration 300 transform hover:scale [1.02] w 1/2" aria label="Submit form" > Gửi </button> </div> </div> </div> ); }; export default UserModifyModal;

Prompt
Component Preview

About

UserModifyModal - Easily edit user details and permissions with a responsive UI built with React and Tailwind. Features email suggesti. Download instantly!

Share

Last updated 1 month ago