Compare commits
33 Commits
16-refacto
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f9ba88b24 | |||
| 9df3938d94 | |||
| 3eb7072866 | |||
| a5f54f485c | |||
| de254806b6 | |||
| 7eca4cdcac | |||
| 76ef88e811 | |||
| 42ea93ff6a | |||
| ee7a15efc2 | |||
| 0ec110f45e | |||
| 03e1778e63 | |||
| ccba80f54e | |||
| 97c83f69eb | |||
| f6029fd89f | |||
| a256ef99c0 | |||
| 39a748ff0e | |||
| 81a01ae4ed | |||
| 4e30f3e7a5 | |||
| 28a1d07e98 | |||
| 222f90df02 | |||
| aae4b28089 | |||
| fa87a56ad1 | |||
| 5b4ee67c23 | |||
| 07f5663c75 | |||
| 6ab5b9f1df | |||
| a55eff43fb | |||
| 99eb10f61d | |||
| f00595187f | |||
| 8c0ad9bc3e | |||
|
|
b4056fa715 | ||
|
|
b832cd7ecf | ||
|
|
09ff31ac82 | ||
|
|
cd49f68db1 |
33
.drone.yml
Normal file
33
.drone.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: "Backend"
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
image: mcr.microsoft.com/dotnet/sdk:8.0
|
||||
commands:
|
||||
- dotnet build
|
||||
- dotnet test
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker
|
||||
settings:
|
||||
username: prtsie
|
||||
password:
|
||||
from_secret: docker_pass
|
||||
registry: git.prtsie.ru
|
||||
repo: git.prtsie.ru/prtsie/schengen-visa-${DRONE_BRANCH}
|
||||
tags:
|
||||
- latest
|
||||
|
||||
- name: deploy
|
||||
image: appleboy/drone-ssh
|
||||
settings:
|
||||
script_stop: true
|
||||
host: prtsie.ru:1337
|
||||
username: deploy
|
||||
key:
|
||||
from_secret: ssh_key
|
||||
script:
|
||||
- cd /deploy
|
||||
- ./deploy.sh ${DRONE_BRANCH}
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -33,3 +33,5 @@ _UpgradeReport_Files/
|
||||
Thumbs.db
|
||||
Desktop.ini
|
||||
.DS_Store
|
||||
|
||||
.env
|
||||
|
||||
@@ -6,7 +6,7 @@ public static class Constants
|
||||
{
|
||||
public readonly static Regex EnglishWordRegex = new("^[a-zA-Z']*$");
|
||||
|
||||
public readonly static Regex EnglishPhraseRegex = new(@"^[a-zA-Z №0-9;,\-_+=#*']*$");
|
||||
public readonly static Regex EnglishPhraseRegex = new("""^[a-zA-Z №0-9;,\-_+=#*'\"]*$""");
|
||||
|
||||
public readonly static Regex PhoneNumRegex = new(@"^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$");
|
||||
}
|
||||
@@ -35,7 +35,7 @@ public class VisaApplicationRequestsHandler(
|
||||
return mapper.Map<List<VisaApplicationPreview>>(visaApplications);
|
||||
}
|
||||
|
||||
/// <summary> <inheritdoc cref="IVisaApplicationRequestsHandler.GetApplicationForApplicantAsync"/> </summary>
|
||||
/// <inheritdoc cref="IVisaApplicationRequestsHandler.GetApplicationForApplicantAsync"/>
|
||||
public async Task<VisaApplicationModel> GetApplicationForApplicantAsync(Guid id, CancellationToken cancellationToken)
|
||||
{
|
||||
var applicant = await applicants.FindByUserIdAsync(userIdProvider.GetUserId(), cancellationToken);
|
||||
@@ -1,5 +1,4 @@
|
||||
@using BlazorWebAssemblyVisaApiClient.ErrorHandling
|
||||
|
||||
<GlobalErrorHandler >
|
||||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
@@ -2,7 +2,6 @@
|
||||
@using BlazorWebAssemblyVisaApiClient.ErrorHandling
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider
|
||||
@using VisaApiClient
|
||||
|
||||
@code {
|
||||
public static AuthData? AuthData;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
@using BlazorWebAssemblyVisaApiClient.ErrorHandling
|
||||
@using VisaApiClient
|
||||
|
||||
@code
|
||||
{
|
||||
[CascadingParameter] protected GlobalErrorHandler ErrorHandler { get; set; } = null!;
|
||||
@@ -1,5 +1,4 @@
|
||||
@using VisaApiClient
|
||||
|
||||
<div>
|
||||
<div >
|
||||
<label >
|
||||
@@ -1,5 +1,4 @@
|
||||
@using VisaApiClient
|
||||
|
||||
<div>
|
||||
<div >
|
||||
<label >
|
||||
@@ -1,5 +1,4 @@
|
||||
@using VisaApiClient
|
||||
|
||||
<div>
|
||||
<div >
|
||||
<label>
|
||||
@@ -1,6 +1,5 @@
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
|
||||
@using VisaApiClient
|
||||
|
||||
<div>
|
||||
<div >
|
||||
<label>
|
||||
@@ -1,7 +1,7 @@
|
||||
@using System.Linq.Expressions
|
||||
@typeparam TItem where TItem : class
|
||||
@using System.Linq.Expressions
|
||||
@using System.Reflection
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers
|
||||
@typeparam TItem where TItem : class
|
||||
@typeparam TMember where TMember : struct, Enum
|
||||
|
||||
<InputSelect TValue="TMember" @bind-Value="selected">
|
||||
@@ -1,6 +1,5 @@
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
|
||||
@using VisaApiClient
|
||||
|
||||
<div>
|
||||
<label>
|
||||
Issuer:<br/>
|
||||
@@ -1,6 +1,5 @@
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
|
||||
@using VisaApiClient
|
||||
|
||||
<div>
|
||||
<label>
|
||||
Number:<br/>
|
||||
@@ -1,7 +1,6 @@
|
||||
@using System.Net
|
||||
@using BlazorWebAssemblyVisaApiClient.Common.Exceptions
|
||||
@using VisaApiClient
|
||||
|
||||
<CascadingValue Value="this">
|
||||
<Modal @ref="modal">
|
||||
<BodyTemplate>
|
||||
@@ -1,17 +1,17 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers;
|
||||
|
||||
public static class EnumExtensions
|
||||
{
|
||||
public static string GetDisplayName(this Enum value)
|
||||
{
|
||||
var enumMembers = value.GetType().GetMembers();
|
||||
var member = enumMembers.First(info => info.Name == value.ToString());
|
||||
var displayAttribute = (DisplayAttribute?)member
|
||||
.GetCustomAttributes(typeof(DisplayAttribute), false)
|
||||
.FirstOrDefault();
|
||||
var displayName = displayAttribute?.Name ?? value.ToString();
|
||||
return displayName;
|
||||
}
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers;
|
||||
|
||||
public static class EnumExtensions
|
||||
{
|
||||
public static string GetDisplayName(this Enum value)
|
||||
{
|
||||
var enumMembers = value.GetType().GetMembers();
|
||||
var member = enumMembers.First(info => info.Name == value.ToString());
|
||||
var displayAttribute = (DisplayAttribute?)member
|
||||
.GetCustomAttributes(typeof(DisplayAttribute), false)
|
||||
.FirstOrDefault();
|
||||
var displayName = displayAttribute?.Name ?? value.ToString();
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
@page "/authorities/add"
|
||||
@using AutoMapper
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models
|
||||
@using VisaApiClient
|
||||
@using BlazorWebAssemblyVisaApiClient.Components
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models
|
||||
@using FluentValidation
|
||||
@using VisaApiClient
|
||||
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
|
||||
|
||||
<EditForm Model="requestModel" class="with-centered-content">
|
||||
@@ -1,143 +1,143 @@
|
||||
@page "/applications"
|
||||
@using BlazorWebAssemblyVisaApiClient.Common.Exceptions
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models
|
||||
@using VisaApiClient
|
||||
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
|
||||
|
||||
<PageTitle>Applications</PageTitle>
|
||||
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Destination Country</th>
|
||||
<th>Visa Category</th>
|
||||
<th>Request date</th>
|
||||
<th>Days requested</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach (var application in applications)
|
||||
{
|
||||
var rowClass = application.Status switch
|
||||
{
|
||||
ApplicationStatus.Pending => "",
|
||||
ApplicationStatus.Approved => "table-success",
|
||||
ApplicationStatus.Rejected => "table-danger",
|
||||
ApplicationStatus.Closed => "table-danger",
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
<tr class="@rowClass">
|
||||
<td>@application.DestinationCountry</td>
|
||||
<td>@(((VisaCategoryModel)application.VisaCategory).GetDisplayName())</td>
|
||||
<td>@application.RequestDate.ToString("d")</td>
|
||||
<td>@application.ValidDaysRequested</td>
|
||||
<td>@application.Status.GetDisplayName()</td>
|
||||
<td>
|
||||
<NavLink href="@($"/applications/{application.Id}")">
|
||||
<button class="btn-primary">See</button>
|
||||
</NavLink>
|
||||
@if (currentRole == Constants.ApplicantRole)
|
||||
{
|
||||
<span> | </span>
|
||||
<input type="button" class="btn-outline-primary" @onclick="() => DownloadApplication(application)" value="Download"/>
|
||||
if (application.Status is ApplicationStatus.Pending)
|
||||
{
|
||||
<span> | </span>
|
||||
<input type="button" class="border-danger" @onclick="() => CloseApplication(application)" value="Close"/>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table >
|
||||
|
||||
<script>
|
||||
window.downloadFileFromStream = async (contentStreamReference) => {
|
||||
const arrayBuffer = await contentStreamReference.arrayBuffer();
|
||||
const blob = new Blob([arrayBuffer]);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchorElement = document.createElement('a');
|
||||
anchorElement.href = url;
|
||||
anchorElement.download = 'Application.xlsx';
|
||||
anchorElement.click();
|
||||
anchorElement.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
</script>
|
||||
|
||||
@code {
|
||||
private string currentRole = null!;
|
||||
private List<VisaApplicationPreview> applications = [];
|
||||
|
||||
[Inject] private IUserDataProvider UserDataProvider { get; set; } = null!;
|
||||
|
||||
[Inject] private IJSRuntime JavaScriptInterop { get; set; } = null!;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
currentRole = UserDataProvider.CurrentRole ?? throw new NotLoggedInException();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
|
||||
await Fetch();
|
||||
}
|
||||
|
||||
private async Task Fetch()
|
||||
{
|
||||
try
|
||||
{
|
||||
applications = currentRole switch
|
||||
{
|
||||
Constants.ApplicantRole => (await Client.GetApplicationsForApplicantAsync()).OrderByDescending(a => a.RequestDate).ToList(),
|
||||
Constants.ApprovingAuthorityRole => (await Client.GetPendingAsync()).OrderByDescending(a => a.RequestDate).ToList(),
|
||||
_ => throw new NotLoggedInException()
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CloseApplication(VisaApplicationPreview application)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Client.CloseApplicationAsync(application.Id);
|
||||
application.Status = ApplicationStatus.Closed;
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DownloadApplication(VisaApplicationPreview application)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await Client.DownloadApplicationForApplicantAsync(application.Id);
|
||||
using var streamRef = new DotNetStreamReference(stream: response.Stream);
|
||||
|
||||
await JavaScriptInterop.InvokeVoidAsync("downloadFileFromStream", streamRef);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@page "/applications"
|
||||
@using BlazorWebAssemblyVisaApiClient.Common.Exceptions
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models
|
||||
@using VisaApiClient
|
||||
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
|
||||
|
||||
<PageTitle>Applications</PageTitle>
|
||||
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Destination Country</th>
|
||||
<th>Visa Category</th>
|
||||
<th>Request date</th>
|
||||
<th>Days requested</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach (var application in applications)
|
||||
{
|
||||
var rowClass = application.Status switch
|
||||
{
|
||||
ApplicationStatus.Pending => "",
|
||||
ApplicationStatus.Approved => "table-success",
|
||||
ApplicationStatus.Rejected => "table-danger",
|
||||
ApplicationStatus.Closed => "table-danger",
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
<tr class="@rowClass">
|
||||
<td>@application.DestinationCountry</td>
|
||||
<td>@(((VisaCategoryModel)application.VisaCategory).GetDisplayName())</td>
|
||||
<td>@application.RequestDate.ToString("d")</td>
|
||||
<td>@application.ValidDaysRequested</td>
|
||||
<td>@application.Status.GetDisplayName()</td>
|
||||
<td>
|
||||
<NavLink href="@($"/applications/{application.Id}")">
|
||||
<button class="btn-primary">See</button>
|
||||
</NavLink>
|
||||
@if (currentRole == Constants.ApplicantRole)
|
||||
{
|
||||
<span> | </span>
|
||||
<input type="button" class="btn-outline-primary" @onclick="() => DownloadApplication(application)" value="Download"/>
|
||||
if (application.Status is ApplicationStatus.Pending)
|
||||
{
|
||||
<span> | </span>
|
||||
<input type="button" class="border-danger" @onclick="() => CloseApplication(application)" value="Close"/>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table >
|
||||
|
||||
<script>
|
||||
window.downloadFileFromStream = async (contentStreamReference) => {
|
||||
const arrayBuffer = await contentStreamReference.arrayBuffer();
|
||||
const blob = new Blob([arrayBuffer]);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchorElement = document.createElement('a');
|
||||
anchorElement.href = url;
|
||||
anchorElement.download = 'Application.xlsx';
|
||||
anchorElement.click();
|
||||
anchorElement.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
</script>
|
||||
|
||||
@code {
|
||||
private string currentRole = null!;
|
||||
private List<VisaApplicationPreview> applications = [];
|
||||
|
||||
[Inject] private IUserDataProvider UserDataProvider { get; set; } = null!;
|
||||
|
||||
[Inject] private IJSRuntime JavaScriptInterop { get; set; } = null!;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
currentRole = UserDataProvider.CurrentRole ?? throw new NotLoggedInException();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
|
||||
await Fetch();
|
||||
}
|
||||
|
||||
private async Task Fetch()
|
||||
{
|
||||
try
|
||||
{
|
||||
applications = currentRole switch
|
||||
{
|
||||
Constants.ApplicantRole => (await Client.GetApplicationsForApplicantAsync()).OrderByDescending(a => a.RequestDate).ToList(),
|
||||
Constants.ApprovingAuthorityRole => (await Client.GetPendingAsync()).OrderByDescending(a => a.RequestDate).ToList(),
|
||||
_ => throw new NotLoggedInException()
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CloseApplication(VisaApplicationPreview application)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Client.CloseApplicationAsync(application.Id);
|
||||
application.Status = ApplicationStatus.Closed;
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DownloadApplication(VisaApplicationPreview application)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await Client.DownloadApplicationForApplicantAsync(application.Id);
|
||||
using var streamRef = new DotNetStreamReference(stream: response.Stream);
|
||||
|
||||
await JavaScriptInterop.InvokeVoidAsync("downloadFileFromStream", streamRef);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
@page "/"
|
||||
@using BlazorWebAssemblyVisaApiClient.Components.Auth
|
||||
@using VisaApiClient
|
||||
@using BlazorWebAssemblyVisaApiClient.Components.FormComponents.Applicants
|
||||
@using BlazorWebAssemblyVisaApiClient.Components
|
||||
@using BlazorWebAssemblyVisaApiClient.Components.Auth
|
||||
@using BlazorWebAssemblyVisaApiClient.Components.FormComponents.Applicants
|
||||
@using VisaApiClient
|
||||
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
|
||||
|
||||
<PageTitle>Authentication</PageTitle>
|
||||
@@ -1,11 +1,11 @@
|
||||
@page "/authorities/{authorityId}/{oldEmail}"
|
||||
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
|
||||
@using BlazorWebAssemblyVisaApiClient.Common.Exceptions
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider
|
||||
@using VisaApiClient
|
||||
@using BlazorWebAssemblyVisaApiClient.Components
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider
|
||||
@using FluentValidation
|
||||
@using VisaApiClient
|
||||
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
|
||||
|
||||
<EditForm Model="model" class="with-centered-content">
|
||||
<div >
|
||||
@@ -1,17 +1,17 @@
|
||||
@page "/applications/new"
|
||||
@using System.Net
|
||||
@using AutoMapper
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models
|
||||
@using VisaApiClient
|
||||
@using BlazorWebAssemblyVisaApiClient.Components
|
||||
@using BlazorWebAssemblyVisaApiClient.Components.FormComponents
|
||||
@using BlazorWebAssemblyVisaApiClient.Components.FormComponents.VisaApplications
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models
|
||||
@using FluentValidation
|
||||
@using Newtonsoft.Json.Linq
|
||||
@using BlazorWebAssemblyVisaApiClient.Components.FormComponents
|
||||
@using VisaApiClient
|
||||
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
|
||||
|
||||
<PageTitle>New Application</PageTitle>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user