mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-06 00:36:39 +00:00
added manage user layout to project page
This commit is contained in:
parent
6cf52b256b
commit
d6d46f2850
7 changed files with 129 additions and 29 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -7,4 +7,5 @@ app.db*
|
|||
.DS_Store
|
||||
app.db
|
||||
client/node_modules
|
||||
client/src/pages/TestPage.tsx
|
||||
Scripts/
|
||||
|
|
|
|||
25
README.md
25
README.md
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
73
client/src/components/UsersModal.tsx
Normal file
73
client/src/components/UsersModal.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue