Feature-based folder structure

1. Created feature-based folder structure - Components now organized by domain feature
  2. Moved all components - 20+ files moved to new locations
  3. Updated _Imports.razor - Added all new namespace paths for global component access
  4. Updated CustomThemes.cs namespace - Changed from WebApp.Components.Layout to WebApp.Components.Shared.Layout
  5. Removed old using directives - Cleaned up Login.razor and Routes.razor
  6. Removed empty directories - Cleaned up old folder structure
This commit is contained in:
2025-12-03 22:04:23 -05:00
parent bd04483bed
commit 2d5d075879
38 changed files with 13 additions and 4 deletions
@@ -0,0 +1,278 @@
using MudBlazor;
namespace WebApp.Components.Shared.Layout
{
public static class CustomThemes
{
/*
!
* Bootswatch v5.3.3 (https://bootswatch.com)
* Theme: cerulean
* Copyright 2012-2024 Thomas Park
* Licensed under MIT
* Based on Bootstrap
*/
public static readonly MudTheme Ceruleantheme = new()
{
PaletteLight = new PaletteLight()
{
Black = "#000",
White = "#fff",
Primary = "#2fa4e7ff",
PrimaryContrastText = "#d5edfaff",
Secondary = "#e9ecef",
SecondaryContrastText = "#495057ff",
Tertiary = "#dee2e6ff",
TertiaryContrastText = "#495057ff",
Info = "#033c73",
InfoContrastText = "#cdd8e3",
Success = "#73a839",
SuccessContrastText = "#e3eed7",
Warning = "#dd5600",
WarningContrastText = "#f8ddcc",
Error = "rgba(244,67,54,1)",
ErrorContrastText = "rgba(255,255,255,1)",
Dark = "#343a40",
DarkContrastText = "#ced4da",
TextPrimary = "#13425cff",
TextSecondary = "#5d5e60",
TextDisabled = "rgba(0,0,0,0.3764705882352941)",
ActionDefault = "rgba(0,0,0,0.5372549019607843)",
ActionDisabled = "rgba(0,0,0,0.25882352941176473)",
ActionDisabledBackground = "rgba(0,0,0,0.11764705882352941)",
Background = "rgba(255,255,255,1)",
BackgroundGray = "rgba(245,245,245,1)",
Surface = "rgba(255,255,255,1)",
DrawerBackground = "#e9ecefff",
DrawerText = "#495057ff",
DrawerIcon = "#e9ecef",
AppbarBackground = "#2fa4e7ff",
AppbarText = "#d5edfaff",
LinesDefault = "rgba(0,0,0,0.11764705882352941)",
LinesInputs = "rgba(189,189,189,1)",
TableLines = "rgba(224,224,224,1)",
TableStriped = "rgba(0,0,0,0.0196078431372549)",
TableHover = "rgba(0,0,0,0.0392156862745098)",
Divider = "rgba(224,224,224,1)",
DividerLight = "rgba(0,0,0,0.8)",
PrimaryDarken = "#13425c",
PrimaryLighten = "#d5edfa",
SecondaryDarken = "#5d5e60",
SecondaryLighten = "#fbfbfc",
TertiaryDarken = "rgba(73, 80, 87, 0.5)",
TertiaryLighten = "rgba(73, 80, 87, 0.5)",
InfoDarken = "#01182e",
InfoLighten = "#cdd8e3",
SuccessDarken = "#2e4317",
SuccessLighten = "#e3eed7",
WarningDarken = "#582200",
WarningLighten = "#f8ddcc",
ErrorDarken = "rgb(242,28,13)",
ErrorLighten = "rgb(246,96,85)",
DarkDarken = "rgb(46,46,46)",
DarkLighten = "rgb(87,87,87)",
HoverOpacity = 0.06,
RippleOpacity = 0.1,
RippleOpacitySecondary = 0.2,
GrayDefault = "#9E9E9E",
GrayLight = "#BDBDBD",
GrayLighter = "#E0E0E0",
GrayDark = "#757575",
GrayDarker = "#616161",
OverlayDark = "rgba(33,33,33,0.4980392156862745)",
OverlayLight = "rgba(255,255,255,0.4980392156862745)",
},
PaletteDark = new PaletteDark()
{
Black = "#000",
White = "#fff",
Primary = "#2fa4e7ff",
PrimaryContrastText = "#d5edfaff",
Secondary = "#e9ecef",
SecondaryContrastText = "#2f2f30",
Tertiary = "rgba(222, 226, 230, 0.5)",
TertiaryContrastText = "#2b3035",
Info = "#026e8eff",
InfoContrastText = "#010c17",
Success = "#73a839",
SuccessContrastText = "#17220b",
Warning = "#dd5600",
WarningContrastText = "#2c1100",
Error = "rgba(244,67,54,1)",
ErrorContrastText = "rgba(255,255,255,1)",
Dark = "#343a40ff",
DarkContrastText = "#1a1d20",
TextPrimary = "#82c8f1",
TextSecondary = "#f2f4f5",
TextDisabled = "rgba(255,255,255,0.2)",
ActionDefault = "rgba(173,173,177,1)",
ActionDisabled = "rgba(255,255,255,0.25882352941176473)",
ActionDisabledBackground = "rgba(255,255,255,0.11764705882352941)",
Background = "rgba(50,51,61,1)",
BackgroundGray = "rgba(39,39,47,1)",
Surface = "#212529ff",
DrawerBackground = "#2f2f30ff",
DrawerText = "#e9ecef",
DrawerIcon = "#e9ecef",
AppbarBackground = "#2fa4e7ff",
AppbarText = "#d5edfaff",
LinesDefault = "rgba(255,255,255,0.11764705882352941)",
LinesInputs = "rgba(255,255,255,0.2980392156862745)",
TableLines = "rgba(255,255,255,0.11764705882352941)",
TableStriped = "rgba(255,255,255,0.2)",
Divider = "#ffffff73",
DividerLight = "#ffffff2e",
PrimaryDarken = "#82c8f1",
PrimaryLighten = "#09212e",
SecondaryDarken = "#f2f4f5",
SecondaryLighten = "#2f2f30",
TertiaryDarken = "rgba(222, 226, 230, 0.5)",
TertiaryLighten = "rgba(222, 226, 230, 0.5)",
InfoDarken = "#688aab",
InfoLighten = "#010c17",
SuccessDarken = "#abcb88",
SuccessLighten = "#17220b",
WarningDarken = "#eb9a66",
WarningLighten = "#2c1100",
ErrorDarken = "rgb(242,28,13)",
ErrorLighten = "rgb(246,96,85)",
DarkDarken = "rgb(23,23,28)",
DarkLighten = "rgb(56,56,67)",
},
LayoutProperties = new LayoutProperties()
{
DefaultBorderRadius = "4px",
DrawerMiniWidthLeft = "56px",
DrawerMiniWidthRight = "56px",
DrawerWidthLeft = "240px",
DrawerWidthRight = "240px",
AppbarHeight = "64px",
},
Typography = new Typography()
{
Default = new DefaultTypography
{
FontFamily = ["Roboto", "Helvetica", "Arial", "sans-serif"],
FontWeight = "400",
FontSize = ".875rem",
LineHeight = "1.43",
LetterSpacing = ".01071em",
TextTransform = "none",
},
H1 = new H1Typography
{
FontWeight = "300",
FontSize = "6rem",
LineHeight = "1.167",
LetterSpacing = "-.01562em",
TextTransform = "none",
},
H2 = new H2Typography
{
FontWeight = "300",
FontSize = "3.75rem",
LineHeight = "1.2",
LetterSpacing = "-.00833em",
TextTransform = "none",
},
H3 = new H3Typography
{
FontWeight = "400",
FontSize = "3rem",
LineHeight = "1.167",
LetterSpacing = "0",
TextTransform = "none",
},
H4 = new H4Typography
{
FontWeight = "400",
FontSize = "2.125rem",
LineHeight = "1.235",
LetterSpacing = ".00735em",
TextTransform = "none",
},
H5 = new H5Typography
{
FontWeight = "400",
FontSize = "1.5rem",
LineHeight = "1.334",
LetterSpacing = "0",
TextTransform = "none",
},
H6 = new H6Typography
{
FontWeight = "500",
FontSize = "1.25rem",
LineHeight = "1.6",
LetterSpacing = ".0075em",
TextTransform = "none",
},
Subtitle1 = new Subtitle1Typography
{
FontWeight = "400",
FontSize = "1rem",
LineHeight = "1.75",
LetterSpacing = ".00938em",
TextTransform = "none",
},
Subtitle2 = new Subtitle2Typography
{
FontWeight = "500",
FontSize = ".875rem",
LineHeight = "1.57",
LetterSpacing = ".00714em",
TextTransform = "none",
},
Body1 = new Body1Typography
{
FontWeight = "400",
FontSize = "1rem",
LineHeight = "1.5",
LetterSpacing = ".00938em",
TextTransform = "none",
},
Body2 = new Body2Typography
{
FontWeight = "400",
FontSize = ".875rem",
LineHeight = "1.43",
LetterSpacing = ".01071em",
TextTransform = "none",
},
Button = new ButtonTypography
{
FontWeight = "500",
FontSize = ".875rem",
LineHeight = "1.75",
LetterSpacing = ".02857em",
TextTransform = "uppercase",
},
Caption = new CaptionTypography
{
FontWeight = "400",
FontSize = ".75rem",
LineHeight = "1.66",
LetterSpacing = ".03333em",
TextTransform = "none",
},
Overline = new OverlineTypography
{
FontWeight = "400",
FontSize = ".75rem",
LineHeight = "2.66",
LetterSpacing = ".08333em",
TextTransform = "none",
},
},
ZIndex = new ZIndex()
{
Drawer = 1100,
Popover = 1200,
AppBar = 1300,
Dialog = 1400,
Snackbar = 1500,
Tooltip = 1600,
},
};
}
}
@@ -0,0 +1,7 @@
@inherits LayoutComponentBase
<MudThemeProvider Theme="CustomThemes.Ceruleantheme" />
<MudPopoverProvider />
<MudDialogProvider />
@Body
@@ -0,0 +1,43 @@
@inherits LayoutComponentBase
@inject IConfiguration Configuration
<MudThemeProvider Theme="CustomThemes.Ceruleantheme" />
<MudPopoverProvider />
<MudDialogProvider />
<MudLayout>
<MudAppBar Class="no-print">
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
TSA Chapter Organizer - @Configuration["ChapterSettings:Name"]
<MudSpacer />
<AuthorizeView>
<MudText Typo="Typo.body2">Logged in</MudText>
<form action="Auth/CookieLogout" method="post">
<button type="submit" class="btn btn-primary">Logout</button>
</form>
</AuthorizeView>
</MudAppBar>
<MudDrawer @bind-Open="@_drawerOpen" Class="no-print">
<NavMenu/>
</MudDrawer>
<MudMainContent>
<MudContainer MaxWidth="MaxWidth.ExtraLarge">
@Body
</MudContainer>
</MudMainContent>
</MudLayout>
@code {
bool _drawerOpen = true;
void DrawerToggle()
{
_drawerOpen = !_drawerOpen;
}
}
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
@@ -0,0 +1,96 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}
.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}
.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
@@ -0,0 +1,23 @@
@using WebApp.Models
@inject IConfiguration Configuration
<MudPaper Width="250px" Class="d-inline-flex py-3" Elevation="0">
<MudNavMenu Class="mud-width-full">
<MudLink Typo="Typo.h6" Href="/" Class="px-4">TSA Chapter Organizer</MudLink>
<MudText Typo="Typo.body2" Class="px-4 mud-text-secondary">@Configuration["ChapterSettings:Name"]</MudText>
<MudDivider Class="my-2"/>
<MudNavLink Href="/events" Icon="@AppIcons.Events">Events</MudNavLink>
<MudNavLink Href="/students" Icon="@Icons.Material.Filled.People">Students</MudNavLink>
<MudNavGroup Title="Teams" Icon="@Icons.Material.Outlined.Groups" Expanded="true">
<MudNavLink Href="/teams" Match="NavLinkMatch.All" Icon="@AppIcons.Teams">Teams</MudNavLink>
<MudNavLink Href="/teams/printout" Icon="@Icons.Material.Filled.Print">Print out</MudNavLink>
<MudNavLink Href="/teams/handout" Icon="@Icons.Material.Filled.Print">Handout</MudNavLink>
</MudNavGroup>
<MudNavLink Href="/meeting-schedule/" Icon="@AppIcons.Scheduler">Schedule</MudNavLink>
<MudNavGroup Title="Team Building" Icon="@Icons.Material.Filled.GroupAdd" Expanded="true">
<MudNavLink Href="/students/event-ranking" Icon="@AppIcons.EventRank">Event Ranking</MudNavLink>
<MudNavLink Href="/teams/assignment" Icon="@AppIcons.TeamAssignment">Team Assignment</MudNavLink>
</MudNavGroup>
</MudNavMenu>
</MudPaper>
@@ -0,0 +1,105 @@
.navbar-toggler {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: blue;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item ::deep .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.nav-scrollable {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}