loading states

This commit is contained in:
2024-08-29 15:25:54 -06:00
parent 10afc745a9
commit 9d6a3d1199
5 changed files with 114 additions and 11 deletions

View File

@@ -1,4 +1,5 @@
using LocalModels; using LocalModels;
using Management.Services; using Management.Services;
public class CourseMarkdownLoader public class CourseMarkdownLoader
@@ -38,14 +39,23 @@ public class CourseMarkdownLoader
throw new LoadCourseFromFileException(errorMessage); throw new LoadCourseFromFileException(errorMessage);
} }
LocalCourseSettings settings = await loadCourseSettings(courseDirectory); try
var modules = await loadCourseModules(courseDirectory);
return new()
{ {
Settings = settings,
Modules = modules LocalCourseSettings settings = await loadCourseSettings(courseDirectory);
}; var modules = await loadCourseModules(courseDirectory);
return new()
{
Settings = settings,
Modules = modules
};
}
catch (Exception)
{
Console.WriteLine($"failed to load course at path: ${courseDirectory}");
throw;
}
} }
private async Task<LocalCourseSettings> loadCourseSettings(string courseDirectory) private async Task<LocalCourseSettings> loadCourseSettings(string courseDirectory)
@@ -106,7 +116,15 @@ public class CourseMarkdownLoader
.Select(async filePath => .Select(async filePath =>
{ {
var rawFile = (await File.ReadAllTextAsync(filePath)).Replace("\r\n", "\n"); var rawFile = (await File.ReadAllTextAsync(filePath)).Replace("\r\n", "\n");
return LocalAssignment.ParseMarkdown(rawFile); try
{
return LocalAssignment.ParseMarkdown(rawFile);
}
catch
{
Console.WriteLine($"error loading assignment at path {filePath}");
throw;
}
}) })
.ToArray(); .ToArray();
return await Task.WhenAll(assignmentPromises); return await Task.WhenAll(assignmentPromises);
@@ -145,8 +163,17 @@ public class CourseMarkdownLoader
var pagePromises = pageFiles var pagePromises = pageFiles
.Select(async path => .Select(async path =>
{ {
var rawPage = (await File.ReadAllTextAsync(path)).Replace("\r\n", "\n"); var rawPage = (await File.ReadAllTextAsync(path)).Replace("\r\n", "\n");
return LocalCoursePage.ParseMarkdown(rawPage); try
{
return LocalCoursePage.ParseMarkdown(rawPage);
}
catch
{
Console.WriteLine($"error loading page at path {path}");
throw;
}
}) })
.ToArray(); .ToArray();

View File

@@ -7,8 +7,8 @@ export default function CourseList() {
return ( return (
<div> <div>
{courses.map((c) => ( {courses.map((c) => (
<Link href={`/course/${c.settings.name}`} key={c.settings.name}> <Link href={`/course/${c}`} key={c}>
{c.settings.name}{" "} {c}{" "}
</Link> </Link>
))} ))}
</div> </div>

View File

@@ -0,0 +1,10 @@
import { Spinner } from "@/components/Spinner";
import React from "react";
export default function Loading() {
return (
<div>
<Spinner />
</div>
);
}

View File

@@ -0,0 +1,10 @@
import React from "react";
import "./spinner.css"
export const Spinner = () => {
return (
<div className="text-center m-3">
<span className="loader"></span>
</div>
);
};

View File

@@ -0,0 +1,56 @@
.loader {
width: 48px;
height: 48px;
border-radius: 50%;
display: inline-block;
position: relative;
border: 3px solid;
border-color: #6c757d #6c757d transparent transparent;
box-sizing: border-box;
animation: rotation 2s linear infinite;
}
.loader::after,
.loader::before {
content: '';
box-sizing: border-box;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
border: 3px solid;
border-color: transparent transparent #092565 #092565;
width: 40px;
height: 40px;
border-radius: 50%;
box-sizing: border-box;
animation: rotationBack 1s linear infinite;
transform-origin: center center;
}
/* #092565 */
/* #3a0647 */
.loader::before {
width: 32px;
height: 32px;
border-color: #6c757d #6c757d transparent transparent;
animation: rotation 3s linear infinite;
}
@keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes rotationBack {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-360deg);
}
}