mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-12 11:46:40 +00:00
pull latest backend
This commit is contained in:
commit
b12a61bb21
24 changed files with 59 additions and 53 deletions
|
|
@ -8,12 +8,12 @@ using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using TicketManager.Data;
|
using TicketManager.Data;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
using TicketManager.DTO;
|
using TicketManager.Resources;
|
||||||
|
|
||||||
|
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
// [Authorize]
|
[Authorize]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
[Route("api/v1/users")]
|
[Route("api/v1/users")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@ using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using TicketManager.Data;
|
using TicketManager.Data;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
using TicketManager.DTO;
|
using TicketManager.Resources;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
// [Authorize(Roles = "Admin")]
|
// [Authorize(Roles = "Admin")]
|
||||||
// [Authorize]
|
[Authorize]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
[Route("api/v1/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
|
@ -180,6 +180,9 @@ namespace TicketManager.Controllers
|
||||||
EndingDate = projectDto.EndingDate,
|
EndingDate = projectDto.EndingDate,
|
||||||
Manager = await _context.AppUsers.FindAsync(projectDto.ManagerId)
|
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.Projects.Add(project);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@ using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using TicketManager.Data;
|
using TicketManager.Data;
|
||||||
using TicketManager.DTO;
|
using TicketManager.Resources;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
// [Authorize]
|
[Authorize]
|
||||||
[Route("api/v1/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class TicketsController : ControllerBase
|
public class TicketsController : ControllerBase
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace TicketManager.Models
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public DateTime UpdateDate { get; private set; } = DateTime.Now;
|
public DateTime UpdateDate { get; private set; } = DateTime.Now;
|
||||||
public ActivityType ActivityType { get; set; } = ActivityType.Undefined;
|
public ActivityType ActivityType { get; set; } = ActivityType.Undefined;
|
||||||
public AppUser User { get; set; }
|
// public Guid UserId { get; set; }
|
||||||
public int UserId { get; set; }
|
public int TaskId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace TicketManager.Models
|
namespace TicketManager.Models
|
||||||
{
|
{
|
||||||
|
|
@ -39,6 +40,7 @@ namespace TicketManager.Models
|
||||||
[Display(Name = "Avatar")]
|
[Display(Name = "Avatar")]
|
||||||
public string Picture { get; set; }
|
public string Picture { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public List<Assignment> Assignments { get; set; } = new List<Assignment>();
|
public List<Assignment> Assignments { get; set; } = new List<Assignment>();
|
||||||
|
|
||||||
[Display(Name = "Activity")]
|
[Display(Name = "Activity")]
|
||||||
|
|
|
||||||
|
|
@ -3,25 +3,13 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace TicketManager.Models
|
namespace TicketManager.Models
|
||||||
{
|
{
|
||||||
// public interface ITask
|
public interface ITask
|
||||||
public abstract class ITask
|
|
||||||
{
|
{
|
||||||
int Id { get; set; }
|
int Id { get; set; }
|
||||||
string Title { get; set; }
|
string Title { get; set; }
|
||||||
string Description { get; set; }
|
string Description { get; set; }
|
||||||
DateTime CreationDate { get; }
|
DateTime CreationDate { get; }
|
||||||
DateTime PlannedEnding { get; set; }
|
DateTime EndingDate { get; set; }
|
||||||
List<Activity> Activities { get; set; }
|
List<Activity> Activities { get; set; }
|
||||||
|
|
||||||
public virtual void AddLogEntry(string description)//, User user)
|
|
||||||
{
|
|
||||||
Activity Activity = new Activity()
|
|
||||||
{
|
|
||||||
Description = description,
|
|
||||||
ActivityType = ActivityType.Undefined,
|
|
||||||
// User = user,
|
|
||||||
};
|
|
||||||
Activities.Add(Activity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using TicketManager.DTO;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace TicketManager.Models
|
namespace TicketManager.Models
|
||||||
{
|
{
|
||||||
|
|
@ -20,11 +20,13 @@ namespace TicketManager.Models
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
[DataType(DataType.Date)]
|
[DataType(DataType.Date)]
|
||||||
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = false)]
|
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
|
||||||
|
ApplyFormatInEditMode = false)]
|
||||||
public DateTime CreationDate { get; private set; } = DateTime.Now;
|
public DateTime CreationDate { get; private set; } = DateTime.Now;
|
||||||
|
|
||||||
[DataType(DataType.Date)]
|
[DataType(DataType.Date)]
|
||||||
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
|
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
|
||||||
|
ApplyFormatInEditMode = true)]
|
||||||
public DateTime EndingDate { get; set; }
|
public DateTime EndingDate { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Progress")]
|
[Display(Name = "Progress")]
|
||||||
|
|
@ -45,6 +47,7 @@ namespace TicketManager.Models
|
||||||
[Display(Name = "Project Manager")]
|
[Display(Name = "Project Manager")]
|
||||||
public AppUser Manager { get; set; }
|
public AppUser Manager { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public List<Assignment> Assignments { get; set; } = new List<Assignment>();
|
public List<Assignment> Assignments { get; set; } = new List<Assignment>();
|
||||||
|
|
||||||
public List<Ticket> Tickets { get; set; } = new List<Ticket>();
|
public List<Ticket> Tickets { get; set; } = new List<Ticket>();
|
||||||
|
|
@ -109,5 +112,17 @@ namespace TicketManager.Models
|
||||||
{
|
{
|
||||||
this.Status = Status.Done;
|
this.Status = Status.Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LogAction(string description, ActivityType type = ActivityType.Undefined)//, Guid userId)
|
||||||
|
{
|
||||||
|
Activity Activity = new Activity()
|
||||||
|
{
|
||||||
|
Description = description,
|
||||||
|
ActivityType = type,
|
||||||
|
TaskId = this.Id,
|
||||||
|
// UserId = userId
|
||||||
|
};
|
||||||
|
Activities.Add(Activity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
- `React` client on the front-end (TypeScript)
|
- `React` client on the front-end (TypeScript)
|
||||||
- [Materialize](https://materializecss.com) CSS librairy for styling
|
- [Materialize](https://materializecss.com) CSS librairy for styling
|
||||||
- API: Newtonsoft.Json, to avoid cycle errors
|
|
||||||
- Hosting: ?
|
- Hosting: ?
|
||||||
- Authentication : [Auth0](https://auth0.com/)
|
- Authentication : [Auth0](https://auth0.com/)
|
||||||
- Analytics : Google Analytics & Mixpanel
|
- Analytics : Google Analytics & Mixpanel
|
||||||
|
|
@ -48,6 +47,6 @@
|
||||||
- [ ] error page redirect when offline.
|
- [ ] error page redirect when offline.
|
||||||
- [x] ticket/files/activities list placeholders when empty
|
- [x] ticket/files/activities list placeholders when empty
|
||||||
- [ ] think about public/private DTO's constructor, getters and setters
|
- [ ] think about public/private DTO's constructor, getters and setters
|
||||||
- [x] write dtos without circular dependencies
|
- [<span style="color:red">X</span>] write dtos without circular dependencies.
|
||||||
- [ ] use dtoRequest for PutProjects
|
- [ ] use dtoRequest for PutProjects
|
||||||
- [ ] render avatarlist after UserModal Update
|
- [ ] render avatarlist after UserModal Update
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class AppUserDTO
|
public class AppUserDTO
|
||||||
{
|
{
|
||||||
|
|
@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class AppUserDTORead
|
public class AppUserDTORead
|
||||||
{
|
{
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class NewAppUserDTO
|
public class NewAppUserDTO
|
||||||
{
|
{
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class NewProjectDTO
|
public class NewProjectDTO
|
||||||
{
|
{
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class ProjectDTO
|
public class ProjectDTO
|
||||||
{
|
{
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class ProjectDTORequest
|
public class ProjectDTORequest
|
||||||
{
|
{
|
||||||
|
|
@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class NewTicketDTO
|
public class NewTicketDTO
|
||||||
{
|
{
|
||||||
|
|
@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class TicketDTO
|
public class TicketDTO
|
||||||
{
|
{
|
||||||
|
|
@ -20,7 +20,7 @@ namespace TicketManager.DTO
|
||||||
Difficulty = ticket.Difficulty.ToString();
|
Difficulty = ticket.Difficulty.ToString();
|
||||||
Category = ticket.Category.ToString();
|
Category = ticket.Category.ToString();
|
||||||
CreatorId = ticket.CreatorId;
|
CreatorId = ticket.CreatorId;
|
||||||
Project = new ProjectDTORequest(ticket.Project);
|
Project = ticket.Project != null ? new ProjectDTORequest(ticket.Project) : null;
|
||||||
Notes = ticket.Notes;
|
Notes = ticket.Notes;
|
||||||
Activities = ticket.Activities;
|
Activities = ticket.Activities;
|
||||||
Files = ticket.Files;
|
Files = ticket.Files;
|
||||||
|
|
@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.DTO
|
namespace TicketManager.Resources
|
||||||
{
|
{
|
||||||
public class TicketDTORead
|
public class TicketDTORead
|
||||||
{
|
{
|
||||||
|
|
@ -12,9 +12,7 @@ using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
|
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
|
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using TicketManager.Data;
|
using TicketManager.Data;
|
||||||
|
|
||||||
[assembly: ApiController]
|
[assembly: ApiController]
|
||||||
|
|
@ -48,12 +46,7 @@ namespace TicketManager
|
||||||
options.Audience = "https://localhost:5001/api/V1/";
|
options.Audience = "https://localhost:5001/api/V1/";
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddControllers()
|
services.AddControllers();
|
||||||
.AddNewtonsoftJson(options =>
|
|
||||||
{
|
|
||||||
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // avoid cycle ref errors
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
services.AddSpaStaticFiles(configuration =>
|
services.AddSpaStaticFiles(configuration =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ using Microsoft.Data.Sqlite;
|
||||||
using TicketManager.Controllers;
|
using TicketManager.Controllers;
|
||||||
using TicketManager.Data;
|
using TicketManager.Data;
|
||||||
using TicketManager.Models;
|
using TicketManager.Models;
|
||||||
using TicketManager.DTO;
|
using TicketManager.Resources;
|
||||||
|
|
||||||
|
|
||||||
namespace TicketManager.Tests
|
namespace TicketManager.Tests
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useState, ChangeEvent, useEffect, FormEvent } from "react";
|
import React, { FC, useState, ChangeEvent, FormEvent, useEffect } from "react";
|
||||||
import { Modal } from "./Modal";
|
import { Modal } from "./Modal";
|
||||||
import { AvatarList } from "./AvatarList";
|
import { AvatarList } from "./AvatarList";
|
||||||
import { User } from "../types/User";
|
import { User } from "../types/User";
|
||||||
|
|
@ -10,9 +10,9 @@ import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
handleClose: () => void;
|
|
||||||
users: User[];
|
users: User[];
|
||||||
allUsers: User[];
|
allUsers: User[];
|
||||||
|
handleClose(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UsersModal: FC<IProps> = ({
|
export const UsersModal: FC<IProps> = ({
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React, { FC } from "react";
|
||||||
import { Redirect } from "react-router-dom";
|
import { Redirect } from "react-router-dom";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
error: any;
|
error: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ErrorController: FC<IProps> = ({ error }) => {
|
export const ErrorController: FC<IProps> = ({ error }) => {
|
||||||
|
|
@ -10,6 +10,9 @@ export const ErrorController: FC<IProps> = ({ error }) => {
|
||||||
case "Bad Request":
|
case "Bad Request":
|
||||||
return <Redirect to="/400" />;
|
return <Redirect to="/400" />;
|
||||||
|
|
||||||
|
case "Unauthorized":
|
||||||
|
return <Redirect to="/401" />;
|
||||||
|
|
||||||
case "Not Found":
|
case "Not Found":
|
||||||
return <Redirect to="/404" />;
|
return <Redirect to="/404" />;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export const ProjectController: FC = () => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
|
console.error(ex);
|
||||||
setHasError(true);
|
setHasError(true);
|
||||||
setError(ex);
|
setError(ex);
|
||||||
}
|
}
|
||||||
|
|
@ -42,8 +43,8 @@ export const ProjectController: FC = () => {
|
||||||
setAllUsers((response.parsedBody as unknown) as User[]);
|
setAllUsers((response.parsedBody as unknown) as User[]);
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
// setHasError(true);
|
setHasError(true);
|
||||||
// setError(ex);
|
setError(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,5 +56,7 @@ export async function patch<T>(
|
||||||
|
|
||||||
const headers: Headers = new Headers({
|
const headers: Headers = new Headers({
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json",
|
||||||
|
Authorization:
|
||||||
|
"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UWkNSRFEzUkRnd1FUQXlNRFExTmtOQ09UQXlSamhGTURaRU1Ea3pNRGxHUkRrelFqZENSZyJ9.eyJpc3MiOiJodHRwczovL2Rldi1meWpydm9oeC5hdXRoMC5jb20vIiwic3ViIjoiR3dlZTlGUnN3ejNWNE5vZFVRTjJIcjJyQjJTMDI1UmZAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjUwMDEvYXBpL1YxLyIsImlhdCI6MTU4Mjk3MTQyMSwiZXhwIjoxNTgzMDU3ODIxLCJhenAiOiJHd2VlOUZSc3d6M1Y0Tm9kVVFOMkhyMnJCMlMwMjVSZiIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.mH_ejE0gpMXrMIVUV7afuagTopCxm2x7F7Ash9L7zfOCQnw71E7NPsEh8w2_nFFz3lwm988vGbJhB_1G0oetK3VnqgahHn-ZJfk8RhQeKZQtCddbFCXSZzbsvi8XekpN2qLSZswrfxM4hiNfedQW1sM6wSbVbv4q6MrpPrtnepOo5lu67b9eHQZA5MQGqCLqqAZtEAa4Z8bVUCUcf3wU4e9W38LngrMSEMN62_ZZ8AVnjFVQ97zWEadJhYT54S9tVioY8jNR-38qjuYH_ZP3mVQg8INza9YFiYzIsIgdYufhorb_cSXc1qK1ZhHf4kRHaiHCYan-c9nN9SM9MCYA9A"
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export const AppRouter = () => {
|
||||||
<TicketController />
|
<TicketController />
|
||||||
</Route> */}
|
</Route> */}
|
||||||
|
|
||||||
<Route path="/404">
|
<Route path="/401">
|
||||||
<NotFoundPage />
|
<NotFoundPage />
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue