Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
868 changes: 220 additions & 648 deletions CulinaryCommandApp/Components/Pages/Assignments/AdminAssignTask.razor

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.assign-task-page {
--assign-green: #009A3B;
--assign-green-dark: #007a2f;
--assign-green-soft: #2ca259;
}

.assign-task-page .page-heading {
border-left: 4px solid var(--assign-green-soft);
padding-left: 1rem;
}

.assign-task-page ::deep .card {
border-radius: 1.1rem;
border: 1px solid #e9ecef;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
}

.assign-task-page ::deep .form-control,
.assign-task-page ::deep .form-select,
.assign-task-page ::deep .input-group-text,
.assign-task-page ::deep .btn {
border-radius: 0.9rem;
}

.assign-task-page ::deep .btn-success,
.assign-task-page ::deep .btn-primary {
background-color: var(--assign-green);
border-color: var(--assign-green);
}

.assign-task-page ::deep .btn-success:hover,
.assign-task-page ::deep .btn-primary:hover,
.assign-task-page ::deep .btn-success:focus,
.assign-task-page ::deep .btn-primary:focus {
background-color: var(--assign-green-dark);
border-color: var(--assign-green-dark);
}

.assign-task-page ::deep .badge {
font-weight: 600;
border-radius: 999px;
}

.assign-task-page ::deep .bg-success,
.assign-task-page ::deep .text-bg-success {
background-color: var(--assign-green) !important;
color: #ffffff !important;
}

.assign-task-page ::deep details summary::-webkit-details-marker {
display: none;
}
117 changes: 117 additions & 0 deletions CulinaryCommandApp/Components/Pages/Assignments/ManualTaskForm.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
@using CulinaryCommand.Data.Entities
@using CulinaryCommand.Data.Enums
@using CulinaryCommandApp.Components.Pages.Assignments
@using CulinaryCommandApp.Recipe.Entities
@using Microsoft.AspNetCore.Components.Forms

<details class="card shadow-sm border-0">
<summary class="card-body d-flex justify-content-between align-items-center fw-semibold" style="cursor:pointer; list-style:none;">
<span>Create Task Manually</span>
<span class="badge bg-light text-dark border">Team: @TeamMembers.Count</span>
</summary>

<div class="card-body pt-0">
<EditForm Model="Model" OnValidSubmit="HandleSubmit">
<DataAnnotationsValidator />
<ValidationSummary />

<div class="mb-3">
<label class="form-label">Task type</label>
<InputSelect class="form-select" @bind-Value="Model.TaskType">
<option value="@WorkTaskKind.Generic">General task</option>
<option value="@WorkTaskKind.PrepFromRecipe">Prep from recipe / ingredient</option>
</InputSelect>
</div>

<div class="mb-3">
<label class="form-label">Task name</label>
<InputText class="form-control" @bind-Value="Model.Name" />
</div>

<div class="row g-3">
<div class="col-12 col-sm-6">
<label class="form-label">Station</label>
<InputSelect class="form-select" @bind-Value="Model.Station">
@foreach (var station in StationOptions)
{
<option value="@station">@station</option>
}
</InputSelect>
</div>

<div class="col-12 col-sm-6">
<label class="form-label">Priority</label>
<InputSelect class="form-select" @bind-Value="Model.Priority">
@foreach (var priority in PriorityOptions)
{
<option value="@priority">@priority</option>
}
</InputSelect>
</div>
</div>

@if (Model.TaskType == WorkTaskKind.PrepFromRecipe)
{
<div class="mb-3 mt-3">
<label class="form-label">Recipe</label>
<InputSelect class="form-select" @bind-Value="Model.RecipeId">
<option value="">Select a recipe</option>
@foreach (var recipe in Recipes)
{
<option value="@recipe.RecipeId">@recipe.Title</option>
}
</InputSelect>
</div>

<div class="row g-3">
<div class="col-6">
<label class="form-label">Par</label>
<InputNumber class="form-control" @bind-Value="Model.Par" />
</div>
<div class="col-6">
<label class="form-label">Current count</label>
<InputNumber class="form-control" @bind-Value="Model.Count" />
</div>
</div>
}

<div class="row g-3 mt-1">
<div class="col-12 col-sm-6">
<label class="form-label">Assign to</label>
<InputSelect class="form-select" @bind-Value="Model.UserId">
<option value="">Unassigned</option>
@foreach (var user in TeamMembers)
{
<option value="@user.Id">@user.Name (@user.Role)</option>
}
</InputSelect>
</div>

<div class="col-12 col-sm-6">
<label class="form-label">Due date</label>
<InputDate class="form-control" @bind-Value="Model.DueDate" />
</div>
</div>

<div class="mt-3">
<label class="form-label">Notes</label>
<InputTextArea class="form-control" rows="3" @bind-Value="Model.Notes" />
</div>

<button type="submit" class="btn btn-success w-100 mt-4">
Assign Task
</button>
</EditForm>
</div>
</details>

@code {
[Parameter] public TaskFormModel Model { get; set; } = default!;
[Parameter] public List<User> TeamMembers { get; set; } = new();
[Parameter] public List<Recipe> Recipes { get; set; } = new();
[Parameter] public List<string> StationOptions { get; set; } = new();
[Parameter] public List<string> PriorityOptions { get; set; } = new();
[Parameter] public EventCallback OnSubmit { get; set; }

private Task HandleSubmit() => OnSubmit.InvokeAsync();
}
104 changes: 104 additions & 0 deletions CulinaryCommandApp/Components/Pages/Assignments/QuickAssignPanel.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
@using CulinaryCommand.Data.Entities
@using Microsoft.AspNetCore.Components.Forms

<div class="card shadow-sm border-0">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-3">
<div>
<h5 class="fw-semibold mb-1 text-success">Quick Assign</h5>
<div class="text-muted small">
@SelectedTemplates.Count task@(SelectedTemplates.Count == 1 ? "" : "s") selected
</div>
</div>

<button class="btn btn-outline-secondary btn-sm" @onclick="HandleClear">
Clear
</button>
</div>

<div class="mb-3">
<div class="d-flex flex-wrap gap-2">
@foreach (var template in SelectedTemplates)
{
<span class="badge rounded-pill bg-light text-dark border px-3 py-2">
@template.Name
</span>
}
</div>
</div>

<div class="row g-3">
<div class="col-12 col-md-4">
<label class="form-label">Assign to</label>
<InputSelect class="form-select" @bind-Value="AssignedUserIdValue">
<option value="">Unassigned</option>
@foreach (var user in TeamMembers)
{
<option value="@user.Id">@user.Name (@user.Role)</option>
}
</InputSelect>
</div>

<div class="col-12 col-md-4">
<label class="form-label">Due date</label>
<InputDate class="form-control" @bind-Value="DueDateValue" />
</div>

<div class="col-12 col-md-4">
<label class="form-label">Priority override</label>
<InputSelect class="form-select" @bind-Value="PriorityValue">
<option value="Keep Original">Keep Original</option>
@foreach (var priority in PriorityOptions)
{
<option value="@priority">@priority</option>
}
</InputSelect>
</div>
</div>

<div class="d-flex justify-content-end gap-2 mt-4">
<button class="btn btn-light border" @onclick="HandleClear">
Cancel
</button>
<button class="btn btn-success" @onclick="HandleAssign">
Assign Selected Tasks
</button>
</div>
</div>
</div>

@code {
[Parameter] public List<TaskTemplate> SelectedTemplates { get; set; } = new();
[Parameter] public List<User> TeamMembers { get; set; } = new();
[Parameter] public List<string> PriorityOptions { get; set; } = new();
[Parameter] public int? AssignedUserId { get; set; }
[Parameter] public EventCallback<int?> AssignedUserIdChanged { get; set; }
[Parameter] public DateTime DueDate { get; set; }
[Parameter] public EventCallback<DateTime> DueDateChanged { get; set; }
[Parameter] public string Priority { get; set; } = "Keep Original";
[Parameter] public EventCallback<string> PriorityChanged { get; set; }
[Parameter] public EventCallback OnAssign { get; set; }
[Parameter] public EventCallback OnClear { get; set; }

private int? AssignedUserIdValue
{
get => AssignedUserId;
set => _ = AssignedUserIdChanged.InvokeAsync(value);
}

private DateTime DueDateValue
{
get => DueDate;
set => _ = DueDateChanged.InvokeAsync(value);
}

private string PriorityValue
{
get => Priority;
set => _ = PriorityChanged.InvokeAsync(value);
}

private Task HandleAssign() => OnAssign.InvokeAsync();

private Task HandleClear() => OnClear.InvokeAsync();
}
Loading
Loading