mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
loading states
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using LocalModels;
|
using LocalModels;
|
||||||
|
|
||||||
using Management.Services;
|
using Management.Services;
|
||||||
|
|
||||||
public class CourseMarkdownLoader
|
public class CourseMarkdownLoader
|
||||||
@@ -38,6 +39,9 @@ public class CourseMarkdownLoader
|
|||||||
throw new LoadCourseFromFileException(errorMessage);
|
throw new LoadCourseFromFileException(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
LocalCourseSettings settings = await loadCourseSettings(courseDirectory);
|
LocalCourseSettings settings = await loadCourseSettings(courseDirectory);
|
||||||
var modules = await loadCourseModules(courseDirectory);
|
var modules = await loadCourseModules(courseDirectory);
|
||||||
|
|
||||||
@@ -47,6 +51,12 @@ public class CourseMarkdownLoader
|
|||||||
Modules = modules
|
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");
|
||||||
|
try
|
||||||
|
{
|
||||||
return LocalAssignment.ParseMarkdown(rawFile);
|
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");
|
||||||
|
try
|
||||||
|
{
|
||||||
return LocalCoursePage.ParseMarkdown(rawPage);
|
return LocalCoursePage.ParseMarkdown(rawPage);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Console.WriteLine($"error loading page at path {path}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
10
nextjs/src/app/course/[courseName]/loading.tsx
Normal file
10
nextjs/src/app/course/[courseName]/loading.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Spinner } from "@/components/Spinner";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
10
nextjs/src/components/Spinner.tsx
Normal file
10
nextjs/src/components/Spinner.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
||||||
56
nextjs/src/components/spinner.css
Normal file
56
nextjs/src/components/spinner.css
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user