diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..6edfdbc81e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,18 @@ +{ + "javascript.format.insertSpaceAfterCommaDelimiter": true, + "javascript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": true, + "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": true, + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true, + "editor.renderWhitespace": "boundary", + "editor.fontSize": 14, + "editor.rulers": [ + 100, + 120 + ], + "editor.tabSize": 2, + "javascript.updateImportsOnFileMove.enabled": "never", + "workbench.iconTheme": "material-icon-theme", + "workbench.colorTheme": "Oceanic Plus" +} diff --git a/app/javascript/src/components/Clients/ChartBar.tsx b/app/javascript/src/components/Clients/ChartBar.tsx new file mode 100644 index 0000000000..bf26a29509 --- /dev/null +++ b/app/javascript/src/components/Clients/ChartBar.tsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import ReactTooltip from "react-tooltip"; +import { IChartBarGraph } from './interface'; + +const GetClientBar = ({ client, totalHours, index }:IChartBarGraph) => { + const chartColor = ["miru-chart-green", "miru-chart-blue", "miru-chart-pink", "miru-chart-orange"]; + const chartColorIndex = index%4; + const randomColor = chartColor[chartColorIndex]; + + const hourPercentage = (client.hoursLogged * 100)/totalHours; + + const divStyle = { + width: `${hourPercentage}%` + }; + return ( +
+ +

{client.name}

+

{client.hoursLogged}

+
+ +
+ ); +}; + +export default GetClientBar; diff --git a/app/javascript/src/components/Clients/Client.tsx b/app/javascript/src/components/Clients/Client.tsx index 1351297d8b..0bcbe5e75a 100644 --- a/app/javascript/src/components/Clients/Client.tsx +++ b/app/javascript/src/components/Clients/Client.tsx @@ -31,41 +31,52 @@ export const Client = ({ setClientToDelete, setShowDeleteDialog }: IClient) => { + const [grayColor, setGrayColor] = React.useState(""); + const [isHover, setHover] = React.useState(false); + + const handleMouseEnter = () => { + setGrayColor("bg-miru-gray-100"); + setHover(true); + }; + + const handleMouseLeave = () => { + setGrayColor(""); + setHover(false); + }; + return ( - - + + {name} - + {email} - + {hoursLogged} - {isAdminUser && ( - <> - - - - - - - - )} + + {isAdminUser && isHover && + } + + + { isAdminUser && isHover && + } + ); }; diff --git a/app/javascript/src/components/Clients/ClientBarGraph.tsx b/app/javascript/src/components/Clients/ClientBarGraph.tsx new file mode 100644 index 0000000000..9f920aad10 --- /dev/null +++ b/app/javascript/src/components/Clients/ClientBarGraph.tsx @@ -0,0 +1,69 @@ +import * as React from "react"; +import GetClientBar from "./ChartBar"; +import { IChartBar } from './interface'; + +const ClientBarGraph = ({ clients , totalHours }:IChartBar) => { + return ( +
+
+ +
+

+ TOTAL HOURS: {totalHours} +

+
+ {clients.map((client, index) => { + return ; + }) + } +
+
+ + 0 + + + {totalHours} + +
+
+
+

+ OVERDUE +

+

+ $35.3K +

+
+
+

+ OUTSTANDING +

+

+ $35.3K +

+
+
+
+ ); +}; + +export default ClientBarGraph; diff --git a/app/javascript/src/components/Clients/index.tsx b/app/javascript/src/components/Clients/index.tsx index 75d6381162..c9cbf612c8 100644 --- a/app/javascript/src/components/Clients/index.tsx +++ b/app/javascript/src/components/Clients/index.tsx @@ -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(false); const [showDeleteDialog, setShowDeleteDialog] = React.useState(false); const [clientToEdit, setClientToEdit] = React.useState({}); const [clientToDelete, setClientToDelete] = React.useState({}); + const totalHours:number = getTotalHours(clients); React.useEffect(() => { setAuthHeaders(); @@ -25,25 +35,26 @@ const Clients = ({ clients, editIcon, deleteIcon, isAdminUser }) => {
-
+ { isAdminUser && } +
- + diff --git a/app/javascript/src/components/Clients/interface.ts b/app/javascript/src/components/Clients/interface.ts new file mode 100644 index 0000000000..ab2cd7ce49 --- /dev/null +++ b/app/javascript/src/components/Clients/interface.ts @@ -0,0 +1,27 @@ +interface ClientArray { + clients: [{ + id: number; + name: string; + email: string; + phone: string; + address: string; + hoursLogged: string; + editIcon: string; + deleteIcon: string; + isAdminUser: boolean; + setShowEditDialog: any; + setClientToEdit: any; + setClientToDelete: any; + setShowDeleteDialog: any; + }]; +} + +export interface IChartBar extends ClientArray { + totalHours: number; +} + +export interface IChartBarGraph { + totalHours: number; + index: number; + client: any; +} diff --git a/package.json b/package.json index ac243bb295..c3db0aaf2f 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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" } } diff --git a/tailwind.config.js b/tailwind.config.js index 8b88613171..d1f84e510f 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -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);" diff --git a/yarn.lock b/yarn.lock index 6fae1b6e59..2dd97ff6d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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" @@ -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"
CLIENT EMAIL ID HOURS LOGGED