Skip to content
This repository was archived by the owner on May 7, 2026. It is now read-only.
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
Binary file added .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion rocky-interface/src/lib/components/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { selectedCourseId } from '$lib/stores/courseStore';
import { openCourseComposer } from '$lib/stores/courseComposerStore';
import { framesForRole, toFrameLabel, type FrameName } from '$lib/types/frame';
import {sidebarOpen} from '$lib/stores/sidebarStore';

const frames = Object.keys(frameMap) as FrameName[];
const isAdmin = $derived(Boolean(page.data.currentUser?.isAdmin));
Expand Down Expand Up @@ -108,6 +109,7 @@
}

currentFrame.set(frame);
sidebarOpen.set(false);
} catch (error) {
console.error('Session validation error:', error);
window.location.href = '/login';
Expand Down Expand Up @@ -152,6 +154,7 @@
selectedCourseId.set(courseId);
await handleFrameChange('courses');
courseMenuOpen = false;
sidebarOpen.set(false);
requestAnimationFrame(() => {
requestAnimationFrame(() => {
scrollToTopOfApp();
Expand All @@ -167,7 +170,11 @@
}
</script>

<nav class="sidebar">
{#if $sidebarOpen}
<div class="sidebar-backdrop" onclick={() => sidebarOpen.set(false)} aria-hidden="true"></div>
{/if}

<nav class="sidebar" class:open={$sidebarOpen}>
{#each framesBeforeCourses as frame}
<button class="nav-link" class:active={activeFrame === frame} onclick={() => handleFrameChange(frame)}>{toFrameLabel(frame)}</button>
{/each}
Expand Down
7 changes: 7 additions & 0 deletions rocky-interface/src/lib/components/Topbar.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
<script lang="ts">
import type { User } from '$lib/types/user';
import '$lib/styles/components/topbar.css';
import {sidebarOpen} from '$lib/stores/sidebarStore';

let { user = null }: { user: User | null } = $props();

let showAdministration = $derived(Boolean(user?.isAdmin));
</script>

<header class="topbar">
<button class="hamburger" aria-label="Toggle menu" onclick={() => sidebarOpen.update(open => !open)}>
<span class="hamburger-line"></span>
<span class="hamburger-line"></span>
<span class="hamburger-line"></span>
</button>
Comment on lines +12 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Class name mismatch: hamburger lines won't be styled.

The spans use class="hamburger-line" but the CSS in components.css (lines 61-67) defines .hamburger-span. This mismatch will cause the hamburger icon bars to be invisible/unstyled.

🐛 Fix: Use consistent class name

Either update the HTML to match the CSS:

 <button class="hamburger" aria-label="Toggle menu" onclick={() => sidebarOpen.update(open => !open)}>
-  <span class="hamburger-line"></span>
-  <span class="hamburger-line"></span>
-  <span class="hamburger-line"></span>
+  <span class="hamburger-span"></span>
+  <span class="hamburger-span"></span>
+  <span class="hamburger-span"></span>
 </button>

Or update the CSS in components.css to use .hamburger-line instead of .hamburger-span.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button class="hamburger" aria-label="Toggle menu" onclick={() => sidebarOpen.update(open => !open)}>
<span class="hamburger-line"></span>
<span class="hamburger-line"></span>
<span class="hamburger-line"></span>
</button>
<button class="hamburger" aria-label="Toggle menu" onclick={() => sidebarOpen.update(open => !open)}>
<span class="hamburger-span"></span>
<span class="hamburger-span"></span>
<span class="hamburger-span"></span>
</button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocky-interface/src/lib/components/Topbar.svelte` around lines 12 - 16, The
hamburger spans in Topbar.svelte use class="hamburger-line" but the stylesheet
defines .hamburger-span, so the lines are unstyled; fix by making the class
names consistent—either change the three <span> elements in Topbar.svelte to use
class="hamburger-span" or update the CSS selector in components.css from
.hamburger-span to .hamburger-line so that the styles apply to the spans
rendered by the Topbar component.


<img src="/rocky.svg" alt="Rocky" class="brand-logo" />
<div class="brand-text">
<div class="brand-name">Rocky</div>
Expand Down
48 changes: 25 additions & 23 deletions rocky-interface/src/lib/components/views/DashboardView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -110,30 +110,32 @@
</div>
</div>

{#if isLoading}
<div class="empty-state">
<p>Loading courses...</p>
</div>
{:else if error}
<div class="empty-state">
<p><strong>Error:</strong> {error}</p>
</div>
{:else if courses.length === 0}
<div class="empty-state">
<p>No courses available.</p>
</div>
{:else if viewMode === 'card'}
<div class="grid grid-3">
{#each courses as course}
<CourseCard {course} mode="card" on:open={handleOpenCourse} />
{/each}
<div class="section">
{#if isLoading}
<div class="empty-state">
<p>Loading courses...</p>
</div>
{:else if error}
<div class="empty-state">
<p><strong>Error:</strong> {error}</p>
</div>
{:else}
<div class="grid grid-1">
{#each courses as course}
<CourseCard {course} mode="list" on:open={handleOpenCourse} />
{/each}
{:else if courses.length === 0}
<div class="empty-state">
<p>No courses available.</p>
</div>
{/if}
{:else if viewMode === 'card'}
<div class="grid grid-3">
{#each courses as course}
<CourseCard {course} mode="card" on:open={handleOpenCourse} />
{/each}
</div>
{:else}
<div class="grid grid-1">
{#each courses as course}
<CourseCard {course} mode="list" on:open={handleOpenCourse} />
{/each}
</div>
{/if}
</div>
</ViewShell>

3 changes: 3 additions & 0 deletions rocky-interface/src/lib/stores/sidebarStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { writable } from "svelte/store";

export const sidebarOpen = writable(false);
93 changes: 82 additions & 11 deletions rocky-interface/src/lib/styles/components/components.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,34 @@
margin-left: auto;
}

/* Hamburger menu styles, doesn't show on desktop */
.hamburger {
display:none;
flex-direction: column;
justify-content: center;
gap: 5px;
background: transparent;
border: none;
cursor: pointer;
padding: 4px;
min-width: 48px;
min-height: 48px;
}

.hamburger-line {
display: block;
width: 24px;
height: 2px;
background: white;
border-radius: 2px;
}

@media (max-width: 768px) {
.hamburger {
display: flex;
}
}

/* ========== SIDEBAR ========== */
.sidebar {
width: var(--size-sidebar-width);
Expand Down Expand Up @@ -84,6 +112,36 @@
flex: 1;
}

/* Overlay for mobile sidebar */
@media (max-width: 768px) {
.sidebar {
position: fixed;
top: var(--size-topbar-height);
left: 0;
height: calc(100% - var(--size-topbar-height));
transform: translateX(-100%);
transition: transform 0.25s ease;
z-index: 200;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

.sidebar.open {
transform: translateX(0);
}
}
.sidebar-backdrop {
display: none;
}

@media (max-width: 768px) {
.sidebar-backdrop {
display: block;
position: fixed;
inset: var(--size-topbar-height) 0 0 0;
background: rgba(0, 0, 0, 0.4);
z-index: 199;
}
}

.course-tab-group {
position: relative;
}
Expand Down Expand Up @@ -192,16 +250,26 @@

/* ========== WIDGET PANEL ========== */
.widget-panel {
width: var(--size-widget-panel-width);
min-width: var(--size-widget-panel-width);
height: 100%;
background: var(--color-bg-secondary);
border: 1px solid var(--color-gray-300);
box-shadow: var(--shadow-widget);
padding: var(--space-lg) var(--space-lg);
box-sizing: border-box;
overflow: visible;
flex-shrink: 0;
width: var(--size-widget-panel-width);
min-width: var(--size-widget-panel-width);
height: 100%;
background: var(--color-bg-secondary);
border: 1px solid var(--color-gray-300);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-widget);
padding: var(--space-lg) var(--space-lg);
box-sizing: border-box;
overflow: visible;
flex-shrink: 0;
}

@media (max-width: 768px) {
.widget-panel {
width: 100%;
min-width: 0;
height: auto;
border-top: 1px solid var(--color-gray-300);
}
}

.widget-panel-title {
Expand Down Expand Up @@ -484,9 +552,11 @@
}

.view-menu-backdrop {
position: fixed;
position: absolute ;
inset: 0;
z-index: 10;
background: transparent;
border-radius: 10px;
}

.view-menu {
Expand Down Expand Up @@ -535,6 +605,7 @@

.view-switcher {
position: relative;
z-index: 11;
}

/* ========== KPI/ANALYTICS CARDS ========== */
Expand Down
27 changes: 17 additions & 10 deletions rocky-interface/src/lib/styles/layout/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@
min-width: 0;
}

@media (max-width: 1200px) {
.page-layout {
gap: var(--space-md);
}
@media (max-width: 768px) {
.app-content {
padding: var(--space-lg);
overflow-x: hidden;
}
.page-layout {
flex-direction: column;
}
}

/* ========== VIEW/PAGE STRUCTURE ========== */
Expand Down Expand Up @@ -85,12 +89,14 @@
}

.view-content {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding-right: var(--space-sm);
scrollbar-width: thin;
scrollbar-color: var(--color-gray-300) transparent;
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding-right: var(--space-sm);
padding-top: var(--space-sm);
margin-top: calc(-1 * var(--space-sm));
scrollbar-width: thin;
scrollbar-color: var(--color-gray-300) transparent;
}

.view-content::-webkit-scrollbar {
Expand Down Expand Up @@ -146,6 +152,7 @@
border-radius: var(--radius-xl);
padding: var(--space-lg);
box-shadow: var(--shadow-md);
min-height: fit-content;
min-height: 100%;
}

Expand Down
4 changes: 4 additions & 0 deletions rocky-interface/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ export default defineConfig(({ mode }) => {
}
};
});

optimizeDeps: {
exclude: ['@azure/msal-browser']
}
Loading