diff --git a/Controllers/AppUsersController.cs b/Controllers/AppUsersController.cs index 372c1ac..48579e2 100644 --- a/Controllers/AppUsersController.cs +++ b/Controllers/AppUsersController.cs @@ -13,7 +13,7 @@ using TicketManager.Resources; namespace TicketManager.Controllers { - // [Authorize] + [Authorize] [Produces("application/json")] [Route("api/v1/users")] [ApiController] @@ -64,7 +64,7 @@ namespace TicketManager.Controllers [HttpGet("{id}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> GetUser(Guid id) + public async Task> GetUser(string id) { var user = await _context.AppUsers .Include(u => u.Assignments) @@ -103,7 +103,7 @@ namespace TicketManager.Controllers [HttpPut("{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutUser(Guid id, AppUser user) + public async Task PutUser(string id, AppUser user) { if (id != user.Id) { @@ -159,6 +159,7 @@ namespace TicketManager.Controllers var user = new AppUser() { + Id = userDto.Id, FirstName = userDto.FirstName, LastName = userDto.LastName, Presentation = userDto.Presentation, @@ -202,7 +203,7 @@ namespace TicketManager.Controllers } [HttpGet("{id}/projects")] - public async Task>> GetAppUserProjects(Guid id) + public async Task>> GetAppUserProjects(string id) { var user = await _context.AppUsers .Include(u => u.Assignments) @@ -218,7 +219,7 @@ namespace TicketManager.Controllers } [HttpGet("{id}/tickets/")] - public async Task>> GetAppUserTickets(Guid id) + public async Task>> GetAppUserTickets(string id) { var user = await _context.AppUsers .Include(u => u.Assignments) @@ -233,7 +234,7 @@ namespace TicketManager.Controllers return user.GetTickets().Select(t => new TicketDTORead(t)).ToList(); } - private bool UserExists(Guid id) + private bool UserExists(string id) { return _context.AppUsers.Any(e => e.Id == id); } diff --git a/Controllers/ProjectsController.cs b/Controllers/ProjectsController.cs index 0bd41d0..e37435f 100644 --- a/Controllers/ProjectsController.cs +++ b/Controllers/ProjectsController.cs @@ -13,7 +13,7 @@ using System; namespace TicketManager.Controllers { // [Authorize(Roles = "Admin")] - // [Authorize] + [Authorize] [Produces("application/json")] [Route("api/v1/[controller]")] [ApiController] @@ -180,11 +180,15 @@ namespace TicketManager.Controllers EndingDate = projectDto.EndingDate, Manager = await _context.AppUsers.FindAsync(projectDto.ManagerId) }; - // project.LogAction( - // $"{project.Title} has been created by {project.Manager.FullName}.", - // ActivityType.StartTask); _context.Projects.Add(project); + _context.Assignments.Add(new Assignment() + { + Project = project, + ProjectId = project.Id, + User = project.Manager, + UserId = project.Manager.Id + }); await _context.SaveChangesAsync(); var dto = new ProjectDTO(project); return CreatedAtAction("GetProject", new { id = project.Id }, dto); @@ -271,7 +275,7 @@ namespace TicketManager.Controllers [HttpPatch("{id}/members")] public async Task> SetProjectMembers( [FromRoute] int id, - [FromBody] Guid[] membersId) + [FromBody] string[] membersId) { Project project = await _context.Projects .Include(p => p.Assignments) diff --git a/Controllers/TicketsController.cs b/Controllers/TicketsController.cs index efc6132..6a447b7 100644 --- a/Controllers/TicketsController.cs +++ b/Controllers/TicketsController.cs @@ -10,7 +10,7 @@ using TicketManager.Models; namespace TicketManager.Controllers { - // [Authorize] + [Authorize] [Route("api/v1/[controller]")] [ApiController] public class TicketsController : ControllerBase @@ -105,6 +105,9 @@ namespace TicketManager.Controllers Description = ticketDto.Description, EndingDate = ticketDto.EndingDate, CreatorId = ticketDto.CreatorId, + Category = (Category)ticketDto.Category, + Impact = (Impact)ticketDto.Impact, + Difficulty = (Difficulty)ticketDto.Difficulty, Project = await _context.Projects.FindAsync(ticketDto.ProjectId) }; diff --git a/Models/AppUser.cs b/Models/AppUser.cs index 43e0924..f0f5b93 100644 --- a/Models/AppUser.cs +++ b/Models/AppUser.cs @@ -8,7 +8,7 @@ namespace TicketManager.Models { public class AppUser { - public Guid Id { get; set; } + public string Id { get; set; } [Required] [StringLength(50)] diff --git a/Models/Assignment.cs b/Models/Assignment.cs index d31396e..8be0d17 100644 --- a/Models/Assignment.cs +++ b/Models/Assignment.cs @@ -5,7 +5,7 @@ namespace TicketManager.Models public class Assignment { public AppUser User { get; set; } - public Guid UserId { get; set; } + public string UserId { get; set; } public Project Project { get; set; } public int ProjectId { get; set; } } diff --git a/Models/Ticket.cs b/Models/Ticket.cs index 3ebeefb..a3a580d 100644 --- a/Models/Ticket.cs +++ b/Models/Ticket.cs @@ -28,7 +28,7 @@ namespace TicketManager.Models public Impact Impact { get; set; } = Impact.Undefined; public Difficulty Difficulty { get; set; } = Difficulty.Undefined; public Category Category { get; set; } = Category.Undefined; - public Guid CreatorId { get; set; } + public string CreatorId { get; set; } [Display(Name = "Project")] public Project Project { get; set; } diff --git a/README.md b/README.md index 273ea67..80af4b6 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,6 @@ - [ ] Query progression info in UserPage - [x] Add info fields in New Ticket Form - [ ] Filter users in Users Modal +- [ ] EditForms for Project and Ticket +- [ ] Admin Page +- [ ] Use auth0 user info to create appUser account diff --git a/Resources/AppUser/AppUserDTO.cs b/Resources/AppUser/AppUserDTO.cs index ee6d90d..51839d7 100644 --- a/Resources/AppUser/AppUserDTO.cs +++ b/Resources/AppUser/AppUserDTO.cs @@ -23,7 +23,7 @@ namespace TicketManager.Resources Tickets = user.GetTickets().Select(u => new TicketDTORead(u)).ToList(); } - public Guid Id { get; set; } + public string Id { get; set; } public string FirstName { get; set; } diff --git a/Resources/AppUser/AppUserDTORead.cs b/Resources/AppUser/AppUserDTORead.cs index 494476a..70fb3a0 100644 --- a/Resources/AppUser/AppUserDTORead.cs +++ b/Resources/AppUser/AppUserDTORead.cs @@ -20,7 +20,7 @@ namespace TicketManager.Resources Picture = user.Picture; } - public Guid Id { get; set; } + public string Id { get; set; } public string FirstName { get; set; } diff --git a/Resources/AppUser/NewAppUserDTO.cs b/Resources/AppUser/NewAppUserDTO.cs index 1b146e7..9110195 100644 --- a/Resources/AppUser/NewAppUserDTO.cs +++ b/Resources/AppUser/NewAppUserDTO.cs @@ -4,6 +4,8 @@ namespace TicketManager.Resources { public class NewAppUserDTO { + public string Id { get; set; } + [Required] public string FirstName { get; set; } public string LastName { get; set; } diff --git a/Resources/Project/NewProjectDTO.cs b/Resources/Project/NewProjectDTO.cs index 8043069..244c484 100644 --- a/Resources/Project/NewProjectDTO.cs +++ b/Resources/Project/NewProjectDTO.cs @@ -11,6 +11,6 @@ namespace TicketManager.Resources [Required] public DateTime EndingDate { get; set; } [Required] - public Guid ManagerId { get; set; } + public string ManagerId { get; set; } } } \ No newline at end of file diff --git a/Resources/Ticket/NewTicketDTO.cs b/Resources/Ticket/NewTicketDTO.cs index a8ebb28..92b3f96 100644 --- a/Resources/Ticket/NewTicketDTO.cs +++ b/Resources/Ticket/NewTicketDTO.cs @@ -16,13 +16,13 @@ namespace TicketManager.Resources [DataType(DataType.Date)] public DateTime EndingDate { get; set; } - public string Impact { get; set; } + public int Impact { get; set; } - public string Difficulty { get; set; } + public int Difficulty { get; set; } - public string Category { get; set; } + public int Category { get; set; } [Required] - public Guid CreatorId { get; set; } + public string CreatorId { get; set; } [Required] public int ProjectId { get; set; } } diff --git a/Resources/Ticket/TicketDTO.cs b/Resources/Ticket/TicketDTO.cs index 9446271..472be62 100644 --- a/Resources/Ticket/TicketDTO.cs +++ b/Resources/Ticket/TicketDTO.cs @@ -47,7 +47,7 @@ namespace TicketManager.Resources public string Category { get; set; } - public Guid CreatorId { get; set; } + public string CreatorId { get; set; } public ProjectDTORead Project { get; set; } diff --git a/Resources/Ticket/TicketDTORead.cs b/Resources/Ticket/TicketDTORead.cs index 620a044..ee3a4f9 100644 --- a/Resources/Ticket/TicketDTORead.cs +++ b/Resources/Ticket/TicketDTORead.cs @@ -44,7 +44,7 @@ namespace TicketManager.Resources public string Category { get; set; } - public Guid CreatorId { get; set; } + public string CreatorId { get; set; } public List Notes { get; set; } = new List(); public List Files { get; set; } = new List(); diff --git a/app.db b/app.db index a8c3bd0..6fa35e2 100644 Binary files a/app.db and b/app.db differ diff --git a/client/package-lock.json b/client/package-lock.json index 378ba1e..5bf7da7 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1288,22 +1288,35 @@ } }, "@material-ui/core": { - "version": "4.9.8", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.9.8.tgz", - "integrity": "sha512-4cslpG6oLoPWUfwPkX+hvbak4hAGiOfgXOu/UIYeeMrtsTEebC0Mirjoby7zhS4ny86YI3rXEFW6EZDmlj5n5w==", + "version": "4.9.13", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.9.13.tgz", + "integrity": "sha512-GEXNwUr+laZ0N+F1efmHB64Fyg+uQIRXLqbSejg3ebSXgLYNpIjnMOPRfWdu4rICq0dAIgvvNXGkKDMcf3AMpA==", "requires": { "@babel/runtime": "^7.4.4", - "@material-ui/styles": "^4.9.6", - "@material-ui/system": "^4.9.6", - "@material-ui/types": "^5.0.0", - "@material-ui/utils": "^4.9.6", + "@material-ui/react-transition-group": "^4.3.0", + "@material-ui/styles": "^4.9.13", + "@material-ui/system": "^4.9.13", + "@material-ui/types": "^5.0.1", + "@material-ui/utils": "^4.9.12", "@types/react-transition-group": "^4.2.0", - "clsx": "^1.0.2", + "clsx": "^1.0.4", "hoist-non-react-statics": "^3.3.2", - "popper.js": "^1.14.1", + "popper.js": "^1.16.1-lts", "prop-types": "^15.7.2", "react-is": "^16.8.0", "react-transition-group": "^4.3.0" + }, + "dependencies": { + "@material-ui/utils": { + "version": "4.9.12", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.9.12.tgz", + "integrity": "sha512-/0rgZPEOcZq5CFA4+4n6Q6zk7fi8skHhH2Bcra8R3epoJEYy5PL55LuMazPtPH1oKeRausDV/Omz4BbgFsn1HQ==", + "requires": { + "@babel/runtime": "^7.4.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0" + } + } } }, "@material-ui/icons": { @@ -1326,16 +1339,27 @@ "react-is": "^16.8.0" } }, + "@material-ui/react-transition-group": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@material-ui/react-transition-group/-/react-transition-group-4.3.0.tgz", + "integrity": "sha512-CwQ0aXrlUynUTY6sh3UvKuvye1o92en20VGAs6TORnSxUYeRmkX8YeTUN3lAkGiBX1z222FxLFO36WWh6q73rQ==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "@material-ui/styles": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.9.6.tgz", - "integrity": "sha512-ijgwStEkw1OZ6gCz18hkjycpr/3lKs1hYPi88O/AUn4vMuuGEGAIrqKVFq/lADmZUNF3DOFIk8LDkp7zmjPxtA==", + "version": "4.9.13", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.9.13.tgz", + "integrity": "sha512-lWlXJanBdHQ18jW/yphedRokHcvZD1GdGzUF/wQxKDsHwDDfO45ZkAxuSBI202dG+r1Ph483Z3pFykO2obeSRA==", "requires": { "@babel/runtime": "^7.4.4", "@emotion/hash": "^0.8.0", - "@material-ui/types": "^5.0.0", + "@material-ui/types": "^5.0.1", "@material-ui/utils": "^4.9.6", - "clsx": "^1.0.2", + "clsx": "^1.0.4", "csstype": "^2.5.2", "hoist-non-react-statics": "^3.3.2", "jss": "^10.0.3", @@ -1350,9 +1374,9 @@ } }, "@material-ui/system": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.6.tgz", - "integrity": "sha512-QtfoAePyqXoZ2HUVSwGb1Ro0kucMCvVjbI0CdYIR21t0Opgfm1Oer6ni9P5lfeXA39xSt0wCierw37j+YES48Q==", + "version": "4.9.13", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.13.tgz", + "integrity": "sha512-6AlpvdW6KJJ5bF1Xo2OD13sCN8k+nlL36412/bWnWZOKIfIMo/Lb8c8d1DOIaT/RKWxTEUaWnKZjabVnA3eZjA==", "requires": { "@babel/runtime": "^7.4.4", "@material-ui/utils": "^4.9.6", @@ -1360,9 +1384,9 @@ } }, "@material-ui/types": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.0.0.tgz", - "integrity": "sha512-UeH2BuKkwDndtMSS0qgx1kCzSMw+ydtj0xx/XbFtxNSTlXydKwzs5gVW5ZKsFlAkwoOOQ9TIsyoCC8hq18tOwg==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.0.1.tgz", + "integrity": "sha512-wURPSY7/3+MAtng3i26g+WKwwNE3HEeqa/trDBR5+zWKmcjO+u9t7Npu/J1r+3dmIa/OeziN9D/18IrBKvKffw==" }, "@material-ui/utils": { "version": "4.9.6", @@ -3779,11 +3803,11 @@ "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=" }, "css-vendor": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.7.tgz", - "integrity": "sha512-VS9Rjt79+p7M0WkPqcAza4Yq1ZHrsHrwf7hPL/bjQB+c1lwmAI+1FXxYTYt818D/50fFVflw0XKleiBN5RITkg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", "requires": { - "@babel/runtime": "^7.6.2", + "@babel/runtime": "^7.8.3", "is-in-browser": "^1.0.2" } }, @@ -4223,9 +4247,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.9.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", - "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", + "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -12926,9 +12950,10 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==" + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", + "dev": true }, "underscore": { "version": "1.9.2", diff --git a/client/package.json b/client/package.json index eb38d0b..d0231e5 100644 --- a/client/package.json +++ b/client/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@auth0/auth0-spa-js": "^1.6.4", - "@material-ui/core": "^4.9.8", + "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.47", "@testing-library/jest-dom": "^4.2.4", @@ -24,7 +24,7 @@ "react-router-dom": "^5.1.2", "react-scripts": "3.3.1", "react-swipeable-views": "^0.13.9", - "typescript": "^3.7.5", + "typescript": "^3.8.3", "underscore": "^1.9.2" }, "scripts": { @@ -48,4 +48,4 @@ "last 1 safari version" ] } -} +} \ No newline at end of file diff --git a/client/public/index.html b/client/public/index.html index eb30249..2b59b87 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -11,12 +11,6 @@ /> - - { - const { getByText } = render(); - const linkElement = getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/client/src/App.tsx b/client/src/App.tsx index 9415eaa..cf09fcf 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,21 +1,17 @@ import React from "react"; import { Router } from "react-router-dom"; import { useAuth0 } from "./authentication/auth0"; -import * as createHistory from "history"; -// import history from "./utils/history"; import MainLayout from "./layouts/MainLayout"; -import { AppRouter } from "./utils/router"; - -export const history = createHistory.createBrowserHistory(); +import AppRouter from "./routes/AppRouter"; +import history from "./utils/history"; +import Preloader from "./components/Preloader"; export default function App() { const { loading } = useAuth0(); - if (loading) { - return
Loading...
; - } - - return ( + return loading ? ( + + ) : ( diff --git a/client/src/VM/ProjectVM.ts b/client/src/VM/ProjectVM.ts index 3b89e72..d5be49f 100644 --- a/client/src/VM/ProjectVM.ts +++ b/client/src/VM/ProjectVM.ts @@ -1,9 +1,9 @@ -import { Ticket } from "../types/Ticket"; -import { Project } from "../types/Project"; -import { AppFile } from "../types/AppFile"; -import { Activity } from "../types/Activity"; -import { User } from "../types/User"; -import { getRemainingdays } from "../utils/methods"; +import Activity from "../types/Activity"; +import AppFile from "../types/AppFile"; +import Project from "../types/Project"; +import Ticket from "../types/Ticket"; +import User from "../types/User"; +import getRemainingdays from "../utils/methods"; export default class ProjectVM { public id: number; @@ -47,7 +47,7 @@ export default class ProjectVM { this.ticketsDone = this.tickets === undefined ? 0 - : this.tickets.filter(t => t.status === "Done").length; + : this.tickets.filter((t) => t.status === "Done").length; this.remainingDays = getRemainingdays(project.endingDate); this.allProjects = allProjects; } diff --git a/client/src/VM/TicketVM.ts b/client/src/VM/TicketVM.ts index 6b6d641..5518275 100644 --- a/client/src/VM/TicketVM.ts +++ b/client/src/VM/TicketVM.ts @@ -1,8 +1,8 @@ -import { Ticket } from "../types/Ticket"; -import { Project } from "../types/Project"; -import { User } from "../types/User"; +import Project from "../types/Project"; +import Ticket from "../types/Ticket"; +import User from "../types/User"; -export class TicketVM { +export default class TicketVM { public id: number; public title: string; public description: string; diff --git a/client/src/VM/UserVM.ts b/client/src/VM/UserVM.ts index 0ddbfcf..0930e58 100644 --- a/client/src/VM/UserVM.ts +++ b/client/src/VM/UserVM.ts @@ -1,7 +1,7 @@ -import { Project } from "../types/Project"; -import { Ticket } from "../types/Ticket"; -import { User } from "../types/User"; -import { Activity } from "../types/Activity"; +import Activity from "../types/Activity"; +import Project from "../types/Project"; +import Ticket from "../types/Ticket"; +import User from "../types/User"; export class UserVM { public id: string; @@ -16,9 +16,8 @@ export class UserVM { public projects: Project[]; public tickets: Ticket[]; public activities: Activity[]; - public allUsers: User[]; - public constructor(user: User, allUsers: User[]) { + public constructor(user: User) { this.id = user.id; this.firstName = user.firstName; this.lastName = user.lastName; @@ -31,6 +30,5 @@ export class UserVM { this.projects = user.projects; this.tickets = user.tickets; this.activities = user.activities; - this.allUsers = allUsers; } } diff --git a/client/src/authentication/auth0.jsx b/client/src/authentication/auth0.jsx index aa5194a..33521f5 100644 --- a/client/src/authentication/auth0.jsx +++ b/client/src/authentication/auth0.jsx @@ -1,4 +1,3 @@ -// src/react-auth0-spa.js import React, { useState, useEffect, useContext } from "react"; import createAuth0Client from "@auth0/auth0-spa-js"; @@ -68,6 +67,7 @@ export const Auth0Provider = ({ setIsAuthenticated(true); setUser(user); }; + return ( auth0Client.loginWithRedirect(...p), getTokenSilently: (...p) => auth0Client.getTokenSilently(...p), getTokenWithPopup: (...p) => auth0Client.getTokenWithPopup(...p), - logout: (...p) => auth0Client.logout(...p) + logout: (...p) => auth0Client.logout(...p), }} > {children} diff --git a/client/src/authentication/helpers.ts b/client/src/authentication/helpers.ts new file mode 100644 index 0000000..3a8a915 --- /dev/null +++ b/client/src/authentication/helpers.ts @@ -0,0 +1,9 @@ +/** + * retrieve userId + * @param user Auth0 user object + */ +export const getUID = (user: any) => { + const { sub } = user; + const uid = sub.split("|")[1]; + return uid; +}; diff --git a/client/src/components/ActivityCollection.tsx b/client/src/components/ActivityCollection.tsx index c347cc2..3f9476b 100644 --- a/client/src/components/ActivityCollection.tsx +++ b/client/src/components/ActivityCollection.tsx @@ -1,12 +1,12 @@ import React, { FC } from "react"; -import { Activity } from "../types/Activity"; +import Activity from "../types/Activity"; type IProps = { activities: Activity[]; filterText: string; }; -export const ActivityCollection: FC = ({ activities, filterText }) => { +const ActivityCollection: FC = ({ activities, filterText }) => { return activities === undefined ? ( <> ) : ( @@ -17,7 +17,7 @@ export const ActivityCollection: FC = ({ activities, filterText }) => { ) : ( activities .filter( - a => + (a) => a.description .toLowerCase() .includes(filterText.toLowerCase()) || @@ -67,3 +67,4 @@ export const ActivityEntry: FC = ({ activity }) => { ); }; +export default ActivityCollection; diff --git a/client/src/components/Avatars/AvatarList.tsx b/client/src/components/Avatars/AvatarList.tsx index 5c1cf8a..0507aee 100644 --- a/client/src/components/Avatars/AvatarList.tsx +++ b/client/src/components/Avatars/AvatarList.tsx @@ -1,9 +1,8 @@ import React, { FC } from "react"; import { Link } from "react-router-dom"; -import Avatar from "@material-ui/core/Avatar"; +import { makeStyles, Theme, createStyles, Avatar } from "@material-ui/core"; import AvatarGroup from "@material-ui/lab/AvatarGroup"; -import { User } from "../../types/User"; -import { makeStyles, Theme, createStyles } from "@material-ui/core"; +import User from "../../types/User"; interface AvatarListProps { users: User[]; @@ -34,3 +33,5 @@ export const AvatarList: FC = ({ users }) => { ); }; + +export default AvatarList; diff --git a/client/src/components/Avatars/UserAvatar.tsx b/client/src/components/Avatars/UserAvatar.tsx index 6bbd826..c887cdf 100644 --- a/client/src/components/Avatars/UserAvatar.tsx +++ b/client/src/components/Avatars/UserAvatar.tsx @@ -12,17 +12,17 @@ const useStyles = makeStyles((theme: Theme) => root: { display: "flex", "& > *": { - margin: theme.spacing(1) - } + margin: theme.spacing(1), + }, }, small: { width: theme.spacing(3), - height: theme.spacing(3) + height: theme.spacing(3), }, large: { width: theme.spacing(10), - height: theme.spacing(10) - } + height: theme.spacing(10), + }, }) ); @@ -35,3 +35,5 @@ export const UserAvatar: FC = ({ picture, alt }) => { ); }; + +export default UserAvatar; diff --git a/client/src/components/ButtonAppBar.tsx b/client/src/components/ButtonAppBar.tsx index d652d15..8ae9de2 100644 --- a/client/src/components/ButtonAppBar.tsx +++ b/client/src/components/ButtonAppBar.tsx @@ -1,30 +1,36 @@ import React from "react"; +import { Link } from "react-router-dom"; +import { + AppBar, + Button, + IconButton, + Toolbar, + Typography, + Avatar, +} from "@material-ui/core"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; -import AppBar from "@material-ui/core/AppBar"; -import Toolbar from "@material-ui/core/Toolbar"; -import Typography from "@material-ui/core/Typography"; -import Button from "@material-ui/core/Button"; -import IconButton from "@material-ui/core/IconButton"; import MenuIcon from "@material-ui/icons/Menu"; +import * as ROUTES from "../constants/routes"; import { useAuth0 } from "../authentication/auth0"; +import { getUID } from "../authentication/helpers"; const useStyles = makeStyles((theme: Theme) => createStyles({ root: { - flexGrow: 1 + flexGrow: 1, }, menuButton: { - marginRight: theme.spacing(2) + marginRight: theme.spacing(2), }, title: { - flexGrow: 1 - } + flexGrow: 1, + }, }) ); export default function ButtonAppBar() { const classes = useStyles(); - const { isAuthenticated, loginWithRedirect, logout } = useAuth0(); + const { isAuthenticated, loginWithRedirect, logout, user } = useAuth0(); return (
@@ -39,18 +45,31 @@ export default function ButtonAppBar() { - {!isAuthenticated ? ( - ) : ( - + <> + + + )} diff --git a/client/src/components/Buttons/Button.tsx b/client/src/components/Buttons/Button.tsx index bb3c49b..ca40ec2 100644 --- a/client/src/components/Buttons/Button.tsx +++ b/client/src/components/Buttons/Button.tsx @@ -9,12 +9,12 @@ interface IProps { onClick?: (e: MouseEvent) => void; } -export const Button: FC = ({ +const Button: FC = ({ size = "small", shape = "", color, onClick, - children + children, }) => { return ( ); }; + +export default Button; diff --git a/client/src/components/Buttons/FloatingButton.tsx b/client/src/components/Buttons/FloatingButton.tsx index ea28e6d..29e9ead 100644 --- a/client/src/components/Buttons/FloatingButton.tsx +++ b/client/src/components/Buttons/FloatingButton.tsx @@ -10,13 +10,7 @@ interface IProps { text?: string; } -export const FloatingButton: FC = ({ - color, - icon, - size, - text, - onClick -}) => { +const FloatingButton: FC = ({ color, icon, size, text, onClick }) => { return ( @@ -24,3 +18,5 @@ export const FloatingButton: FC = ({ ); }; + +export default FloatingButton; diff --git a/client/src/components/Cards/HorizontalCard.tsx b/client/src/components/Cards/HorizontalCard.tsx index d915df5..a8d5732 100644 --- a/client/src/components/Cards/HorizontalCard.tsx +++ b/client/src/components/Cards/HorizontalCard.tsx @@ -1,11 +1,8 @@ import React, { FC, ReactNode } from "react"; import { Link } from "react-router-dom"; import { makeStyles } from "@material-ui/core/styles"; -import Card from "@material-ui/core/Card"; -import CardActions from "@material-ui/core/CardActions"; -import CardContent from "@material-ui/core/CardContent"; -import Typography from "@material-ui/core/Typography"; -import { ProgressBar } from "../Progress/ProgressBar"; +import { Card, CardActions, CardContent, Typography } from "@material-ui/core"; +import ProgressBar from "../Progress/ProgressBar"; interface IProps { title?: string; @@ -22,7 +19,7 @@ const useStyles = makeStyles({ }, }); -export const HorizontalCard: FC = ({ +const HorizontalCard: FC = ({ title, link = "#", content, @@ -46,3 +43,5 @@ export const HorizontalCard: FC = ({ ); }; + +export default HorizontalCard; diff --git a/client/src/components/Cards/ProjectCard.tsx b/client/src/components/Cards/ProjectCard.tsx index 3f3fe9a..19231e6 100644 --- a/client/src/components/Cards/ProjectCard.tsx +++ b/client/src/components/Cards/ProjectCard.tsx @@ -1,10 +1,10 @@ import React, { FC } from "react"; -import { HorizontalCard } from "./HorizontalCard"; import { makeStyles, Theme, createStyles } from "@material-ui/core"; -import { AvatarList } from "../Avatars/AvatarList"; -import { ProgressInfo } from "../Progress/ProgressInfo"; -import { User } from "../../types/User"; -import { getRemainingdays } from "../../utils/methods"; +import HorizontalCard from "./HorizontalCard"; +import AvatarList from "../Avatars/AvatarList"; +import ProgressInfo from "../Progress/ProgressInfo"; +import User from "../../types/User"; +import getRemainingdays from "../../utils/methods"; interface IProps { title?: string; diff --git a/client/src/components/Cards/TicketCard.tsx b/client/src/components/Cards/TicketCard.tsx index 9018c84..8cbb129 100644 --- a/client/src/components/Cards/TicketCard.tsx +++ b/client/src/components/Cards/TicketCard.tsx @@ -1,9 +1,9 @@ import React, { FC, MouseEvent } from "react"; import { Button, Typography, Grid } from "@material-ui/core"; -import { HorizontalCard } from "./HorizontalCard"; +import HorizontalCard from "./HorizontalCard"; import TicketChipsArray from "./TicketChipsArray"; -import { Ticket } from "../../types/Ticket"; -import { getRemainingdays } from "../../utils/methods"; +import Ticket from "../../types/Ticket"; +import getRemainingdays from "../../utils/methods"; interface IProps { ticket?: Ticket; diff --git a/client/src/components/FileCollection.tsx b/client/src/components/FileCollection.tsx index 4f25ec3..1a1f416 100644 --- a/client/src/components/FileCollection.tsx +++ b/client/src/components/FileCollection.tsx @@ -1,12 +1,14 @@ import React, { FC } from "react"; +import { + Avatar, + ListItemAvatar, + List, + ListItemText, + ListItem, +} from "@material-ui/core"; import { createStyles, Theme, makeStyles } from "@material-ui/core/styles"; -import List from "@material-ui/core/List"; -import ListItem from "@material-ui/core/ListItem"; -import ListItemText from "@material-ui/core/ListItemText"; -import ListItemAvatar from "@material-ui/core/ListItemAvatar"; -import Avatar from "@material-ui/core/Avatar"; import WorkIcon from "@material-ui/icons/Work"; -import { AppFile } from "../types/AppFile"; +import AppFile from "../types/AppFile"; type IProps = { files: AppFile[]; @@ -18,12 +20,12 @@ const useStyles = makeStyles((theme: Theme) => root: { width: "100%", maxWidth: 360, - backgroundColor: theme.palette.background.paper - } + backgroundColor: theme.palette.background.paper, + }, }) ); -export const FileCollection: FC = ({ files, filterText }) => { +const FileCollection: FC = ({ files, filterText }) => { const classes = useStyles(); return ( @@ -32,7 +34,7 @@ export const FileCollection: FC = ({ files, filterText }) => { ) : ( files .filter( - f => + (f) => f.name.toLowerCase().includes(filterText.toLowerCase()) || f.format.toLowerCase().includes(filterText.toLowerCase()) ) @@ -61,3 +63,4 @@ export const FileEntry: FC = ({ file }) => { ); }; +export default FileCollection; diff --git a/client/src/components/FilterBar.tsx b/client/src/components/FilterBar.tsx index bae32cb..328e484 100644 --- a/client/src/components/FilterBar.tsx +++ b/client/src/components/FilterBar.tsx @@ -1,9 +1,7 @@ import React, { FC, ChangeEvent, MouseEvent } from "react"; import { useRouteMatch } from "react-router-dom"; +import { Grid, TextField } from "@material-ui/core"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; -import TextField from "@material-ui/core/TextField"; -import { Grid } from "@material-ui/core"; -// import { AccountCircle, FilterList, FilterListSharp } from "@material-ui/icons"; type IProps = { filterText: string; @@ -28,7 +26,7 @@ const useStyles = makeStyles((theme: Theme) => }) ); -export const FilterBar: FC = ({ +const FilterBar: FC = ({ filterText, handleChange, // clearFilterText @@ -55,3 +53,4 @@ export const FilterBar: FC = ({
); }; +export default FilterBar; diff --git a/client/src/components/Footer.tsx b/client/src/components/Footer.tsx index 09a94eb..b6cda25 100644 --- a/client/src/components/Footer.tsx +++ b/client/src/components/Footer.tsx @@ -1,8 +1,7 @@ import React, { FC } from "react"; -import Typography from "@material-ui/core/Typography"; +import { Link as RouterLink } from "react-router-dom"; +import { Container, Typography, Link } from "@material-ui/core"; import { makeStyles } from "@material-ui/core/styles"; -import Container from "@material-ui/core/Container"; -import Link from "@material-ui/core/Link"; interface IProps { brand: string; @@ -11,14 +10,14 @@ interface IProps { const copyParams: IProps = { brand: "BugBuster", - text: "Made with 🔥" + text: "Made with 🔥", }; const Copyright: FC = ({ brand, text }) => { return ( {"© "} - + {brand} {" "} {new Date().getFullYear()} @@ -27,15 +26,15 @@ const Copyright: FC = ({ brand, text }) => { ); }; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ footer: { padding: theme.spacing(3, 2), marginTop: "auto", backgroundColor: theme.palette.type === "light" ? theme.palette.grey[200] - : theme.palette.grey[800] - } + : theme.palette.grey[800], + }, })); export default function Footer() { diff --git a/client/src/components/Header.tsx b/client/src/components/Header.tsx index a93d504..1d0d7a4 100644 --- a/client/src/components/Header.tsx +++ b/client/src/components/Header.tsx @@ -6,7 +6,7 @@ type HeaderProps = { description: string; }; -export const Header: FC = ({ title, description }) => { +const Header: FC = ({ title, description }) => { return ( @@ -18,3 +18,5 @@ export const Header: FC = ({ title, description }) => { ); }; + +export default Header; diff --git a/client/src/components/InputField.tsx b/client/src/components/InputField.tsx index 6dc5468..888b142 100644 --- a/client/src/components/InputField.tsx +++ b/client/src/components/InputField.tsx @@ -1,6 +1,6 @@ import React, { FC } from "react"; -export const InputField: FC = () => { +const InputField: FC = () => { return (
@@ -8,3 +8,5 @@ export const InputField: FC = () => {
); }; + +export default InputField; diff --git a/client/src/components/InputFile.tsx b/client/src/components/InputFile.tsx index c4257e7..3c36e5c 100644 --- a/client/src/components/InputFile.tsx +++ b/client/src/components/InputFile.tsx @@ -3,22 +3,20 @@ import { CloudUpload } from "@material-ui/icons"; import { makeStyles, createStyles, Theme } from "@material-ui/core/styles"; import Button from "@material-ui/core/Button"; -export const InputFile: FC = () => { +const InputFile: FC = () => { return ( - <> -
-
- - - - -
-
- +
+
+ + + + +
+
); }; @@ -26,12 +24,12 @@ const useStyles = makeStyles((theme: Theme) => createStyles({ root: { "& > *": { - margin: theme.spacing(1) - } + margin: theme.spacing(1), + }, }, input: { - display: "none" - } + display: "none", + }, }) ); @@ -60,3 +58,5 @@ const UploadButton: FC = () => { ); }; + +export default InputFile; diff --git a/client/src/components/Lists/ActivityList.tsx b/client/src/components/Lists/ActivityList.tsx index c70082c..69513d9 100644 --- a/client/src/components/Lists/ActivityList.tsx +++ b/client/src/components/Lists/ActivityList.tsx @@ -1,13 +1,13 @@ import React, { FC, useState, ChangeEvent, MouseEvent } from "react"; -import { ActivityCollection } from "../ActivityCollection"; -import { Activity } from "../../types/Activity"; -import { FilterBar } from "../FilterBar"; +import ActivityCollection from "../ActivityCollection"; +import FilterBar from "../FilterBar"; +import Activity from "../../types/Activity"; type IProps = { activities: Activity[]; }; -export const ActivityList: FC = ({ activities }) => { +const ActivityList: FC = ({ activities }) => { const [filterText, setFilterText] = useState(""); const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { setFilterText(""); @@ -30,3 +30,5 @@ export const ActivityList: FC = ({ activities }) => { ); }; + +export default ActivityList; diff --git a/client/src/components/Lists/AppFileList.tsx b/client/src/components/Lists/AppFileList.tsx index 028d18b..4dfc589 100644 --- a/client/src/components/Lists/AppFileList.tsx +++ b/client/src/components/Lists/AppFileList.tsx @@ -1,15 +1,15 @@ import React, { FC, useState, ChangeEvent, MouseEvent } from "react"; -import { AppFile } from "../../types/AppFile"; -import { FileCollection } from "../FileCollection"; -import { InputFile } from "../InputFile"; -import { FilterBar } from "../FilterBar"; import { Grid, Typography } from "@material-ui/core"; +import FileCollection from "../FileCollection"; +import FilterBar from "../FilterBar"; +import InputFile from "../InputFile"; +import AppFile from "../../types/AppFile"; type IProps = { files: AppFile[]; }; -export const FileList: FC = ({ files }) => { +const FileList: FC = ({ files }) => { const [filterText, setFilterText] = useState(""); const clearFilterText = (e: MouseEvent): void => { setFilterText(""); @@ -38,3 +38,5 @@ export const FileList: FC = ({ files }) => { ); }; + +export default FileList; diff --git a/client/src/components/Lists/MemberList.tsx b/client/src/components/Lists/MemberList.tsx index 631fe80..909cefb 100644 --- a/client/src/components/Lists/MemberList.tsx +++ b/client/src/components/Lists/MemberList.tsx @@ -1,13 +1,13 @@ import React, { FC, useState, ChangeEvent, MouseEvent } from "react"; -import { UsersModalEntry } from "../Modals/UsersModalEntry"; -import { FilterBar } from "../FilterBar"; -import { User } from "../../types/User"; +import FilterBar from "../FilterBar"; +import UsersModalEntry from "../Modals/UsersModalEntry"; +import User from "../../types/User"; interface IProps { users: User[]; } -export const MemberList: FC = ({ users }) => { +const MemberList: FC = ({ users }) => { const [members, setMembers] = useState([]); const [filterText, setFilterText] = useState(""); const clearFilterText = (e: MouseEvent): void => { @@ -37,3 +37,5 @@ export const MemberList: FC = ({ users }) => { ); }; + +export default MemberList; diff --git a/client/src/components/Lists/ProjectList.tsx b/client/src/components/Lists/ProjectList.tsx index 873e83a..1517b0b 100644 --- a/client/src/components/Lists/ProjectList.tsx +++ b/client/src/components/Lists/ProjectList.tsx @@ -6,12 +6,11 @@ import { createStyles, Theme, } from "@material-ui/core"; -import { FilterBar } from "../FilterBar"; +import FilterBar from "../FilterBar"; import ProjectCard from "../Cards/ProjectCard"; -import { FloatingButton } from "../Buttons/FloatingButton"; -import { NewProjectModal } from "../Modals/NewProjectModal"; -import { Project } from "../../types/Project"; -import { User } from "../../types/User"; +import FloatingButton from "../Buttons/FloatingButton"; +import NewProjectModal from "../Modals/NewProjectModal"; +import Project from "../../types/Project"; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -27,10 +26,9 @@ const useStyles = makeStyles((theme: Theme) => type IProps = { projects: Project[]; - allUsers: User[]; }; -export const ProjectList: FC = ({ projects, allUsers }) => { +const ProjectList: FC = ({ projects }) => { const [filterText, setFilterText] = useState(""); const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { setFilterText(""); @@ -59,7 +57,6 @@ export const ProjectList: FC = ({ projects, allUsers }) => { setShowNew(false); }} show={showNew} - allUsers={allUsers} /> = ({ projects, allUsers }) => { ); }; + +export default ProjectList; diff --git a/client/src/components/Lists/TicketList.tsx b/client/src/components/Lists/TicketList.tsx index e6910c5..50e554a 100644 --- a/client/src/components/Lists/TicketList.tsx +++ b/client/src/components/Lists/TicketList.tsx @@ -6,15 +6,14 @@ import { Theme, createStyles, } from "@material-ui/core"; -import { FloatingButton } from "../Buttons/FloatingButton"; -import { FilterBar } from "../FilterBar"; -import { HttpResponse } from "../../types/HttpResponse"; -import { Ticket } from "../../types/Ticket"; -import { NewTicketModal } from "../Modals/NewTicketModal"; -import { Project } from "../../types/Project"; -import { put } from "../../utils/http"; -import { Constants } from "../../utils/Constants"; +import FloatingButton from "../Buttons/FloatingButton"; +import FilterBar from "../FilterBar"; import TicketCard from "../Cards/TicketCard"; +import NewTicketModal from "../Modals/NewTicketModal"; +import Ticket from "../../types/Ticket"; +import Project from "../../types/Project"; +import { useAuth0 } from "../../authentication/auth0"; +import { TicketService } from "../../services"; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -34,7 +33,7 @@ type TicketListProps = { addButton?: Boolean; }; -export const TicketList: FC = ({ +const TicketList: FC = ({ tickets, allProjects, addButton = true, @@ -59,6 +58,14 @@ export const TicketList: FC = ({ t.title.toLowerCase().includes(filterText.toLowerCase()) ); + const { getTokenSilently } = useAuth0(); + + const handleValidate = async (id: number) => { + const token = await getTokenSilently(); + const Tickets = new TicketService(token); + await Tickets.close(id.toString()); + }; + const classes = useStyles(); return ( @@ -99,28 +106,24 @@ export const TicketList: FC = ({ /> -
- {filteredTickets.length === 0 ? ( - - ) : ( - filteredTickets.map((t: Ticket) => ( - { - e.preventDefault(); - await put>( - `${Constants.ticketsURI}/${t.id}/closed`, - {} - ); - }} - /> - )) - )} -
+ {filteredTickets.length === 0 ? ( + + ) : ( + filteredTickets.map((t: Ticket) => ( + { + handleValidate(t.id); + }} + /> + )) + )}
); }; + +export default TicketList; diff --git a/client/src/components/LogInForm.tsx b/client/src/components/LogInForm.tsx index 4a85da7..b215d6b 100644 --- a/client/src/components/LogInForm.tsx +++ b/client/src/components/LogInForm.tsx @@ -1,7 +1,7 @@ import React, { FC } from "react"; -import { InputField } from "./InputField"; -import { PasswordField } from "./PasswordField"; -import { Button } from "./Buttons/Button"; +import InputField from "./InputField"; +import PasswordField from "./PasswordField"; +import Button from "./Buttons/Button"; export const LogInForm: FC = () => { return ( diff --git a/client/src/components/Modals/Modal.tsx b/client/src/components/Modals/Modal.tsx index 705f172..d4745ca 100644 --- a/client/src/components/Modals/Modal.tsx +++ b/client/src/components/Modals/Modal.tsx @@ -1,6 +1,6 @@ import React, { FC } from "react"; -import Dialog from "@material-ui/core/Dialog"; import { + Dialog, DialogTitle, Typography, IconButton, @@ -36,7 +36,7 @@ const useStyles = makeStyles((theme: Theme) => }) ); -export const Modal: FC = ({ +const Modal: FC = ({ handleClose, show, action, @@ -77,3 +77,5 @@ export const Modal: FC = ({ ); }; + +export default Modal; diff --git a/client/src/components/Modals/NewProjectModal.tsx b/client/src/components/Modals/NewProjectModal.tsx index 3d63126..ad8fa35 100644 --- a/client/src/components/Modals/NewProjectModal.tsx +++ b/client/src/components/Modals/NewProjectModal.tsx @@ -1,36 +1,48 @@ import React, { FC, useState, FormEvent } from "react"; import { TextField } from "@material-ui/core"; -import { Modal } from "./Modal"; -import { Project } from "../../types/Project"; -import { User } from "../../types/User"; -import { post } from "../../utils/http"; -import { Constants } from "../../utils/Constants"; +import Modal from "./Modal"; +import Preloader from "../Preloader"; +import { useAuth0 } from "../../authentication/auth0"; +import { ProjectService } from "../../services"; +import { getUID } from "../../authentication/helpers"; +import { today } from "../../utils/methods"; interface IProps { show: boolean; handleClose: () => void; - allUsers: User[]; } -export const NewProjectModal: FC = ({ show, handleClose }) => { +const NewProjectModal: FC = ({ show, handleClose }) => { const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); - const [endingDate, setEndingDate] = useState(""); + const [endingDate, setEndingDate] = useState(today()); + const [loading, setLoading] = useState(false); + const { getTokenSilently, user } = useAuth0(); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); + setLoading(true); let newProject = { title: title, description: description, endingDate: new Date(endingDate).toISOString(), - managerId: "cd179eb7-3a54-4060-b22c-3e947bdffcbc", // get current User id + managerId: getUID(user), }; - await post(`${Constants.projectsURI}`, newProject); + const token = await getTokenSilently(); + const Projects = new ProjectService(token); + Projects.add(newProject).catch((err) => console.error(err)); + setLoading(false); + setTitle(""); + setDescription(""); + setEndingDate(today()); + handleClose(); }; - return ( + return loading ? ( + + ) : ( = ({ show, handleClose }) => { ); }; + +export default NewProjectModal; diff --git a/client/src/components/Modals/NewTicketModal.tsx b/client/src/components/Modals/NewTicketModal.tsx index 9493b17..a2638e9 100644 --- a/client/src/components/Modals/NewTicketModal.tsx +++ b/client/src/components/Modals/NewTicketModal.tsx @@ -7,14 +7,16 @@ import { makeStyles, Theme, } from "@material-ui/core"; -import { Modal } from "./Modal"; -import { Ticket } from "../../types/Ticket"; -import { Project } from "../../types/Project"; -import { post } from "../../utils/http"; -import { Constants } from "../../utils/Constants"; +import Modal from "./Modal"; +import Project from "../../types/Project"; import Category from "../../types/enums/category"; import Impact from "../../types/enums/impact"; import Difficulty from "../../types/enums/difficulty"; +import { TicketService } from "../../services"; +import { useAuth0 } from "../../authentication/auth0"; +import { getUID } from "../../authentication/helpers"; +import { today } from "../../utils/methods"; +import Preloader from "../Preloader"; interface IProps { show: boolean; @@ -28,42 +30,50 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); -export const NewTicketModal: FC = ({ - show, - handleClose, - allProjects, -}) => { - const [title, setTitle] = useState(""); - const [description, setDescription] = useState(""); - const [endingDate, setEndingDate] = useState(""); - +const NewTicketModal: FC = ({ show, handleClose, allProjects }) => { + const { getTokenSilently, user } = useAuth0(); const { url } = useRouteMatch(); const id = url.split("/")[2]; const [projectId, setProjectId] = useState(id); - const [categoryID, setCategoryID] = useState(0); - const [impactID, setImpactID] = useState(0); - const [difficultyID, setDifficultyID] = useState(0); + const [title, setTitle] = useState(""); + const [description, setDescription] = useState(""); + const [endingDate, setEndingDate] = useState(today()); + const [categoryID, setCategoryID] = useState(1); + const [impactID, setImpactID] = useState(1); + const [difficultyID, setDifficultyID] = useState(1); + const [loading, setLoading] = useState(false); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); + setLoading(true); let newTicket = { title: title, description: description, endingDate: new Date(endingDate).toISOString(), - creatorId: "20bf4b2a-7209-4826-96cd-29c2bc937a94", // get current User id + creatorId: getUID(user), projectId: parseInt(projectId), impact: impactID, difficulty: difficultyID, category: categoryID, }; - // const response: HttpResponse = - await post(`${Constants.ticketsURI}`, newTicket); + const token = await getTokenSilently(); + const Tickets = new TicketService(token); + Tickets.add(newTicket).catch((err) => console.error(err)); + setLoading(false); + setTitle(""); + setDescription(""); + setEndingDate(today()); + setCategoryID(1); + setImpactID(1); + setDifficultyID(1); handleClose(); }; const classes = useStyles(); - return ( + return loading ? ( + + ) : ( = ({ className={classes.select} > {Category.map((c: string, i: number) => ( - + {c} ))} @@ -181,7 +191,7 @@ export const NewTicketModal: FC = ({ margin="normal" > {Impact.map((c: string, i: number) => ( - + {c} ))} @@ -202,7 +212,7 @@ export const NewTicketModal: FC = ({ margin="normal" > {Difficulty.map((c: string, i: number) => ( - + {c} ))} @@ -211,3 +221,5 @@ export const NewTicketModal: FC = ({ ); }; + +export default NewTicketModal; diff --git a/client/src/components/Modals/UsersModal.tsx b/client/src/components/Modals/UsersModal.tsx index 4b915f9..8e34526 100644 --- a/client/src/components/Modals/UsersModal.tsx +++ b/client/src/components/Modals/UsersModal.tsx @@ -1,20 +1,22 @@ import React, { FC, useState, ChangeEvent, FormEvent } from "react"; import { useParams } from "react-router-dom"; -import { Grid } from "@material-ui/core"; +import { + Avatar, + Checkbox, + Grid, + List, + ListItem, + ListItemSecondaryAction, + ListItemText, + ListItemAvatar, +} from "@material-ui/core"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; -import List from "@material-ui/core/List"; -import ListItem from "@material-ui/core/ListItem"; -import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction"; -import ListItemText from "@material-ui/core/ListItemText"; -import ListItemAvatar from "@material-ui/core/ListItemAvatar"; -import Checkbox from "@material-ui/core/Checkbox"; -import Avatar from "@material-ui/core/Avatar"; -import { Modal } from "./Modal"; -import { AvatarList } from "../Avatars/AvatarList"; -import { FilterBar } from "../FilterBar"; -import { User } from "../../types/User"; -import { patch } from "../../utils/http"; -import { Constants } from "../../utils/Constants"; +import AvatarList from "../Avatars/AvatarList"; +import FilterBar from "../FilterBar"; +import Modal from "./Modal"; +import User from "../../types/User"; +import { ProjectService } from "../../services"; +import { useAuth0 } from "../../authentication/auth0"; interface IProps { show: boolean; @@ -33,12 +35,7 @@ const useStyles = makeStyles((theme: Theme) => }) ); -export const UsersModal: FC = ({ - show, - handleClose, - users, - allUsers, -}) => { +const UsersModal: FC = ({ show, handleClose, users, allUsers }) => { const { id } = useParams(); const [filterText, setFilterText] = useState(""); @@ -62,12 +59,14 @@ export const UsersModal: FC = ({ setMembers(newChecked); }; + const { getTokenSilently } = useAuth0(); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); - await patch( - `${Constants.projectsURI}/${id}/members`, - members //.map((m) => m.id) - ); + if (id !== undefined) { + const token = await getTokenSilently(); + const Projects = new ProjectService(token); + await Projects.setMembers(id, members); + } handleClose(); }; @@ -112,3 +111,5 @@ export const UsersModal: FC = ({ ); }; + +export default UsersModal; diff --git a/client/src/components/Modals/UsersModalEntry.tsx b/client/src/components/Modals/UsersModalEntry.tsx index 7e7f04c..d3a5943 100644 --- a/client/src/components/Modals/UsersModalEntry.tsx +++ b/client/src/components/Modals/UsersModalEntry.tsx @@ -1,5 +1,5 @@ import React, { FC } from "react"; -import { User } from "../../types/User"; +import User from "../../types/User"; interface IProps { setMembers: React.Dispatch>; @@ -7,7 +7,7 @@ interface IProps { user: User; } -export const UsersModalEntry: FC = ({ user, setMembers, members }) => { +const UsersModalEntry: FC = ({ user, setMembers, members }) => { const match: (id: string) => boolean = (id: string) => { return Boolean(members.find((m) => m.id === id)); }; @@ -40,3 +40,5 @@ export const UsersModalEntry: FC = ({ user, setMembers, members }) => { ); }; + +export default UsersModalEntry; diff --git a/client/src/components/Navbar.tsx b/client/src/components/Navbar.tsx index 3432b0a..ec0fa54 100644 --- a/client/src/components/Navbar.tsx +++ b/client/src/components/Navbar.tsx @@ -1,7 +1,7 @@ import React from "react"; import { useAuth0 } from "../authentication/auth0"; -export const NavBar = () => { +const NavBar = () => { const { isAuthenticated, loginWithRedirect, logout } = useAuth0(); return ( @@ -14,3 +14,5 @@ export const NavBar = () => { ); }; + +export default NavBar; diff --git a/client/src/components/NewTicketForm.tsx b/client/src/components/NewTicketForm.tsx deleted file mode 100644 index aac5205..0000000 --- a/client/src/components/NewTicketForm.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React, { FC } from "react"; -import { TextField, MenuItem } from "@material-ui/core"; -import { Project } from "../types/Project"; - -interface IProps { - title: string; - setTitle: React.Dispatch>; - description: string; - setDescription: React.Dispatch>; - endingDate: string; - setEndingDate: React.Dispatch>; - allProjects: Project[]; - projectId: string; - setProjectId: React.Dispatch>; -} - -export const NewTicketForm: FC = ({ - title, - setTitle, - description, - setDescription, - endingDate, - setEndingDate, - allProjects, - projectId, - setProjectId, -}) => { - return ( - <> - {/*
-
- date_range - ) => - setEndingDate(e.target.value) - } - /> - -
- -
- -
-
*/} - - ); -}; diff --git a/client/src/components/Panels/ProjectTabPanel.tsx b/client/src/components/Panels/ProjectTabPanel.tsx index b3fb77f..17d6677 100644 --- a/client/src/components/Panels/ProjectTabPanel.tsx +++ b/client/src/components/Panels/ProjectTabPanel.tsx @@ -1,16 +1,11 @@ import React, { FC, useState, ReactNode } from "react"; -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 SwipeableViews from "react-swipeable-views"; -import { Ticket } from "../../types/Ticket"; -import { Project } from "../../types/Project"; -import { TicketList } from "../Lists/TicketList"; -// import { FileList } from "./AppFileList"; -import { AppFile } from "../../types/AppFile"; +import { makeStyles, Theme, useTheme } from "@material-ui/core/styles"; +import { AppBar, Box, Tab, Tabs, Typography } from "@material-ui/core"; +import Ticket from "../../types/Ticket"; +import Project from "../../types/Project"; +import TicketList from "../Lists/TicketList"; +import AppFile from "../../types/AppFile"; interface TabProps { children?: ReactNode; @@ -59,7 +54,7 @@ interface IProps { allProjects: Project[]; } -export const ProjectTabPanel: FC = ({ +const ProjectTabPanel: FC = ({ tickets, tabNames, files, @@ -116,3 +111,5 @@ export const ProjectTabPanel: FC = ({ ); }; + +export default ProjectTabPanel; diff --git a/client/src/components/Panels/TabRouter.tsx b/client/src/components/Panels/TabRouter.tsx index 24f9286..bc2da24 100644 --- a/client/src/components/Panels/TabRouter.tsx +++ b/client/src/components/Panels/TabRouter.tsx @@ -1,12 +1,12 @@ import React, { FC } from "react"; import { Route, useRouteMatch, Redirect } from "react-router-dom"; -import { TabRouterHeader } from "./TabRouterHeader"; -import { TicketList } from "../Lists/TicketList"; -import { FileList } from "../Lists/AppFileList"; -import { Ticket } from "../../types/Ticket"; -import { AppFile } from "../../types/AppFile"; -import { Activity } from "../../types/Activity"; -import { Project } from "../../types/Project"; +import TabRouterHeader from "./TabRouterHeader"; +import TicketList from "../Lists/TicketList"; +import FileList from "../Lists/AppFileList"; +import Ticket from "../../types/Ticket"; +import AppFile from "../../types/AppFile"; +import Activity from "../../types/Activity"; +import Project from "../../types/Project"; interface IProps { tickets: Ticket[]; @@ -17,7 +17,7 @@ interface IProps { allProjects: Project[]; } -export const TabRouter: FC = ({ +const TabRouter: FC = ({ tickets, tabNames, files, @@ -48,3 +48,5 @@ export const TabRouter: FC = ({ ); }; + +export default TabRouter; diff --git a/client/src/components/Panels/TabRouterHeader.tsx b/client/src/components/Panels/TabRouterHeader.tsx index 2bd15ef..baaaae0 100644 --- a/client/src/components/Panels/TabRouterHeader.tsx +++ b/client/src/components/Panels/TabRouterHeader.tsx @@ -6,9 +6,9 @@ interface IProps { tabNames: string[]; } -export const TabRouterHeader: FC = ({ +const TabRouterHeader: FC = ({ tabNames, - tabClass = `tab col s${12 / tabNames.length}` + tabClass = `tab col s${12 / tabNames.length}`, }) => { const [isActive, setIsActive] = useState(0); const nTabs = tabNames.length; @@ -31,7 +31,7 @@ export const TabRouterHeader: FC = ({ className="indicator indigo lighten-2" style={{ left: `${(isActive / nTabs) * 100}%`, - right: `${(1 - (isActive + 1) / nTabs) * 100}%` + right: `${(1 - (isActive + 1) / nTabs) * 100}%`, }} > @@ -54,7 +54,7 @@ const TabUnit: FC = ({ setIsActive, text, value, - nTabs + nTabs, }) => { const { url } = useRouteMatch(); return ( @@ -63,7 +63,7 @@ const TabUnit: FC = ({ key={value} style={{ left: `${(isActive / nTabs) * 100}%`, - right: `${(1 - (isActive + 1) / nTabs) * 100}%` + right: `${(1 - (isActive + 1) / nTabs) * 100}%`, }} > = ({ ); }; + +export default TabRouterHeader; diff --git a/client/src/components/Panels/UserTabPanel.tsx b/client/src/components/Panels/UserTabPanel.tsx index ad0c2ba..8674425 100644 --- a/client/src/components/Panels/UserTabPanel.tsx +++ b/client/src/components/Panels/UserTabPanel.tsx @@ -1,16 +1,11 @@ import React, { FC, useState, ReactNode } 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 { Ticket } from "../../types/Ticket"; -import { Project } from "../../types/Project"; -import { ProjectList } from "../Lists/ProjectList"; -import { TicketList } from "../Lists/TicketList"; -import { User } from "../../types/User"; +import { AppBar, Box, Tab, Tabs, Typography } from "@material-ui/core"; +import ProjectList from "../Lists/ProjectList"; +import TicketList from "../Lists/TicketList"; +import Ticket from "../../types/Ticket"; +import Project from "../../types/Project"; interface TabProps { children?: ReactNode; @@ -55,15 +50,9 @@ interface IProps { tabNames: string[]; tickets: Ticket[]; projects: Project[]; - allUsers: User[]; } -export const UserTabPanel: FC = ({ - tickets, - tabNames, - projects, - allUsers, -}) => { +const UserTabPanel: FC = ({ tickets, tabNames, projects }) => { const classes = useStyles(); const theme = useTheme(); const [value, setValue] = useState(0); @@ -98,7 +87,7 @@ export const UserTabPanel: FC = ({ onChangeIndex={handleChangeIndex} > - + @@ -107,3 +96,4 @@ export const UserTabPanel: FC = ({ ); }; +export default UserTabPanel; diff --git a/client/src/components/Panels/UserTabRouter.tsx b/client/src/components/Panels/UserTabRouter.tsx index 6a45d4d..218990a 100644 --- a/client/src/components/Panels/UserTabRouter.tsx +++ b/client/src/components/Panels/UserTabRouter.tsx @@ -1,10 +1,9 @@ import React, { FC } from "react"; import { Route, useRouteMatch, Redirect } from "react-router-dom"; -import { TabRouterHeader } from "./TabRouterHeader"; -import { ProjectList } from "../Lists/ProjectList"; -import { Ticket } from "../../types/Ticket"; -import { Project } from "../../types/Project"; -import { TicketList } from "../Lists/TicketList"; +import TabRouterHeader from "./TabRouterHeader"; +import TicketList from "../Lists/TicketList"; +import Ticket from "../../types/Ticket"; +import Project from "../../types/Project"; interface IProps { tabNames: string[]; @@ -33,3 +32,5 @@ export const UserTabRouter: FC = ({ tickets, tabNames, projects }) => { ); }; + +export default UserTabRouter; diff --git a/client/src/components/PasswordField.tsx b/client/src/components/PasswordField.tsx index d30d302..ea5ac53 100644 --- a/client/src/components/PasswordField.tsx +++ b/client/src/components/PasswordField.tsx @@ -1,6 +1,6 @@ import React, { FC } from "react"; -export const PasswordField: FC = () => { +const PasswordField: FC = () => { return (
@@ -8,3 +8,5 @@ export const PasswordField: FC = () => {
); }; + +export default PasswordField; diff --git a/client/src/components/Preloader.tsx b/client/src/components/Preloader.tsx index 5c77cca..5c63a34 100644 --- a/client/src/components/Preloader.tsx +++ b/client/src/components/Preloader.tsx @@ -1,55 +1,24 @@ import React, { FC } from "react"; +import { Backdrop, CircularProgress } from "@material-ui/core"; +import { makeStyles, createStyles, Theme } from "@material-ui/core/styles"; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + backdrop: { + zIndex: theme.zIndex.drawer + 1, + color: "#fff", + }, + }) +); + +const Preloader: FC = () => { + const classes = useStyles(); -export const Preloader: FC = () => { return ( -
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
+ + + ); }; + +export default Preloader; diff --git a/client/src/components/ProfileSelector.tsx b/client/src/components/ProfileSelector.tsx index 3c6fdb9..4b2aeae 100644 --- a/client/src/components/ProfileSelector.tsx +++ b/client/src/components/ProfileSelector.tsx @@ -1,8 +1,8 @@ import React, { FC } from "react"; -import { UserAvatar } from "./Avatars/UserAvatar"; import { Link } from "react-router-dom"; +import { UserAvatar } from "./Avatars/UserAvatar"; -export const ProfileSelector: FC = () => { +const ProfileSelector: FC = () => { return (
@@ -20,3 +20,4 @@ export const ProfileSelector: FC = () => {
); }; +export default ProfileSelector; diff --git a/client/src/components/Progress/ProgressBar.tsx b/client/src/components/Progress/ProgressBar.tsx index e3f837c..670764e 100644 --- a/client/src/components/Progress/ProgressBar.tsx +++ b/client/src/components/Progress/ProgressBar.tsx @@ -1,7 +1,6 @@ import React, { FC } from "react"; +import { Box, LinearProgress } from "@material-ui/core"; import { makeStyles, Theme, createStyles } from "@material-ui/core/styles"; -import LinearProgress from "@material-ui/core/LinearProgress"; -import { Box } from "@material-ui/core"; type IProps = { value: number; @@ -18,7 +17,7 @@ const useStyles = makeStyles((theme: Theme) => }) ); -export const ProgressBar: FC = ({ value }) => { +const ProgressBar: FC = ({ value }) => { // const styleString: CSSProperties = { width: `${value}%` }; // let barColor: string = "green"; @@ -43,3 +42,5 @@ export const ProgressBar: FC = ({ value }) => { ); }; + +export default ProgressBar; diff --git a/client/src/components/Progress/ProgressInfo.tsx b/client/src/components/Progress/ProgressInfo.tsx index eaaf028..cf9ec37 100644 --- a/client/src/components/Progress/ProgressInfo.tsx +++ b/client/src/components/Progress/ProgressInfo.tsx @@ -20,7 +20,7 @@ type IProps = { // }) // ); -export const ProgressInfo: FC = ({ +const ProgressInfo: FC = ({ tasksDone, tasksTotalCount, remainingDays, @@ -39,3 +39,5 @@ export const ProgressInfo: FC = ({ ); }; + +export default ProgressInfo; diff --git a/client/src/components/SignInSide.tsx b/client/src/components/SignInSide.tsx index bb58e38..ef44700 100644 --- a/client/src/components/SignInSide.tsx +++ b/client/src/components/SignInSide.tsx @@ -2,20 +2,17 @@ import React from "react"; import Avatar from "@material-ui/core/Avatar"; import Button from "@material-ui/core/Button"; import CssBaseline from "@material-ui/core/CssBaseline"; -import TextField from "@material-ui/core/TextField"; -import FormControlLabel from "@material-ui/core/FormControlLabel"; -import Checkbox from "@material-ui/core/Checkbox"; -import Link from "@material-ui/core/Link"; import Paper from "@material-ui/core/Paper"; import Grid from "@material-ui/core/Grid"; import LockOutlinedIcon from "@material-ui/icons/LockOutlined"; import Typography from "@material-ui/core/Typography"; import { makeStyles, createStyles, Theme } from "@material-ui/core/styles"; +import { useAuth0 } from "../authentication/auth0"; const useStyles = makeStyles((theme: Theme) => createStyles({ root: { - height: "100vh" + height: "100vh", }, image: { backgroundImage: "url(https://source.unsplash.com/daily?dev)", @@ -25,30 +22,31 @@ const useStyles = makeStyles((theme: Theme) => ? theme.palette.grey[50] : theme.palette.grey[900], backgroundSize: "cover", - backgroundPosition: "center" + backgroundPosition: "center", }, paper: { margin: theme.spacing(8, 4), display: "flex", flexDirection: "column", - alignItems: "center" + alignItems: "center", }, avatar: { margin: theme.spacing(1), - backgroundColor: theme.palette.secondary.main + backgroundColor: theme.palette.secondary.main, }, form: { width: "100%", - marginTop: theme.spacing(1) + marginTop: theme.spacing(1), }, submit: { - margin: theme.spacing(3, 0, 2) - } + margin: theme.spacing(3, 0, 2), + }, }) ); export default function SignInSide() { const classes = useStyles(); + const { loginWithRedirect } = useAuth0(); return ( @@ -63,53 +61,16 @@ export default function SignInSide() { Sign in
- - - } - label="Remember me" - /> - - - - Forgot password? - - - - - {"Don't have an account? Sign Up"} - - -
diff --git a/client/src/components/UserHeader.tsx b/client/src/components/UserHeader.tsx index 98f6ff9..9b7f8d9 100644 --- a/client/src/components/UserHeader.tsx +++ b/client/src/components/UserHeader.tsx @@ -1,6 +1,6 @@ import React, { FC } from "react"; -import { Header } from "../components/Header"; -import { UserAvatar } from "./Avatars/UserAvatar"; +import Header from "../components/Header"; +import UserAvatar from "./Avatars/UserAvatar"; import { Grid, // makeStyles, Theme @@ -19,7 +19,7 @@ interface IProps { // }, // })); -export const UserHeader: FC = ({ fullName, presentation, picture }) => { +const UserHeader: FC = ({ fullName, presentation, picture }) => { // const classes = useStyles(); return ( //
@@ -34,3 +34,5 @@ export const UserHeader: FC = ({ fullName, presentation, picture }) => { //
); }; + +export default UserHeader; diff --git a/client/src/constants/routes.ts b/client/src/constants/routes.ts new file mode 100644 index 0000000..b9b2344 --- /dev/null +++ b/client/src/constants/routes.ts @@ -0,0 +1,7 @@ +export const HOME: string = "/"; +export const PROJECTS: string = "/projects"; +export const TICKETS: string = "/tickets"; +export const USERS: string = "/users"; +export const SIGN_IN: string = "/signin"; +export const NOT_FOUND: string = "/404"; +export const TEST: string = "/test"; diff --git a/client/src/controllers/ErrorController.tsx b/client/src/controllers/ErrorController.tsx index 0f00683..9b7edb8 100644 --- a/client/src/controllers/ErrorController.tsx +++ b/client/src/controllers/ErrorController.tsx @@ -5,7 +5,7 @@ interface IProps { error: string; } -export const ErrorController: FC = ({ error }) => { +const ErrorController: FC = ({ error }) => { switch (error) { case "Bad Request": return ; @@ -20,3 +20,5 @@ export const ErrorController: FC = ({ error }) => { return ; } }; + +export default ErrorController; diff --git a/client/src/controllers/HomeController.tsx b/client/src/controllers/HomeController.tsx index cf821ae..fbabe73 100644 --- a/client/src/controllers/HomeController.tsx +++ b/client/src/controllers/HomeController.tsx @@ -1,6 +1,8 @@ import React, { FC } from "react"; -import { HomePage } from "../pages/HomePage"; +import HomePage from "../pages/HomePage"; -export const HomeController: FC = () => { +const HomeController: FC = () => { return ; }; + +export default HomeController; diff --git a/client/src/controllers/ProjectController.tsx b/client/src/controllers/ProjectController.tsx index 427bd8f..a84599e 100644 --- a/client/src/controllers/ProjectController.tsx +++ b/client/src/controllers/ProjectController.tsx @@ -1,16 +1,15 @@ import React, { FC, useState, useEffect } from "react"; import { useParams } from "react-router-dom"; -import { ErrorController } from "./ErrorController"; -import { ProjectPage } from "../pages/ProjectPage"; +import ErrorController from "./ErrorController"; +import ProjectPage from "../pages/ProjectPage"; import ProjectVM from "../VM/ProjectVM"; -import { Project } from "../types/Project"; -import { HttpResponse } from "../types/HttpResponse"; -import { Preloader } from "../components/Preloader"; -import { Constants } from "../utils/Constants"; -import { get } from "../utils/http"; -import { User } from "../types/User"; +import Project from "../types/Project"; +import User from "../types/User"; +import Preloader from "../components/Preloader"; +import { ProjectService, UserService } from "../services"; +import { useAuth0 } from "../authentication/auth0"; -export const ProjectController: FC = () => { +const ProjectController: FC = () => { const [project, setProject] = useState({} as Project); const [allUsers, setAllUsers] = useState([]); const [allProjects, setAllProjects] = useState([]); @@ -18,61 +17,62 @@ export const ProjectController: FC = () => { const [hasError, setHasError] = useState(false); const [error, setError] = useState(""); const { id } = useParams(); - - async function httpGetProjects(id: string): Promise { - try { - const response: HttpResponse = await get( - `${Constants.projectsURI}/${id}` - ); - if (response.parsedBody !== undefined) { - setProject(response.parsedBody); - setIsLoading(false); - } - } catch (ex) { - console.error(ex); - setHasError(true); - setError(ex); - } - } - - async function httpGetAllUsers(): Promise { - try { - const response: HttpResponse = await get( - `${Constants.usersURI}` - ); - if (response.parsedBody !== undefined) { - setAllUsers((response.parsedBody as unknown) as User[]); - } - } catch (ex) { - setHasError(true); - setError(ex); - } - } - - async function httpGetAllProjects(): Promise { - try { - const response: HttpResponse = await get( - `${Constants.projectsURI}` - ); - if (response.parsedBody !== undefined) { - setAllProjects((response.parsedBody as unknown) as Project[]); - } - } catch (ex) { - setHasError(true); - setError(ex); - } - } + const { getTokenSilently } = useAuth0(); useEffect(() => { + const getProject = async (id: string): Promise => { + const token = await getTokenSilently(); + try { + const Projects = new ProjectService(token); + const project: Project = await Projects.get(id); + if (project !== undefined) { + setProject(project); + setIsLoading(false); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + }; + + const getAllUsers = async (): Promise => { + const token = await getTokenSilently(); + try { + const Users = new UserService(token); + const response: User[] = await Users.all(); + if (response !== undefined) { + setAllUsers(response); + setIsLoading(false); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + }; + + const getAllProjects = async (): Promise => { + const token = await getTokenSilently(); + try { + const Projects = new ProjectService(token); + const response: Project[] = await Projects.all(); + if (response !== undefined) { + setAllProjects(response); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + }; + if (id !== undefined) { - httpGetProjects(id); - httpGetAllUsers(); - httpGetAllProjects(); + getProject(id); + getAllUsers(); + getAllProjects(); } else { setHasError(true); setError("Bad Request"); } - }, [id]); + }, [id, getTokenSilently]); if (hasError) { return ; @@ -81,3 +81,5 @@ export const ProjectController: FC = () => { const viewModel = new ProjectVM(project, allUsers, allProjects); return isLoading ? : ; }; + +export default ProjectController; diff --git a/client/src/controllers/TicketController.tsx b/client/src/controllers/TicketController.tsx index 0cccd54..28de0c5 100644 --- a/client/src/controllers/TicketController.tsx +++ b/client/src/controllers/TicketController.tsx @@ -1,45 +1,44 @@ 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"; +import ErrorController from "./ErrorController"; +import TicketPage from "../pages/TicketPage"; +import TicketVM from "../VM/TicketVM"; +import Ticket from "../types/Ticket"; +import Preloader from "../components/Preloader"; +import { useAuth0 } from "../authentication/auth0"; +import { TicketService } from "../services"; -export const TicketController: FC = () => { +const TicketController: FC = () => { 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); - } - } + const { getTokenSilently } = useAuth0(); useEffect(() => { + const getTicket = async (id: string): Promise => { + const token = await getTokenSilently(); + try { + const Tickets = new TicketService(token); + const response: Ticket = await Tickets.get(id); + if (response !== undefined) { + setTicket(response); + setIsLoading(false); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + }; + if (id !== undefined) { - httpGetTicket(id); + getTicket(id); } else { setHasError(true); setError("Bad Request"); } - }, [id]); + }, [id, getTokenSilently]); if (hasError) { return ; @@ -48,3 +47,5 @@ export const TicketController: FC = () => { const viewModel = new TicketVM(ticket); return isLoading ? : ; }; + +export default TicketController; diff --git a/client/src/controllers/UserController.tsx b/client/src/controllers/UserController.tsx index fc31881..e7b7b1a 100644 --- a/client/src/controllers/UserController.tsx +++ b/client/src/controllers/UserController.tsx @@ -1,66 +1,75 @@ import React, { FC, useState, useEffect } from "react"; import { useParams } from "react-router-dom"; -import { UserPage } from "../pages/UserPage"; +import ErrorController from "./ErrorController"; +import UserPage from "../pages/UserPage"; import { UserVM } from "../VM/UserVM"; -import { User } from "../types/User"; -import { HttpResponse } from "../types/HttpResponse"; -import { Preloader } from "../components/Preloader"; -import { get } from "../utils/http"; -import { Constants } from "../utils/Constants"; -import { ErrorController } from "./ErrorController"; +import User from "../types/User"; +import Preloader from "../components/Preloader"; +import { UserService } from "../services"; +import { useAuth0 } from "../authentication/auth0"; +import { getUID } from "../authentication/helpers"; -export const UserController: FC = () => { +const UserController: FC = () => { const [isLoading, setIsLoading] = useState(true); - const [user, setUser] = useState({} as User); + const [account, setAccount] = useState({} as User); const [hasError, setHasError] = useState(false); const [error, setError] = useState(""); - const [allUsers, setAllUsers] = useState([]); const { id } = useParams(); - - async function httpGetUser(id: string): Promise { - try { - const response: HttpResponse = await get( - `${Constants.usersURI}/${id}` - ); - if (response.parsedBody !== undefined) { - setUser(response.parsedBody); - setIsLoading(false); - } - } catch (ex) { - console.error(ex); - setHasError(true); - setError(ex); - } - } - - async function httpGetAllUsers(): Promise { - try { - const response: HttpResponse = await get( - `${Constants.usersURI}` - ); - if (response.parsedBody !== undefined) { - setAllUsers((response.parsedBody as unknown) as User[]); - } - } catch (ex) { - setHasError(true); - setError(ex); - } - } + const { getTokenSilently, user } = useAuth0(); useEffect(() => { + const getUser = async (id: string): Promise => { + const token = await getTokenSilently(); + const Users = new UserService(token); + let response: User | undefined; + + try { + response = await Users.get(id); + } catch (ex) { + if (ex === "Not Found") { + // create user + const { given_name, family_name, email, nickname, picture } = user; + const newUser: User = { + id: getUID(user), + firstName: given_name, + lastName: family_name, + fullName: `${given_name} ${family_name}`, + email, + presentation: nickname, + picture, + phone: "", + creationDate: Date.now().toLocaleString(), + activities: [], + projects: [], + tickets: [], + }; + response = await Users.add(newUser); + } else { + setHasError(true); + setError(ex); + } + } finally { + if (response !== undefined) { + setAccount(response); + setIsLoading(false); + } + } + }; + if (id !== undefined) { - httpGetUser(id); - httpGetAllUsers(); + getUser(id); } else { setHasError(true); setError("Bad Request"); } - }, [id]); + }, [id, getTokenSilently, user]); if (hasError) { return ; } - const viewModel = new UserVM(user, allUsers); + const viewModel = new UserVM(account); return isLoading ? : ; }; + +export default UserController; diff --git a/client/src/index.jsx b/client/src/index.jsx index 6668661..407bbac 100644 --- a/client/src/index.jsx +++ b/client/src/index.jsx @@ -6,7 +6,7 @@ import { Auth0Provider } from "./authentication/auth0"; import config from "./authentication/config.json"; import history from "./utils/history"; -const onRedirectCallback = appState => { +const onRedirectCallback = (appState) => { history.push( appState && appState.targetUrl ? appState.targetUrl @@ -18,6 +18,7 @@ ReactDOM.render( diff --git a/client/src/pages/HomePage.tsx b/client/src/pages/HomePage.tsx index e6fe164..57f3804 100644 --- a/client/src/pages/HomePage.tsx +++ b/client/src/pages/HomePage.tsx @@ -1,23 +1,7 @@ -import React from "react"; -// import { LogInForm } from "../components/LogInForm"; -// import { ProfileSelector } from "../components/ProfileSelector"; -import SignInSide from "../components/SignInSide"; +import React, { FC } from "react"; -export const HomePage: React.FC = () => { - return ( - //
- //
- //

Ticket Manager

- //
- //
- // - //
- //
- // - //
- //
- //
- //
- - ); +const HomePage: FC = () => { + return
HomePage
; }; + +export default HomePage; diff --git a/client/src/pages/NotFoundPage.tsx b/client/src/pages/NotFoundPage.tsx index 5b60c5e..1283edf 100644 --- a/client/src/pages/NotFoundPage.tsx +++ b/client/src/pages/NotFoundPage.tsx @@ -1,9 +1,8 @@ import React, { FC } from "react"; import PageLayout from "../layouts/PageLayout"; -import { Header } from "../components/Header"; +import Header from "../components/Header"; -interface IProps {} -export const NotFoundPage: FC = () => { +const NotFoundPage: FC = () => { return ( } @@ -11,3 +10,5 @@ export const NotFoundPage: FC = () => { /> ); }; + +export default NotFoundPage; diff --git a/client/src/pages/ProjectPage.tsx b/client/src/pages/ProjectPage.tsx index 43e12cd..02746f0 100644 --- a/client/src/pages/ProjectPage.tsx +++ b/client/src/pages/ProjectPage.tsx @@ -1,14 +1,14 @@ import React, { FC, useState } from "react"; import { Grid, makeStyles, Theme } from "@material-ui/core"; -import { Header } from "../components/Header"; -import { AvatarList } from "../components/Avatars/AvatarList"; -import { ProgressBar } from "../components/Progress/ProgressBar"; -import { FloatingButton } from "../components/Buttons/FloatingButton"; -import { UsersModal } from "../components/Modals/UsersModal"; -import { ProjectTabPanel } from "../components/Panels/ProjectTabPanel"; +import Header from "../components/Header"; +import AvatarList from "../components/Avatars/AvatarList"; +import ProgressBar from "../components/Progress/ProgressBar"; +import FloatingButton from "../components/Buttons/FloatingButton"; +import UsersModal from "../components/Modals/UsersModal"; +import ProjectTabPanel from "../components/Panels/ProjectTabPanel"; +import ProgressInfo from "../components/Progress/ProgressInfo"; import ProjectVM from "../VM/ProjectVM"; import PageLayout from "../layouts/PageLayout"; -import { ProgressInfo } from "../components/Progress/ProgressInfo"; interface IProps { viewModel: ProjectVM; @@ -22,7 +22,7 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); -export const ProjectPage: FC = ({ viewModel }) => { +const ProjectPage: FC = ({ viewModel }) => { const { // id, title, @@ -97,3 +97,5 @@ export const ProjectPage: FC = ({ viewModel }) => { /> ); }; + +export default ProjectPage; diff --git a/client/src/pages/SigninPage.tsx b/client/src/pages/SigninPage.tsx new file mode 100644 index 0000000..59241d2 --- /dev/null +++ b/client/src/pages/SigninPage.tsx @@ -0,0 +1,20 @@ +import React, { FC } from "react"; +import { Redirect } from "react-router-dom"; +import SignInSide from "../components/SignInSide"; +import { useAuth0 } from "../authentication/auth0"; +import { getUID } from "../authentication/helpers"; +import * as ROUTES from "../constants/routes"; + +const SigninPage: FC = () => { + const { isAuthenticated, user } = useAuth0(); + + if (isAuthenticated) { + // retrieve userId + const uid = getUID(user); + return ; + } else { + return ; + } +}; + +export default SigninPage; diff --git a/client/src/pages/TicketPage.tsx b/client/src/pages/TicketPage.tsx index 7ed4937..37782e0 100644 --- a/client/src/pages/TicketPage.tsx +++ b/client/src/pages/TicketPage.tsx @@ -2,12 +2,12 @@ import React, { FC } from "react"; import { Link } from "react-router-dom"; import { makeStyles, Theme, Grid, Typography } from "@material-ui/core"; import { Timer } from "@material-ui/icons"; +import TicketVM from "../VM/TicketVM"; import PageLayout from "../layouts/PageLayout"; -import { TicketVM } from "../VM/TicketVM"; -import { Header } from "../components/Header"; -import { AvatarList } from "../components/Avatars/AvatarList"; +import Header from "../components/Header"; +import AvatarList from "../components/Avatars/AvatarList"; import TicketChipsArray from "../components/Cards/TicketChipsArray"; -import { getRemainingdays } from "../utils/methods"; +import getRemainingdays from "../utils/methods"; interface IProps { viewModel: TicketVM; @@ -16,7 +16,6 @@ interface IProps { const useStyles = makeStyles((theme: Theme) => ({ root: { margin: theme.spacing(1), - // flexGrow: 1, }, table: { margin: "auto", @@ -28,7 +27,7 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); -export const TicketPage: FC = ({ viewModel }) => { +const TicketPage: FC = ({ viewModel }) => { const { title, description, @@ -133,3 +132,5 @@ export const TicketPage: FC = ({ viewModel }) => { // // ); // }; + +export default TicketPage; diff --git a/client/src/pages/UserPage.tsx b/client/src/pages/UserPage.tsx index b3d8e2c..fc358e0 100644 --- a/client/src/pages/UserPage.tsx +++ b/client/src/pages/UserPage.tsx @@ -1,22 +1,15 @@ import React, { FC } from "react"; import { UserVM } from "../VM/UserVM"; -import { UserHeader } from "../components/UserHeader"; -import { UserTabPanel } from "../components/Panels/UserTabPanel"; +import UserHeader from "../components/UserHeader"; +import UserTabPanel from "../components/Panels/UserTabPanel"; import PageLayout from "../layouts/PageLayout"; interface IProps { viewModel: UserVM; } -export const UserPage: FC = ({ viewModel }) => { - const { - fullName, - presentation, - picture, - projects, - tickets, - allUsers, - } = viewModel; +const UserPage: FC = ({ viewModel }) => { + const { fullName, presentation, picture, projects, tickets } = viewModel; const tabNames: string[] = ["Projects", "Tickets"]; return ( @@ -33,9 +26,10 @@ export const UserPage: FC = ({ viewModel }) => { tabNames={tabNames} projects={projects} tickets={tickets} - allUsers={allUsers} /> } /> ); }; + +export default UserPage; diff --git a/client/src/routes/AppRouter.tsx b/client/src/routes/AppRouter.tsx new file mode 100644 index 0000000..d2d529a --- /dev/null +++ b/client/src/routes/AppRouter.tsx @@ -0,0 +1,33 @@ +import React from "react"; +import { Route, Switch } from "react-router-dom"; +import PrivateRoute from "./PrivateRoute"; +import HomeController from "../controllers/HomeController"; +import ProjectController from "../controllers/ProjectController"; +import UserController from "../controllers/UserController"; +import TicketController from "../controllers/TicketController"; +import NotFoundPage from "../pages/NotFoundPage"; +import TestPage from "../pages/TestPage"; +import SigninPage from "../pages/SigninPage"; +import * as ROUTES from "../constants/routes"; + +const AppRouter = () => { + return ( + + + + + + + + + + ); +}; + +export default AppRouter; diff --git a/client/src/utils/PrivateRoute.jsx b/client/src/routes/PrivateRoute.jsx similarity index 75% rename from client/src/utils/PrivateRoute.jsx rename to client/src/routes/PrivateRoute.jsx index 61f1d4d..03ea69b 100644 --- a/client/src/utils/PrivateRoute.jsx +++ b/client/src/routes/PrivateRoute.jsx @@ -2,7 +2,7 @@ import React, { useEffect } from "react"; import { Route } from "react-router-dom"; import { useAuth0 } from "../authentication/auth0"; -export const PrivateRoute = ({ component: Component, path, ...rest }) => { +const PrivateRoute = ({ component: Component, path, ...rest }) => { const { loading, isAuthenticated, loginWithRedirect } = useAuth0(); useEffect(() => { @@ -11,14 +11,16 @@ export const PrivateRoute = ({ component: Component, path, ...rest }) => { } const fn = async () => { await loginWithRedirect({ - appState: { targetUrl: window.location.pathname } + appState: { targetUrl: window.location.pathname }, }); }; fn(); }, [loading, isAuthenticated, loginWithRedirect, path]); - const render = props => + const render = (props) => isAuthenticated === true ? : null; return ; }; + +export default PrivateRoute; diff --git a/client/src/services/http.ts b/client/src/services/http.ts new file mode 100644 index 0000000..7908950 --- /dev/null +++ b/client/src/services/http.ts @@ -0,0 +1,72 @@ +import HttpResponse from "../types/HttpResponse"; + +export default class HttpHandler { + private newHeaders = async (token: string) => { + // const { getTokenSilently } = useAuth0(); + // const token = await getTokenSilently(); + + return new Headers({ + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }); + }; + + private execute = async (request: RequestInfo): Promise> => { + const response: HttpResponse = await fetch(request); + try { + response.parsedBody = await response.json(); + } catch (ex) {} + if (!response.ok) { + throw response.statusText; + } + return response; + }; + + get = async (path: string, token: string): Promise> => { + const args: RequestInit = { + method: "get", + headers: await this.newHeaders(token), + }; + return await this.execute(new Request(path, args)); + }; + + post = async ( + path: string, + body: any, + token: string + ): Promise> => { + const args: RequestInit = { + method: "post", + headers: await this.newHeaders(token), + body: JSON.stringify(body), + }; + return await this.execute(new Request(path, args)); + }; + + put = async ( + path: string, + body: any, + token: string + ): Promise> => { + const args: RequestInit = { + method: "put", + headers: await this.newHeaders(token), + body: JSON.stringify(body), + }; + return await this.execute(new Request(path, args)); + }; + + patch = async ( + path: string, + body: any, + token: string + ): Promise> => { + const args: RequestInit = { + method: "patch", + headers: await this.newHeaders(token), + body: JSON.stringify(body), + }; + return await this.execute(new Request(path, args)); + }; +} diff --git a/client/src/services/index.ts b/client/src/services/index.ts new file mode 100644 index 0000000..40ca183 --- /dev/null +++ b/client/src/services/index.ts @@ -0,0 +1,13 @@ +import ProjectService from "./project"; +import TicketService from "./ticket"; +import UserService from "./user"; + +export default interface IService { + all(): Promise; + get(id: string): Promise; + add(item: any): Promise; + update(id: string, item: T): Promise; + delete(id: string): Promise; +} + +export { ProjectService, TicketService, UserService }; diff --git a/client/src/services/project.ts b/client/src/services/project.ts new file mode 100644 index 0000000..22ff989 --- /dev/null +++ b/client/src/services/project.ts @@ -0,0 +1,44 @@ +import IService from "."; +import Project from "../types/Project"; +import HttpHandler from "./http"; + +interface NewProject { + title: string; + description: string; + endingDate: string; + managerId: string; +} +export default class ProjectService implements IService { + constructor(private key: string) {} + + private http = new HttpHandler(); + private path: string = "/api/v1/projects"; + + all = async (): Promise => { + const response = await this.http.get(this.path, this.key); + return (response.parsedBody as unknown) as Project[]; + }; + + get = async (id: string): Promise => { + const response = await this.http.get(`${this.path}/${id}`, this.key); + const body = response.parsedBody; + return body ?? ({} as Project); + }; + + add = async (item: NewProject): Promise => { + const response = await this.http.post(this.path, item, this.key); + const body = response.parsedBody; + return body ?? ({} as Project); + }; + + update(id: string, item: Project): Promise { + throw new Error("Method not implemented."); + } + delete(id: string): Promise { + throw new Error("Method not implemented."); + } + + setMembers = async (id: string, members: string[]): Promise => { + await this.http.patch(`${this.path}/${id}/members`, members, this.key); + }; +} diff --git a/client/src/services/ticket.ts b/client/src/services/ticket.ts new file mode 100644 index 0000000..de9eb4e --- /dev/null +++ b/client/src/services/ticket.ts @@ -0,0 +1,50 @@ +import IService from "."; +import Ticket from "../types/Ticket"; +import HttpHandler from "./http"; + +interface NewTicket { + title: string; + description: string; + endingDate: string; + creatorId: string; + projectId: number; + impact: number; + difficulty: number; + category: number; +} + +export default class TicketService implements IService { + constructor(private key: string) {} + + private http = new HttpHandler(); + private path: string = "/api/v1/tickets"; + + all = async (): Promise => { + const response = await this.http.get(this.path, this.key); + return (response.parsedBody as unknown) as Ticket[]; + }; + + get = async (id: string): Promise => { + const response = await this.http.get(`${this.path}/${id}`, this.key); + const body = response.parsedBody; + return body ?? ({} as Ticket); + }; + + add = async (item: NewTicket): Promise => { + const response = await this.http.post(this.path, item, this.key); + const body = response.parsedBody; + return body ?? ({} as Ticket); + }; + + update(id: string, item: Ticket): Promise { + throw new Error("Method not implemented."); + } + + delete(id: string): Promise { + throw new Error("Method not implemented."); + } + + close = async (id: string): Promise => { + await this.http.put(`${this.path}/${id}/closed`, {}, this.key); + }; +} diff --git a/client/src/services/user.ts b/client/src/services/user.ts new file mode 100644 index 0000000..0a81b6b --- /dev/null +++ b/client/src/services/user.ts @@ -0,0 +1,35 @@ +import IService from "."; +import User from "../types/User"; +import HttpHandler from "./http"; + +export default class UserService implements IService { + constructor(private key: string) {} + + private http = new HttpHandler(); + private path: string = "/api/v1/users"; + + all = async (): Promise => { + const response = await this.http.get(this.path, this.key); + return (response.parsedBody as unknown) as User[]; + }; + + get = async (id: string): Promise => { + const response = await this.http.get(`${this.path}/${id}`, this.key); + const body = response.parsedBody; + return body ?? ({} as User); + }; + + add = async (item: User): Promise => { + const response = await this.http.post(this.path, item, this.key); + const body = response.parsedBody; + return body ?? ({} as User); + }; + + update = async (id: string, item: User): Promise => { + throw new Error("Method not implemented."); + }; + + delete = async (id: string): Promise => { + throw new Error("Method not implemented."); + }; +} diff --git a/client/src/types/Activity.ts b/client/src/types/Activity.ts index 4fb8157..d6d3c6c 100644 --- a/client/src/types/Activity.ts +++ b/client/src/types/Activity.ts @@ -1,7 +1,7 @@ -import { User } from "./User"; -import { Ticket } from "./Ticket"; +import User from "./User"; +import Ticket from "./Ticket"; -export interface Activity { +export default interface Activity { id: number; description: string; date: Date; diff --git a/client/src/types/AppFile.ts b/client/src/types/AppFile.ts index 6fc9cec..ee714f8 100644 --- a/client/src/types/AppFile.ts +++ b/client/src/types/AppFile.ts @@ -1,6 +1,6 @@ -import { User } from "./User"; +import User from "./User"; -export interface AppFile { +export default interface AppFile { id: number; name: string; description: string; diff --git a/client/src/types/HttpResponse.ts b/client/src/types/HttpResponse.ts index a5825c0..e6865f9 100644 --- a/client/src/types/HttpResponse.ts +++ b/client/src/types/HttpResponse.ts @@ -1,3 +1,3 @@ -export interface HttpResponse extends Response { +export default interface HttpResponse extends Response { parsedBody?: T; } diff --git a/client/src/types/Note.ts b/client/src/types/Note.ts index 0cf71ff..dcb7784 100644 --- a/client/src/types/Note.ts +++ b/client/src/types/Note.ts @@ -1,3 +1,3 @@ -export interface Note { +export default interface Note { Id: number; } diff --git a/client/src/types/Project.ts b/client/src/types/Project.ts index b42af19..7abb871 100644 --- a/client/src/types/Project.ts +++ b/client/src/types/Project.ts @@ -1,9 +1,9 @@ -import { Ticket } from "./Ticket"; -import { User } from "./User"; -import { AppFile } from "./AppFile"; -import { Activity } from "./Activity"; +import AppFile from "./AppFile"; +import Activity from "./Activity"; +import Ticket from "./Ticket"; +import User from "./User"; -export interface Project { +export default interface Project { id: number; title: string; description: string; diff --git a/client/src/types/Ticket.ts b/client/src/types/Ticket.ts index 6d32d88..ea46005 100644 --- a/client/src/types/Ticket.ts +++ b/client/src/types/Ticket.ts @@ -1,7 +1,7 @@ -import { Project } from "./Project"; -import { User } from "./User"; +import Project from "./Project"; +import User from "./User"; -export interface Ticket { +export default interface Ticket { id: number; title: string; description: string; diff --git a/client/src/types/User.ts b/client/src/types/User.ts index 7cdfb58..5cb1d43 100644 --- a/client/src/types/User.ts +++ b/client/src/types/User.ts @@ -1,8 +1,8 @@ -import { Activity } from "./Activity"; -import { Project } from "./Project"; -import { Ticket } from "./Ticket"; +import Activity from "./Activity"; +import Project from "./Project"; +import Ticket from "./Ticket"; -export interface User { +export default interface User { id: string; firstName: string; lastName: string; diff --git a/client/src/utils/Constants.ts b/client/src/utils/Constants.ts index cdfb2b9..5025e15 100644 --- a/client/src/utils/Constants.ts +++ b/client/src/utils/Constants.ts @@ -1,4 +1,4 @@ -export class Constants { +export default class Constants { static projectsURI: string = "/api/v1/projects"; static ticketsURI: string = "/api/v1/tickets"; static usersURI: string = "/api/v1/users"; diff --git a/client/src/utils/history.ts b/client/src/utils/history.ts index 6a454a1..89c46e3 100644 --- a/client/src/utils/history.ts +++ b/client/src/utils/history.ts @@ -1,2 +1,4 @@ -import { createBrowserHistory } from "history"; -export default createBrowserHistory; +import * as createHistory from "history"; +const history = createHistory.createBrowserHistory(); + +export default history; diff --git a/client/src/utils/http.ts b/client/src/utils/http.ts index 07b99b1..28acd29 100644 --- a/client/src/utils/http.ts +++ b/client/src/utils/http.ts @@ -1,4 +1,4 @@ -import { HttpResponse } from "../types/HttpResponse"; +import HttpResponse from "../types/HttpResponse"; export async function http(request: RequestInfo): Promise> { const response: HttpResponse = await fetch(request); @@ -24,7 +24,7 @@ export async function post( args: RequestInit = { method: "post", headers: headers, - body: JSON.stringify(body) + body: JSON.stringify(body), } ): Promise> { return await http(new Request(path, args)); @@ -36,7 +36,7 @@ export async function put( args: RequestInit = { method: "put", headers: headers, - body: JSON.stringify(body) + body: JSON.stringify(body), } ): Promise> { return await http(new Request(path, args)); @@ -48,7 +48,7 @@ export async function patch( args: RequestInit = { method: "patch", headers: headers, - body: JSON.stringify(body) + body: JSON.stringify(body), } ): Promise> { return await http(new Request(path, args)); @@ -58,5 +58,5 @@ const headers: Headers = new Headers({ Accept: "application/json", "Content-Type": "application/json", Authorization: - "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UWkNSRFEzUkRnd1FUQXlNRFExTmtOQ09UQXlSamhGTURaRU1Ea3pNRGxHUkRrelFqZENSZyJ9.eyJpc3MiOiJodHRwczovL2Rldi1meWpydm9oeC5hdXRoMC5jb20vIiwic3ViIjoiR3dlZTlGUnN3ejNWNE5vZFVRTjJIcjJyQjJTMDI1UmZAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjUwMDEvYXBpL1YxLyIsImlhdCI6MTU4NDE5ODQ4MCwiZXhwIjoxNTg0Mjg0ODgwLCJhenAiOiJHd2VlOUZSc3d6M1Y0Tm9kVVFOMkhyMnJCMlMwMjVSZiIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.I1D49ILGBLhnq9biIA0y6Ra93zTKRDJI_rfGvU05MtT1zkI1ZliX9P-7LyKeWBv8tPonB6gT12lJiai_GHBET8kKbXNqwfVvDJ3eqYK-TtTqfL65RfWL9tQfQybHbfuF9M0oiXMqWMqmsc5Umpp4a3bLTQgwkUEKxcdMm84L7zoaqMycns4mFojWpQJKfPa64oZFDIXYy6hPDXcX50Djuk1m-aqMhtpmqkZvPfwEjvtEtGGCTOJHV7uugn3r8Wk4HX02ShrV676GICE1Yw7eHufAbY7yvHz3ImZ1cfEVrRbbijPA2vogXd5RmqNyindDDlT1Y_C80U0DyvhS7P7apQ" + "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UWkNSRFEzUkRnd1FUQXlNRFExTmtOQ09UQXlSamhGTURaRU1Ea3pNRGxHUkRrelFqZENSZyJ9.eyJpc3MiOiJodHRwczovL2Rldi1meWpydm9oeC5hdXRoMC5jb20vIiwic3ViIjoiR3dlZTlGUnN3ejNWNE5vZFVRTjJIcjJyQjJTMDI1UmZAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjUwMDEvYXBpL1YxLyIsImlhdCI6MTU4NDE5ODQ4MCwiZXhwIjoxNTg0Mjg0ODgwLCJhenAiOiJHd2VlOUZSc3d6M1Y0Tm9kVVFOMkhyMnJCMlMwMjVSZiIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.I1D49ILGBLhnq9biIA0y6Ra93zTKRDJI_rfGvU05MtT1zkI1ZliX9P-7LyKeWBv8tPonB6gT12lJiai_GHBET8kKbXNqwfVvDJ3eqYK-TtTqfL65RfWL9tQfQybHbfuF9M0oiXMqWMqmsc5Umpp4a3bLTQgwkUEKxcdMm84L7zoaqMycns4mFojWpQJKfPa64oZFDIXYy6hPDXcX50Djuk1m-aqMhtpmqkZvPfwEjvtEtGGCTOJHV7uugn3r8Wk4HX02ShrV676GICE1Yw7eHufAbY7yvHz3ImZ1cfEVrRbbijPA2vogXd5RmqNyindDDlT1Y_C80U0DyvhS7P7apQ", }); diff --git a/client/src/utils/methods.ts b/client/src/utils/methods.ts index 8051548..32c9b12 100644 --- a/client/src/utils/methods.ts +++ b/client/src/utils/methods.ts @@ -1,7 +1,12 @@ -export const getRemainingdays: (endDate: string) => number = ( - endDate: string -) => { +const getRemainingdays: (endDate: string) => number = (endDate: string) => { let endingDate: Date = new Date(endDate); let today: Date = new Date(); return Math.abs(endingDate.getDate() - today.getDate()); }; + +export default getRemainingdays; + +/** + * get today date + */ +export const today = (): string => new Date().toISOString().split("T")[0]; diff --git a/client/src/utils/router.tsx b/client/src/utils/router.tsx deleted file mode 100644 index 1a316fe..0000000 --- a/client/src/utils/router.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from "react"; -import { Route, Switch } from "react-router-dom"; -import { HomeController } from "../controllers/HomeController"; -import { ProjectController } from "../controllers/ProjectController"; -import { UserController } from "../controllers/UserController"; -import { TicketController } from "../controllers/TicketController"; -import { NotFoundPage } from "../pages/NotFoundPage"; - -export const AppRouter = () => { - return ( - - {/* - - */} - - - - - - - - - - - - - - - - - - - - - - ); -}; diff --git a/client/tsconfig.json b/client/tsconfig.json index af10394..2ca2076 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es6", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, @@ -13,7 +13,14 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "react" + "jsx": "react", + "sourceMap": true, + "declaration": false, + "emitDecoratorMetadata": true, + "downlevelIteration": true, + "experimentalDecorators": true, + "importHelpers": true, + "typeRoots": ["node_modules/@types"] }, "include": ["src"] }