I have a function that shows a list of customers and their details. However, when I click on the name of the customer, I want a drawer to open. The data within that draw should be specific to the customer (which I originally fetched). Plus I have a tab within the drawer that will fetch additional data for the customer based on their userID. I need this userID
passed on from the initial list to the Drawer. I am stuck here because I am unable to figure out how to make that connection between the list and the Drawer
.
import React, { useState, useEffect } from "react";
import axios from "axios";
import { Button, Space, Descriptions, Tabs, List, Avatar, Drawer } from "antd";
import { BulbOutlined, MessageOutlined } from "@ant-design/icons";
import UserIdeas from "./UserIdeas";
import UserMessages from "./UserMessages";
const UserDrawer = () => {
const [user_list, getData] = useState("");
//get a list of users and their information. UserID is the key
//Data looks like this
// [ {title: 'Ahmed xxx', userId:1, email: 'ahmed@xx.com' , location: 'Canada' }, {title: 'Ahmed2 xxx', userId:2, email: 'ahmed2@xx.com' , location: 'Canada' },]
const getAllData = () => {
var user_access_token = localStorage.getItem("user_access_token");
axios
.get(process.env.REACT_APP_API_URL + "reports/product/1/users", {
headers: {
Authorization: "Bearer " + user_access_token,
},
})
.then((response) => {
const allData = response.data;
getData(allData);
})
.catch((error) => console.error(error));
};
useEffect(() => {
getAllData();
}, []);
const [open, setOpen] = useState(false);
const [size, setSize] = useState();
const showLargeDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
//Menu of the Tabs. Need to pass the UserId for each customer to the component to display the data associated with the user
const items = [
{
key: "1",
label: (
<span>
<BulbOutlined /> Ideas
</span>
),
children: <UserIdeas user_id={item.userId} />,
},
{
key: "2",
label: (
<span>
<MessageOutlined /> Comments
</span>
),
children: <UserMessages user_id={item.userId} />,
},
];
return (
<>
<List
itemLayout="vertical"
dataSource={user_list}
renderItem={(item) => (
<List.Item>
<List.Item.Meta
title={
<a onClick={showLargeDrawer} key={`a-${item.userId}`}>
{item.title}
</a>
}
/>
</List.Item>
)}
/>
<Drawer
title={item.title} //show the title of the user
placement="right"
size={size}
onClose={onClose}
open={open}
// dataSource={user_list}
extra={
<Space>
{" "}
<Button type="primary" onClick={onClose}>
close
</Button>
</Space>
}
>
<Descriptions>
<Descriptions.Item label="E-Mail Address"> {email}</Descriptions.Item>
<Descriptions.Item label="Location">{location}</Descriptions.Item>
</Descriptions>
<Tabs
tabPosition={"left"}
defaultActiveKey="1"
items={items}
closable
/>
</Drawer>
</>
);
};
export default UserDrawer;
You need a couple of things to show the correct data on the drawer. The first one is to add a state that stores the selected user index on your list.
const [selectedUser, setSelectedUser] = useState(null);
By default no user will be selected
You also have to change the function showLargeDrawer to something like this, where you get the element where userId is the same that the one on the clicked item, store it on selectedUser and setOpen to true
const showLargeDrawer = (userId) => {
const chosenUser = user_list?.find(user=>user.userId===userId) ?? null;
setSelectedUser(chosenUser);
setOpen(true);
};
And on the onclick function on the List
onClick={()=>showLargeDrawer(item.userId)}
Finally on the Description you simply show the properties of the selectedUser
<Descriptions>
<Descriptions.Item label="E-Mail Address">
{selectedUser?.email ?? 'No email found'}
</Descriptions.Item>
<Descriptions.Item label="Location">
{selectedUser?.location ?? 'No location found'}
</Descriptions.Item>
</Descriptions>
With this additions to your code it will work the way you want to.