A
Anonymous

User Details Component - Copy this React, Tailwind Component to your project

import-React,-{-useState-}-from-"react";-import-{-Menu-}-from-"@headlessui/react";-import-{-FiMoreVertical,-FiEdit2,-FiTrash2,-FiEye-}-from-"react-icons/fi";-import-{-CSSTransition-}-from-"react-transition-group";-const-UserDetails-=-()-=>-{-const-[users,-setUsers]-=-useState([-{-id:-1,-username:-"john_doe",-email:-"john@example.com",-location:-"New-York",-phone:-"+1-234-567-8900",-role:-"Administrator",-joinDate:-"2023-01-15"-},-{-id:-2,-username:-"jane_smith",-email:-"jane@example.com",-location:-"London",-phone:-"+44-234-567-8900",-role:-"Editor",-joinDate:-"2023-02-20"-},-{-id:-3,-username:-"mike_wilson",-email:-"mike@example.com",-location:-"Tokyo",-phone:-"+81-234-567-8900",-role:-"User",-joinDate:-"2023-03-10"-},-]);-const-[errors,-setErrors]-=-useState({});-const-[editingId,-setEditingId]-=-useState(null);-const-[expandedId,-setExpandedId]-=-useState(null);-const-validateField-=-(name,-value)-=>-{-switch-(name)-{-case-"username":-return-value.length-<-3-?-"Username-must-be-at-least-3-characters"-:-"";-case-"email":-return-!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)-?-"Please-enter-a-valid-email"-:-"";-case-"location":-return-value.length-<-2-?-"Location-must-be-at-least-2-characters"-:-"";-default:-return-"";-}-};-const-handleEdit-=-(id)-=>-{-setEditingId(id);-};-const-handleDelete-=-(id)-=>-{-setUsers(users.filter((user)-=>-user.id-!==-id));-};-const-handleUpdate-=-(id,-field,-value)-=>-{-const-error-=-validateField(field,-value);-setErrors({-...errors,-[`${id}-${field}`]:-error-});-if-(!error)-{-setUsers(-users.map((user)-=>-user.id-===-id-?-{-...user,-[field]:-value-}-:-user-)-);-}-};-const-handleViewDetails-=-(id)-=>-{-setExpandedId(expandedId-===-id-?-null-:-id);-};-return-(-<div-className="min-h-screen-bg-gradient-to-br-from-blue-50-to-indigo-100-p-6">-<div-className="max-w-6xl-mx-auto">-<div-className="bg-white-rounded-xl-shadow-lg-overflow-hidden">-<div-className="overflow-x-auto">-<table-className="min-w-full-divide-y-divide-gray-200">-<thead-className="bg-gray-50">-<tr>-<th-scope="col"-className="px-6-py-3-text-left-text-xs-font-medium-text-gray-500-uppercase-tracking-wider">#</th>-<th-scope="col"-className="px-6-py-3-text-left-text-xs-font-medium-text-gray-500-uppercase-tracking-wider">Username</th>-<th-scope="col"-className="px-6-py-3-text-left-text-xs-font-medium-text-gray-500-uppercase-tracking-wider">Email</th>-<th-scope="col"-className="px-6-py-3-text-left-text-xs-font-medium-text-gray-500-uppercase-tracking-wider">Location</th>-<th-scope="col"-className="px-6-py-3-text-left-text-xs-font-medium-text-gray-500-uppercase-tracking-wider">Actions</th>-</tr>-</thead>-<tbody-className="bg-white-divide-y-divide-gray-200">-{users.map((user,-index)-=>-(-<React.Fragment-key={user.id}>-<tr-className="hover:bg-gray-50-transition-colors">-<td-className="px-6-py-4-whitespace-nowrap-text-sm-text-gray-500">{index-+-1}</td>-<td-className="px-6-py-4-whitespace-nowrap">-<CSSTransition-in={editingId-===-user.id}-timeout={200}-classNames="fade">-<div>-{editingId-===-user.id-?-(-<div>-<input-type="text"-className="form-input-rounded-md-shadow-sm-border-gray-300-focus:border-indigo-300-focus:ring-focus:ring-indigo-200-focus:ring-opacity-50"-value={user.username}-onChange={(e)-=>-handleUpdate(user.id,-"username",-e.target.value)}-aria-label="Username"-/>-{errors[`${user.id}-username`]-&&-(-<p-className="text-red-500-text-xs-mt-1">{errors[`${user.id}-username`]}</p>-)}-</div>-)-:-(-<span-className="text-sm-font-medium-text-gray-900">{user.username}</span>-)}-</div>-</CSSTransition>-</td>-<td-className="px-6-py-4-whitespace-nowrap">-<CSSTransition-in={editingId-===-user.id}-timeout={200}-classNames="fade">-<div>-{editingId-===-user.id-?-(-<div>-<input-type="email"-className="form-input-rounded-md-shadow-sm-border-gray-300-focus:border-indigo-300-focus:ring-focus:ring-indigo-200-focus:ring-opacity-50"-value={user.email}-onChange={(e)-=>-handleUpdate(user.id,-"email",-e.target.value)}-aria-label="Email"-/>-{errors[`${user.id}-email`]-&&-(-<p-className="text-red-500-text-xs-mt-1">{errors[`${user.id}-email`]}</p>-)}-</div>-)-:-(-<span-className="text-sm-text-gray-900">{user.email}</span>-)}-</div>-</CSSTransition>-</td>-<td-className="px-6-py-4-whitespace-nowrap">-<CSSTransition-in={editingId-===-user.id}-timeout={200}-classNames="fade">-<div>-{editingId-===-user.id-?-(-<div>-<input-type="text"-className="form-input-rounded-md-shadow-sm-border-gray-300-focus:border-indigo-300-focus:ring-focus:ring-indigo-200-focus:ring-opacity-50"-value={user.location}-onChange={(e)-=>-handleUpdate(user.id,-"location",-e.target.value)}-aria-label="Location"-/>-{errors[`${user.id}-location`]-&&-(-<p-className="text-red-500-text-xs-mt-1">{errors[`${user.id}-location`]}</p>-)}-</div>-)-:-(-<span-className="text-sm-text-gray-900">{user.location}</span>-)}-</div>-</CSSTransition>-</td>-<td-className="px-6-py-4-whitespace-nowrap-text-right-text-sm-font-medium">-<Menu-as="div"-className="relative-inline-block-text-left">-<Menu.Button-className="inline-flex-justify-center-w-full-rounded-md-border-border-gray-300-shadow-sm-px-4-py-2-bg-white-text-sm-font-medium-text-gray-700-hover:bg-gray-50-focus:outline-none-focus:ring-2-focus:ring-offset-2-focus:ring-indigo-500">-<FiMoreVertical-className="h-5-w-5"-aria-hidden="true"-/>-</Menu.Button>-<Menu.Items-className="origin-top-right-absolute-right-0-mt-2-w-56-rounded-md-shadow-lg-bg-white-ring-1-ring-black-ring-opacity-5-focus:outline-none">-<div-className="py-1">-<Menu.Item>-{({-active-})-=>-(-<button-onClick={()-=>-handleEdit(user.id)}-className={`${active-?-"bg-gray-100-text-gray-900"-:-"text-gray-700"}-group-flex-items-center-px-4-py-2-text-sm-w-full`}->-<FiEdit2-className="mr-3-h-5-w-5-text-gray-400-group-hover:text-gray-500"-aria-hidden="true"-/>-Edit-</button>-)}-</Menu.Item>-<Menu.Item>-{({-active-})-=>-(-<button-onClick={()-=>-handleDelete(user.id)}-className={`${active-?-"bg-gray-100-text-gray-900"-:-"text-gray-700"}-group-flex-items-center-px-4-py-2-text-sm-w-full`}->-<FiTrash2-className="mr-3-h-5-w-5-text-gray-400-group-hover:text-gray-500"-aria-hidden="true"-/>-Delete-</button>-)}-</Menu.Item>-<Menu.Item>-{({-active-})-=>-(-<button-onClick={()-=>-handleViewDetails(user.id)}-className={`${active-?-"bg-gray-100-text-gray-900"-:-"text-gray-700"}-group-flex-items-center-px-4-py-2-text-sm-w-full`}->-<FiEye-className="mr-3-h-5-w-5-text-gray-400-group-hover:text-gray-500"-aria-hidden="true"-/>-View-Details-</button>-)}-</Menu.Item>-</div>-</Menu.Items>-</Menu>-</td>-</tr>-{expandedId-===-user.id-&&-(-<tr>-<td-colSpan="5"-className="px-6-py-4">-<div-className="bg-gray-50-rounded-lg-p-4-shadow-sm">-<div-className="grid-grid-cols-2-gap-4">-<div>-<p-className="text-sm-font-medium-text-gray-500">Phone-Number</p>-<p-className="mt-1-text-sm-text-gray-900">{user.phone}</p>-</div>-<div>-<p-className="text-sm-font-medium-text-gray-500">Role</p>-<p-className="mt-1-text-sm-text-gray-900">{user.role}</p>-</div>-<div>-<p-className="text-sm-font-medium-text-gray-500">Join-Date</p>-<p-className="mt-1-text-sm-text-gray-900">{user.joinDate}</p>-</div>-<div>-<p-className="text-sm-font-medium-text-gray-500">Status</p>-<span-className="mt-1-inline-flex-items-center-px-2.5-py-0.5-rounded-full-text-xs-font-medium-bg-green-100-text-green-800">Active</span>-</div>-</div>-</div>-</td>-</tr>-)}-</React.Fragment>-))}-</tbody>-</table>-</div>-</div>-</div>-</div>-);-};-export-default-UserDetails;

Prompt
Component Preview

About

UserDetailsComponent - Manage user profiles with editable fields, validation, and action menus. Built with React and Tailwind. Get instant access!

Share

Last updated 1 month ago