diff --git a/.gitignore b/.gitignore index 0b93d06..58baf12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ .vs/ .vscode/ .DS_Store -bin/ -obj/ -app.db* +**bin/ +**obj/ Data/Interfaces Data/UnitOfWork.cs Data/*Repository.cs diff --git a/Controllers/AppUsersController.cs b/Controllers/AppUsersController.cs index f93ade2..2c1b759 100644 --- a/Controllers/AppUsersController.cs +++ b/Controllers/AppUsersController.cs @@ -43,6 +43,7 @@ namespace TicketManager.Controllers return await _context.AppUsers .Include(u => u.Assignments) .ThenInclude(a => a.Project) + .ThenInclude(p => p.Tickets) .Include(u => u.Activities) .AsNoTracking() .Select(u => new AppUserDTO(u)) @@ -68,6 +69,7 @@ namespace TicketManager.Controllers var user = await _context.AppUsers .Include(u => u.Assignments) .ThenInclude(a => a.Project) + .ThenInclude(p => p.Tickets) .Include(u => u.Activities) .AsNoTracking() .FirstOrDefaultAsync(u => u.Id == id); @@ -80,12 +82,12 @@ namespace TicketManager.Controllers } /// - /// Updates the specific project with Id. + /// Updates the specific user with Id. /// /// /// Sample request: /// - /// PUT: api/v1/Projects/3 + /// PUT: api/v1/Users/3 /// { /// "id": "357727fd-5262-4522-b8a3-38271d43de84", /// "firstName": "Thomas", @@ -97,7 +99,7 @@ namespace TicketManager.Controllers /// /// /// Request was succesful but no content is changed - /// If the required project is null + /// If the required User is null [HttpPut("{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -129,12 +131,12 @@ namespace TicketManager.Controllers } /// - /// Creates a project. + /// Creates a User. /// /// /// Sample request: /// - /// POST: api/v1/Projects/ + /// POST: api/v1/Users/ /// { /// "firstName": "Thomas", /// "lastName": "Price", @@ -144,7 +146,7 @@ namespace TicketManager.Controllers /// } /// /// - /// Returns the created project + /// Returns the created User [HttpPost] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -174,15 +176,15 @@ namespace TicketManager.Controllers } /// - /// Deletes the project identified by its Id + /// Deletes the User identified by its Id /// /// /// Sample request: /// - /// DELETE: api/v1/Projects/5 + /// DELETE: api/v1/Users/5 /// /// - /// Returns the deleted project + /// Returns the deleted User [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [HttpDelete("{id}")] @@ -205,6 +207,7 @@ namespace TicketManager.Controllers var user = await _context.AppUsers .Include(u => u.Assignments) .ThenInclude(a => a.Project) + .ThenInclude(p => p.Tickets) .AsNoTracking() .FirstOrDefaultAsync(u => u.Id == id); if (user == null) diff --git a/Controllers/TicketsController.cs b/Controllers/TicketsController.cs index 4895621..78891dd 100644 --- a/Controllers/TicketsController.cs +++ b/Controllers/TicketsController.cs @@ -28,6 +28,8 @@ namespace TicketManager.Controllers { return await _context.Tickets .Include(t => t.Project) + .ThenInclude(p => p.Assignments) + .ThenInclude(a => a.User) .Include(t => t.Files) .Include(t => t.Activities) .Include(t => t.Notes) @@ -42,6 +44,8 @@ namespace TicketManager.Controllers { var ticket = await _context.Tickets .Include(t => t.Project) + .ThenInclude(p => p.Assignments) + .ThenInclude(a => a.User) .Include(t => t.Files) .Include(t => t.Activities) .Include(t => t.Notes) diff --git a/Models/AppUser.cs b/Models/AppUser.cs index 9dd2315..43e0924 100644 --- a/Models/AppUser.cs +++ b/Models/AppUser.cs @@ -55,7 +55,10 @@ namespace TicketManager.Models public List GetTickets() { var tickets = new List(); - GetProjects().ForEach(p => tickets.Concat(p.Tickets)); + foreach (var p in GetProjects()) + { + tickets.AddRange(p.Tickets); + } return tickets; } } diff --git a/README.md b/README.md index 4980c9f..fb4ca2d 100644 --- a/README.md +++ b/README.md @@ -50,4 +50,5 @@ - [x] write dtos without circular dependencies. - [ ] use dtoRequest for PutProjects - [ ] render avatarlist after UserModal Update -- [ ] Form validators +- [x] Form validators +- [ ] Azure diff --git a/app.db b/app.db new file mode 100644 index 0000000..ac293e3 Binary files /dev/null and b/app.db differ diff --git a/client/src/VM/TicketVM.ts b/client/src/VM/TicketVM.ts index fa5323c..6b6d641 100644 --- a/client/src/VM/TicketVM.ts +++ b/client/src/VM/TicketVM.ts @@ -1,5 +1,33 @@ -export class TicketVM { - public Id?: number; +import { Ticket } from "../types/Ticket"; +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; + } } diff --git a/client/src/VM/UserVM.ts b/client/src/VM/UserVM.ts index 175da9a..5152faf 100644 --- a/client/src/VM/UserVM.ts +++ b/client/src/VM/UserVM.ts @@ -1,19 +1,34 @@ import { Project } from "../types/Project"; import { Ticket } from "../types/Ticket"; import { User } from "../types/User"; +import { Activity } from "../types/Activity"; export class UserVM { + public id: string; + public firstName: string; + public lastName: string; public fullName: string; public presentation: string; + public email: string; + public phone: string; + public creationDate: string; public picture: string; public projects: Project[]; public tickets: Ticket[]; + public activities: Activity[]; public constructor(user: User) { + this.id = user.id; + this.firstName = user.firstName; + this.lastName = user.lastName; this.fullName = user.fullName; this.presentation = user.presentation; + this.email = user.email; + this.phone = user.phone; + this.creationDate = user.creationDate; this.picture = user.picture; this.projects = user.projects; this.tickets = user.tickets; + this.activities = user.activities; } } diff --git a/client/src/components/AvatarList.tsx b/client/src/components/AvatarList.tsx index 33dc256..606111f 100644 --- a/client/src/components/AvatarList.tsx +++ b/client/src/components/AvatarList.tsx @@ -1,5 +1,6 @@ import React, { FC } from "react"; import { User } from "../types/User"; +import { Link } from "react-router-dom"; interface AvatarListProps { users: User[]; @@ -11,14 +12,15 @@ export const AvatarList: FC = ({ users }) => { ) : ( <> {users.map((user: User, i: number) => ( - {user.fullName} + + {user.fullName} + ))} ); diff --git a/client/src/components/HorizontalCard.tsx b/client/src/components/HorizontalCard.tsx index 815804c..8d53495 100644 --- a/client/src/components/HorizontalCard.tsx +++ b/client/src/components/HorizontalCard.tsx @@ -6,13 +6,13 @@ interface IProps { title?: string; remainingDays?: string; validateTicket?: (event: MouseEvent) => void; - // archiveTicket: (event: MouseEvent) => void; + link?: string; } export const HorizontalCard: FC = ({ title, remainingDays, - // archiveTicket, + link = "#", validateTicket }) => { return ( @@ -23,7 +23,7 @@ export const HorizontalCard: FC = ({
- + {title ?? "Nothing to do"}
diff --git a/client/src/components/InputField.tsx b/client/src/components/InputField.tsx new file mode 100644 index 0000000..6dc5468 --- /dev/null +++ b/client/src/components/InputField.tsx @@ -0,0 +1,10 @@ +import React, { FC } from "react"; + +export const InputField: FC = () => { + return ( +
+ + +
+ ); +}; diff --git a/client/src/components/LogInForm.tsx b/client/src/components/LogInForm.tsx new file mode 100644 index 0000000..9ef2fb0 --- /dev/null +++ b/client/src/components/LogInForm.tsx @@ -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 ( +
+
+
+

Login

+
+ + + + +
+
+
+ ); +}; diff --git a/client/src/components/NewTicketModal.tsx b/client/src/components/NewTicketModal.tsx index 03c7ccd..055974f 100644 --- a/client/src/components/NewTicketModal.tsx +++ b/client/src/components/NewTicketModal.tsx @@ -1,12 +1,12 @@ 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 { NewTicketForm } from "./NewTicketForm"; import { Ticket } from "../types/Ticket"; import { Project } from "../types/Project"; import { post } from "../utils/http"; import { Constants } from "../utils/Constants"; -import { HttpResponse } from "../types/HttpResponse"; +// import { HttpResponse } from "../types/HttpResponse"; interface IProps { show: boolean; @@ -38,12 +38,9 @@ export const NewTicketModal: FC = ({ creatorId: "20bf4b2a-7209-4826-96cd-29c2bc937a94", projectId: parseInt(projectId) }; - // console.log(newTicket); - const response: HttpResponse = await post( - `${Constants.ticketsURI}`, - newTicket - ); - // console.log(response.parsedBody); + + // const response: HttpResponse = + await post(`${Constants.ticketsURI}`, newTicket); handleClose(); }; diff --git a/client/src/components/PasswordField.tsx b/client/src/components/PasswordField.tsx new file mode 100644 index 0000000..d30d302 --- /dev/null +++ b/client/src/components/PasswordField.tsx @@ -0,0 +1,10 @@ +import React, { FC } from "react"; + +export const PasswordField: FC = () => { + return ( +
+ + +
+ ); +}; diff --git a/client/src/components/ProfileSelector.tsx b/client/src/components/ProfileSelector.tsx new file mode 100644 index 0000000..f689262 --- /dev/null +++ b/client/src/components/ProfileSelector.tsx @@ -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 ( +
+
+
+

Select a profile

+ + + +
Demo User
+
+
+
+ ); +}; diff --git a/client/src/components/ProjectList.tsx b/client/src/components/ProjectList.tsx index 85d1460..a574d41 100644 --- a/client/src/components/ProjectList.tsx +++ b/client/src/components/ProjectList.tsx @@ -1,6 +1,5 @@ import React, { FC, useState, ChangeEvent, MouseEvent } from "react"; import { Ticket } from "../types/Ticket"; -import { FloatingButton } from "./FloatingButton"; import { HorizontalCard } from "./HorizontalCard"; import { FilterBar } from "./FilterBar"; import { put } from "../utils/http"; @@ -17,19 +16,13 @@ export const ProjectList: FC = ({ projects }) => { const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { setFilterText(""); }; - // const archiveTicket = () => {}; - const onClick: (e: MouseEvent) => void = (e: MouseEvent) => { - e.preventDefault(); - setShowNew(true); - }; const handleChange: (e: ChangeEvent) => void = ( e: ChangeEvent ) => { setFilterText(e.target.value); }; - const [showNew, setShowNew] = useState(false); let filteredTickets = projects.filter( t => t.status !== "Done" && @@ -39,18 +32,13 @@ export const ProjectList: FC = ({ projects }) => { <>

Projects

-
-
+
    {filteredTickets.length === 0 ? ( @@ -60,6 +48,7 @@ export const ProjectList: FC = ({ projects }) => { key={t.id} title={t.title} remainingDays={t.endingDate} + link={`/projects/${t.id}`} validateTicket={async (e: MouseEvent) => { e.preventDefault(); await put>( @@ -67,7 +56,6 @@ export const ProjectList: FC = ({ projects }) => { {} ); }} - // archiveTicket={archiveTicket} /> )) )} diff --git a/client/src/components/TicketList.tsx b/client/src/components/TicketList.tsx index 677af17..149eabe 100644 --- a/client/src/components/TicketList.tsx +++ b/client/src/components/TicketList.tsx @@ -12,9 +12,14 @@ import { Project } from "../types/Project"; type TicketListProps = { tickets: Ticket[]; allProjects: Project[]; + addButton?: Boolean; }; -export const TicketList: FC = ({ tickets, allProjects }) => { +export const TicketList: FC = ({ + tickets, + allProjects, + addButton = true +}) => { const [filterText, setFilterText] = useState(""); const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { setFilterText(""); @@ -47,11 +52,13 @@ export const TicketList: FC = ({ tickets, allProjects }) => { allProjects={allProjects} />

    Tickets

    - + {addButton && ( + + )} = ({ tickets, allProjects }) => { key={t.id} title={t.title} remainingDays={t.endingDate} + link={`/tickets/${t.id}`} validateTicket={async (e: MouseEvent) => { e.preventDefault(); await put>( diff --git a/client/src/components/UserTabRouter.tsx b/client/src/components/UserTabRouter.tsx index d68c8e2..af30bf3 100644 --- a/client/src/components/UserTabRouter.tsx +++ b/client/src/components/UserTabRouter.tsx @@ -27,7 +27,7 @@ export const UserTabRouter: FC = ({ tickets, tabNames, projects }) => { - +
diff --git a/client/src/controllers/ProjectController.tsx b/client/src/controllers/ProjectController.tsx index 3d30d04..427bd8f 100644 --- a/client/src/controllers/ProjectController.tsx +++ b/client/src/controllers/ProjectController.tsx @@ -77,6 +77,7 @@ export const ProjectController: FC = () => { if (hasError) { return ; } + const viewModel = new ProjectVM(project, allUsers, allProjects); return isLoading ? : ; }; diff --git a/client/src/controllers/TicketController.tsx b/client/src/controllers/TicketController.tsx index 5d3a949..0cccd54 100644 --- a/client/src/controllers/TicketController.tsx +++ b/client/src/controllers/TicketController.tsx @@ -1,111 +1,50 @@ -import React, { FC } from "react"; +import React, { FC, useState, useEffect } from "react"; +import { useParams } from "react-router-dom"; import { TicketPage } from "../pages/TicketPage"; +import { ErrorController } from "./ErrorController"; +import { HttpResponse } from "../types/HttpResponse"; +import { Preloader } from "../components/Preloader"; +import { get } from "../utils/http"; +import { Constants } from "../utils/Constants"; +import { Ticket } from "../types/Ticket"; +import { TicketVM } from "../VM/TicketVM"; export const TicketController: FC = () => { - return ; + const [isLoading, setIsLoading] = useState(true); + const [ticket, setTicket] = useState({} as Ticket); + const [hasError, setHasError] = useState(false); + const [error, setError] = useState(""); + const { id } = useParams(); + + async function httpGetTicket(id: string): Promise { + try { + const response: HttpResponse = await get( + `${Constants.ticketsURI}/${id}` + ); + if (response.parsedBody !== undefined) { + setTicket(response.parsedBody); + setIsLoading(false); + } + } catch (ex) { + console.error(ex); + setHasError(true); + setError(ex); + } + } + + useEffect(() => { + if (id !== undefined) { + httpGetTicket(id); + } else { + setHasError(true); + setError("Bad Request"); + } + }, [id]); + + if (hasError) { + return ; + } + + const viewModel = new TicketVM(ticket); + return isLoading ? : ; }; - -// const viewModel = new ProjectVM(project); - -// const tickets: Ticket[] = [ -// { -// id: 1, -// title: "Client objective meeting", -// description: "Client objective meeting", -// plannedEnding: "2020-02-17 15:51:02.787373", -// status: "Done" -// }, -// { -// id: 2, -// title: "Assemble Outcomes Report for client", -// description: "Assemble Outcomes Report for client", -// plannedEnding: "2020-02-27 15:51:02.787373", -// status: "To Do" -// } -// ]; - -// const users: User[] = [ -// { -// id: "1", -// firstName: "PacMan", -// picture: -// "data:image/jpeg;base64,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" -// }, -// { -// id: "2", -// firstName: "Avatar", -// picture: -// "data:image/png;base64,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" -// }, -// { -// id: "3", -// firstName: "Zoey", -// picture: -// "data:image/jpeg;base64,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" -// }, -// { -// id: "4", -// firstName: "Kory", -// picture: -// "data:image/jpeg;base64,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" -// } -// ]; - -// const files: AppFile[] = [ -// { -// id: 1, -// name: "SRS", -// description: "App blueprint", -// size: 15, -// format: "pdf" -// }, -// { -// id: 2, -// name: "Business Model Canvas", -// description: "Path to 1B$", -// size: 2100, -// format: "png" -// } -// ]; - -// const activities: Activity[] = [ -// { -// id: 1, -// description: " completed the task ", -// date: new Date(), -// user: users[0], -// ticket: tickets[0] -// }, -// { -// id: 2, -// description: " added the task ", -// date: new Date(), -// user: users[1], -// ticket: tickets[1] -// }, -// { -// id: 3, -// description: " rescheduled the task ", -// date: new Date(), -// user: users[2], -// ticket: tickets[1] -// }, -// { -// id: 4, -// description: " added the task ", -// date: new Date(), -// user: users[3], -// ticket: tickets[0] -// } -// ]; -// const project: Project = { -// id: 1, -// title: "Project Title", -// description: "What is it about", -// progression: 25, -// tickets: tickets, -// users: users, -// plannedEnding: "2020-02-17 15:51:02.787373", -// files: files, -// activities: activities -// }; diff --git a/client/src/controllers/UserController.tsx b/client/src/controllers/UserController.tsx index afc337b..181a3fa 100644 --- a/client/src/controllers/UserController.tsx +++ b/client/src/controllers/UserController.tsx @@ -1,90 +1,50 @@ import React, { FC, useState, useEffect } from "react"; +import { useParams } from "react-router-dom"; import { UserPage } from "../pages/UserPage"; import { UserVM } from "../VM/UserVM"; import { User } from "../types/User"; -import { AppFile } from "../types/AppFile"; -import { Activity } from "../types/Activity"; -import { Ticket } from "../types/Ticket"; +import { HttpResponse } from "../types/HttpResponse"; import { Preloader } from "../components/Preloader"; +import { get } from "../utils/http"; +import { Constants } from "../utils/Constants"; +import { ErrorController } from "./ErrorController"; export const UserController: FC = () => { const [isLoading, setIsLoading] = useState(true); + const [user, setUser] = useState({} as User); + const [hasError, setHasError] = useState(false); + const [error, setError] = useState(""); + const { id } = useParams(); - const user: User = { - id: "resldsm,dgd", - firstName: "David", - lastName: "Whittaker", - fullName: "David Whittaker", - presentation: "Interface designer and front-end developer", - creationDate: new Date().toDateString(), - email: "dw@mail.au", - 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[] + async function httpGetUser(id: string): Promise { + try { + const response: HttpResponse = await get( + `${Constants.usersURI}/${id}` + ); + if (response.parsedBody !== undefined) { + setUser(response.parsedBody); + setIsLoading(false); } - ], - tickets: [ - { - id: 1, - 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: [] - }; + } catch (ex) { + console.error(ex); + setHasError(true); + setError(ex); + } + } + useEffect(() => { - setTimeout(() => setIsLoading(false), 1000); - }); + if (id !== undefined) { + httpGetUser(id); + } else { + setHasError(true); + setError("Bad Request"); + } + }, [id]); + + if (hasError) { + return ; + } + const viewModel = new UserVM(user); return isLoading ? : ; }; diff --git a/client/src/pages/HomePage.tsx b/client/src/pages/HomePage.tsx index cc4a722..d6676c9 100644 --- a/client/src/pages/HomePage.tsx +++ b/client/src/pages/HomePage.tsx @@ -1,9 +1,21 @@ import React from "react"; +import { LogInForm } from "../components/LogInForm"; +import { ProfileSelector } from "../components/ProfileSelector"; export const HomePage: React.FC = () => { return ( -
-

HomePage

+
+
+

Ticket Manager

+
+
+ +
+
+ +
+
+
); }; diff --git a/client/src/pages/TicketPage.tsx b/client/src/pages/TicketPage.tsx index 4036985..df4f640 100644 --- a/client/src/pages/TicketPage.tsx +++ b/client/src/pages/TicketPage.tsx @@ -1,23 +1,79 @@ import React, { FC } from "react"; import { Header } from "../components/Header"; 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 = ({ 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 ( - <> -
- {/* */} - - {/* // - // - // - // - // - // */} - +
+
+
+ + +
+
+
+ In project: {" "} + {project.title} +
+
+
+ timer + Due in {daysToEnd} days +
+
+ +
+
+ Status: {status} + {/* close */} +
+ +
+ Category: {category} + {/* close */} +
+ +
+ Impact: {impact} + {/* close */} +
+ +
+ Difficulty: {difficulty} + {/* close */} +
+ + {/* */} +
+
+
); }; diff --git a/client/src/types/Ticket.ts b/client/src/types/Ticket.ts index be6cac3..6d32d88 100644 --- a/client/src/types/Ticket.ts +++ b/client/src/types/Ticket.ts @@ -1,10 +1,17 @@ import { Project } from "./Project"; +import { User } from "./User"; export interface Ticket { id: number; title: string; description: string; - status: string; + creationDate: string; endingDate: string; + status: string; + impact: string; + difficulty: string; + category: string; + creatorId: string; project: Project; + users: User[]; } diff --git a/client/src/utils/http.ts b/client/src/utils/http.ts index a050343..07b99b1 100644 --- a/client/src/utils/http.ts +++ b/client/src/utils/http.ts @@ -58,5 +58,5 @@ const headers: Headers = new Headers({ Accept: "application/json", "Content-Type": "application/json", 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" }); diff --git a/client/src/utils/router.tsx b/client/src/utils/router.tsx index 8d99a96..88a01d4 100644 --- a/client/src/utils/router.tsx +++ b/client/src/utils/router.tsx @@ -1,19 +1,12 @@ import React from "react"; -import { - Router, - Route, - Switch - // Redirect - //Link, NavLink -} from "react-router-dom"; +import { Router, Route, Switch } from "react-router-dom"; 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 { NotFoundPage } from "../pages/NotFoundPage"; -import { TestPage } from "../pages/TestPage"; 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(); @@ -22,24 +15,27 @@ export const AppRouter = () => {
- + {/* + */} + + + - {/* - - */} + - {/* - - */} - + + + + +