add UserTabPanel Component and minor refactoring

This commit is contained in:
Ruidy Nemausat 2020-04-03 10:53:10 +02:00
parent 4406063253
commit f9e1fd9392
24 changed files with 269 additions and 138 deletions

115
client/package-lock.json generated
View file

@ -1714,6 +1714,14 @@
"@types/react-router": "*" "@types/react-router": "*"
} }
}, },
"@types/react-swipeable-views": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/@types/react-swipeable-views/-/react-swipeable-views-0.13.0.tgz",
"integrity": "sha512-orrreCcXev6IUXDuHf07RDDCAoIZRMSr95eyWmYNRfjic7w/O+68iPu0NCysVls+UygRNvoqZMuXI72N/58E1w==",
"requires": {
"@types/react": "*"
}
},
"@types/react-transition-group": { "@types/react-transition-group": {
"version": "4.2.4", "version": "4.2.4",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.2.4.tgz", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.2.4.tgz",
@ -8014,6 +8022,11 @@
"object.assign": "^4.1.0" "object.assign": "^4.1.0"
} }
}, },
"keycode": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
"integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
},
"killable": { "killable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -10850,6 +10863,16 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.5.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.5.tgz",
"integrity": "sha512-+DMR2k5c6BqMDSMF8hLH0vYKtKTeikiFW+fj0LClN+XZg4N9b8QUAdHC62CGWNLTi/gnuuemNcNcTFrCvK1f+A==" "integrity": "sha512-+DMR2k5c6BqMDSMF8hLH0vYKtKTeikiFW+fj0LClN+XZg4N9b8QUAdHC62CGWNLTi/gnuuemNcNcTFrCvK1f+A=="
}, },
"react-event-listener": {
"version": "0.6.6",
"resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.6.tgz",
"integrity": "sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw==",
"requires": {
"@babel/runtime": "^7.2.0",
"prop-types": "^15.6.0",
"warning": "^4.0.1"
}
},
"react-is": { "react-is": {
"version": "16.12.0", "version": "16.12.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
@ -10961,6 +10984,85 @@
"workbox-webpack-plugin": "4.3.1" "workbox-webpack-plugin": "4.3.1"
} }
}, },
"react-swipeable-views": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/react-swipeable-views/-/react-swipeable-views-0.13.9.tgz",
"integrity": "sha512-WXC2FKYvZ9QdJ31v9LjEJEl1bA7E4AcaloTkbW0uU0dYf5uvv4aOpiyxubvOkVl1a5L2UAHmKSif4TmJ9usrSg==",
"requires": {
"@babel/runtime": "7.0.0",
"prop-types": "^15.5.4",
"react-swipeable-views-core": "^0.13.7",
"react-swipeable-views-utils": "^0.13.9",
"warning": "^4.0.1"
},
"dependencies": {
"@babel/runtime": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
"integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
"requires": {
"regenerator-runtime": "^0.12.0"
}
},
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
"react-swipeable-views-core": {
"version": "0.13.7",
"resolved": "https://registry.npmjs.org/react-swipeable-views-core/-/react-swipeable-views-core-0.13.7.tgz",
"integrity": "sha512-ekn9oDYfBt0oqJSGGwLEhKvn+QaqMGTy//9dURTLf+vp7W5j6GvmKryYdnwJCDITaPFI2hujXV4CH9krhvaE5w==",
"requires": {
"@babel/runtime": "7.0.0",
"warning": "^4.0.1"
},
"dependencies": {
"@babel/runtime": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
"integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
"requires": {
"regenerator-runtime": "^0.12.0"
}
},
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
"react-swipeable-views-utils": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/react-swipeable-views-utils/-/react-swipeable-views-utils-0.13.9.tgz",
"integrity": "sha512-QLGxRKrbJCbWz94vkWLzb1Daaa2Y/TZKmsNKQ6WSNrS+chrlfZ3z9tqZ7YUJlW6pRWp3QZdLSY3UE3cN0TXXmw==",
"requires": {
"@babel/runtime": "7.0.0",
"keycode": "^2.1.7",
"prop-types": "^15.6.0",
"react-event-listener": "^0.6.0",
"react-swipeable-views-core": "^0.13.7",
"shallow-equal": "^1.2.1"
},
"dependencies": {
"@babel/runtime": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
"integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
"requires": {
"regenerator-runtime": "^0.12.0"
}
},
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
"react-transition-group": { "react-transition-group": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.3.0.tgz", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.3.0.tgz",
@ -11747,6 +11849,11 @@
} }
} }
}, },
"shallow-equal": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
},
"shebang-command": { "shebang-command": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@ -13129,6 +13236,14 @@
"makeerror": "1.0.x" "makeerror": "1.0.x"
} }
}, },
"warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"requires": {
"loose-envify": "^1.0.0"
}
},
"watchpack": { "watchpack": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",

View file

@ -16,12 +16,14 @@
"@types/react": "^16.9.19", "@types/react": "^16.9.19",
"@types/react-dom": "^16.9.5", "@types/react-dom": "^16.9.5",
"@types/react-router-dom": "^5.1.3", "@types/react-router-dom": "^5.1.3",
"@types/react-swipeable-views": "^0.13.0",
"@types/underscore": "^1.9.4", "@types/underscore": "^1.9.4",
"history": "^4.10.1", "history": "^4.10.1",
"react": "^16.12.0", "react": "^16.12.0",
"react-dom": "^16.12.0", "react-dom": "^16.12.0",
"react-router-dom": "^5.1.2", "react-router-dom": "^5.1.2",
"react-scripts": "3.3.1", "react-scripts": "3.3.1",
"react-swipeable-views": "^0.13.9",
"typescript": "^3.7.5", "typescript": "^3.7.5",
"underscore": "^1.9.2" "underscore": "^1.9.2"
}, },

View file

@ -12,9 +12,7 @@ export const ActivityList: FC<IProps> = ({ activities }) => {
const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => {
setFilterText(""); setFilterText("");
}; };
const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = ( const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
e: ChangeEvent<HTMLInputElement>
) => {
setFilterText(e.target.value); setFilterText(e.target.value);
}; };

View file

@ -10,12 +10,10 @@ type IProps = {
export const FileList: FC<IProps> = ({ files }) => { export const FileList: FC<IProps> = ({ files }) => {
const [filterText, setFilterText] = useState<string>(""); const [filterText, setFilterText] = useState<string>("");
const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { const clearFilterText = (e: MouseEvent): void => {
setFilterText(""); setFilterText("");
}; };
const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = ( const handleChange = (e: ChangeEvent<HTMLInputElement>): void => {
e: ChangeEvent<HTMLInputElement>
) => {
setFilterText(e.target.value); setFilterText(e.target.value);
}; };
return ( return (

View file

@ -3,7 +3,6 @@ import { Link } from "react-router-dom";
import Avatar from "@material-ui/core/Avatar"; import Avatar from "@material-ui/core/Avatar";
import AvatarGroup from "@material-ui/lab/AvatarGroup"; import AvatarGroup from "@material-ui/lab/AvatarGroup";
import { User } from "../types/User"; import { User } from "../types/User";
import { UserAvatar } from "./UserAvatar";
interface AvatarListProps { interface AvatarListProps {
users: User[]; users: User[];

View file

@ -1,5 +1,4 @@
import React from "react"; import React from "react";
import { Link } from "react-router-dom";
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar"; import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar"; import Toolbar from "@material-ui/core/Toolbar";

View file

@ -7,7 +7,6 @@ type IProps = {
}; };
export const FileCollection: FC<IProps> = ({ files, filterText }) => { export const FileCollection: FC<IProps> = ({ files, filterText }) => {
console.log();
return ( return (
<> <>
<ul className="collection"> <ul className="collection">

View file

@ -1,10 +1,7 @@
import React, { FC, MouseEvent } from "react"; import React, { FC, MouseEvent } from "react";
import { Fab, SvgIconTypeMap } from "@material-ui/core"; import { Fab } from "@material-ui/core";
import { OverridableComponent } from "@material-ui/core/OverridableComponent";
import AddIcon from "@material-ui/icons/Add"; import AddIcon from "@material-ui/icons/Add";
import { Button } from "./Button";
interface IProps { interface IProps {
icon?: string; icon?: string;
color?: "inherit" | "primary" | "secondary" | "default" | undefined; color?: "inherit" | "primary" | "secondary" | "default" | undefined;
@ -13,20 +10,6 @@ interface IProps {
text?: string; text?: string;
} }
// export const FloatingButton: FC<IProps> = ({
// icon = "add",
// size = "small",
// color = "red",
// onClick
// }) => {
// const iconComponent = <i className="material-icons left">{icon}</i>;
// return (
// <Button color={color} size={size} shape="btn-floating" onClick={onClick}>
// {iconComponent}
// </Button>
// );
// };
export const FloatingButton: FC<IProps> = ({ export const FloatingButton: FC<IProps> = ({
color, color,
icon, icon,

View file

@ -1,23 +1,31 @@
import React from "react"; import React, { FC } from "react";
import { AppBar } from "@material-ui/core";
import CssBaseline from "@material-ui/core/CssBaseline";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
import Container from "@material-ui/core/Container"; import Container from "@material-ui/core/Container";
import Link from "@material-ui/core/Link"; import Link from "@material-ui/core/Link";
function Copyright() { interface IProps {
brand: string;
text: string;
}
const copyParams: IProps = {
brand: "BugBuster",
text: "Made with 🔥"
};
const Copyright: FC<IProps> = ({ brand, text }) => {
return ( return (
<Typography variant="body2" color="textSecondary"> <Typography variant="body2" color="textSecondary">
{"© "} {"© "}
<Link color="inherit" href="/"> <Link color="inherit" href="/">
BugBuster {brand}
</Link>{" "} </Link>{" "}
{new Date().getFullYear()} {new Date().getFullYear()}
{". All Rights Reserved. Made with 🔥"} {`. All Rights Reserved. ${text}`}
</Typography> </Typography>
); );
} };
const useStyles = makeStyles(theme => ({ const useStyles = makeStyles(theme => ({
footer: { footer: {
@ -46,7 +54,7 @@ export default function Footer() {
Ruidy Nemausat Ruidy Nemausat
</Link>{" "} </Link>{" "}
</Typography> </Typography>
<Copyright /> <Copyright brand={copyParams.brand} text={copyParams.text} />
</Container> </Container>
</footer> </footer>
); );

View file

@ -45,11 +45,6 @@ export const HorizontalCard: FC<IProps> = ({
check check
</i> </i>
</Link> </Link>
{/* <Link to="#">
<i className="material-icons" onClick={archiveTicket}>
archive
</i>
</Link> */}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,8 +1,6 @@
import React, { FC } from "react"; import React, { FC } from "react";
type IProps = {}; export const InputFile: FC = () => {
export const InputFile: FC<IProps> = () => {
return ( return (
<> <>
<form action="/upload"> <form action="/upload">

View file

@ -10,12 +10,10 @@ interface IProps {
export const MemberList: FC<IProps> = ({ users }) => { export const MemberList: FC<IProps> = ({ users }) => {
const [members, setMembers] = useState<User[]>([]); const [members, setMembers] = useState<User[]>([]);
const [filterText, setFilterText] = useState<string>(""); const [filterText, setFilterText] = useState<string>("");
const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { const clearFilterText = (e: MouseEvent): void => {
setFilterText(""); setFilterText("");
}; };
const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = ( const handleChange = (e: ChangeEvent<HTMLInputElement>): void => {
e: ChangeEvent<HTMLInputElement>
) => {
setFilterText(e.target.value); setFilterText(e.target.value);
}; };
return ( return (

View file

@ -6,11 +6,10 @@ import { Ticket } from "../types/Ticket";
import { Project } from "../types/Project"; import { Project } from "../types/Project";
import { post } from "../utils/http"; import { post } from "../utils/http";
import { Constants } from "../utils/Constants"; import { Constants } from "../utils/Constants";
// import { HttpResponse } from "../types/HttpResponse";
interface IProps { interface IProps {
show: boolean; show: boolean;
handleClose(): void; handleClose: () => void;
allProjects: Project[]; allProjects: Project[];
} }

View file

@ -1,41 +0,0 @@
import React, { FC } from "react";
import { useRouteMatch } from "react-router-dom";
import { TabRouterHeader } from "./TabRouterHeader";
interface IProps {
tabNames: string[];
description: string;
setDescription: React.Dispatch<React.SetStateAction<string>>;
title: string;
setTitle: React.Dispatch<React.SetStateAction<string>>;
endingDate: string;
setEndingDate: React.Dispatch<React.SetStateAction<string>>;
}
export const NewTicketTabRouter: FC<IProps> = ({
tabNames,
description,
setDescription,
title,
setTitle,
endingDate,
setEndingDate
}) => {
const { url } = useRouteMatch();
return (
<>
<div className="row">
<TabRouterHeader tabNames={tabNames} />
{/* <NewTicketForm
title={title}
setTitle={setTitle}
description={description}
setDescription={setDescription}
endingDate={endingDate}
setEndingDate={setEndingDate}
/> */}
</div>
</>
);
};

View file

@ -1,5 +1,4 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { HorizontalCard } from "./HorizontalCard";
import { UserAvatar } from "./UserAvatar"; import { UserAvatar } from "./UserAvatar";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";

View file

@ -1,4 +1,4 @@
import React, { FC, CSSProperties } from "react"; import React, { FC } from "react";
import { makeStyles, Theme, createStyles } from "@material-ui/core/styles"; import { makeStyles, Theme, createStyles } from "@material-ui/core/styles";
import LinearProgress from "@material-ui/core/LinearProgress"; import LinearProgress from "@material-ui/core/LinearProgress";
import { Box } from "@material-ui/core"; import { Box } from "@material-ui/core";
@ -25,23 +25,23 @@ const useStyles = makeStyles((theme: Theme) =>
export const ProgressBar: FC<IProps> = ({ export const ProgressBar: FC<IProps> = ({
value, value,
max = 100, // max = 100,
tasksDone, tasksDone,
tasksTotalCount, tasksTotalCount,
remainingDays remainingDays
}) => { }) => {
const styleString: CSSProperties = { width: `${value}%` }; // const styleString: CSSProperties = { width: `${value}%` };
let barColor: string = "green"; // let barColor: string = "green";
if (value < 100) { // if (value < 100) {
barColor = "yellow"; // barColor = "yellow";
} // }
if (value < 200 / 3) { // if (value < 200 / 3) {
barColor = "orange"; // barColor = "orange";
} // }
if (value < 100 / 3) { // if (value < 100 / 3) {
barColor = "red"; // barColor = "red";
} // }
const classes = useStyles(); const classes = useStyles();

View file

@ -17,9 +17,7 @@ export const ProjectList: FC<IProps> = ({ projects }) => {
setFilterText(""); setFilterText("");
}; };
const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = ( const handleChange = (e: ChangeEvent<HTMLInputElement>): void => {
e: ChangeEvent<HTMLInputElement>
) => {
setFilterText(e.target.value); setFilterText(e.target.value);
}; };

View file

@ -3,7 +3,6 @@ import { Route, useRouteMatch, Redirect } from "react-router-dom";
import { TabRouterHeader } from "./TabRouterHeader"; import { TabRouterHeader } from "./TabRouterHeader";
import { TicketList } from "./TicketList"; import { TicketList } from "./TicketList";
import { FileList } from "./AppFileList"; import { FileList } from "./AppFileList";
// import { ActivityList } from "./ActivityList";
import { Ticket } from "../types/Ticket"; import { Ticket } from "../types/Ticket";
import { AppFile } from "../types/AppFile"; import { AppFile } from "../types/AppFile";
import { Activity } from "../types/Activity"; import { Activity } from "../types/Activity";

View file

@ -21,17 +21,15 @@ export const TicketList: FC<TicketListProps> = ({
addButton = true addButton = true
}) => { }) => {
const [filterText, setFilterText] = useState<string>(""); const [filterText, setFilterText] = useState<string>("");
const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { const clearFilterText = (e: MouseEvent): void => {
setFilterText(""); setFilterText("");
}; };
const onClick: (e: MouseEvent) => void = (e: MouseEvent) => { const onClick = (e: MouseEvent): void => {
e.preventDefault(); e.preventDefault();
setShowNew(true); setShowNew(true);
}; };
const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = ( const handleChange = (e: ChangeEvent<HTMLInputElement>): void => {
e: ChangeEvent<HTMLInputElement>
) => {
setFilterText(e.target.value); setFilterText(e.target.value);
}; };

View file

@ -7,20 +7,6 @@ interface IProps {
alt: string; alt: string;
} }
// export const Avatar: FC<IProps> = () => {
// return (
// <>
// <img
// className="circle"
// src={picture}
// height="100vh"
// width="100vh"
// alt="user avatar"
// />
// </>
// );
// };
const useStyles = makeStyles((theme: Theme) => const useStyles = makeStyles((theme: Theme) =>
createStyles({ createStyles({
root: { root: {

View file

@ -0,0 +1,102 @@
import React, { FC } from "react";
import SwipeableViews from "react-swipeable-views";
import { makeStyles, Theme, useTheme } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import { Header } from "./Header";
import { Ticket } from "../types/Ticket";
import { Project } from "../types/Project";
import { ProjectList } from "./ProjectList";
import { TicketList } from "./TicketList";
interface TabProps {
children?: React.ReactNode;
dir?: string;
index: any;
value: any;
}
const TabPanel: FC<TabProps> = (props: TabProps) => {
const { children, value, index, ...other } = props;
return (
<Typography
component="div"
role="tabpanel"
hidden={value !== index}
id={`full-width-tabpanel-${index}`}
aria-labelledby={`full-width-tab-${index}`}
{...other}
>
{value === index && <Box p={3}>{children}</Box>}
</Typography>
);
};
const a11yProps = (index: any) => {
return {
id: `full-width-tab-${index}`,
"aria-controls": `full-width-tabpanel-${index}`
};
};
const useStyles = makeStyles((theme: Theme) => ({
root: {
backgroundColor: theme.palette.background.paper,
width: 500
}
}));
interface IProps {
tabNames: string[];
tickets: Ticket[];
projects: Project[];
}
export const UserTabPanel: FC<IProps> = ({ tickets, tabNames, projects }) => {
const classes = useStyles();
const theme = useTheme();
const [value, setValue] = React.useState(0);
const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => {
setValue(newValue);
};
const handleChangeIndex = (index: number) => {
setValue(index);
};
return (
<div className={classes.root}>
<AppBar position="static" color="default">
<Tabs
value={value}
onChange={handleChange}
indicatorColor="primary"
textColor="primary"
variant="fullWidth"
aria-label="full width tabs example"
>
{tabNames.map((t: string, i: number) => (
<Tab label={t} {...a11yProps({ i })} />
))}
</Tabs>
</AppBar>
<SwipeableViews
axis={theme.direction === "rtl" ? "x-reverse" : "x"}
index={value}
onChangeIndex={handleChangeIndex}
>
<TabPanel value={value} index={0} dir={theme.direction}>
<ProjectList projects={projects} />
</TabPanel>
<TabPanel value={value} index={1} dir={theme.direction}>
<TicketList tickets={tickets} allProjects={[]} addButton={false} />
</TabPanel>
</SwipeableViews>
</div>
);
};

View file

@ -1,4 +1,4 @@
import React, { FC, useState, ChangeEvent, FormEvent, useEffect } from "react"; import React, { FC, useState, ChangeEvent, FormEvent } from "react";
import { Modal } from "./Modal"; import { Modal } from "./Modal";
import { AvatarList } from "./AvatarList"; import { AvatarList } from "./AvatarList";
import { User } from "../types/User"; import { User } from "../types/User";
@ -25,9 +25,7 @@ export const UsersModal: FC<IProps> = ({
const [members, setMembers] = useState<User[]>(users); const [members, setMembers] = useState<User[]>(users);
const { id } = useParams(); const { id } = useParams();
const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = ( const handleChange = (e: ChangeEvent<HTMLInputElement>): void => {
e: ChangeEvent<HTMLInputElement>
) => {
setFilterText(e.target.value); setFilterText(e.target.value);
}; };
@ -42,7 +40,6 @@ export const UsersModal: FC<IProps> = ({
handleClose(); handleClose();
}; };
useEffect(() => {});
return ( return (
<Modal show={show} handleClose={handleClose}> <Modal show={show} handleClose={handleClose}>
<div className="row valign-wrapper indigo"> <div className="row valign-wrapper indigo">

View file

@ -2,10 +2,12 @@ import React, { FC } from "react";
import { UserVM } from "../VM/UserVM"; import { UserVM } from "../VM/UserVM";
import { UserHeader } from "../components/UserHeader"; import { UserHeader } from "../components/UserHeader";
import { UserTabRouter } from "../components/UserTabRouter"; import { UserTabRouter } from "../components/UserTabRouter";
import { UserTabPanel } from "../components/UserTabPanel";
interface IProps { interface IProps {
viewModel: UserVM; viewModel: UserVM;
} }
export const UserPage: FC<IProps> = ({ viewModel }) => { export const UserPage: FC<IProps> = ({ viewModel }) => {
const { fullName, presentation, picture, projects, tickets } = viewModel; const { fullName, presentation, picture, projects, tickets } = viewModel;
const tabNames: string[] = ["Projects", "Tickets"]; const tabNames: string[] = ["Projects", "Tickets"];
@ -17,7 +19,7 @@ export const UserPage: FC<IProps> = ({ viewModel }) => {
fullName={fullName} fullName={fullName}
presentation={presentation} presentation={presentation}
/> />
<UserTabRouter <UserTabPanel
tabNames={tabNames} tabNames={tabNames}
projects={projects} projects={projects}
tickets={tickets} tickets={tickets}

View file

@ -6,14 +6,14 @@ import { ProjectController } from "../controllers/ProjectController";
import { UserController } from "../controllers/UserController"; import { UserController } from "../controllers/UserController";
import { TicketController } from "../controllers/TicketController"; import { TicketController } from "../controllers/TicketController";
import { NotFoundPage } from "../pages/NotFoundPage"; import { NotFoundPage } from "../pages/NotFoundPage";
// import { TestPage } from "../pages/TestPage"; import { TestPage } from "../pages/TestPage";
export const AppRouter = () => { export const AppRouter = () => {
return ( return (
<Switch> <Switch>
{/* <Route exact path="/"> <Route exact path="/test">
<TestPage /> <TestPage />
</Route> */} </Route>
<Route exact path="/"> <Route exact path="/">
<HomeController /> <HomeController />