Files
chapter-organizer/WebApp/Components/Features/Students/Components/StudentNotePanel.razor
T
poprhythmandCursor 4cfd85b902 feat: import leftover student fields into notes and show them on the roster
Store leftover CSV columns on hidden student notes, move catalog import to /events/import, and persist Students index columns from Chapter Settings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-29 23:55:03 -04:00

105 lines
2.8 KiB
Plaintext

@using Core.Services
@using PSC.Blazor.Components.MarkdownEditor
@inject INotesService NotesService
@inject INoteNamingService NoteNamingService
@inject MarkdownTablePasteService MarkdownTablePasteService
@inject ISnackbar Snackbar
<MudText Typo="Typo.h5" Class="mb-4">Notes</MudText>
@if (_isLoading)
{
<MudProgressLinear Indeterminate="true" />
}
else if (ReadOnly)
{
@if (string.IsNullOrWhiteSpace(_content))
{
<MudText Class="mud-text-secondary">No notes yet.</MudText>
}
else
{
@((MarkupString)MarkdownHelper.ToHtml(_content))
}
}
else
{
<MudText Typo="Typo.caption" Class="mud-text-secondary mb-2">Markdown is supported. Imported fields appear in a table and can be edited.</MudText>
<MarkdownEditor Value="@_content"
ValueChanged="@((string? value) => _content = value ?? string.Empty)"
Placeholder="Student notes..."
AutoSaveEnabled="false"
NativeSpellChecker="false" />
}
@code {
[Parameter]
public int StudentId { get; set; }
[Parameter]
public bool ReadOnly { get; set; }
private string _content = string.Empty;
private int? _noteId;
private int _loadedStudentId;
private bool _isLoading = true;
private bool _pasteInitialized;
protected override async Task OnParametersSetAsync()
{
if (StudentId <= 0 || _loadedStudentId == StudentId)
return;
_isLoading = true;
try
{
var note = await NotesService.GetStudentNoteAsync(StudentId);
_noteId = note?.Id;
_content = note?.Content ?? string.Empty;
_loadedStudentId = StudentId;
}
finally
{
_isLoading = false;
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (ReadOnly || _pasteInitialized)
return;
await Task.Delay(150);
await MarkdownTablePasteService.InitializeAsync();
_pasteInitialized = true;
}
public async Task SaveAsync()
{
if (StudentId <= 0)
return;
if (_noteId is null)
{
if (string.IsNullOrWhiteSpace(_content))
return;
var created = await NotesService.CreateNoteAsync(new Note
{
Title = NoteNamingService.GetStudentNoteTitle(StudentId),
Content = _content
});
_noteId = created.Id;
return;
}
var existing = await NotesService.GetNoteAsync(_noteId.Value);
if (existing is null)
return;
if (string.Equals(existing.Content ?? string.Empty, _content, StringComparison.Ordinal))
return;
existing.Content = _content;
await NotesService.UpdateNoteAsync(existing);
}
}