mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-12 11:46:40 +00:00
project page ticket tab done
This commit is contained in:
parent
112ccbefee
commit
b861a65892
5 changed files with 99 additions and 139 deletions
|
|
@ -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>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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`}>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue