Files
PhotoShare/PhotoShareHelri/Components/Pages/PhotoSelector.razor
T
2026-05-16 21:29:22 +02:00

224 lines
7.0 KiB
Plaintext

@page "/PhotoSelect"
@rendermode InteractiveServer
@using BlazorBootstrap;
@using Microsoft.AspNetCore.WebUtilities
@using ModelsLib
@using PhotoShareHelri.Components.Blocs
@using System.Text
@inject NavigationManager NavManager
@inject EmailService mailService
@inject PhotoService ShootingDb
@inject IDialogService DialogService
@using MudBlazor
<MudContainer MaxWidth="MaxWidth.Large" Class="d-flex justify-center mt-6 mb-6">
<MudPaper Elevation="3" Class="pa-6 selection-wrapper">
<!-- Header -->
<MudStack Spacing="1" AlignItems="AlignItems.Center" Class="mb-4 text-center">
<MudText Typo="Typo.h4">Sélection des photos</MudText>
<MudText Typo="Typo.h6" Class="title-shoot">@Title</MudText>
</MudStack>
<!-- Action top -->
<MudStack AlignItems="AlignItems.Center" Class="mb-3">
<MudButton Variant="Variant.Outlined"
Color="Color.Dark"
Disabled="@(SelectedImages.Count == 0)"
OnClick="SendSelection">
Valider la sélection
</MudButton>
</MudStack>
<!-- Compteur -->
<MudText Typo="Typo.body1" Align="Align.Center" Class="mb-4">
@SelectedImages.Count / @MaxSelect photo(s) sélectionnée(s)
</MudText>
<!-- Galerie -->
<MudGrid Justify="Justify.Center" Spacing="3">
@for (int index = 0; index < Images.Count; index++)
{
var img = Images[index];
var isSelected = SelectedImages.Contains(img);
var buttonClass = $"select-icon-btn {(isSelected ? "selected" : "not-selected")}";
<MudItem xs="12" sm="6" md="4" lg="3" xl="2">
<MudPaper Class="image-card pa-2 position-relative" Elevation="2">
<MudImage Src="@img"
Alt="Photo sélection"
Class="gallery-thumb"
Fluid="true"
@onclick="() => OpenModalZoom(img)" />
<div @onclick:stopPropagation="true">
<MudIconButton Icon="@(isSelected? Icons.Material.Filled.Check : Icons.Material.Outlined.RadioButtonUnchecked)"
Class="@buttonClass"
Disabled="@(SelectedImages.Count >= MaxSelect && !isSelected)"
OnClick="() => ToggleImage(img)" />
</div>
</MudPaper>
</MudItem>
}
</MudGrid>
<!-- Action bottom -->
<MudStack AlignItems="AlignItems.Center" Class="mt-5">
<MudButton Variant="Variant.Outlined"
Disabled="@(SelectedImages.Count == 0)"
Color="Color.Dark"
OnClick="SendSelection">
Valider la sélection
</MudButton>
</MudStack>
</MudPaper>
</MudContainer>
<ModalDiapo IsOpen="@IsModalZoomOpen"
CurrentImage="@CurrentImage"
CurrentIndex="@CurrentIndex"
IsSelector="true"
Total="@Images.Count"
CanNext="@CanNext"
CanPrevious="@CanPrevious"
MaxSelect="@MaxSelect"
SelectedImages="@SelectedImages"
IsSelected="@(CurrentImage != null && SelectedImages.Contains(CurrentImage))"
OnClose="CloseModalZoom"
OnNext="NextModalZoom"
OnPrevious="PreviousModalZoom"
Toggle="() => ToggleImage(CurrentImage!)" />
@code {
#region Variables
HashSet<string> SelectedImages = new();
private int MaxSelect = 1;
// Liste des images disponibles
private List<string> Images = new();
public string Title { get; set; }
bool IsModalZoomOpen = false;
string? CurrentImage;
int CurrentIndex =>
CurrentImage == null ? -1 : Images.IndexOf(CurrentImage);
bool CanNext => CurrentIndex >= 0 && CurrentIndex < Images.Count - 1;
bool CanPrevious => CurrentIndex > 0;
private string ShootingId;
private ShootingData Datas { get; set; }
#endregion
#region modal zoom
/// <summary>
/// Ouverture de la modal à partir du clic sur image voulu
/// </summary>
void OpenModalZoom(string img)
{
CurrentImage = img;
IsModalZoomOpen = true;
}
///<summary>
/// fermeture de la modal
/// </summary>
void CloseModalZoom()
{
IsModalZoomOpen = false;
}
/// <summary>
/// photo suivante dans la modal
/// dans la liste des photos affichés
/// </summary>
void NextModalZoom()
{
if (CanNext)
CurrentImage = Images[CurrentIndex + 1];
}
/// <summary>
/// photo précédente
/// </summary>
void PreviousModalZoom()
{
if (CanPrevious)
CurrentImage = Images[CurrentIndex - 1];
}
#endregion
/// <summary>
/// arrivé sur la page
/// </summary>
protected override async Task OnInitializedAsync()
{
//récupération de l'identifiant de shooting, si identifiant null ou si recherche inexistante redirection vers la page de recherche de shooting
var uri = NavManager.ToAbsoluteUri(NavManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("Id", out var id))
{
Datas = ShootingDb.GetInfosShooting(id);
if (!string.IsNullOrEmpty(id))
{
ShootingId = id;
Images = ShootingDb.LireContenu(ShootingId);
}
Title = "Résultat du shooting " + Datas.Key;
}
}
/// <summary>
/// Séléction de l'image dans la liste des photos choisies
/// </summary>
/// <param name="img">image sélectionné par son hash</param>
private void ToggleImage(string img)
{
if (SelectedImages.Contains(img))
{
SelectedImages.Remove(img);
}
else
{
SelectedImages.Add(img);
}
}
/// <summary>
/// envoi par mail de la sélection des photos
/// </summary>
private async void SendSelection()
{
if (SelectedImages == null || SelectedImages.Count == 0)
return;
var fichiers = string.Join(";", SelectedImages)
.Split(';', StringSplitOptions.RemoveEmptyEntries)
.Select(Path.GetFileName)
.ToList();
var body = new StringBuilder();
body.Append("<h3>Photos sélectionnées 📸</h3>");
body.Append("<ul>");
foreach (var fichier in fichiers)
{
body.Append($"<li>{fichier}</li>");
}
body.Append("</ul>");
mailService.EnvoyerMailAsync("Confirmation sélection du shooting" + ShootingId, body).GetAwaiter();
Datas.IsPhotosSelected = true;
await ShootingDb.UpdateShootingInfo(Datas);
}
}