mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-12 11:46:40 +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 React, { FC } from "react";
|
||||||
import { AppRouter } from "./utils/router";
|
import { AppRouter } from "./utils/router";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
|
import Layout from "./pages/Layout";
|
||||||
|
|
||||||
const App: FC = () => {
|
const App: FC = () => {
|
||||||
return (
|
return <Layout />;
|
||||||
<>
|
|
||||||
{/* <NavBar />
|
|
||||||
<BreadCrumb /> */}
|
|
||||||
<AppRouter />
|
|
||||||
{/* <Footer /> */}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ type AvatarListProps = {
|
||||||
|
|
||||||
export const AvatarList: FC<AvatarListProps> = ({ avatars }) => {
|
export const AvatarList: FC<AvatarListProps> = ({ avatars }) => {
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row valign-wrapper">
|
||||||
{avatars.map((avatar: string) => (
|
{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" />
|
<FloatingButton icon="add" color="grey" size="small" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ type HeaderProps = {
|
||||||
export const Header: FC<HeaderProps> = ({ title, description }) => {
|
export const Header: FC<HeaderProps> = ({ title, description }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h2>{title}</h2>
|
<h1>{title}</h1>
|
||||||
<h4>{description}</h4>
|
<p className="lead">{description}</p>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,37 @@
|
||||||
import React, { FC } from "react";
|
import React, { FC, HTMLAttributes, CSSProperties } from "react";
|
||||||
|
|
||||||
type ProgressBarProps = {
|
type ProgressBarProps = {
|
||||||
value: number;
|
value: number;
|
||||||
max?: 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 (
|
return (
|
||||||
<div className="row">
|
<>
|
||||||
<progress value={value} max={max}></progress>
|
<div className="row">
|
||||||
</div>
|
<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 { ProgressBar } from "../components/ProgressBar";
|
||||||
import { TicketList } from "../components/TicketList";
|
import { TicketList } from "../components/TicketList";
|
||||||
import ProjectVM from "../viewModels/ProjectVM";
|
import ProjectVM from "../viewModels/ProjectVM";
|
||||||
|
import { TabRouter } from "../components/TabRouter";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
viewModel: ProjectVM;
|
viewModel: ProjectVM;
|
||||||
}
|
}
|
||||||
export const ProjectPage: FC<IProps> = ({ viewModel }) => {
|
export const ProjectPage: FC<IProps> = ({ viewModel }) => {
|
||||||
const { title, description, avatars, value, tickets } = viewModel;
|
const {
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
avatars,
|
||||||
|
value,
|
||||||
|
tickets,
|
||||||
|
ticketsDone,
|
||||||
|
ticketsTotalCount,
|
||||||
|
remainingDays
|
||||||
|
} = viewModel;
|
||||||
return (
|
return (
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<Header title={title} description={description} />
|
<Header title={title} description={description} />
|
||||||
<AvatarList avatars={avatars} />
|
<AvatarList avatars={avatars} />
|
||||||
<ProgressBar value={value} />
|
<ProgressBar
|
||||||
{/* <TabView> */}
|
value={value}
|
||||||
<TicketList tickets={tickets} />
|
tasksDone={ticketsDone}
|
||||||
{/* <ChildFile />
|
tasksTotalCount={ticketsTotalCount}
|
||||||
|
remainingDays={remainingDays}
|
||||||
|
/>
|
||||||
|
<TabRouter>
|
||||||
|
{/* <TabRouterSelector/> */}
|
||||||
|
<TicketList tickets={tickets} />
|
||||||
|
{/* <ChildFile />
|
||||||
<ChildActivity /> */}
|
<ChildActivity /> */}
|
||||||
{/* </TabView> */}
|
</TabRouter>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,6 @@ export interface Project {
|
||||||
description: string;
|
description: string;
|
||||||
progression: number;
|
progression: number;
|
||||||
tickets: Ticket[];
|
tickets: Ticket[];
|
||||||
// getMembers(): User[];
|
users: User[];
|
||||||
|
plannedEnding: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
export interface Ticket {
|
export interface Ticket {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export interface User {
|
export interface User {
|
||||||
Id: number;
|
id: string;
|
||||||
Picture: string;
|
picture: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue