mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-06 00:36:39 +00:00
tab router header
This commit is contained in:
parent
4a711aa8ef
commit
057a6f9b13
13 changed files with 222 additions and 40 deletions
|
|
@ -1,16 +1,10 @@
|
|||
import React, { FC } from "react";
|
||||
import { AppRouter } from "./utils/router";
|
||||
import "./App.css";
|
||||
import Layout from "./pages/Layout";
|
||||
|
||||
const App: FC = () => {
|
||||
return (
|
||||
<>
|
||||
{/* <NavBar />
|
||||
<BreadCrumb /> */}
|
||||
<AppRouter />
|
||||
{/* <Footer /> */}
|
||||
</>
|
||||
);
|
||||
return <Layout />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ type AvatarListProps = {
|
|||
|
||||
export const AvatarList: FC<AvatarListProps> = ({ avatars }) => {
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="row valign-wrapper">
|
||||
{avatars.map((avatar: string) => (
|
||||
<img className="circle" src={avatar} width="50vh" height="50vh" />
|
||||
<img className="circle" src={avatar} width="32vh" height="32vh" />
|
||||
))}
|
||||
<FloatingButton icon="add" color="grey" size="small" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ type HeaderProps = {
|
|||
export const Header: FC<HeaderProps> = ({ title, description }) => {
|
||||
return (
|
||||
<>
|
||||
<h2>{title}</h2>
|
||||
<h4>{description}</h4>
|
||||
<h1>{title}</h1>
|
||||
<p className="lead">{description}</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,37 @@
|
|||
import React, { FC } from "react";
|
||||
import React, { FC, HTMLAttributes, CSSProperties } from "react";
|
||||
|
||||
type ProgressBarProps = {
|
||||
value: number;
|
||||
max?: number;
|
||||
tasksTotalCount?: number;
|
||||
tasksDone?: number;
|
||||
remainingDays?: number;
|
||||
};
|
||||
|
||||
export const ProgressBar: FC<ProgressBarProps> = ({ value, max = 100 }) => {
|
||||
export const ProgressBar: FC<ProgressBarProps> = ({
|
||||
value,
|
||||
max = 100,
|
||||
tasksDone,
|
||||
tasksTotalCount,
|
||||
remainingDays
|
||||
}) => {
|
||||
const styleString: CSSProperties = { width: `${value}%` };
|
||||
return (
|
||||
<div className="row">
|
||||
<progress value={value} max={max}></progress>
|
||||
</div>
|
||||
<>
|
||||
<div className="row">
|
||||
<div className="progress">
|
||||
<div className="determinate" style={styleString}></div>
|
||||
</div>
|
||||
<div>
|
||||
<i className="left material-icons">playlist_add_check</i>
|
||||
<span>
|
||||
{tasksDone}/{tasksTotalCount}
|
||||
</span>
|
||||
<div className="right">
|
||||
<span>Due {remainingDays} days</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
22
client/src/components/TabRouter.tsx
Normal file
22
client/src/components/TabRouter.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import React, { FC } from "react";
|
||||
import { TabRouterHeader } from "./TabRouterHeader";
|
||||
|
||||
interface IProps {}
|
||||
export const TabRouter: FC<IProps> = ({ children }) => {
|
||||
return (
|
||||
<>
|
||||
<div className="row">
|
||||
<TabRouterHeader />
|
||||
<div id="test1" className="col s12">
|
||||
Tickets
|
||||
</div>
|
||||
<div id="test2" className="col s12">
|
||||
Files
|
||||
</div>
|
||||
<div id="test3" className="col s12">
|
||||
Activity
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
77
client/src/components/TabRouterHeader.tsx
Normal file
77
client/src/components/TabRouterHeader.tsx
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import React, { FC, useState } from "react";
|
||||
|
||||
interface TabUnitProps {
|
||||
tabClass: string;
|
||||
isActive: number;
|
||||
setIsActive: React.Dispatch<React.SetStateAction<number>>;
|
||||
text: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const TabUnit: FC<TabUnitProps> = ({
|
||||
tabClass,
|
||||
isActive,
|
||||
setIsActive,
|
||||
text,
|
||||
value
|
||||
}) => {
|
||||
return (
|
||||
<li className={tabClass} key={value}>
|
||||
<a
|
||||
id={value}
|
||||
className={isActive === parseInt(value) ? "active" : ""}
|
||||
href={`#${text}`}
|
||||
onClick={() => setIsActive(parseInt(value))}
|
||||
>
|
||||
{text}
|
||||
</a>
|
||||
</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="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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
15
client/src/pages/Layout.tsx
Normal file
15
client/src/pages/Layout.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import React, { FC } from "react";
|
||||
import { AppRouter } from "../utils/router";
|
||||
|
||||
const Layout: FC = () => {
|
||||
return (
|
||||
<>
|
||||
{/* <NavBar />
|
||||
<BreadCrumb /> */}
|
||||
<AppRouter />
|
||||
{/* <Footer /> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Layout;
|
||||
|
|
@ -4,23 +4,39 @@ import { AvatarList } from "../components/AvatarList";
|
|||
import { ProgressBar } from "../components/ProgressBar";
|
||||
import { TicketList } from "../components/TicketList";
|
||||
import ProjectVM from "../viewModels/ProjectVM";
|
||||
import { TabRouter } from "../components/TabRouter";
|
||||
|
||||
interface IProps {
|
||||
viewModel: ProjectVM;
|
||||
}
|
||||
export const ProjectPage: FC<IProps> = ({ viewModel }) => {
|
||||
const { title, description, avatars, value, tickets } = viewModel;
|
||||
const {
|
||||
title,
|
||||
description,
|
||||
avatars,
|
||||
value,
|
||||
tickets,
|
||||
ticketsDone,
|
||||
ticketsTotalCount,
|
||||
remainingDays
|
||||
} = viewModel;
|
||||
return (
|
||||
<div className="section">
|
||||
<div className="container">
|
||||
<Header title={title} description={description} />
|
||||
<AvatarList avatars={avatars} />
|
||||
<ProgressBar value={value} />
|
||||
{/* <TabView> */}
|
||||
<TicketList tickets={tickets} />
|
||||
{/* <ChildFile />
|
||||
<ProgressBar
|
||||
value={value}
|
||||
tasksDone={ticketsDone}
|
||||
tasksTotalCount={ticketsTotalCount}
|
||||
remainingDays={remainingDays}
|
||||
/>
|
||||
<TabRouter>
|
||||
{/* <TabRouterSelector/> */}
|
||||
<TicketList tickets={tickets} />
|
||||
{/* <ChildFile />
|
||||
<ChildActivity /> */}
|
||||
{/* </TabView> */}
|
||||
</TabRouter>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ export interface Project {
|
|||
description: string;
|
||||
progression: number;
|
||||
tickets: Ticket[];
|
||||
// getMembers(): User[];
|
||||
users: User[];
|
||||
plannedEnding: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
export interface Ticket {
|
||||
id: number;
|
||||
title: string;
|
||||
status: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export interface User {
|
||||
Id: number;
|
||||
Picture: string;
|
||||
id: string;
|
||||
picture: string;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue