Post MVP fixes#298
Conversation
Full landing page matching ConvertAI design reference: - sticky nav with logo, Convert/API/Pricing links, Sign in / Sign up free - hero with gradient bg, headline, CTA buttons, social proof, drag-and-drop converter visual with floating format badges - quick conversion pills (PNG→JPG, JPG→PNG, PNG→WEBP, etc.) - 6-card features grid (Image Conversion, Quality Control, REST API, Fast Processing, Secure & Private, Conversion History) - feature pills row (6 Formats, sub-second, auto-delete, API, credits) - supported formats section with colored PNG/JPG/WEBP/PDF icons - stats bar with purple→blue→orange gradient (1k+ users, 10k+ files, 4.9/5 rating, 99.9% uptime) - 3-column testimonials with avatars, names, star ratings - CTA banner with gradient border - 5-column footer with product/account/resources links - auth-aware CTAs (dashboard for logged-in users, register for guests)
- gradient circle logo (orange→pink→purple) with italic C - FileConverter brand with gradient on 'Converter' (pink→purple) - nav: Convert↓, API + New badge (pink→orange gradient pill), Pricing, History, Settings↓ - right: globe+EN language selector with border, Sign in text link, Sign up free gradient button (pink→orange, rounded-lg) - all colors via inline styles to avoid Tailwind JIT purge - sticky header with blur backdrop and subtle bottom border
- badge: sparkle icon + 'Instant Image Conversion', lavender border/bg - h1 line 1: 'Any Image.' in violet #7c3aed, 900 weight, -2px tracking - h1 line 2: 'Any Format.' in dark #111827 - h1 line 3: 'Makes It Fast.' gradient pink→orange (#ec4899→#f97316) - font-size: clamp(56px,6vw,80px) matching large reference scale - subtitle: 18px gray, max-width 420px - CTA: gradient pink→orange button (Get Started Free) + plain Sign in - social proof: 5 overlapping avatars (AS/MD/LW/PS/DC) with initials and brand colors, -10px overlap, 2.5px white border - star row: 5 amber stars inline + bold 4.9 + 'Trusted by 1k+ users'
…adding - reduced hero top padding pt-10 pb-16 (was py-20/py-28) - headline font-size clamp(64px,7.5vw,96px) + letter-spacing -3px (airier) - removed Get Started Free / Sign in buttons from hero - guests: see full dashboard-style dropzone (dashed border, upload icon, 'Drop your file here', Choose file button) — click redirects to /register - authenticated users: @livewire('dashboard.dashboard-converter') embedded - right column: social proof avatars/stars + 3 conversion cards (PNG→JPG 0.3s, JPG→WEBP 0.4s, PNG→PDF 0.5s) + security badge
…type - upload form moved to RIGHT column (card with shadow, dropzone + quick pills) - LEFT column: badge + headline + subtitle + social proof avatars/stars - headline: clamp(52px,5.5vw,72px) — slightly smaller but 900 weight, tighter - pt-16 top padding (matches reference spacing from header) - social proof (AS/MD/LW/PS/DC + stars + 4.9) directly under subtitle - right card: white bg, rounded-2xl, dashed dropzone + 3 quick conversion buttons (PNG→JPG, JPG→WEBP, PNG→PDF) + 'Already have an account? Sign in' - auth users: livewire converter embedded on right
…, CTA, tools slider) Guest conversion: - Allow conversions without an account via guest_token on files and conversion jobs - GuestConverter Livewire component and guest download route/controller - CreateConversionJobAction accepts nullable user, skips credit checks for guests Landing page: - Hero: larger headline/subtitle, tighter column gap, wider converter form - Text-only FileConverter logo (bigger, bolder, Geist) across all layouts incl. auth pages - Pixel-perfect sections from design reference: 100+ Formats chips, gradient stats bar, testimonials with photo avatars and per-card accent colors, CTA banner - Tools That Do More: pastel gradient feature cards in a scroll-snap slider - Removed quick-conversions chips and feature pills sections - SVG file-type icons in converter format cards; cursor-pointer on settings controls Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds guest-token-backed upload, conversion, and download support; simplifies several image converter option schemas; and updates branding, fonts, and shared UI components. ChangesGuest Conversion Feature
Estimated code review effort: 4 (Complex) | ~60 minutes Converter Options Schema Simplification
Estimated code review effort: 2 (Simple) | ~15 minutes Branding and UI Styling Updates
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
@CodeRabbit review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
resources/views/components/application-logo.blade.php (1)
6-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse design tokens for the logo colors
resources/views/components/application-logo.blade.phphardcodestext-gray-900and the pink/purple gradient in a reusable component; switch tovar(--ca-*)/ca-gradient-primaryor document the exception indocs/design/design-contract.md.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@resources/views/components/application-logo.blade.php` around lines 6 - 8, The application logo component is hardcoding color values instead of using the shared design tokens. Update the markup in application-logo.blade.php to replace the literal text color and gradient classes with the appropriate var(--ca-*) token or ca-gradient-primary utility, keeping the styling consistent with the design system; if this component must remain an exception, document that explicitly in docs/design/design-contract.md.Source: Coding guidelines
resources/views/components/stepper.blade.php (1)
27-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd an accessible name to the clickable stepper button.
The
<button>renders the step label as visible text, but screen readers would benefit from a more descriptivearia-label(e.g., "Go back to File step") to clarify the action, since the button navigates rather than submits.♿ Suggested accessibility improvement
<button type="button" + aria-label="Go back to {{ $label }} step" wire:click="{{ $handler }}"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@resources/views/components/stepper.blade.php` around lines 27 - 35, The stepper button in the component lacks an accessible name that describes its navigation action. Update the button element in the stepper view to include an appropriate aria-label based on the step label so screen readers announce the action clearly, and make sure the label still matches the behavior driven by the existing wire:click handler.resources/views/components/file-icon.blade.php (1)
8-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse RateGuru tokens instead of hardcoded hex colors.
The format-to-color mapping uses raw hex values (
#10b981,#f59e0b,#0ea5e9,#ef4444,#64748b) directly in the SVG fills. As per coding guidelines, reusable UI components must use RateGuru tokens and must not introduce random Tailwind color utilities unless the deviation is documented indocs/design/design-contract.md.If these colors are intentional brand choices for file-type icons, consider defining them as CSS custom properties (e.g.,
--file-png:#10b981``) in your token system and referencing them viavar(--file-png), or document the deviation in the design contract.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@resources/views/components/file-icon.blade.php` around lines 8 - 12, The file icon color mapping in the file-icon component is using hardcoded hex values instead of RateGuru tokens. Update the icon color definitions in file-icon.blade.php so the SVG fills reference approved design tokens or CSS custom properties (for example via the existing file-type mapping in the component), and if these brand colors are intentional, document the exception in design-contract.md rather than leaving raw hex values in the component.Source: Coding guidelines
routes/web.php (1)
19-21: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winConsider a throttle on the public guest download route.
This endpoint is unauthenticated and enumerable by
conversionId. Token checks in the controller prevent access, but adding->middleware('throttle:...')limits brute-force/enumeration attempts against the guest flow.🛡️ Suggestion
Route::get('/guest/conversions/{conversionId}/download', GuestDownloadConversionController::class) + ->middleware('throttle:60,1') ->name('guest.conversions.download');🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@routes/web.php` around lines 19 - 21, The guest conversion download route is public and enumerable, so add rate limiting to the Route::get definition for GuestDownloadConversionController to reduce brute-force attempts. Update the route registration in web.php to include a throttle middleware with an appropriate limit for the guest flow, keeping the existing token-based controller checks intact.app/Actions/Files/StoreUploadedFileAction.php (1)
33-49: 🩺 Stability & Availability | 🔵 TrivialGuest uploads bypass all storage limits.
For guests the entire quota/limit block is skipped and files land in
uploads/guestswith no per-session or global cap. The only guard is the client-side 10 MBmaxinGuestConverter::storeUpload, which is trivially bypassed by hitting the endpoint directly. Consider a throttle/rate limit and an aggregate size cap for guest uploads to prevent disk exhaustion.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/Actions/Files/StoreUploadedFileAction.php` around lines 33 - 49, Guest uploads are skipping the storage quota check in StoreUploadedFileAction, so the uploads/guests path has no server-side cap. Update StoreUploadedFileAction to enforce a guest storage limit as part of the existing user limit flow, using a guest-specific aggregate usage check before calling store() and Storage::disk('local'). Consider adding a shared helper in the upload/storage flow so both authenticated and guest uploads are validated consistently, and ensure GuestConverter::storeUpload is not the only protection.resources/views/livewire/guest-converter.blade.php (1)
193-198: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueInconsistent color usage.
These error blocks use raw Tailwind
red-200/red-50/red-700/red-600while the rest of this view uses the--ca-dangerdesign token (e.g. Line 121). Align for consistency.Also applies to: 282-285
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@resources/views/livewire/guest-converter.blade.php` around lines 193 - 198, The failed-state error block still uses raw Tailwind red shades instead of the existing --ca-danger token used elsewhere in this view. Update the $step === 'failed' section, and the matching error block around the other referenced range, to use the same design-token-based border/background/text classes as the rest of guest-converter.blade.php so the error styling stays consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/Livewire/GuestConverter.php`:
- Around line 61-67: The guest ownership token in Livewire should not be
writable from the client, because `guestToken` is used to scope `FileRecord` and
`ConversionJob` lookups. Update `GuestConverter::mount` and the query paths to
rely on the session-backed token directly (same source as
`GuestDownloadConversionController`) or otherwise make `guestToken`
non-hydratable/locked so payload tampering cannot redirect access to another
guest’s records.
---
Nitpick comments:
In `@app/Actions/Files/StoreUploadedFileAction.php`:
- Around line 33-49: Guest uploads are skipping the storage quota check in
StoreUploadedFileAction, so the uploads/guests path has no server-side cap.
Update StoreUploadedFileAction to enforce a guest storage limit as part of the
existing user limit flow, using a guest-specific aggregate usage check before
calling store() and Storage::disk('local'). Consider adding a shared helper in
the upload/storage flow so both authenticated and guest uploads are validated
consistently, and ensure GuestConverter::storeUpload is not the only protection.
In `@resources/views/components/application-logo.blade.php`:
- Around line 6-8: The application logo component is hardcoding color values
instead of using the shared design tokens. Update the markup in
application-logo.blade.php to replace the literal text color and gradient
classes with the appropriate var(--ca-*) token or ca-gradient-primary utility,
keeping the styling consistent with the design system; if this component must
remain an exception, document that explicitly in docs/design/design-contract.md.
In `@resources/views/components/file-icon.blade.php`:
- Around line 8-12: The file icon color mapping in the file-icon component is
using hardcoded hex values instead of RateGuru tokens. Update the icon color
definitions in file-icon.blade.php so the SVG fills reference approved design
tokens or CSS custom properties (for example via the existing file-type mapping
in the component), and if these brand colors are intentional, document the
exception in design-contract.md rather than leaving raw hex values in the
component.
In `@resources/views/components/stepper.blade.php`:
- Around line 27-35: The stepper button in the component lacks an accessible
name that describes its navigation action. Update the button element in the
stepper view to include an appropriate aria-label based on the step label so
screen readers announce the action clearly, and make sure the label still
matches the behavior driven by the existing wire:click handler.
In `@resources/views/livewire/guest-converter.blade.php`:
- Around line 193-198: The failed-state error block still uses raw Tailwind red
shades instead of the existing --ca-danger token used elsewhere in this view.
Update the $step === 'failed' section, and the matching error block around the
other referenced range, to use the same design-token-based
border/background/text classes as the rest of guest-converter.blade.php so the
error styling stays consistent.
In `@routes/web.php`:
- Around line 19-21: The guest conversion download route is public and
enumerable, so add rate limiting to the Route::get definition for
GuestDownloadConversionController to reduce brute-force attempts. Update the
route registration in web.php to include a throttle middleware with an
appropriate limit for the guest flow, keeping the existing token-based
controller checks intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f5cb3bbc-1762-4981-9950-e66547c23186
⛔ Files ignored due to path filters (5)
public/images/avatars/avatar-1.jpgis excluded by!**/*.jpgpublic/images/avatars/avatar-2.jpgis excluded by!**/*.jpgpublic/images/avatars/avatar-3.jpgis excluded by!**/*.jpgpublic/images/avatars/avatar-4.jpgis excluded by!**/*.jpgpublic/images/avatars/avatar-5.jpgis excluded by!**/*.jpg
📒 Files selected for processing (40)
app/Actions/Conversions/CreateConversionJobAction.phpapp/Actions/Conversions/RecordConversionResultFileAction.phpapp/Actions/Files/StoreUploadedFileAction.phpapp/Conversion/Drivers/Image/PngToJpgDriver.phpapp/Http/Controllers/GuestDownloadConversionController.phpapp/Jobs/ProcessConversionJob.phpapp/Livewire/GuestConverter.phpapp/Models/ConversionJob.phpapp/Models/FileRecord.phpapp/Support/Converters/Image/JpgToPdfConverter.phpapp/Support/Converters/Image/JpgToPngConverter.phpapp/Support/Converters/Image/JpgToWebpConverter.phpapp/Support/Converters/Image/PngToJpgConverter.phpapp/Support/Converters/Image/PngToPdfConverter.phpapp/Support/Converters/Image/PngToWebpConverter.phpapp/Support/Files/FileExpirationPolicy.phpdatabase/migrations/2026_06_25_130755_add_guest_token_to_conversion_jobs_table.phpdatabase/migrations/2026_06_25_130755_add_guest_token_to_files_table.phpresources/views/components/application-logo.blade.phpresources/views/components/button.blade.phpresources/views/components/file-icon.blade.phpresources/views/components/layouts/app.blade.phpresources/views/components/stepper.blade.phpresources/views/layouts/app.blade.phpresources/views/layouts/guest.blade.phpresources/views/layouts/navigation.blade.phpresources/views/livewire/dashboard/dashboard-converter.blade.phpresources/views/livewire/dashboard/dashboard-converter/fields/segmented.blade.phpresources/views/livewire/dashboard/dashboard-converter/fields/select.blade.phpresources/views/livewire/guest-converter.blade.phpresources/views/welcome.blade.phproutes/web.phptests/Feature/Auth/AuthPagesTest.phptests/Feature/Livewire/DashboardConverterSettingsStepTest.phptests/Unit/Converters/Image/JpgToPdfConverterTest.phptests/Unit/Converters/Image/JpgToPngConverterTest.phptests/Unit/Converters/Image/JpgToWebpConverterTest.phptests/Unit/Converters/Image/PngToJpgConverterTest.phptests/Unit/Converters/Image/PngToPdfConverterTest.phptests/Unit/Converters/Image/PngToWebpConverterTest.php
💤 Files with no reviewable changes (6)
- app/Support/Converters/Image/JpgToPdfConverter.php
- app/Support/Converters/Image/JpgToPngConverter.php
- app/Support/Converters/Image/PngToJpgConverter.php
- app/Support/Converters/Image/PngToPdfConverter.php
- app/Support/Converters/Image/JpgToWebpConverter.php
- app/Support/Converters/Image/PngToWebpConverter.php
…1y, design tokens - Lock guestToken with #[Locked] so it cannot be tampered with from the client - Enforce a 100MB aggregate storage quota for guest uploads (StoreUploadedFileAction) - Add aria-label to stepper back-navigation buttons - Replace raw red-* Tailwind classes with --ca-danger design tokens in guest converter error states - Rate-limit the guest conversion download route (throttle:30,1) - Align landing page section widths with hero (1320px) across header, sections, footer Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
Tests
Summary by cubic
Adds a guest converter flow and a new landing page. Guests can upload, convert, and download files without an account; files expire in 2 hours and are scoped by a session
guest_token.New Features
user_idandguest_tokenonfilesandconversion_jobs; credit checks skipped; 100 MB guest storage quota enforced; 2‑hour expiry for guest files/results.GuestConverter(upload → format → settings → convert) with progress polling and error states; guest token locked via#[Locked].PngToJpgDrivernow usesbackground_colorto match the schema; tests updated.Migration
guest_tokenand makeuser_idnullable onfilesandconversion_jobs.localstorage disk is available.Written for commit 92b95d8. Summary will update on new commits.
Summary by CodeRabbit