Skip to content

chore: redesign pages and components.#93

Open
Polqt wants to merge 1 commit intomainfrom
feat/student-ticket-attachments
Open

chore: redesign pages and components.#93
Polqt wants to merge 1 commit intomainfrom
feat/student-ticket-attachments

Conversation

@Polqt
Copy link
Owner

@Polqt Polqt commented Feb 28, 2026

Summary by Sourcery

Redesign the ticket board and admin dashboard sections to provide a single, scrollable board view with expandable ticket details and improved layout behavior.

Enhancements:

  • Replace the previous list/board toggle with a unified board view featuring expandable ticket cards that surface key metadata and navigation to full ticket details.
  • Refine ticket board loading, empty, and per-column empty states with updated grid layouts and skeleton/placeholder content.
  • Improve the admin dashboard layout by making the main content area height-aware and enhancing the ticket volume chart bar sizing for clearer visual scaling.
  • Wrap the admin dashboard ticket board in a fixed-height section to maintain consistent scrolling and layout within the dashboard.

Summary by CodeRabbit

  • New Features

    • Added expandable ticket cards allowing users to view ticket details directly on the dashboard without navigating away.
    • Introduced "Recent Support Activity" section displaying recent support tickets.
  • UI/UX Improvements

    • Enhanced volume bar animations with responsive height rendering.
    • Redesigned ticket board with grid-based layout and accordion-style ticket expansion.
    • Improved dashboard organization with collapsible ticket details showing description, location, student info, category, and comments.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 28, 2026

Reviewer's Guide

Refactors the ticket board into a single expandable grid layout with richer ticket details and role-aware navigation, adjusts admin dashboard layout to better contain scrollable content, and improves the ticket volume chart bar sizing/animation.

Sequence diagram for clicking a ticket and navigating to full view

sequenceDiagram
  actor User
  participant TicketBoard as TicketBoard_svelte
  participant Router as SvelteRouter
  participant AdminPage as AdminTicketDetailsPage
  participant StudentPage as StudentTicketDetailsPage

  User->>TicketBoard: Click ViewFullDetails for ticket
  TicketBoard->>TicketBoard: navigateToFullView(ticket)
  TicketBoard->>TicketBoard: Check role from authStore
  alt role is admin
    TicketBoard->>Router: goto(/admin/tickets/{ticket.id})
    Router->>AdminPage: Render admin ticket details
  else role is not admin
    TicketBoard->>Router: goto(/tickets/{ticket.ticket_number})
    Router->>StudentPage: Render student ticket details
  end
Loading

Class diagram for TicketBoard and related ticket types

classDiagram
  class TicketBoard_svelte {
    +number_or_null expandedTicketId
    +Ticket[] tickets
    +boolean isLoading
    +string role
    +TicketColumn[] columns
    +toggleExpand(number ticketId) void
    +navigateToFullView(Ticket ticket) void
  }

  class Ticket {
    +number id
    +string ticket_number
    +string title
    +string description
    +string priority
    +string building
    +string room_name
    +Student student
    +Category category
    +string created_at
    +number_or_null comments_count
  }

  class TicketColumn {
    +string title
    +string color
    +string dotColor
    +Ticket[] reports
  }

  class Student {
    +string name
    +string email
  }

  class Category {
    +string name
  }

  class TicketsStore {
    +Ticket[] tickets
    +boolean isLoading
  }

  class AuthStore {
    +string role
  }

  class TicketConfig {
    +string[] baseColumns
    +getPriorityKey(string priority) string
    +priorityConfig map
  }

  class DateUtil {
    +formatDate(string date) string
  }

  TicketBoard_svelte --> Ticket : uses
  TicketBoard_svelte --> TicketColumn : groups tickets into
  TicketBoard_svelte --> TicketsStore : reads tickets and isLoading
  TicketBoard_svelte --> AuthStore : reads role
  TicketBoard_svelte --> TicketConfig : uses priority configuration
  TicketBoard_svelte --> DateUtil : uses for created_at formatting
  Ticket --> Student : has
  Ticket --> Category : has
  TicketColumn --> Ticket : contains reports
Loading

Flow diagram for ticket click expanding inline details

flowchart TD
  A_UserClick[User clicks ticket card header] --> B_CheckExpanded{Is expandedTicketId equal to ticket.id?}
  B_CheckExpanded -- Yes --> C_Collapse[Set expandedTicketId to null]
  C_Collapse --> D_RenderCollapsed[Render compact ticket card only]
  B_CheckExpanded -- No --> E_Expand[Set expandedTicketId to ticket.id]
  E_Expand --> F_RenderExpanded[Render ticket card with inline details]

  F_RenderExpanded --> G_ShowDescription[Show description text]
  F_RenderExpanded --> H_ShowLocation[Show building and room_name]
  F_RenderExpanded --> I_ShowStudent[Show student.name or student.email]
  F_RenderExpanded --> J_ShowMeta[Show category.name and formatted created_at]
  F_RenderExpanded --> K_ShowCommentsCount[Show comments_count if greater than 0]
  F_RenderExpanded --> L_ShowActionButton[Show View Full Details button]

  L_ShowActionButton --> M_UserClickView[User clicks View Full Details]
  M_UserClickView --> N_NavigateFullView["Call navigateToFullView(ticket)"]
Loading

Flow diagram for admin ticket volume bar height and animation

flowchart TD
  A_InputValue[Input bar.value] --> B_ComputeBaseHeight[Compute height = bar.value * 3]
  B_ComputeBaseHeight --> C_ClampHeight[If height < 10 then height = 10]
  C_ClampHeight --> D_ApplyClass{Height range}

  D_ApplyClass -->|height == 10| H2[Apply class h-2]
  D_ApplyClass -->|10 < height <= 20| H4[Apply class h-4]
  D_ApplyClass -->|20 < height <= 30| H8[Apply class h-8]
  D_ApplyClass -->|30 < height <= 40| H12[Apply class h-12]
  D_ApplyClass -->|40 < height <= 50| H16[Apply class h-16]
  D_ApplyClass -->|50 < height <= 60| H20[Apply class h-20]
  D_ApplyClass -->|60 < height <= 80| H24[Apply class h-24]
  D_ApplyClass -->|80 < height <= 100| H32[Apply class h-32]
  D_ApplyClass -->|height > 100| H40[Apply class h-40]

  H2 --> E_RenderBar[Render div.bg-primary/20 with transition-all duration-300]
  H4 --> E_RenderBar
  H8 --> E_RenderBar
  H12 --> E_RenderBar
  H16 --> E_RenderBar
  H20 --> E_RenderBar
  H24 --> E_RenderBar
  H32 --> E_RenderBar
  H40 --> E_RenderBar

  E_RenderBar --> F_FillInner[Render inner div filling bottom with bar.value% height]
  F_FillInner --> G_FinalDisplay[Animated volume bar shown in dashboard]
Loading

File-Level Changes

Change Details Files
Redesigned ticket board UI to a single grid layout with expandable ticket cards and richer detail view.
  • Removed list vs grid view mode toggle and associated list rendering logic, standardizing on a grid-based board layout.
  • Introduced expandedTicketId state and toggleExpand handler to control per-ticket expansion within each column.
  • Reworked ticket card structure into a collapsible card with summary header and expanded detail section including description, location, student, category, date, comments count, and a ‘View Full Details’ action.
  • Updated loading and empty states to match the new grid layout and adjusted column containers to be fully scrollable within the board height.
  • Switched ticket iteration to keyed {#each} blocks, derived priorityKey once per ticket, and added a placeholder for empty columns.
frontend/src/components/ui/tickets/TicketBoard.svelte
Updated ticket navigation behavior to be role-aware and aligned with new admin ticket URL.
  • Replaced generic navigate handler with navigateToFullView that routes admins to /admin/tickets/{id} and non-admins to /tickets/{ticket_number}.
  • Removed role-conditional list layout and now use role only for navigation target selection.
frontend/src/components/ui/tickets/TicketBoard.svelte
Enhanced admin dashboard layout and ticket volume chart visualization.
  • Ensured the main scrollable dashboard content has min-h-0 to cooperate with flexbox height constraints.
  • Wrapped TicketBoard in a fixed-height section to keep it contained within the dashboard layout.
  • Refined the volume bar chart by computing a height value per bar and mapping it to Tailwind height utility classes with transitions for smoother visual changes.
frontend/src/components/ui/admin/AdminDashboard.svelte

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 28, 2026

📝 Walkthrough

Walkthrough

This PR modifies the admin dashboard and ticket board components. AdminDashboard updates volume bar styling from inline to class-based heights and introduces a new "Recent Support Activity" section containing the TicketBoard. The TicketBoard refactors from a per-column layout to a grid-based accordion with collapsible rows, replacing the navigate function with toggleExpand and navigateToFullView helpers.

Changes

Cohort / File(s) Summary
Admin Dashboard Volume Bar Styling
frontend/src/components/ui/admin/AdminDashboard.svelte
Replaces inline height styles on volume bars with dynamic class-based heights and transitions. Adds min-h-0 to main content container. Introduces new "Recent Support Activity" section wrapping TicketBoard with height constraints and a "See all" link.
Ticket Board Layout & Navigation Refactor
frontend/src/components/ui/tickets/TicketBoard.svelte
Transitions from per-column rendering to grid-based accordion layout with collapsible row details. Replaces navigate() function with toggleExpand(ticketId) for local expansion state and navigateToFullView(ticket) for role-aware routing. Displays expanded ticket metadata (description, location, student, category, date, comments) and updates loading/empty states to match new presentation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Rows expand like burrows deep,
Tickets nested, secrets keep,
Volume bars dance smooth and light,
Dashboard layouts, oh so right!
Grid and grid, detail to show,
Rabbit's refactor steals the show!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'chore: redesign pages and components' is overly vague and generic, describing the type of work without specifying which pages/components or the actual changes made. Consider more specific titles like 'refactor: implement accordion-based ticket board layout' or 'feat: redesign AdminDashboard and TicketBoard with improved responsiveness' to better convey the primary changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/student-ticket-attachments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In the volume chart loop you introduce an i index ({#each volume as bar, i}) that is never used; consider removing the index to avoid unused-variable noise and keep the template clean.
  • The TicketBoard layout now uses a fixed grid grid-cols-4 for both loading and loaded states, which may not adapt well to smaller viewports; consider making the column count responsive with breakpoint classes (e.g., grid-cols-1 md:grid-cols-2 xl:grid-cols-4).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the `volume` chart loop you introduce an `i` index (`{#each volume as bar, i}`) that is never used; consider removing the index to avoid unused-variable noise and keep the template clean.
- The `TicketBoard` layout now uses a fixed `grid grid-cols-4` for both loading and loaded states, which may not adapt well to smaller viewports; consider making the column count responsive with breakpoint classes (e.g., `grid-cols-1 md:grid-cols-2 xl:grid-cols-4`).

## Individual Comments

### Comment 1
<location path="frontend/src/components/ui/tickets/TicketBoard.svelte" line_range="75" />
<code_context>
-{:else if viewMode === "grid"}
-  <div class="flex gap-6 pb-4 flex-1 overflow-x-auto overflow-y-hidden">
+{:else}
+  <div class="grid grid-cols-4 gap-4 h-full min-h-0">
     {#each columns as column}
-      <div
</code_context>
<issue_to_address>
**suggestion:** The fixed 4‑column grid layout may not adapt well to smaller viewports.

The previous horizontally scrollable flex layout handled narrow screens more gracefully. With `grid grid-cols-4`, small viewports may now show cramped columns or overflow with no horizontal scroll. Consider responsive grid classes (e.g. `grid-cols-1 md:grid-cols-2 xl:grid-cols-4`) or restoring horizontal scrolling on small screens.

Suggested implementation:

```
  <div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-4 h-full min-h-0">

```

If your design system prefers different breakpoints (e.g. `md` instead of `sm`, or using `lg:grid-cols-3 xl:grid-cols-4`), you can adjust the responsive classes accordingly. Also, if you still want horizontal scrolling on the very smallest screens, you could wrap this grid in a container with `overflow-x-auto` and a `min-w-[<some-width>]` to reintroduce scroll behavior while keeping the responsive grid.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

{:else if viewMode === "grid"}
<div class="flex gap-6 pb-4 flex-1 overflow-x-auto overflow-y-hidden">
{:else}
<div class="grid grid-cols-4 gap-4 h-full min-h-0">
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: The fixed 4‑column grid layout may not adapt well to smaller viewports.

The previous horizontally scrollable flex layout handled narrow screens more gracefully. With grid grid-cols-4, small viewports may now show cramped columns or overflow with no horizontal scroll. Consider responsive grid classes (e.g. grid-cols-1 md:grid-cols-2 xl:grid-cols-4) or restoring horizontal scrolling on small screens.

Suggested implementation:

  <div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-4 h-full min-h-0">

If your design system prefers different breakpoints (e.g. md instead of sm, or using lg:grid-cols-3 xl:grid-cols-4), you can adjust the responsive classes accordingly. Also, if you still want horizontal scrolling on the very smallest screens, you could wrap this grid in a container with overflow-x-auto and a min-w-[<some-width>] to reintroduce scroll behavior while keeping the responsive grid.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (6)
frontend/src/components/ui/admin/AdminDashboard.svelte (3)

132-145: Unused loop index variable i.

The index i from the {#each volume as bar, i} destructuring is declared but never used. Remove it to avoid confusion.

♻️ Remove unused variable
-                  {`#each` volume as bar, i}
+                  {`#each` volume as bar}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/admin/AdminDashboard.svelte` around lines 132 -
145, The {`#each`} block declares an unused index variable—update the loop
declaration from "{`#each` volume as bar, i}" to "{`#each` volume as bar}" in the
AdminDashboard.svelte component (the block that defines bar and computes height)
and remove any reference to "i" if present; this eliminates the unused variable
warning while preserving the existing bar/height logic and classes.

170-189: "Recent Support Activity" card appears to be incomplete.

The card contains only a header with a "See all" link but no actual content displaying recent activity. Is this intentional as a placeholder, or is the activity list meant to be added?

Would you like me to help implement the activity list content for this section, or should this be tracked as a follow-up task?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/admin/AdminDashboard.svelte` around lines 170 -
189, The "Recent Support Activity" card in AdminDashboard.svelte currently only
renders a header and "See all" link but no activity items; update the card to
render the recent activities by iterating over a recentActivities array (e.g., a
prop, store, or data loaded in this component) and outputting each item as a
list or using a SupportActivityItem component, include an empty-state message
when recentActivities is empty and a loading/skeleton UI while fetching; ensure
the rendered items live inside the card-body where the header is and keep the
existing "See all" link to /admin/tickets.

133-145: Class-based height logic creates visual inconsistency.

The height calculation bar.value * 3 maps to discrete height classes, but the thresholds create uneven visual jumps. For example, a value of 7 (height=21) gets h-8, while value 10 (height=30) also gets h-8. Additionally, the inner div always has h-full, making the gradient fill the entire bar regardless of the calculated height—the dynamic height already represents the "filled" portion.

Consider whether inline styles with style="height: {height}px" would provide smoother, more accurate visual representation of the data, or adjust the threshold ranges to better reflect the data distribution.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/admin/AdminDashboard.svelte` around lines 133 -
145, Replace the discrete class-based height mapping for the progress bar (the
computed height variable derived from bar.value) with a smooth inline style:
compute height = Math.max(bar.value * 3, 10) and apply it as style="height:
{height}px" on the bar container or the fill element instead of using the
multiple class:h-* conditionals; also remove the inner div's unconditional
h-full so the fill height reflects the dynamic style (references: height,
bar.value, the inner div that currently has h-full and the class:h-*
conditionals).
frontend/src/components/ui/tickets/TicketBoard.svelte (3)

58-65: Apply the same responsive consideration to the loading skeleton.

The loading skeleton also uses a fixed grid-cols-4, which should match the main grid's responsive behavior for visual consistency.

♻️ Suggested fix
-  <div class="grid grid-cols-4 gap-4">
+  <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/tickets/TicketBoard.svelte` around lines 58 - 65,
The loading skeleton currently uses a fixed "grid grid-cols-4" which breaks
responsive consistency with the main grid; update the skeleton container in
TicketBoard.svelte to use the same responsive grid classes as the main layout
(for example replace "grid grid-cols-4" with "grid grid-cols-1 sm:grid-cols-2
lg:grid-cols-4" or whatever responsive class set the main grid uses) so the
skeleton columns adapt the same way as the real content.

105-136: Add keyboard accessibility for the accordion trigger.

The button element is correctly used for the clickable header, which is good for accessibility. However, consider adding aria-expanded to communicate the expanded state to screen readers.

♻️ Suggested accessibility improvement
              <button
                type="button"
                class="w-full text-left p-3 hover:bg-base-200/50 transition-colors duration-150"
                onclick={() => toggleExpand(ticket.id)}
+               aria-expanded={isExpanded}
              >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/tickets/TicketBoard.svelte` around lines 105 -
136, The accordion trigger button should expose its expanded state to assistive
tech: add an aria-expanded attribute to the button and bind it to the same
boolean used to render the chevron (e.g., isExpanded or your per-ticket
expansion state like expandedTickets.has(ticket.id)) so it emits true/false, and
add aria-controls linking to the collapsible panel id (e.g.,
`panel-{ticket.id}`) so screen readers can associate the button with the
content; update the panel markup to include that matching id.

75-77: Consider responsive behavior for the 4-column grid.

The grid-cols-4 layout is fixed and may cause usability issues on smaller screens or when the dashboard is rendered in a constrained container. Consider adding responsive breakpoints.

♻️ Suggested responsive grid
-  <div class="grid grid-cols-4 gap-4 h-full min-h-0">
+  <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4 h-full min-h-0">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/tickets/TicketBoard.svelte` around lines 75 - 77,
The fixed 4-column grid in TicketBoard.svelte (the div with class "grid
grid-cols-4 gap-4 h-full min-h-0") should be made responsive: replace the
hardcoded grid-cols-4 with responsive Tailwind breakpoint classes (for example
grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4) so the columns (the
{`#each` columns as column} block) reflow on smaller viewports and in constrained
containers; update the container class accordingly and verify column child
styling (the inner "flex flex-col min-h-0 h-full" divs) still behave correctly
at each breakpoint.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/ui/admin/AdminDashboard.svelte`:
- Around line 192-194: Replace the non-standard Tailwind class "h-150" in the
section wrapping the TicketBoard component with a valid Tailwind height utility;
locate the section element that contains <TicketBoard /> in
AdminDashboard.svelte and change "h-150" to a supported value such as a standard
class (e.g., "h-96") or an arbitrary value (e.g., "h-[37.5rem]") so the height
actually applies.

In `@frontend/src/components/ui/tickets/TicketBoard.svelte`:
- Around line 178-181: The code in TicketBoard.svelte accesses
ticket.student.name and ticket.student.email without guarding against
ticket.student being null/undefined; update the rendering to defensively check
for student (e.g., use optional chaining like ticket.student?.name ||
ticket.student?.email or conditional rendering that falls back to a default
string) so that the p element does not throw when ticket.student is missing.
- Around line 193-195: The span rendering ticket.category.name can throw when
ticket.category is null/undefined; update the access in the TicketBoard
component to use optional chaining (and an appropriate fallback) when reading
the category name (refer to the expression ticket.category.name in the span) so
it safely handles missing category objects (e.g., ticket.category?.name or
ticket.category?.name ?? 'Uncategorized').
- Around line 138-141: The component TicketBoard.svelte uses the CSS class
animate-accordion-down but no animation is defined; add a definition in your
global stylesheet (app layout CSS) by declaring an `@keyframes` named
accordion-down and a corresponding rule for .animate-accordion-down that sets
animation: accordion-down <duration> <timing> and forwards the final state, so
the expand animation in TicketBoard.svelte is applied; ensure the keyframes
animate height/transform/opacity as desired and match any existing
animate-accordion-up counterpart if present.

---

Nitpick comments:
In `@frontend/src/components/ui/admin/AdminDashboard.svelte`:
- Around line 132-145: The {`#each`} block declares an unused index
variable—update the loop declaration from "{`#each` volume as bar, i}" to "{`#each`
volume as bar}" in the AdminDashboard.svelte component (the block that defines
bar and computes height) and remove any reference to "i" if present; this
eliminates the unused variable warning while preserving the existing bar/height
logic and classes.
- Around line 170-189: The "Recent Support Activity" card in
AdminDashboard.svelte currently only renders a header and "See all" link but no
activity items; update the card to render the recent activities by iterating
over a recentActivities array (e.g., a prop, store, or data loaded in this
component) and outputting each item as a list or using a SupportActivityItem
component, include an empty-state message when recentActivities is empty and a
loading/skeleton UI while fetching; ensure the rendered items live inside the
card-body where the header is and keep the existing "See all" link to
/admin/tickets.
- Around line 133-145: Replace the discrete class-based height mapping for the
progress bar (the computed height variable derived from bar.value) with a smooth
inline style: compute height = Math.max(bar.value * 3, 10) and apply it as
style="height: {height}px" on the bar container or the fill element instead of
using the multiple class:h-* conditionals; also remove the inner div's
unconditional h-full so the fill height reflects the dynamic style (references:
height, bar.value, the inner div that currently has h-full and the class:h-*
conditionals).

In `@frontend/src/components/ui/tickets/TicketBoard.svelte`:
- Around line 58-65: The loading skeleton currently uses a fixed "grid
grid-cols-4" which breaks responsive consistency with the main grid; update the
skeleton container in TicketBoard.svelte to use the same responsive grid classes
as the main layout (for example replace "grid grid-cols-4" with "grid
grid-cols-1 sm:grid-cols-2 lg:grid-cols-4" or whatever responsive class set the
main grid uses) so the skeleton columns adapt the same way as the real content.
- Around line 105-136: The accordion trigger button should expose its expanded
state to assistive tech: add an aria-expanded attribute to the button and bind
it to the same boolean used to render the chevron (e.g., isExpanded or your
per-ticket expansion state like expandedTickets.has(ticket.id)) so it emits
true/false, and add aria-controls linking to the collapsible panel id (e.g.,
`panel-{ticket.id}`) so screen readers can associate the button with the
content; update the panel markup to include that matching id.
- Around line 75-77: The fixed 4-column grid in TicketBoard.svelte (the div with
class "grid grid-cols-4 gap-4 h-full min-h-0") should be made responsive:
replace the hardcoded grid-cols-4 with responsive Tailwind breakpoint classes
(for example grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4) so the
columns (the {`#each` columns as column} block) reflow on smaller viewports and in
constrained containers; update the container class accordingly and verify column
child styling (the inner "flex flex-col min-h-0 h-full" divs) still behave
correctly at each breakpoint.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abc5fa1 and 5b928e7.

📒 Files selected for processing (2)
  • frontend/src/components/ui/admin/AdminDashboard.svelte
  • frontend/src/components/ui/tickets/TicketBoard.svelte

Comment on lines +192 to +194
<section class="h-150 min-h-0">
<TicketBoard />
</section>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find Tailwind config files
find . -name "tailwind.config.*" -o -name "tailwindcss.config.*" | head -20

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Search for spacing or height config extensions
rg -l "tailwind|spacing|extend" --glob "*.js" --glob "*.ts" --glob "*.json" --glob "*.mjs" --glob "*.cjs" | grep -i "config\|tailwind" | head -20

Repository: Polqt/iComplain

Length of output: 105


🏁 Script executed:

#!/bin/bash
# Check vite.config.ts
cat frontend/vite.config.ts

Repository: Polqt/iComplain

Length of output: 1115


🏁 Script executed:

#!/bin/bash
# Look for PostCSS config
find . -name "postcss.config.*" -o -name ".postcssrc*"

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Search for h-150 in the entire codebase
rg "h-150" --type svelte --type css --type js --type ts

Repository: Polqt/iComplain

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Check for Tailwind in package.json
find . -name "package.json" -exec grep -l "tailwind" {} \;

Repository: Polqt/iComplain

Length of output: 82


🏁 Script executed:

#!/bin/bash
# Check package.json for Tailwind version
cat frontend/package.json | grep -A 5 -B 5 "tailwind"

Repository: Polqt/iComplain

Length of output: 783


🏁 Script executed:

#!/bin/bash
# Search for h-150 without file type restriction
rg "h-150"

Repository: Polqt/iComplain

Length of output: 153


🏁 Script executed:

#!/bin/bash
# Look for tailwind config in frontend directory
find frontend -name "tailwind*" -o -name "*tailwind*" | grep -v node_modules

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Check for CSS files that might contain Tailwind setup
find frontend/src -name "*.css" | head -10

Repository: Polqt/iComplain

Length of output: 183


🏁 Script executed:

#!/bin/bash
# Check frontend directory specifically for tailwind config
ls -la frontend/ | grep -i tailwind

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Look for tailwind.config in frontend root
find frontend -maxdepth 1 -name "tailwind*"

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Check the main layout.css for Tailwind configuration
cat frontend/src/routes/layout.css

Repository: Polqt/iComplain

Length of output: 640


🏁 Script executed:

#!/bin/bash
# Search for any custom spacing configuration
rg "spacing|extend|h-\[|150" frontend/src --type css

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Search for any file with "tailwind" in frontend directory
find frontend -type f -name "*tailwind*" 2>/dev/null

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Check if there's a config file in the root or frontend
ls -la frontend/*.{js,ts,mjs,cjs} 2>/dev/null | grep -E "config|tailwind"

Repository: Polqt/iComplain

Length of output: 360


🏁 Script executed:

#!/bin/bash
# Look for any theme extension or spacing in the entire CSS layer
rg "theme|spacing|extend" frontend/src --type css -A 3

Repository: Polqt/iComplain

Length of output: 330


🏁 Script executed:

#!/bin/bash
# Check if h-150 might be defined elsewhere as arbitrary value or custom class
rg "h-150|150" frontend/src --type css -B 2 -A 2

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Check svelte.config.js for any Tailwind configuration
cat frontend/svelte.config.js

Repository: Polqt/iComplain

Length of output: 682


🏁 Script executed:

#!/bin/bash
# Look for theme configuration in any JS/TS files
rg "theme|spacing|extend" frontend --type js --type ts -A 5 | head -50

Repository: Polqt/iComplain

Length of output: 3022


🏁 Script executed:

#!/bin/bash
# Check if DaisyUI or any plugin might provide h-150
rg "daisyui" frontend/package.json -A 2 -B 2

Repository: Polqt/iComplain

Length of output: 190


🏁 Script executed:

#!/bin/bash
# Check if there's any theme or config definition in Tailwind CSS v4 format in layout.css
cat frontend/src/routes/layout.css | grep -A 20 "@theme\|@config"

Repository: Polqt/iComplain

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Search for any other CSS files that might contain theme configuration
find frontend/src -name "*.css" -exec grep -l "theme\|spacing\|extend\|h-\[" {} \;

Repository: Polqt/iComplain

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Double-check if h-150 might be defined as a custom class anywhere
rg "h-150|\.h-150" frontend

Repository: Polqt/iComplain

Length of output: 153


🏁 Script executed:

#!/bin/bash
# Verify standard Tailwind spacing scale - check Tailwind v4 documentation expectations
# by looking at what heights are being used elsewhere in the codebase
rg "h-\d+" frontend/src --no-filename | sort -u | head -20

Repository: Polqt/iComplain

Length of output: 1519


🏁 Script executed:

#!/bin/bash
# Also check for min-h and max-h utilities to understand the pattern
rg "(min-h|max-h)-\d+" frontend/src --no-filename | sort -u | head -20

Repository: Polqt/iComplain

Length of output: 1236


Remove or replace h-150 with a valid Tailwind height utility.

h-150 is not a standard Tailwind utility (standard values go up to h-96), and there is no custom spacing configuration in your Tailwind setup (v4.1.17) or DaisyUI configuration. This class will be ignored and won't apply any height. Use an arbitrary value like h-[37.5rem] or a standard class instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/admin/AdminDashboard.svelte` around lines 192 -
194, Replace the non-standard Tailwind class "h-150" in the section wrapping the
TicketBoard component with a valid Tailwind height utility; locate the section
element that contains <TicketBoard /> in AdminDashboard.svelte and change
"h-150" to a supported value such as a standard class (e.g., "h-96") or an
arbitrary value (e.g., "h-[37.5rem]") so the height actually applies.

Comment on lines +138 to +141
{#if isExpanded}
<div
class="badge badge-sm whitespace-nowrap {statusConfig[
report.status
].color}"
class="border-t border-base-content/8 bg-base-200/30 p-4 space-y-3
animate-accordion-down"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for accordion-down definition in the codebase
echo "=== Searching for animate-accordion-down definitions ==="
rg -i "accordion-down" --type css --type scss --type js --type ts --type json

echo ""
echo "=== Looking for tailwind config files ==="
fd -i "tailwind" | head -20

echo ""
echo "=== Searching in all animation/keyframes definitions ==="
rg "@keyframes|animation:" | head -50

Repository: Polqt/iComplain

Length of output: 262


🏁 Script executed:

#!/bin/bash
# Get project structure overview
echo "=== Project root files ==="
ls -la | head -20

echo ""
echo "=== Looking for config files broadly ==="
fd -i "config" --type f | grep -E "\.(js|ts|json)$" | head -20

echo ""
echo "=== Search in Svelte files for accordion ==="
fd "\.svelte$" -x rg -l "accordion" {}

echo ""
echo "=== Check package.json for Tailwind ==="
cat package.json 2>/dev/null | head -50

Repository: Polqt/iComplain

Length of output: 1404


🏁 Script executed:

#!/bin/bash
# Check frontend package.json
echo "=== Frontend package.json ==="
cat frontend/package.json 2>/dev/null | grep -A 20 '"dependencies"\|"devDependencies"' | head -50

echo ""
echo "=== Frontend svelte config ==="
cat frontend/svelte.config.js

echo ""
echo "=== Check for global CSS files ==="
fd -e css -e scss frontend/src | head -20

echo ""
echo "=== Check TicketBoard.svelte for animation definition ==="
cat -n frontend/src/components/ui/tickets/TicketBoard.svelte | tail -100

Repository: Polqt/iComplain

Length of output: 6475


🏁 Script executed:

#!/bin/bash
# Check vite config for Tailwind setup
echo "=== Frontend vite.config.ts ==="
cat frontend/vite.config.ts

echo ""
echo "=== Look for CSS entry files ==="
fd -e css frontend/src | head -20

echo ""
echo "=== Check beginning of TicketBoard.svelte for <style> ==="
head -150 frontend/src/components/ui/tickets/TicketBoard.svelte

echo ""
echo "=== Broad search for accordion-down across all files ==="
rg "accordion-down"

Repository: Polqt/iComplain

Length of output: 6973


🏁 Script executed:

#!/bin/bash
# Look for tailwind.config files more broadly
echo "=== Search for tailwind.config files ==="
find frontend -name "tailwind.config*" -o -name "tailwind*" 2>/dev/null

echo ""
echo "=== Find all CSS files recursively ==="
find frontend -name "*.css" -type f 2>/dev/null

echo ""
echo "=== Look for app.svelte or layout ==="
find frontend/src -name "+layout.svelte" -o -name "app.svelte" 2>/dev/null | head -10

echo ""
echo "=== Check for animation definitions using grep ==="
grep -r "@keyframes\|animation:\|animate-" frontend --include="*.css" --include="*.svelte" 2>/dev/null | head -30

Repository: Polqt/iComplain

Length of output: 1532


🏁 Script executed:

#!/bin/bash
# Check the main layout CSS file
echo "=== Frontend src/routes/layout.css ==="
cat frontend/src/routes/layout.css

echo ""
echo "=== Check +layout.svelte for styles ==="
cat frontend/src/routes/+layout.svelte

echo ""
echo "=== Also check app.css if it exists ==="
find frontend/src -name "app.css" -exec cat {} \; 2>/dev/null

Repository: Polqt/iComplain

Length of output: 1541


Define the missing animate-accordion-down animation.

The class animate-accordion-down is used in line 140 but is not defined in any CSS files, Tailwind configuration, or component styles. This animation will not apply without a definition. Add it to frontend/src/routes/layout.css using a @keyframes rule or Tailwind's animation utilities in a configuration file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/tickets/TicketBoard.svelte` around lines 138 -
141, The component TicketBoard.svelte uses the CSS class animate-accordion-down
but no animation is defined; add a definition in your global stylesheet (app
layout CSS) by declaring an `@keyframes` named accordion-down and a corresponding
rule for .animate-accordion-down that sets animation: accordion-down <duration>
<timing> and forwards the final state, so the expand animation in
TicketBoard.svelte is applied; ensure the keyframes animate
height/transform/opacity as desired and match any existing animate-accordion-up
counterpart if present.

Comment on lines +178 to +181
/>
<p class="text-xs text-base-content/60 truncate">
{ticket.student.name || ticket.student.email}
</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard against missing student object.

Accessing ticket.student.name or ticket.student.email will throw if ticket.student is null or undefined. Consider adding a defensive check.

🛡️ Proposed defensive access
                    <p class="text-xs text-base-content/60 truncate">
-                      {ticket.student.name || ticket.student.email}
+                      {ticket.student?.name || ticket.student?.email || "Unknown"}
                    </p>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/tickets/TicketBoard.svelte` around lines 178 -
181, The code in TicketBoard.svelte accesses ticket.student.name and
ticket.student.email without guarding against ticket.student being
null/undefined; update the rendering to defensively check for student (e.g., use
optional chaining like ticket.student?.name || ticket.student?.email or
conditional rendering that falls back to a default string) so that the p element
does not throw when ticket.student is missing.

Comment on lines +193 to +195
<span class="text-base-content/60"
>{ticket.category.name}</span
>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard against missing category object.

Similarly, ticket.category.name could throw if category is missing. Add optional chaining for safety.

🛡️ Proposed defensive access
                      <span class="text-base-content/60"
-                        >{ticket.category.name}</span
+                        >{ticket.category?.name || "Uncategorized"}</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
<span class="text-base-content/60"
>{ticket.category.name}</span
>
<span class="text-base-content/60"
>{ticket.category?.name || "Uncategorized"}</span
>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ui/tickets/TicketBoard.svelte` around lines 193 -
195, The span rendering ticket.category.name can throw when ticket.category is
null/undefined; update the access in the TicketBoard component to use optional
chaining (and an appropriate fallback) when reading the category name (refer to
the expression ticket.category.name in the span) so it safely handles missing
category objects (e.g., ticket.category?.name or ticket.category?.name ??
'Uncategorized').

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant