Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI/clients list page progress #189

Merged
merged 11 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 39 additions & 28 deletions app/javascript/src/components/Clients/Client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,41 +31,52 @@ export const Client = ({
setClientToDelete,
setShowDeleteDialog
}: IClient) => {
const [grayColor, setGrayColor] = React.useState("");
const [isHover, setHover] = React.useState(false);
ajinkyaa marked this conversation as resolved.
Show resolved Hide resolved

const handleMouseEnter = () => {
setGrayColor("bg-miru-gray-100");
setHover(true);
};

const handleMouseLeave = () => {
setGrayColor("");
setHover(false);
};

return (
<tr key={id}>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-miru-dark-purple-1000">
<tr key={id} className={`last:border-b-0 ${grayColor}`} onMouseLeave={handleMouseLeave} onMouseEnter={handleMouseEnter}>
<td className="px-6 py-6 whitespace-nowrap text-sm font-medium text-miru-dark-purple-1000">
{name}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-miru-dark-purple-1000">
<td className="px-6 py-6 whitespace-nowrap text-sm font-medium text-miru-dark-purple-1000">
{email}
</td>
<td className="px-6 py-4 whitespace-nowrap text-right font-black">
<td className="px-6 py-6 whitespace-nowrap text-right font-black">
{hoursLogged}
</td>
{isAdminUser && (
<>
<td className="px-2 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
onClick={() => {
setShowEditDialog(true);
setClientToEdit({ id, name, email, phone, address });
}}
>
<img src={editIcon} alt="" />
</button>
</td>
<td className="px-2 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
onClick={() => {
setShowDeleteDialog(true);
setClientToDelete({ id, name });
}}
>
<img src={deleteIcon} alt="" />
</button>
</td>
</>
)}
<td className="px-2 py-4 whitespace-nowrap text-right text-sm font-medium">
{isAdminUser && isHover && <button
onClick={() => {
setShowEditDialog(true);
setClientToEdit({ id, name, email, phone, address });
}}
>
<img src={editIcon} alt="" />
</button>
}
</td>
<td className="px-2 py-4 whitespace-nowrap text-right text-sm font-medium">
{ isAdminUser && isHover && <button
onClick={() => {
setShowDeleteDialog(true);
setClientToDelete({ id, name });
}}
>
<img src={deleteIcon} alt="" />
</button>
}
</td>
</tr>
);
};
92 changes: 92 additions & 0 deletions app/javascript/src/components/Clients/ClientBarGraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as React from "react";
import ReactTooltip from "react-tooltip";

const getRandomColor = (index) => {
const chartColor = ["miru-chart-green", "miru-chart-blue", "miru-chart-pink", "miru-chart-orange"];
const chartColorIndex = index%4;
return chartColor[chartColorIndex];
};

const GetClientBar = ({ client, totalHours, index }) => {
ajinkyaa marked this conversation as resolved.
Show resolved Hide resolved
const hourPercentage = (client.hoursLogged * 100)/totalHours;
const divStyle = {
width: `${hourPercentage}%`
};
const randomColor = getRandomColor(index);

return (
<div style={divStyle}>
<ReactTooltip id={`registerTip-${index}`} effect="solid" backgroundColor="white" textColor="black" place="top">
<p>{client.name}</p>
<p className="text-center">{client.hoursLogged}</p>
</ReactTooltip>
<button data-tip data-for={`registerTip-${index}`} type="button" className={`bg-${randomColor}-600 w-full h-4 block border-b border-t hover:border-transparent`}></button>
</div>
);
};

const ClientBarGraph = ({ clients , totalHours }) => {
return (
<div className="bg-miru-gray-100 py-10 px-10">
<div className="flex justify-end">
<select className="px-3
py-1.5
text-base
font-normal
bg-transparent bg-clip-padding bg-no-repeat
border-none
transition
ease-in-out
m-0
focus:outline-none
text-miru-dark-purple-600">
<option className="text-miru-dark-purple-600" value="Jon Smith">
THIS WEEK
</option>
</select>
</div>
<p className="mb-3 text-miru-dark-purple-600">
TOTAL HOURS: <span>{totalHours}</span>
</p>
<div className="w-full bg-gray-200 flex h-1">
{clients.map((client, index) => {
return <GetClientBar
client={client}
key={index}
index={index}
totalHours={totalHours}
/>;
})
}
</div>
<div className="flex miru-dark-purple-400 text-normal border-b-2 border-miru-gray-1000 border-b-miru-gray-1000 pb-6 justify-between mt-3">
<span>
0
</span>
<span>
{totalHours}
</span>
</div>
<div className="flex pt-6">
<div className="flex-auto border-r-2 py-2 border-miru-gray-1000 border-r-miru-gray-1000">
<p className="text-miru-dark-purple-600">
OVERDUE
</p>
<h4 className="text-4xl text-miru-dark-purple-600 mt-3">
$35.3K
</h4>
</div>
<div className="flex-auto py-2 pl-5">
<p className="text-miru-dark-purple-600">
OUTSTANDING
</p>
<h4 className="text-4xl mt-3 text-miru-dark-purple-600">
$35.3K
</h4>
</div>
</div>
</div>
);
};

export default ClientBarGraph;
ajinkyaa marked this conversation as resolved.
Show resolved Hide resolved
21 changes: 16 additions & 5 deletions app/javascript/src/components/Clients/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@ import { setAuthHeaders, registerIntercepts } from "apis/axios";

import DeleteClient from "components/Clients/DeleteClient";
import { Client } from "./Client";
import ClientBarGraph from "./ClientBarGraph";
import EditClient from "./EditClient";

const getTotalHours = (clients) => {
let hours = 0;
clients.forEach((item) => {
hours = item.hoursLogged + hours;
});
return hours;
};

const Clients = ({ clients, editIcon, deleteIcon, isAdminUser }) => {
const [showEditDialog, setShowEditDialog] = React.useState<boolean>(false);
const [showDeleteDialog, setShowDeleteDialog] =
React.useState<boolean>(false);
const [clientToEdit, setClientToEdit] = React.useState({});
const [clientToDelete, setClientToDelete] = React.useState({});
const totalHours:number = getTotalHours(clients);

React.useEffect(() => {
setAuthHeaders();
Expand All @@ -25,25 +35,26 @@ const Clients = ({ clients, editIcon, deleteIcon, isAdminUser }) => {
<div className="flex flex-col">
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div className="overflow-hidden border-b-2 border-miru-gray-200">
{ isAdminUser && <ClientBarGraph clients={clients} totalHours={totalHours} /> }
<div className="overflow-hidden">
<table className="min-w-full divide-y divide-gray-200 mt-4">
<thead className="bg-gray-50">
<thead>
<tr>
<th
scope="col"
className="px-6 py-5 text-left text-sm font-semibold text-miru-dark-purple-600 tracking-wider"
className="px-6 py-5 text-left text-tabHeader font-semibold text-miru-dark-purple-600 tracking-wider"
>
CLIENT
</th>
<th
scope="col"
className="px-6 py-5 text-left text-sm font-semibold text-miru-dark-purple-600 tracking-wider"
className="px-6 py-5 text-left text-tabHeader font-semibold text-miru-dark-purple-600 tracking-wider"
>
EMAIL ID
</th>
<th
scope="col"
className="px-6 py-5 text-right text-sm font-semibold text-miru-dark-purple-600 tracking-wider"
className="px-6 py-5 text-right text-tabHeader font-semibold text-miru-dark-purple-600 tracking-wider"
>
HOURS LOGGED
</th>
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@
"postcss": "~7",
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react_ujs": "^2.6.1",
"react-dom": "^17.0.2",
"react-router-dom": "^6.1.1",
"react-toastify": "^8.1.0",
"react-tooltip": "^4.2.21",
"react_ujs": "^2.6.1",
"tailwindcss": "npm:@tailwindcss/postcss7-compat",
"toastr": "^2.1.4",
"typescript": "^4.5.4",
Expand Down Expand Up @@ -79,6 +80,8 @@
"cy:run:staging": "cypress run --browser chrome --headless --record --env configFile=staging --record --key 78e63e75-c093-4cfa-bc9b-d01afbb2aa49",
"cy:open:staging": "cypress open --env configFile=staging",
"lint": "eslint ./cypress",
"lint:fix": "eslint --fix ./cypress"
"lint:fix": "eslint --fix ./cypress",
"lint:ui": "eslint ./app/javascript/src",
"lint:ui:fix": "eslint --fix ./app/javascript/src"
}
}
3 changes: 2 additions & 1 deletion tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ module.exports = {
}
},
fontSize: {
zxl: ["2.5rem", { letterSpacing: "0.05em", lineHeight: "1" }]
zxl: ["2.5rem", { letterSpacing: "0.05em", lineHeight: "1" }],
tabHeader : [ "0.75rem", { letterSpacing: "0.125" }]
},
boxShadow: {
c1: "0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); transition: all 0.3s cubic-bezier(.25,.8,.25,1);"
Expand Down
13 changes: 13 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7477,6 +7477,14 @@ react-toastify@^8.1.0:
dependencies:
clsx "^1.1.1"

react-tooltip@^4.2.21:
version "4.2.21"
resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-4.2.21.tgz#840123ed86cf33d50ddde8ec8813b2960bfded7f"
integrity sha512-zSLprMymBDowknr0KVDiJ05IjZn9mQhhg4PRsqln0OZtURAJ1snt1xi5daZfagsh6vfsziZrc9pErPTDY1ACig==
dependencies:
prop-types "^15.7.2"
uuid "^7.0.3"

react@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
Expand Down Expand Up @@ -8990,6 +8998,11 @@ uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==

uuid@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b"
integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==

uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
Expand Down