project page ticket tab done

This commit is contained in:
Ruidy Nemausat 2020-02-20 10:43:07 +01:00
parent 112ccbefee
commit b861a65892
5 changed files with 99 additions and 139 deletions

View file

@ -1,43 +1,34 @@
import React, { FC, MouseEvent } from "react"; import React, { FC, MouseEvent } from "react";
import { AvatarList } from "./AvatarList"; import { AvatarList } from "./AvatarList";
import { Link } from "react-router-dom";
interface IProps { interface IProps {
title: string; title: string;
tasksTotalCount?: number;
tasksDone?: number;
remainingDays?: number; remainingDays?: number;
avatars: string[];
validateTicket: (event: MouseEvent) => void; validateTicket: (event: MouseEvent) => void;
archiveTicket: (event: MouseEvent) => void; archiveTicket: (event: MouseEvent) => void;
} }
export const HorizontalCard: FC<IProps> = ({ export const HorizontalCard: FC<IProps> = ({
title, title,
tasksDone,
tasksTotalCount,
remainingDays, remainingDays,
avatars,
archiveTicket, archiveTicket,
validateTicket validateTicket
}) => { }) => {
return ( return (
<div className="col s12">
<div className="card horizontal"> <div className="card horizontal">
<div className="card-stacked"> <div className="card-stacked">
<div className="card-content"> <div className="card-content">
<div className="row"> <div className="row">
<div className="card-title"> <div className="card-title">
<h6>{title}</h6> <h6>
<Link to="#">
<b>{title}</b>
</Link>
</h6>
</div> </div>
<span>Due {remainingDays} days</span> <span>Due {remainingDays} days</span>
{/* <AvatarList avatars={avatars} /> */}
<div className="right"> <div className="right">
{/* <i className=" material-icons">playlist_add_check</i>
<span>
{" "}
{tasksDone}/{tasksTotalCount}
</span> */}
<a> <a>
<i className="material-icons" onClick={validateTicket}> <i className="material-icons" onClick={validateTicket}>
check check
@ -53,6 +44,5 @@ export const HorizontalCard: FC<IProps> = ({
</div> </div>
</div> </div>
</div> </div>
</div>
); );
}; };

View file

@ -6,36 +6,22 @@ import { Switch, Route, useRouteMatch, Redirect } from "react-router-dom";
interface IProps { interface IProps {
tickets: Ticket[]; tickets: Ticket[];
tasksTotalCount?: number;
tasksDone?: number;
remainingDays?: number; remainingDays?: number;
avatars: string[]; tabNames: string[];
} }
export const TabRouter: FC<IProps> = ({ export const TabRouter: FC<IProps> = ({ tickets, remainingDays, tabNames }) => {
tickets,
tasksDone,
tasksTotalCount,
remainingDays,
avatars
}) => {
const { url } = useRouteMatch(); const { url } = useRouteMatch();
return ( return (
<> <>
<Switch> <Switch>
<div className="row"> <div className="row">
<TabRouterHeader /> <TabRouterHeader nTabs={tabNames.length} tabNames={tabNames} />
<Redirect from={url} to={`${url}/tickets`} /> <Redirect from={url} to={`${url}/tickets`} />
<Route path={`${url}/tickets`}> <Route path={`${url}/tickets`}>
<TicketList <TicketList tickets={tickets} remainingDays={remainingDays} />
tickets={tickets}
tasksDone={tasksDone}
tasksTotalCount={tasksTotalCount}
remainingDays={remainingDays}
avatars={avatars}
/>
</Route> </Route>
<Route path={`${url}/files`}> <Route path={`${url}/files`}>

View file

@ -1,12 +1,51 @@
import React, { FC, useState } from "react"; import React, { FC, useState } from "react";
import { Link, useRouteMatch } from "react-router-dom"; import { Link, useRouteMatch } from "react-router-dom";
interface IProps {
tabClass?: string;
nTabs: number;
tabNames: string[];
}
export const TabRouterHeader: FC<IProps> = ({
tabClass = "tab col s4",
nTabs,
tabNames
}) => {
const [isActive, setIsActive] = useState(0);
return (
<>
<ul className="tabs z-depth-1">
{tabNames.map((name, i) => (
<TabUnit
text={name}
value={i.toString()}
tabClass={tabClass}
isActive={isActive}
setIsActive={setIsActive}
nTabs={nTabs}
/>
))}
<li
className="indicator"
style={{
left: `${(isActive / nTabs) * 100}%`,
right: `${(1 - (isActive + 1) / nTabs) * 100}%`
}}
></li>
</ul>
</>
);
};
interface TabUnitProps { interface TabUnitProps {
tabClass: string; tabClass: string;
isActive: number; isActive: number;
setIsActive: React.Dispatch<React.SetStateAction<number>>; setIsActive: React.Dispatch<React.SetStateAction<number>>;
text: string; text: string;
value: string; value: string;
nTabs: number;
} }
const TabUnit: FC<TabUnitProps> = ({ const TabUnit: FC<TabUnitProps> = ({
@ -14,15 +53,23 @@ const TabUnit: FC<TabUnitProps> = ({
isActive, isActive,
setIsActive, setIsActive,
text, text,
value value,
nTabs
}) => { }) => {
const { url } = useRouteMatch(); const { url } = useRouteMatch();
return ( return (
<li className={tabClass} key={value}> <li
className={tabClass}
key={value}
style={{
left: `${(isActive / nTabs) * 100}%`,
right: `${(1 - (isActive + 1) / nTabs) * 100}%`
}}
>
<Link <Link
to={`${url}/${text}`} to={`${url}/${text}`}
id={value} id={value}
className={isActive === parseInt(value) ? "active" : ""} className={isActive === parseInt(value) ? "active pink lighten-5" : ""}
onClick={() => setIsActive(parseInt(value))} onClick={() => setIsActive(parseInt(value))}
> >
{text} {text}
@ -30,50 +77,3 @@ const TabUnit: FC<TabUnitProps> = ({
</li> </li>
); );
}; };
interface IProps {
tabClass?: string;
}
export const TabRouterHeader: FC<IProps> = ({
tabClass = "tab col s3",
children
}) => {
const [isActive, setIsActive] = useState(1);
// const switchTab = (e: React.MouseEvent<HTMLAnchorElement>): void => {
// e.preventDefault();
// setIsActive(e.target.id);
// };
return (
<>
<div className="row col s12">
<ul className="tabs">
<TabUnit
text="Tickets"
value="1"
tabClass={tabClass}
isActive={isActive}
setIsActive={setIsActive}
/>
<TabUnit
text="Files"
value="2"
tabClass={tabClass}
isActive={isActive}
setIsActive={setIsActive}
/>
<TabUnit
text="Activity"
value="3"
tabClass={tabClass}
isActive={isActive}
setIsActive={setIsActive}
/>
</ul>
</div>
</>
);
};

View file

@ -5,42 +5,26 @@ import { HorizontalCard } from "./HorizontalCard";
type TicketListProps = { type TicketListProps = {
tickets: Ticket[]; tickets: Ticket[];
tasksTotalCount?: number;
tasksDone?: number;
remainingDays?: number; remainingDays?: number;
avatars: string[];
}; };
export const TicketList: FC<TicketListProps> = ({ export const TicketList: FC<TicketListProps> = ({ tickets, remainingDays }) => {
tickets,
tasksDone,
tasksTotalCount,
remainingDays,
avatars
}) => {
const archiveTicket = () => {}; const archiveTicket = () => {};
const validateTicket = () => {}; const validateTicket = () => {};
return ( return (
<div className="col s12"> <>
<div className="row valign-wrapper"> <div className="row valign-wrapper">
<div className="col s6 m4"> <h3>Tickets</h3>
<h2>Tickets</h2> <FloatingButton color=" blue-grey lighten-4" size="big" />
</div> </div>
<div className="col s6 m8"> <div className="col s12 grey">
<FloatingButton color="grey" size="big" />
</div>
</div>
<ul> <ul>
{tickets.map((t: Ticket) => ( {tickets.map((t: Ticket) => (
<li key={t.id}> <li key={t.id}>
<HorizontalCard <HorizontalCard
title={t.title} title={t.title}
tasksDone={tasksDone}
tasksTotalCount={tasksTotalCount}
remainingDays={remainingDays} remainingDays={remainingDays}
avatars={avatars}
validateTicket={validateTicket} validateTicket={validateTicket}
archiveTicket={archiveTicket} archiveTicket={archiveTicket}
/> />
@ -48,5 +32,6 @@ export const TicketList: FC<TicketListProps> = ({
))} ))}
</ul> </ul>
</div> </div>
</>
); );
}; };

View file

@ -20,6 +20,7 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
ticketsTotalCount, ticketsTotalCount,
remainingDays remainingDays
} = viewModel; } = viewModel;
const tabNames: string[] = ["Tickets", "Files", "Activity"];
return ( return (
<div className="section"> <div className="section">
<div className="container"> <div className="container">
@ -35,11 +36,9 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
remainingDays={remainingDays} remainingDays={remainingDays}
/> />
<TabRouter <TabRouter
tabNames={tabNames}
tickets={tickets} tickets={tickets}
tasksDone={ticketsDone}
tasksTotalCount={ticketsTotalCount}
remainingDays={remainingDays} remainingDays={remainingDays}
avatars={avatars}
/> />
</div> </div>
</div> </div>