• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atlp-rwanda / vikings-ec-fe / 6a81dcf9-2e6d-40d4-b78b-4b7d0bc9415e

pending completion
6a81dcf9-2e6d-40d4-b78b-4b7d0bc9415e

push

circleci

GitHub
feat: implement Display Users (#22)

245 of 445 branches covered (55.06%)

Branch coverage included in aggregate %.

163 of 163 new or added lines in 9 files covered. (100.0%)

1043 of 1308 relevant lines covered (79.74%)

9.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

32.0
/src/components/users/UserRow.js
1
import React, { useState } from 'react'
2
import { useDispatch, useSelector } from 'react-redux';
3
import loader from "../../../public/images/icons/loader.svg";
4
import prof from "../../../public/images/prof.png";
5
import source from "../../assets/threeDot.svg";
6
import DropChildren from "../DropDown";
7
import { getUserActions } from "../../features/auth/userSlice";
8
import { showErrorMessage, showSuccessMessage } from "../../utils/toast";
9
import { changeStatus } from "../../features/auth/changeUserStatusSlice";
10
import { updateRole } from "../../features/auth/rolesSlice";
11

12
export default function UserRow({ user}) {
13
  const { isLoading, data: rolesData } = useSelector((state) => state.roles);
2✔
14
  const { isLoading: loadingStatus } = useSelector(
2✔
15
    (state) => state.changeStatus
2✔
16
  );
17
  const dispatch = useDispatch()
2✔
18
  const [loading,setLoading] = useState(false);
2✔
19
  
20
  const handleUpdateRole = async (userId, role) => {
2✔
21
    try {
×
22
      setLoading(true);
×
23
      const response = await dispatch(
×
24
        updateRole({
25
          payload: { role: role },
26
          id: userId,
27
        })
28
      );
29
      if (response.type === "updateRole/fulfilled") {
×
30
        dispatch(
×
31
          getUserActions.changeField({ userId, field: "role", value: role })
32
        );
33
        showSuccessMessage(response.payload.message);
×
34
      }
35
      setLoading(false)
×
36
    } catch (error) {
37
      showErrorMessage(error.data.message);
×
38
      setLoading(false)
×
39
    }
40
  };
41

42
  const handleStatusChange = async (userId, isActive) => {
2✔
43
    try {
×
44
      setLoading(true);
×
45
      const response = await dispatch(
×
46
        changeStatus({
47
          payload: { isActive: isActive },
48
          id: userId,
49
        })
50
      );
51
      if (response.type === "changeStatus/fulfilled") {
×
52
        dispatch(
×
53
          getUserActions.changeField({
54
            userId,
55
            field: "isActive",
56
            value: isActive,
57
          })
58
        );
59
        showSuccessMessage(response.payload.message);
×
60
      }
61
      setLoading(false)
×
62
    } catch (error) {
63
      showErrorMessage(error.data.message);
×
64
      setLoading(false)
×
65

66
    }
67
  };
68

69
  return (
2✔
70
    <tr className="bg-white border-b" >
71
                <td className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap ">
72
                  <div className="flex items-center">
73
                    {user.avatar ? (
2!
74
                      <img
75
                        src={`${user.avatar}`}
76
                        className="w-8 h-8 rounded-full mr-2"
77
                      />
78
                    ) : (
79
                      <img src={prof} className="w-8 h-8 rounded-full mr-2" />
80
                    )}
81
                    <div>
82
                      <div>{`${user.firstname}`}</div>
83
                      <div className="text-xs text-gray-400">
84
                        {user.lastname}
85
                      </div>
86
                    </div>
87
                  </div>
88
                </td>
89
                <td className="px-6 py-4">
90
                  {`${user.email}`}
91
                  <div className="text-[12px] text-gray-400">
92
                    {user.verified ? "verified" : "not verified"}
2!
93
                  </div>
94
                </td>
95
                <td className="px-6 py-4">{isLoading && loading ? (
4!
96
                              <img
97
                                src={loader}
98
                                className="animate-spin w-[30px] text-center"
99
                              />
100
                            ) : user.role}</td>
101
                <td>
102
                  <button
103
                    className={`px-3 py-1 text-white rounded-2xl text-center ${
104
                      user.isActive ? "bg-green-600" : "bg-red-600"
2!
105
                    }`}
106
                  >
107
                    {loadingStatus && loading ? (
4!
108
                              <img
109
                                src={loader}
110
                                className="animate-spin w-[30px] text-center"
111
                              />
112
                            ) : (user.isActive ? "Active" : "Disabled")}
2!
113
                  </button>
114
                </td>
115
                <td className="">
116
                  <DropChildren
117
                    toggle={
118
                      <img
119
                        src={source}
120
                        className="filter grayscale "
121
                        type="button"
122
                        data-dropdown-toggle="userDropdown"
123
                        data-dropdown-placement="bottom-start"
124
                      />
125
                    }
126
                  >
127
                    <div id="userDropdown" className=" bg-white">
128
                      <div className="px-4 py-3 text-sm  text-black dark:text-white">
129
                        <div className="text-black">
130
                          {`${user.firstname} ${user.lastname}`}
131
                        </div>
132
                        <div className="font-medium truncate text-gray-400">
133
                          {user.email}
134
                        </div>
135
                      </div>
136
                      <ul
137
                        className="py-2 text-sm text-gray-700 dark:text-gray-200"
138
                        aria-labelledby="avatarButton"
139
                      >
140
                        <li>
141
                          <a
142
                            href="#"
143
                            className="block px-4 py-2 text-black hover:bg-gray-100 dark:hover:bg-green-600 dark:hover:text-white"
144
                            onClick={() => handleUpdateRole(user.id, "admin")}
×
145
                          >
146
                            Make admin
147
                          </a>
148
                        </li>
149
                        <li>
150
                          <a
151
                            href="#"
152
                            className="block px-4 py-2 text-black hover:bg-gray-100 dark:hover:bg-green-600 dark:hover:text-white"
153
                            onClick={() => handleUpdateRole(user.id, "seller")}
×
154
                          >
155
                            Make seller
156
                          </a>
157
                        </li>
158
                        <li>
159
                          <a
160
                            href="#"
161
                            className="block px-4 py-2 text-black hover:bg-gray-100 dark:hover:bg-green-600 dark:hover:text-white"
162
                            onClick={() => handleUpdateRole(user.id, "buyer")}
×
163
                          >
164
                            Make buyer
165
                          </a>
166
                        </li>
167
                        <li>
168
                          <a
169
                            href="#"
170
                            className="block px-4 py-2 text-black hover:bg-gray-100 dark:hover:bg-red-600 dark:hover:text-white"
171
                            onClick={() =>
172
                              handleStatusChange(user.id, !user.isActive)
×
173
                            }
174
                          >
175
                            change account status
176
                          </a>
177
                        </li>
178
                      </ul>
179
                    </div>
180
                  </DropChildren>
181
                </td>
182
              </tr>
183
  )
184
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc