Skip to content

Credits#98

Merged
scottgrayson merged 25 commits into
4.xfrom
course-ext-id-fix
Mar 26, 2026
Merged

Credits#98
scottgrayson merged 25 commits into
4.xfrom
course-ext-id-fix

Conversation

@scottgrayson
Copy link
Copy Markdown
Contributor

@scottgrayson scottgrayson commented Mar 18, 2026

Adds optional credits support: config (credits_enabled, credits_label), credit categories model and resource, course–credit category pivot, dashboard/course-card credits display, and migration stubs.

Made with Cursor


Note

Medium Risk
Introduces new persisted data (credit categories and course-credit mappings) plus new dashboard filtering and eager-loading changes; main risk is migration/relationship correctness and performance regressions on course lists.

Overview
Adds an optional “credits” feature flag (filament-lms.credits_enabled) that, when enabled, lets admins define CreditCategory records and assign per-course credits via a new lms_course_credit_category relationship.

Updates the LMS UI and admin to surface credits: course cards now render a resilient image fallback plus credit badges, the dashboard adds a credit-category filter and uses computed courses/filteredCourses, and CourseResource gains a credits repeater, credits summary column, and a credit-category table filter. Registers the new CreditCategoryResource only when credits are enabled.

Improves course list performance by eager-loading lessons_count, step progress, and a new authEnrollment pivot relation to avoid per-course completed_at queries; also changes Course::image_url to return null when no media (tests/docs updated accordingly).

Written by Cursor Bugbot for commit 9848261. This will update automatically on new commits. Configure here.

Comment thread resources/views/components/course-card.blade.php Outdated
Comment thread resources/views/components/course-card.blade.php Outdated
Comment thread resources/views/components/course-card.blade.php Outdated
Comment thread src/Models/Course.php Outdated
Comment thread resources/views/components/course-card.blade.php
Comment thread src/Models/Course.php
Eager-load authEnrollment and lesson counts on the dashboard; use a
configurable placeholder when course media is missing so image_url is
always a string. Course card uses lessons_count and loads credit
relations only when credits are enabled.

Made-with: Cursor
Comment thread resources/views/components/course-card.blade.php
Comment thread src/Models/Course.php Outdated
image_url always returns a non-empty string, making the @else branch
unreachable. Replace the @if/@else with an onerror handler that hides
the broken img and shows the icon fallback instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread resources/views/components/course-card.blade.php Outdated
Comment thread src/Lms.php Outdated
The onerror handler in course-card.blade.php already falls back to the
academic cap icon, so the placeholder URL was never visible in the UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/Pages/Dashboard.php
… route gating, Livewire v4 compat

- Restore string return type on getImageUrlAttribute with placeholder fallback
- Remove unused hasValidCourseImage() and its Storage import
- Cache completion_percentage in blade to avoid duplicate DB queries per card
- Gate CreditCategoryResource route registration behind credits_enabled config
- Add #[Computed] to getFilteredCoursesProperty for Livewire v4 compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/Models/Course.php Outdated
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread src/Pages/Dashboard.php Outdated
scottgrayson and others added 6 commits March 24, 2026 13:17
Rename getFilteredCoursesProperty() to filteredCourses() so the
Livewire v3 #[Computed] attribute properly registers the property
instead of relying on legacy v2 backward compatibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Larastan and PHPStan dev branches are incompatible — minimum-stability: dev
without prefer-stable caused CI to resolve bleeding-edge dev versions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Let the Blade onerror handler show the academic cap icon instead of
falling back to a random stock photo when no course image is uploaded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds COLORS constant (16 Tailwind color names mapped to hex), hexColor(),
badgeStyle(), and nextAvailableColor() methods. Adds color Select field
and color badge column to CreditCategoryResource.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread database/migrations/create_lms_credit_categories_table.php.stub Outdated
Comment thread src/Models/CreditCategory.php
scottgrayson and others added 3 commits March 25, 2026 15:42
…table

Add disableOptionsWhenSelectedInSiblingRepeaterItems() to credit category
select to prevent duplicate entry SQL errors. Add dynamic color to credit
category badges in the course table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The migration defaulted color to 'gray' which isn't a valid key in
CreditCategory::COLORS, causing issues with the form Select dropdown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The UI handles missing course images with an icon, so the config
fallback to course_image_placeholder_url is dead code. Updated tests
to expect null when no media is attached.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread resources/views/components/course-card.blade.php Outdated
scottgrayson and others added 2 commits March 26, 2026 09:50
- Add 'any' option to credit category filter on Dashboard and CourseResource
  to show courses with at least one credit category
- Extract credit-badge Blade component with backdrop-blur for readability
- Use Color::hex() for badge colors instead of Color::all() lookup
- Remove unused badgeStyle() method from CreditCategory model
- Lighten course card fallback background from gray-300 to gray-100

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces JS onerror approach with always-rendered fallback icon as base
layer and absolutely-positioned image on top. Handles null URLs (skips
img tag) and broken URLs (visibility hidden on error). Works reliably
across Livewire re-renders.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread src/Resources/CourseResource.php Outdated
…ering

- Add CreditCategory and CourseCreditCategory factories
- Update credit category migration stubs with full schema
- Add relationships and config for credit category models
- Update dashboard with credit category filtering and improved layout
- Add CreditCategoryResource admin configuration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread src/Models/Course.php
Use Str::beforeLast instead of Str::before to handle category names
containing colons, and consolidate the duplicated color callback into
a reusable static method on CreditCategory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
scottgrayson and others added 4 commits March 26, 2026 12:53
The steps collection is already verified non-empty above, so first()
cannot return null here. The ?? fallback handles the null case.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Step::progress() relationship is scoped to Auth::id(), so using
it when $userId differs from the authenticated user returns incorrect
data. Add the same guard used by completedByUserAt to fall through
to the StepUser query for other users.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Color::hex() returns array<int, string> (shade palette), not array{int, int, int} (RGB tuple).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread src/Models/CreditCategory.php Outdated
…cache

The static $hexMap persisted across the entire PHP process lifetime,
meaning changes to credit categories wouldn't reflect in badge colors
until the process restarted (Octane, queue workers). Laravel's once()
helper caches per-request and flushes automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@scottgrayson scottgrayson merged commit bec14cd into 4.x Mar 26, 2026
8 checks passed
@scottgrayson scottgrayson deleted the course-ext-id-fix branch March 26, 2026 17:27
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