added manage user layout to project page

This commit is contained in:
Ruidy Nemausat 2020-02-23 22:06:18 +01:00
parent 6cf52b256b
commit d6d46f2850
7 changed files with 129 additions and 29 deletions

1
.gitignore vendored
View file

@ -7,4 +7,5 @@ app.db*
.DS_Store
app.db
client/node_modules
client/src/pages/TestPage.tsx
Scripts/

View file

@ -33,15 +33,16 @@
## TO DO
- Write API tests using Postman: request + test, environment variables, mock server
- Annotate API request in controllers
- Annotate Properties in Models
- Write backend tests
- Have a Look at typeahead component
- Ensure Tickets Edits belong to Project Edits
- Ensure Tickets Files belong to Project Files
- Async model methods ?
- update assignments automatically from context
- use PATCH instead of PUT
- logging
- check useRef, useReducer, dispatch
- [ ] Write API tests using Postman: request + test, environment variables, mock server
- [ ] Annotate API request in controllers
- [ ] Annotate Properties in Models
- [ ] Write backend tests
- [ ] Have a Look at typeahead component
- [ ] Ensure Tickets Edits belong to Project Edits
- [ ] Ensure Tickets Files belong to Project Files
- [ ] Async model methods ?
- [ ] update assignments automatically from context
- [ ] use PATCH instead of PUT
- [ ] logging
- [ ] check useRef, useReducer, dispatch
- [ ] error page redirect when offline.

View file

@ -13,7 +13,7 @@ export const FilterBar: FC<IProps> = ({
clearFilterText
}) => {
const { url } = useRouteMatch();
const placeholder: string = url.split("/")[3];
const placeholder: string = url.split("/")[3] || "users";
return (
<>
<div className="nav-wrapper">

View file

@ -1,17 +1,24 @@
import React, { FC } from "react";
import React, { FC, useState, CSSProperties } from "react";
export const Modal: FC = () => {
interface IProps {
handleClose: () => void;
show: boolean;
}
export const Modal: FC<IProps> = ({ handleClose, show, children }) => {
const showHideStyle: CSSProperties = show
? { display: "block", zIndex: 10 }
: { display: "none", zIndex: 10 };
return (
<div id="modal1" className="modal">
<div className="modal-content">
<h4>Modal Header</h4>
<p>A bunch of text</p>
</div>
<div className="modal-footer">
<a href="#!" className="modal-close waves-effect waves-green btn-flat">
Agree
</a>
</div>
<div className="modal" style={showHideStyle}>
<div className="modal-content">{children}</div>
{/* <div className="modal-footer">
<button
className="modal-close waves-effect waves-green btn-flat"
onClick={handleClose}
>
close
</button>
</div> */}
</div>
);
};

View file

@ -0,0 +1,73 @@
import React, { FC, useState, ChangeEvent } from "react";
import { Modal } from "./Modal";
import { AvatarList } from "./AvatarList";
import { User } from "../types/User";
import { FilterBar } from "./FilterBar";
interface IProps {
show: boolean;
handleClose: () => void;
users: User[];
}
export const UsersModal: FC<IProps> = ({ show, handleClose, users }) => {
const [filterText, setFilterText] = useState<string>("");
const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = (
e: ChangeEvent<HTMLInputElement>
) => {
setFilterText(e.target.value);
};
return (
<Modal show={show} handleClose={handleClose}>
<div className="row valign-wrapper blue">
<div className="col s10">
<h4 className="white-text">Manage users</h4>
</div>
<div className="col s2">
<i
className="right material-icons blue lighten-3 circle"
onClick={handleClose}
>
close
</i>
</div>
</div>
<div className="center">
<AvatarList users={users} />
<FilterBar
filterText={filterText}
clearFilterText={() => setFilterText("")}
handleChange={handleChange}
/>
</div>
<form>
<ul>
{users.map((u: User) => (
<li key={u.id}>
<div className="row">
<input
id={u.id}
type="checkbox"
name="active"
value="true"
onChange={() => false}
// checked
/>
<span>
{u.fullName}
<img
className="circle"
src={u.picture}
width="32vh"
height="32vh"
alt={u.fullName}
/>
</span>
</div>
</li>
))}
</ul>
</form>
</Modal>
);
};

View file

@ -1,15 +1,16 @@
import React, { FC } from "react";
import React, { FC, useState } from "react";
import ProjectVM from "../VM/ProjectVM";
import { Header } from "../components/Header";
import { AvatarList } from "../components/AvatarList";
import { ProgressBar } from "../components/ProgressBar";
import ProjectVM from "../VM/ProjectVM";
import { TabRouter } from "../components/TabRouter";
import { FloatingButton } from "../components/FloatingButton";
import { Modal } from "../components/Modal";
import { UsersModal } from "../components/UsersModal";
interface IProps {
viewModel: ProjectVM;
}
export const ProjectPage: FC<IProps> = ({ viewModel }) => {
const {
title,
@ -23,7 +24,9 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
files,
activities
} = viewModel;
const tabNames: string[] = ["Tickets", "Files", "Activity"];
const [showModal, setShowModal] = useState<boolean>(false);
return (
<div className="section">
@ -31,7 +34,17 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
<Header title={title} description={description} />
<div className="row valign-wrapper">
<AvatarList users={users} />
<FloatingButton icon="add" color="grey" size="small" />
<FloatingButton
icon="add"
color="grey"
size="small"
onClick={() => setShowModal(true)}
/>
<UsersModal
show={showModal}
users={users}
handleClose={() => setShowModal(false)}
/>
</div>
<ProgressBar
value={value}

View file

@ -11,6 +11,7 @@ import * as creacteHistory from "history";
// import { HomeController } from "../controllers/HomeController";
import { ProjectController } from "../controllers/ProjectController";
import { NotFoundPage } from "../pages/NotFoundPage";
import { TestPage } from "../pages/TestPage";
// import { UserController } from "../controllers/UserController";
// import { TicketController } from "../controllers/TicketController";
@ -21,6 +22,10 @@ export const AppRouter = () => {
<Router history={history}>
<div className="grey lighten-4">
<Switch>
<Route exact path="/">
<TestPage />
</Route>
{/* <Route path="/">
<HomeController />
</Route>