pull last react

This commit is contained in:
Ruidy Nemausat 2020-03-30 14:39:24 +02:00
commit f12f5f0187
26 changed files with 362 additions and 280 deletions

5
.gitignore vendored
View file

@ -1,9 +1,8 @@
.vs/ .vs/
.vscode/ .vscode/
.DS_Store .DS_Store
bin/ **bin/
obj/ **obj/
app.db*
Data/Interfaces Data/Interfaces
Data/UnitOfWork.cs Data/UnitOfWork.cs
Data/*Repository.cs Data/*Repository.cs

View file

@ -43,6 +43,7 @@ namespace TicketManager.Controllers
return await _context.AppUsers return await _context.AppUsers
.Include(u => u.Assignments) .Include(u => u.Assignments)
.ThenInclude(a => a.Project) .ThenInclude(a => a.Project)
.ThenInclude(p => p.Tickets)
.Include(u => u.Activities) .Include(u => u.Activities)
.AsNoTracking() .AsNoTracking()
.Select(u => new AppUserDTO(u)) .Select(u => new AppUserDTO(u))
@ -68,6 +69,7 @@ namespace TicketManager.Controllers
var user = await _context.AppUsers var user = await _context.AppUsers
.Include(u => u.Assignments) .Include(u => u.Assignments)
.ThenInclude(a => a.Project) .ThenInclude(a => a.Project)
.ThenInclude(p => p.Tickets)
.Include(u => u.Activities) .Include(u => u.Activities)
.AsNoTracking() .AsNoTracking()
.FirstOrDefaultAsync(u => u.Id == id); .FirstOrDefaultAsync(u => u.Id == id);
@ -80,12 +82,12 @@ namespace TicketManager.Controllers
} }
/// <summary> /// <summary>
/// Updates the specific project with Id. /// Updates the specific user with Id.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Sample request: /// Sample request:
/// ///
/// PUT: api/v1/Projects/3 /// PUT: api/v1/Users/3
/// { /// {
/// "id": "357727fd-5262-4522-b8a3-38271d43de84", /// "id": "357727fd-5262-4522-b8a3-38271d43de84",
/// "firstName": "Thomas", /// "firstName": "Thomas",
@ -97,7 +99,7 @@ namespace TicketManager.Controllers
/// ///
/// </remarks> /// </remarks>
/// <response code="204">Request was succesful but no content is changed</response> /// <response code="204">Request was succesful but no content is changed</response>
/// <response code="404">If the required project is null</response> /// <response code="404">If the required User is null</response>
[HttpPut("{id}")] [HttpPut("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
@ -129,12 +131,12 @@ namespace TicketManager.Controllers
} }
/// <summary> /// <summary>
/// Creates a project. /// Creates a User.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Sample request: /// Sample request:
/// ///
/// POST: api/v1/Projects/ /// POST: api/v1/Users/
/// { /// {
/// "firstName": "Thomas", /// "firstName": "Thomas",
/// "lastName": "Price", /// "lastName": "Price",
@ -144,7 +146,7 @@ namespace TicketManager.Controllers
/// } /// }
/// ///
/// </remarks> /// </remarks>
/// <response code="201">Returns the created project</response> /// <response code="201">Returns the created User</response>
[HttpPost] [HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
@ -174,15 +176,15 @@ namespace TicketManager.Controllers
} }
/// <summary> /// <summary>
/// Deletes the project identified by its Id /// Deletes the User identified by its Id
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Sample request: /// Sample request:
/// ///
/// DELETE: api/v1/Projects/5 /// DELETE: api/v1/Users/5
/// ///
/// </remarks> /// </remarks>
/// <response code="200">Returns the deleted project</response> /// <response code="200">Returns the deleted User</response>
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[HttpDelete("{id}")] [HttpDelete("{id}")]
@ -205,6 +207,7 @@ namespace TicketManager.Controllers
var user = await _context.AppUsers var user = await _context.AppUsers
.Include(u => u.Assignments) .Include(u => u.Assignments)
.ThenInclude(a => a.Project) .ThenInclude(a => a.Project)
.ThenInclude(p => p.Tickets)
.AsNoTracking() .AsNoTracking()
.FirstOrDefaultAsync(u => u.Id == id); .FirstOrDefaultAsync(u => u.Id == id);
if (user == null) if (user == null)

View file

@ -28,6 +28,8 @@ namespace TicketManager.Controllers
{ {
return await _context.Tickets return await _context.Tickets
.Include(t => t.Project) .Include(t => t.Project)
.ThenInclude(p => p.Assignments)
.ThenInclude(a => a.User)
.Include(t => t.Files) .Include(t => t.Files)
.Include(t => t.Activities) .Include(t => t.Activities)
.Include(t => t.Notes) .Include(t => t.Notes)
@ -42,6 +44,8 @@ namespace TicketManager.Controllers
{ {
var ticket = await _context.Tickets var ticket = await _context.Tickets
.Include(t => t.Project) .Include(t => t.Project)
.ThenInclude(p => p.Assignments)
.ThenInclude(a => a.User)
.Include(t => t.Files) .Include(t => t.Files)
.Include(t => t.Activities) .Include(t => t.Activities)
.Include(t => t.Notes) .Include(t => t.Notes)

View file

@ -55,7 +55,10 @@ namespace TicketManager.Models
public List<Ticket> GetTickets() public List<Ticket> GetTickets()
{ {
var tickets = new List<Ticket>(); var tickets = new List<Ticket>();
GetProjects().ForEach(p => tickets.Concat(p.Tickets)); foreach (var p in GetProjects())
{
tickets.AddRange(p.Tickets);
}
return tickets; return tickets;
} }
} }

View file

@ -50,4 +50,5 @@
- [<span style="color:red">x</span>] write dtos without circular dependencies. - [<span style="color:red">x</span>] write dtos without circular dependencies.
- [ ] use dtoRequest for PutProjects - [ ] use dtoRequest for PutProjects
- [ ] render avatarlist after UserModal Update - [ ] render avatarlist after UserModal Update
- [ ] Form validators - [x] Form validators
- [ ] Azure

BIN
app.db Normal file

Binary file not shown.

View file

@ -1,5 +1,33 @@
export class TicketVM { import { Ticket } from "../types/Ticket";
public Id?: number; import { Project } from "../types/Project";
import { User } from "../types/User";
public constructor() {} export class TicketVM {
public id: number;
public title: string;
public description: string;
public creationDate: string;
public endingDate: string;
public status: string;
public impact: string;
public difficulty: string;
public category: string;
public creatorId: string;
public project: Project;
public users: User[];
public constructor(ticket: Ticket) {
this.id = ticket.id;
this.title = ticket.title;
this.description = ticket.description;
this.creationDate = ticket.creationDate;
this.endingDate = ticket.endingDate;
this.status = ticket.status;
this.impact = ticket.impact;
this.difficulty = ticket.difficulty;
this.category = ticket.category;
this.creatorId = ticket.creatorId;
this.project = ticket.project;
this.users = ticket.users;
}
} }

View file

@ -1,19 +1,34 @@
import { Project } from "../types/Project"; import { Project } from "../types/Project";
import { Ticket } from "../types/Ticket"; import { Ticket } from "../types/Ticket";
import { User } from "../types/User"; import { User } from "../types/User";
import { Activity } from "../types/Activity";
export class UserVM { export class UserVM {
public id: string;
public firstName: string;
public lastName: string;
public fullName: string; public fullName: string;
public presentation: string; public presentation: string;
public email: string;
public phone: string;
public creationDate: string;
public picture: string; public picture: string;
public projects: Project[]; public projects: Project[];
public tickets: Ticket[]; public tickets: Ticket[];
public activities: Activity[];
public constructor(user: User) { public constructor(user: User) {
this.id = user.id;
this.firstName = user.firstName;
this.lastName = user.lastName;
this.fullName = user.fullName; this.fullName = user.fullName;
this.presentation = user.presentation; this.presentation = user.presentation;
this.email = user.email;
this.phone = user.phone;
this.creationDate = user.creationDate;
this.picture = user.picture; this.picture = user.picture;
this.projects = user.projects; this.projects = user.projects;
this.tickets = user.tickets; this.tickets = user.tickets;
this.activities = user.activities;
} }
} }

View file

@ -1,5 +1,6 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { User } from "../types/User"; import { User } from "../types/User";
import { Link } from "react-router-dom";
interface AvatarListProps { interface AvatarListProps {
users: User[]; users: User[];
@ -11,14 +12,15 @@ export const AvatarList: FC<AvatarListProps> = ({ users }) => {
) : ( ) : (
<> <>
{users.map((user: User, i: number) => ( {users.map((user: User, i: number) => (
<img <Link to={`/users/${user.id}`} key={i}>
key={i} <img
className="circle" className="circle"
src={user.picture} src={user.picture}
width="32vh" width="32vh"
height="32vh" height="32vh"
alt={user.fullName} alt={user.fullName}
/> />
</Link>
))} ))}
</> </>
); );

View file

@ -6,13 +6,13 @@ interface IProps {
title?: string; title?: string;
remainingDays?: string; remainingDays?: string;
validateTicket?: (event: MouseEvent) => void; validateTicket?: (event: MouseEvent) => void;
// archiveTicket: (event: MouseEvent) => void; link?: string;
} }
export const HorizontalCard: FC<IProps> = ({ export const HorizontalCard: FC<IProps> = ({
title, title,
remainingDays, remainingDays,
// archiveTicket, link = "#",
validateTicket validateTicket
}) => { }) => {
return ( return (
@ -23,7 +23,7 @@ export const HorizontalCard: FC<IProps> = ({
<div className="row"> <div className="row">
<div className="card-title"> <div className="card-title">
<h6> <h6>
<Link to="#"> <Link to={link}>
<b>{title ?? "Nothing to do"}</b> <b>{title ?? "Nothing to do"}</b>
</Link> </Link>
</h6> </h6>

View file

@ -0,0 +1,10 @@
import React, { FC } from "react";
export const InputField: FC = () => {
return (
<div className="input-field">
<input id="email" type="text" className="validate" />
<label htmlFor="email">Email</label>
</div>
);
};

View file

@ -0,0 +1,23 @@
import React, { FC } from "react";
import { InputField } from "./InputField";
import { PasswordField } from "./PasswordField";
import { Button } from "./Button";
export const LogInForm: FC = () => {
return (
<div className="section col s10 offset-s1 white z-depth-1">
<div className="row ">
<div className="center ">
<h4>Login</h4>
<form className="col s10 offset-s1">
<InputField />
<PasswordField />
<Button color="indigo" size="large">
Submit
</Button>
</form>
</div>
</div>
</div>
);
};

View file

@ -1,12 +1,12 @@
import React, { FC, useState, FormEvent } from "react"; import React, { FC, useState, FormEvent } from "react";
import { useParams, useRouteMatch } from "react-router-dom"; import { useRouteMatch } from "react-router-dom";
import { Modal } from "./Modal"; import { Modal } from "./Modal";
import { NewTicketForm } from "./NewTicketForm"; import { NewTicketForm } from "./NewTicketForm";
import { Ticket } from "../types/Ticket"; 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"; // import { HttpResponse } from "../types/HttpResponse";
interface IProps { interface IProps {
show: boolean; show: boolean;
@ -38,12 +38,9 @@ export const NewTicketModal: FC<IProps> = ({
creatorId: "20bf4b2a-7209-4826-96cd-29c2bc937a94", creatorId: "20bf4b2a-7209-4826-96cd-29c2bc937a94",
projectId: parseInt(projectId) projectId: parseInt(projectId)
}; };
// console.log(newTicket);
const response: HttpResponse<Ticket> = await post<Ticket>( // const response: HttpResponse<Ticket> =
`${Constants.ticketsURI}`, await post<Ticket>(`${Constants.ticketsURI}`, newTicket);
newTicket
);
// console.log(response.parsedBody);
handleClose(); handleClose();
}; };

View file

@ -0,0 +1,10 @@
import React, { FC } from "react";
export const PasswordField: FC = () => {
return (
<div className="input-field">
<input id="password" type="password" className="validate" />
<label htmlFor="password">Password</label>
</div>
);
};

View file

@ -0,0 +1,20 @@
import React, { FC } from "react";
import { HorizontalCard } from "./HorizontalCard";
import { Avatar } from "./Avatar";
import { Link } from "react-router-dom";
export const ProfileSelector: FC = () => {
return (
<div className="section col s10 offset-s1 white z-depth-1">
<div className="row ">
<div className="center ">
<h4>Select a profile</h4>
<Link to="/users/cd179eb7-3a54-4060-b22c-3e947bdffcbc">
<Avatar picture="https://vignette.wikia.nocookie.net/jamescameronsavatar/images/0/08/Neytiri_Profilbild.jpg/revision/latest/scale-to-width-down/250?cb=20100107164021&path-prefix=de" />
</Link>
<h5>Demo User</h5>
</div>
</div>
</div>
);
};

View file

@ -1,6 +1,5 @@
import React, { FC, useState, ChangeEvent, MouseEvent } from "react"; import React, { FC, useState, ChangeEvent, MouseEvent } from "react";
import { Ticket } from "../types/Ticket"; import { Ticket } from "../types/Ticket";
import { FloatingButton } from "./FloatingButton";
import { HorizontalCard } from "./HorizontalCard"; import { HorizontalCard } from "./HorizontalCard";
import { FilterBar } from "./FilterBar"; import { FilterBar } from "./FilterBar";
import { put } from "../utils/http"; import { put } from "../utils/http";
@ -17,19 +16,13 @@ export const ProjectList: FC<IProps> = ({ projects }) => {
const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => {
setFilterText(""); setFilterText("");
}; };
// const archiveTicket = () => {};
const onClick: (e: MouseEvent) => void = (e: MouseEvent) => {
e.preventDefault();
setShowNew(true);
};
const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = ( const handleChange: (e: ChangeEvent<HTMLInputElement>) => void = (
e: ChangeEvent<HTMLInputElement> e: ChangeEvent<HTMLInputElement>
) => { ) => {
setFilterText(e.target.value); setFilterText(e.target.value);
}; };
const [showNew, setShowNew] = useState(false);
let filteredTickets = projects.filter( let filteredTickets = projects.filter(
t => t =>
t.status !== "Done" && t.status !== "Done" &&
@ -39,18 +32,13 @@ export const ProjectList: FC<IProps> = ({ projects }) => {
<> <>
<div className="row valign-wrapper"> <div className="row valign-wrapper">
<h3>Projects</h3> <h3>Projects</h3>
<FloatingButton
color="indigo lighten-1"
size="small"
onClick={onClick}
/>
<FilterBar <FilterBar
filterText={filterText} filterText={filterText}
handleChange={handleChange} handleChange={handleChange}
clearFilterText={clearFilterText} clearFilterText={clearFilterText}
/> />
</div> </div>
<div className="col s12 grey"> <div className="col s12 grey lighten-1">
<ul> <ul>
{filteredTickets.length === 0 ? ( {filteredTickets.length === 0 ? (
<HorizontalCard /> <HorizontalCard />
@ -60,6 +48,7 @@ export const ProjectList: FC<IProps> = ({ projects }) => {
key={t.id} key={t.id}
title={t.title} title={t.title}
remainingDays={t.endingDate} remainingDays={t.endingDate}
link={`/projects/${t.id}`}
validateTicket={async (e: MouseEvent) => { validateTicket={async (e: MouseEvent) => {
e.preventDefault(); e.preventDefault();
await put<HttpResponse<Ticket>>( await put<HttpResponse<Ticket>>(
@ -67,7 +56,6 @@ export const ProjectList: FC<IProps> = ({ projects }) => {
{} {}
); );
}} }}
// archiveTicket={archiveTicket}
/> />
)) ))
)} )}

View file

@ -12,9 +12,14 @@ import { Project } from "../types/Project";
type TicketListProps = { type TicketListProps = {
tickets: Ticket[]; tickets: Ticket[];
allProjects: Project[]; allProjects: Project[];
addButton?: Boolean;
}; };
export const TicketList: FC<TicketListProps> = ({ tickets, allProjects }) => { export const TicketList: FC<TicketListProps> = ({
tickets,
allProjects,
addButton = true
}) => {
const [filterText, setFilterText] = useState<string>(""); const [filterText, setFilterText] = useState<string>("");
const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => {
setFilterText(""); setFilterText("");
@ -47,11 +52,13 @@ export const TicketList: FC<TicketListProps> = ({ tickets, allProjects }) => {
allProjects={allProjects} allProjects={allProjects}
/> />
<h3>Tickets</h3> <h3>Tickets</h3>
<FloatingButton {addButton && (
color="indigo lighten-3" <FloatingButton
size="small" color="indigo lighten-3"
onClick={onClick} size="small"
/> onClick={onClick}
/>
)}
<FilterBar <FilterBar
filterText={filterText} filterText={filterText}
handleChange={handleChange} handleChange={handleChange}
@ -68,6 +75,7 @@ export const TicketList: FC<TicketListProps> = ({ tickets, allProjects }) => {
key={t.id} key={t.id}
title={t.title} title={t.title}
remainingDays={t.endingDate} remainingDays={t.endingDate}
link={`/tickets/${t.id}`}
validateTicket={async (e: MouseEvent) => { validateTicket={async (e: MouseEvent) => {
e.preventDefault(); e.preventDefault();
await put<HttpResponse<Ticket>>( await put<HttpResponse<Ticket>>(

View file

@ -27,7 +27,7 @@ export const UserTabRouter: FC<IProps> = ({ tickets, tabNames, projects }) => {
</Route> </Route>
<Route path={`${url}/tickets`}> <Route path={`${url}/tickets`}>
<TicketList tickets={tickets} allProjects={[]} /> <TicketList tickets={tickets} allProjects={[]} addButton={false} />
</Route> </Route>
</div> </div>
</> </>

View file

@ -77,6 +77,7 @@ export const ProjectController: FC = () => {
if (hasError) { if (hasError) {
return <ErrorController error={error} />; return <ErrorController error={error} />;
} }
const viewModel = new ProjectVM(project, allUsers, allProjects); const viewModel = new ProjectVM(project, allUsers, allProjects);
return isLoading ? <Preloader /> : <ProjectPage viewModel={viewModel} />; return isLoading ? <Preloader /> : <ProjectPage viewModel={viewModel} />;
}; };

File diff suppressed because one or more lines are too long

View file

@ -1,90 +1,50 @@
import React, { FC, useState, useEffect } from "react"; import React, { FC, useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { UserPage } from "../pages/UserPage"; import { UserPage } from "../pages/UserPage";
import { UserVM } from "../VM/UserVM"; import { UserVM } from "../VM/UserVM";
import { User } from "../types/User"; import { User } from "../types/User";
import { AppFile } from "../types/AppFile"; import { HttpResponse } from "../types/HttpResponse";
import { Activity } from "../types/Activity";
import { Ticket } from "../types/Ticket";
import { Preloader } from "../components/Preloader"; import { Preloader } from "../components/Preloader";
import { get } from "../utils/http";
import { Constants } from "../utils/Constants";
import { ErrorController } from "./ErrorController";
export const UserController: FC = () => { export const UserController: FC = () => {
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [user, setUser] = useState<User>({} as User);
const [hasError, setHasError] = useState(false);
const [error, setError] = useState("");
const { id } = useParams();
const user: User = { async function httpGetUser(id: string): Promise<void> {
id: "resldsm,dgd", try {
firstName: "David", const response: HttpResponse<User> = await get<User>(
lastName: "Whittaker", `${Constants.usersURI}/${id}`
fullName: "David Whittaker", );
presentation: "Interface designer and front-end developer", if (response.parsedBody !== undefined) {
creationDate: new Date().toDateString(), setUser(response.parsedBody);
email: "dw@mail.au", setIsLoading(false);
phone: "0998765432",
picture: require("../images/user_1.jpg"),
projects: [
{
id: 1,
title: "Project Title",
description: "What is it about",
progression: 25,
creationDate: new Date().toDateString(),
endingDate: "2020-02-17 15:51:02.787373",
status: "Todo",
manager: {} as User,
users: [] as User[],
tickets: [] as Ticket[],
files: [] as AppFile[],
activities: [] as Activity[]
} }
], } catch (ex) {
tickets: [ console.error(ex);
{ setHasError(true);
id: 1, setError(ex);
title: "Client objective meeting", }
description: "Client objective meeting", }
endingDate: "2020-02-17 15:51:02.787373",
status: "Done",
project: {
id: 1,
title: "Project Title",
description: "What is it about",
progression: 25,
creationDate: new Date().toDateString(),
endingDate: "2020-02-17 15:51:02.787373",
status: "Todo",
manager: {} as User,
users: [] as User[],
tickets: [] as Ticket[],
files: [] as AppFile[],
activities: [] as Activity[]
}
},
{
id: 2,
title: "Assemble Outcomes Report for client",
description: "Assemble Outcomes Report for client",
endingDate: "2020-02-27 15:51:02.787373",
status: "To Do",
project: {
id: 1,
title: "Project Title",
description: "What is it about",
progression: 25,
creationDate: new Date().toDateString(),
endingDate: "2020-02-17 15:51:02.787373",
status: "Todo",
manager: {} as User,
users: [] as User[],
tickets: [] as Ticket[],
files: [] as AppFile[],
activities: [] as Activity[]
}
}
],
activities: []
};
useEffect(() => { useEffect(() => {
setTimeout(() => setIsLoading(false), 1000); if (id !== undefined) {
}); httpGetUser(id);
} else {
setHasError(true);
setError("Bad Request");
}
}, [id]);
if (hasError) {
return <ErrorController error={error} />;
}
const viewModel = new UserVM(user); const viewModel = new UserVM(user);
return isLoading ? <Preloader /> : <UserPage viewModel={viewModel} />; return isLoading ? <Preloader /> : <UserPage viewModel={viewModel} />;
}; };

View file

@ -1,9 +1,21 @@
import React from "react"; import React from "react";
import { LogInForm } from "../components/LogInForm";
import { ProfileSelector } from "../components/ProfileSelector";
export const HomePage: React.FC = () => { export const HomePage: React.FC = () => {
return ( return (
<div className="App"> <div className="section">
<p>HomePage</p> <div className="container center">
<h1 className="center">Ticket Manager</h1>
<div className="row">
<div className="col s6">
<ProfileSelector />
</div>
<div className="col s6">
<LogInForm />
</div>
</div>
</div>
</div> </div>
); );
}; };

View file

@ -1,23 +1,79 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { Header } from "../components/Header"; import { Header } from "../components/Header";
import { AvatarList } from "../components/AvatarList"; import { AvatarList } from "../components/AvatarList";
import { ProgressBar } from "../components/ProgressBar"; import { TicketVM } from "../VM/TicketVM";
import { getRemainingdays } from "../utils/methods";
import { Link } from "react-router-dom";
interface IProps {
viewModel: TicketVM;
}
export const TicketPage: FC<IProps> = ({ viewModel }) => {
const {
title,
description,
users,
endingDate,
project,
status,
category,
impact,
difficulty
} = viewModel;
const daysToEnd: number = getRemainingdays(endingDate);
// let notes: string = "";
export const TicketPage: FC = () => {
return ( return (
<> <div className="section">
<Header <div className="container">
description="Research, ideate and present brand concepts for client consideration" <Header title={title} description={description} />
title="Brand Concept and Design" <AvatarList users={users} />
/>
{/* <AvatarList users={["../images/user_1.jpg", "../images/user_2.jpg"]} /> */} <div className="row section">
<ProgressBar value={60} /> <div className="col s9">
{/* // <TabView> <h5>
// <ChildTicket/> <b>In project: </b>{" "}
// <ChildFile/> <Link to={`/projects/${project.id}`}>{project.title}</Link>
// <ChildActivity/> </h5>
// </TabView> </div>
// <Notes/> */} <div className="col s3">
</> <i className="left material-icons">timer</i>
<span>Due in {daysToEnd} days</span>
</div>
</div>
<div className="section white center">
<div className="chip">
<span className="indigo-text">Status: </span> {status}
{/* <i className="close material-icons">close</i> */}
</div>
<div className="chip">
<span className="orange-text">Category: </span> {category}
{/* <i className="close material-icons">close</i> */}
</div>
<div className="chip">
<span className="green-text">Impact: </span> {impact}
{/* <i className="close material-icons">close</i> */}
</div>
<div className="chip">
<span className="red-text">Difficulty: </span> {difficulty}
{/* <i className="close material-icons">close</i> */}
</div>
{/* <textarea
id="notes"
className="materialize-textarea validate"
value={notes}
// onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
// setDescription(e.target.value)
// }
></textarea> */}
</div>
</div>
</div>
); );
}; };

View file

@ -1,10 +1,17 @@
import { Project } from "./Project"; import { Project } from "./Project";
import { User } from "./User";
export interface Ticket { export interface Ticket {
id: number; id: number;
title: string; title: string;
description: string; description: string;
status: string; creationDate: string;
endingDate: string; endingDate: string;
status: string;
impact: string;
difficulty: string;
category: string;
creatorId: string;
project: Project; project: Project;
users: User[];
} }

View file

@ -58,5 +58,5 @@ const headers: Headers = new Headers({
Accept: "application/json", Accept: "application/json",
"Content-Type": "application/json", "Content-Type": "application/json",
Authorization: Authorization:
"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UWkNSRFEzUkRnd1FUQXlNRFExTmtOQ09UQXlSamhGTURaRU1Ea3pNRGxHUkRrelFqZENSZyJ9.eyJpc3MiOiJodHRwczovL2Rldi1meWpydm9oeC5hdXRoMC5jb20vIiwic3ViIjoiR3dlZTlGUnN3ejNWNE5vZFVRTjJIcjJyQjJTMDI1UmZAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjUwMDEvYXBpL1YxLyIsImlhdCI6MTU4Mzc0MzE1OSwiZXhwIjoxNTgzODI5NTU5LCJhenAiOiJHd2VlOUZSc3d6M1Y0Tm9kVVFOMkhyMnJCMlMwMjVSZiIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.G1PTca14OLP1Ty3YFJaW0n_LRiG8ib1Nw_OcDH4HgWKgK6sZlIQ6RuAxiJjE0X6c7sxiTmtVhsRF-dqnfXuQcMWouj-8nd5C1LdVco3D08t0megehCeSZ4ffjjDQXQjWwvahTfuxJhXFVwK1M7F-dtLnk6lUJC9EjRg5qwtT5pa_js47RawHZWSfm-h6A1tVVs_cjy4I4xQLThKYQ3bTR5fYGNjnfa2AybE9Dv2Q0JehSDqSt1zCyIAnZTxJmgUWPW7Rp2xnmHf6Usmpy_9P5HbnnuRXZ1IT3dllS6OMIki3xyTeJDlCxhI37Ib1Dtx6PaPbFAP88QiRy2hwSi_S6w" "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UWkNSRFEzUkRnd1FUQXlNRFExTmtOQ09UQXlSamhGTURaRU1Ea3pNRGxHUkRrelFqZENSZyJ9.eyJpc3MiOiJodHRwczovL2Rldi1meWpydm9oeC5hdXRoMC5jb20vIiwic3ViIjoiR3dlZTlGUnN3ejNWNE5vZFVRTjJIcjJyQjJTMDI1UmZAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjUwMDEvYXBpL1YxLyIsImlhdCI6MTU4NDE5ODQ4MCwiZXhwIjoxNTg0Mjg0ODgwLCJhenAiOiJHd2VlOUZSc3d6M1Y0Tm9kVVFOMkhyMnJCMlMwMjVSZiIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.I1D49ILGBLhnq9biIA0y6Ra93zTKRDJI_rfGvU05MtT1zkI1ZliX9P-7LyKeWBv8tPonB6gT12lJiai_GHBET8kKbXNqwfVvDJ3eqYK-TtTqfL65RfWL9tQfQybHbfuF9M0oiXMqWMqmsc5Umpp4a3bLTQgwkUEKxcdMm84L7zoaqMycns4mFojWpQJKfPa64oZFDIXYy6hPDXcX50Djuk1m-aqMhtpmqkZvPfwEjvtEtGGCTOJHV7uugn3r8Wk4HX02ShrV676GICE1Yw7eHufAbY7yvHz3ImZ1cfEVrRbbijPA2vogXd5RmqNyindDDlT1Y_C80U0DyvhS7P7apQ"
}); });

View file

@ -1,19 +1,12 @@
import React from "react"; import React from "react";
import { import { Router, Route, Switch } from "react-router-dom";
Router,
Route,
Switch
// Redirect
//Link, NavLink
} from "react-router-dom";
import * as creacteHistory from "history"; import * as creacteHistory from "history";
// import { TicketPage } from "../pages/TicketPage"; import { HomeController } from "../controllers/HomeController";
// import { HomeController } from "../controllers/HomeController";
import { ProjectController } from "../controllers/ProjectController"; import { ProjectController } from "../controllers/ProjectController";
import { NotFoundPage } from "../pages/NotFoundPage";
import { TestPage } from "../pages/TestPage";
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 { TestPage } from "../pages/TestPage";
export const history = creacteHistory.createBrowserHistory(); export const history = creacteHistory.createBrowserHistory();
@ -22,24 +15,27 @@ export const AppRouter = () => {
<Router history={history}> <Router history={history}>
<div className="grey lighten-3"> <div className="grey lighten-3">
<Switch> <Switch>
<Route exact path="/"> {/* <Route exact path="/">
<TestPage /> <TestPage />
</Route> */}
<Route exact path="/">
<HomeController />
</Route> </Route>
{/* <Route path="/">
<HomeController />
</Route> */}
<Route path="/users/:id"> <Route path="/users/:id">
<UserController /> <UserController />
</Route> </Route>
<Route path="/projects/:id"> <Route path="/projects/:id">
<ProjectController /> <ProjectController />
</Route> </Route>
{/* <Route path="/tickets/:id">
<TicketController />
</Route> */}
<Route path="/401"> <Route path="/tickets/:id">
<TicketController />
</Route>
<Route path="/404">
<NotFoundPage /> <NotFoundPage />
</Route> </Route>
</Switch> </Switch>