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

Project details design #226

Merged
merged 25 commits into from
Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b772b59
Refactor projects page to use react component
shalapatil Mar 16, 2022
2a34682
Add internal api to get projects list
shalapatil Mar 16, 2022
010099a
Add projects index page component file
shalapatil Mar 16, 2022
3d8e700
Add project details to project's index page
shalapatil Mar 16, 2022
04308e0
Add component for project list
shalapatil Mar 17, 2022
1df957e
Show project details page when project gets clicked
shalapatil Mar 17, 2022
9aa24b8
Add API to fetch project details
shalapatil Mar 21, 2022
ad2f54a
Render project details on project page
shalapatil Mar 21, 2022
e4521fc
Add react component for member
shalapatil Mar 24, 2022
6304e72
Fix the suggested changes
shalapatil Mar 24, 2022
5f6970a
Merge remote-tracking branch 'origin/develop' into refactor-projects-…
shalapatil Mar 25, 2022
d8d0636
Fix integration for project details page
shalapatil Mar 25, 2022
1c5a649
Merge remote-tracking branch 'origin/develop' into refactor-projects-…
shalapatil Mar 28, 2022
77fac8a
project details design
Mar 29, 2022
f3db697
conflict resolved
Mar 29, 2022
e002703
project details page
Mar 30, 2022
1b868bf
lint fixes
Mar 30, 2022
6e0a7d2
bannerbox menu and client name updated
Mar 30, 2022
9e2a59c
Merge branch 'develop' into project-details-design
Apr 4, 2022
767c724
UI review comments resolved
Apr 4, 2022
9e3e25d
rubocop issues resolved
Apr 4, 2022
19e426e
lint and review comment fixes
Apr 4, 2022
2292c0b
spacing added
Apr 4, 2022
edec13a
cosmetic changes
Apr 4, 2022
cde2c9f
dropdown updated
Apr 4, 2022
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
4 changes: 4 additions & 0 deletions app/controllers/internal_api/v1/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ def projects
@_projects ||= current_company.projects.kept
end

def projects
@_projects ||= current_company.projects.kept
end

def project
@_project ||= Project.includes(:project_members, project_members: [:user]).find(params[:id])
end
Expand Down
15 changes: 15 additions & 0 deletions app/javascript/src/common/AmountBox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from "react";

const AmountBoxContainer = ({ amountBox, cssClass="" }) => (
<ul className={`page-display__wrap ${cssClass}`}>
{ amountBox.map((data, index) => (
<li key={index} className="page-display__box">
<p className="font-normal text-sm tracking-widest">{data.title}</p>
<p className="text-5xl font-normal mt-3 tracking-widest">{data.amount}</p>
</li>
)
)}
</ul>
);

export default AmountBoxContainer;
52 changes: 52 additions & 0 deletions app/javascript/src/common/ChartBar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { Fragment } from "react";
import ReactTooltip from "react-tooltip";
import { IChartBarGraph, ISingleClient } from "./interface";
import { minutesToHHMM } from "../../helpers/hhmm-parser";

const Client = ({ element, totalMinutes, index }:ISingleClient) => {
const chartColor = ["miru-chart-green", "miru-chart-blue", "miru-chart-pink", "miru-chart-orange"];
const chartColorIndex = index%4;
const randomColor = chartColor[chartColorIndex];
const hourPercentage = (element.minutes * 100)/totalMinutes;

const divStyle = {
width: `${hourPercentage}%`
};

return (
<div style={divStyle}>
<ReactTooltip id={`registerTip-${index}`} effect="solid" backgroundColor="white" textColor="#1D1A31" place="top">
<p className="text-xs">{element.name}</p>
<p className="text-2xl text-center">{minutesToHHMM(element.minutes)}</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>
JijoBose marked this conversation as resolved.
Show resolved Hide resolved
</div>
);
};

const GetClientBar = ({ data, totalMinutes }:IChartBarGraph) => (
<Fragment>
<p className="mb-3 text-tiny text-miru-dark-purple-600 tracking-widest">
TOTAL HOURS: <span className="font-medium">{minutesToHHMM(totalMinutes)}</span>
JijoBose marked this conversation as resolved.
Show resolved Hide resolved
</p>
<div className="w-full bg-gray-200 flex h-1">
{data.map((element, index) => <Client
element={element}
key={index}
index={index}
totalMinutes={totalMinutes}
/>)
}
</div>
<div className="flex text-tiny text-miru-dark-purple-400 tracking-widest pb-6 justify-between mt-3">
<span>
0
JijoBose marked this conversation as resolved.
Show resolved Hide resolved
</span>
<span>
{minutesToHHMM(totalMinutes)}
</span>
</div>
</Fragment>
);

export default GetClientBar;
19 changes: 19 additions & 0 deletions app/javascript/src/common/ChartBar/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
interface ClientArray {
clients: any;
}

export interface IChartBar extends ClientArray {
handleSelectChange: any
totalMinutes: number;
}

export interface ISingleClient {
totalMinutes: number;
index: number;
element: any;
}

export interface IChartBarGraph {
data: any;
totalMinutes: number;
}
102 changes: 102 additions & 0 deletions app/javascript/src/common/Table/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React from "react";
import { useTable, useRowSelect } from "react-table";

const IndeterminateCheckbox = React.forwardRef( // eslint-disable-line react/display-name
({ indeterminate, ...rest }:any, ref) => {
const defaultRef = React.useRef();
const resolvedRef:any = ref || defaultRef;

React.useEffect(() => {
resolvedRef.current.indeterminate = indeterminate;
}, [resolvedRef, indeterminate]);

return (
<div className="flex items-center">
<input type="checkbox" ref={resolvedRef} {...rest} className="opacity-0 absolute h-8 w-8 custom__checkbox" />
<div className="bg-white border-2 border-miru-han-purple-1000 w-5 h-5 flex flex-shrink-0 justify-center items-center mr-2 focus-within:border-blue-500">
<svg className="custom__checkbox-tick fill-current hidden w-2 h-2 text-miru-han-purple-1000 pointer-events-none" version="1.1" viewBox="0 0 17 12" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<g transform="translate(-9 -11)" fill="#5B34EA" fillRule="nonzero">
<path d="m25.576 11.414c0.56558 0.55188 0.56558 1.4439 0 1.9961l-9.404 9.176c-0.28213 0.27529-0.65247 0.41385-1.0228 0.41385-0.37034 0-0.74068-0.13855-1.0228-0.41385l-4.7019-4.588c-0.56584-0.55188-0.56584-1.4442 0-1.9961 0.56558-0.55214 1.4798-0.55214 2.0456 0l3.679 3.5899 8.3812-8.1779c0.56558-0.55214 1.4798-0.55214 2.0456 0z" />
</g>
</g>
</svg>
</div>
</div>
);
}
);

const getTableCheckbox = hooks => {
hooks.visibleColumns.push(columns => [
{
id: "selection",
Header: ({ getToggleAllRowsSelectedProps }) => (
<div>
<IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
</div>
),
Cell: ({ row }) => (
<div>
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
</div>
)
},
...columns
]);
};

const Table = ({
tableHeader,
tableRowArray,
hasCheckbox = false
}) => {

const data = React.useMemo(() => tableRowArray, []);
const columns = React.useMemo(() => tableHeader, []);

const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow
} = useTable(
{
columns,
data
},
useRowSelect,
hasCheckbox ? getTableCheckbox : () => {} // eslint-disable-line @typescript-eslint/no-empty-function
);

return (
<>
<table className="min-w-full divide-y divide-gray-200 mt-4" {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th className={`table__header ${column.cssClass}`} {...column.getHeaderProps()}>{column.render("Header")}</th>
)
)}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.slice(0, 10).map((row, index) => {
prepareRow(row);
const isLastChild = rows.length - 1 !== index;
return (
<tr {...row.getRowProps()} className={isLastChild ? "border-b": ""}>
{row.cells.map(cell => <td className="table__cell" {...cell.getCellProps()}>{cell.render("Cell")}</td>)}
</tr>
);
})}
</tbody>
</table>
</>
);
};

export default Table;
10 changes: 0 additions & 10 deletions app/javascript/src/components/Invoices/BannerBox/index.tsx

This file was deleted.

24 changes: 17 additions & 7 deletions app/javascript/src/components/Invoices/container.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as React from "react";

import BannerBox from "./BannerBox";
import AmountBoxContainer from "common/AmountBox";
import Table from "./Table";

const Container = ({ invoiceList, setInvoiceList }) => {

const handleSelectAll = (isChecked) => {
Expand All @@ -20,13 +19,24 @@ const Container = ({ invoiceList, setInvoiceList }) => {
setInvoiceList(newInvoiceList);
};

const amountBox = [{
title: "OVERDUE",
amount: "$35.5k"
},
{
title: "OUTSTANDING",
amount: "$24.3k"
},
{
title: "AMOUNT IN DRAFT",
amount: "$24.5k"
}];

return (
<React.Fragment>
<ul className="page-display__wrap">
<BannerBox title="OVERDUE" value="$35.5k" />
<BannerBox title="OUTSTANDING" value="$24.3k" />
<BannerBox title="AMOUNT IN DRAFT" value="$24.5k" />
</ul>
<div className="bg-miru-gray-100 py-10 px-10">
<AmountBoxContainer amountBox = {amountBox} cssClass="mt-0" />
</div>
<div>
<Table handleSelectAll={handleSelectAll} handleSelectCheckbox={handleSelectCheckbox} updatedInvoiceList={invoiceList} />
</div>
Expand Down
Loading