-
-
Notifications
You must be signed in to change notification settings - Fork 180
Feat: QR Code Generator plugin v1.0.0 #628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ahaasco
wants to merge
34
commits into
SonicJs-Org:main
Choose a base branch
from
ahaasco:feat/qr-code-plugin
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- STACK.md - Technologies and dependencies - ARCHITECTURE.md - System design and patterns - STRUCTURE.md - Directory layout - CONVENTIONS.md - Code style and patterns - TESTING.md - Test structure - INTEGRATIONS.md - External services
- STACK.md - Technologies and dependencies - ARCHITECTURE.md - System design and patterns - STRUCTURE.md - Directory layout - CONVENTIONS.md - Code style and patterns - TESTING.md - Test structure - INTEGRATIONS.md - External services - CONCERNS.md - Technical debt and issues
Fix HTMX form action attribute that was causing POST requests to malformed URLs like:
POST /admin/redirects/%22/admin/redirects%22
The issue was caused by nested template literals that included extra quotes around
the formAction variable, resulting in literal quote characters being embedded in the URL.
Changed from:
${isEdit ? `hx-put="${formAction}"` : `hx-post="${formAction}"`}
To:
hx-${isEdit ? 'put' : 'post'}="${formAction}"
This ensures the HTTP method is dynamically set without introducing extra quotes
in the URL path.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add comprehensive console logging to POST and PUT handlers in redirect admin routes to help diagnose validation failures. Logs include: - Parsed form body - Constructed input object - Service validation results - Error messages when returning 400 status This will help identify why valid form submissions are getting rejected with 400 Bad Request. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…I consistency Replace custom layout functions in redirect templates with the shared renderAdminLayoutCatalyst template from @sonicjs-cms/core/templates. Benefits: - Eliminates code duplication (removed ~100 lines of duplicate layout code) - Ensures consistent UI/UX across all admin pages - Automatically includes standard admin features (mobile sidebar, user dropdown, migration banner, notifications, etc.) - Easier to maintain - layout updates apply to all admin pages - Preserves custom dialog backdrop styling via inline styles The redirect admin pages now match the standard SonicJS admin design system and will automatically benefit from future admin layout enhancements. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added "Redirects" menu item to both admin layout templates (Catalyst and v2). Menu item appears between "Users" and "Plugins" in the sidebar, pointing to /admin/redirects. Issue: PluginBuilder.addMenuItem() was being called correctly by the plugin, but SonicJS core doesn't yet have a dynamic menu system that collects menu items from plugins. As a workaround, manually added the menu item to the hardcoded baseMenuItems arrays in both layout templates. This enables users to access the redirect management UI from the admin sidebar. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add manifest.json with plugin metadata and permissions - Define TypeScript interfaces for QR codes - Include ErrorCorrectionLevel type and all CRUD interfaces
- Add color-validator for hex color validation and normalization - Add url-validator for QR destination URL validation - Add contrast-checker for WCAG contrast ratio calculation - All utilities tested and working correctly
- Add plugin entry point with PluginBuilder - Register lifecycle hooks (placeholder implementations) - Add metadata for plugin registration - Prepared for service registration in Plan 02
- Add qrcode-svg@^1.1.0 to dependencies - Add @types/qrcode-svg@^1.1.5 to devDependencies - Pure JavaScript QR library with no Canvas dependencies - Compatible with Cloudflare Workers edge runtime Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Implement QRService class with CRUD operations (create, getById, list, update, delete) - Add generate() method using qrcode-svg with 4-module quiet zone - Integrate validation utilities (color, URL, contrast checking) - Support all error correction levels (L, M, Q, H) - Return both SVG string and data URL from generate() - Create qr_codes table migration with soft delete support - Add plugin settings management - Add lifecycle methods (install, activate, deactivate, uninstall) - 620 lines of comprehensive service implementation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Import QRService from services/qr.service - Register service with builder.addService as singleton - Update lifecycle hooks to use QRService methods - Install hook creates QRService and calls install() - Activate hook creates QRService and calls activate() - Deactivate hook calls deactivate() and cleans up - Uninstall hook calls uninstall() and cleans up - Configure hook calls saveSettings() - Export QRService and types for external use Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Install linkedom for SVG DOM manipulation - Create svg-shapes.ts with path generators for all shape variants - Export CornerShape (square, rounded, dots, extra-rounded) - Export DotShape (square, rounded, dots, diamond) - Export getPathGenerator helper function
- Add SvgCustomizer class for post-processing qrcode-svg output - Implement eye region detection (7x7 at three corners) - Support cornerShape, dotShape, and eyeColor options - Use linkedom for SVG DOM parsing - Handle 4-module quiet zone padding in position calculations - Export customize() and generateCustomizedSvg() methods
- Add CornerShape type (square, rounded, dots, extra-rounded) - Add DotShape type (square, rounded, dots, diamond) - Add cornerShape, dotShape, eyeColor to QRCode interface - Add shape fields to CreateQRCodeInput and UpdateQRCodeInput - Add shape options to QRCodeGenerateOptions - Add default shape settings to QRGeneratorSettings
- LogoEmbedder class with embed() method for SVG composition - Enforces 25% max logo coverage (safe for scannability) - Adds white padding (10% default) behind logo for visibility - Preserves logo aspect ratio in positioning - Helper methods: calculateAspectRatio, isValidLogoDataUrl, estimateLogoSize - Convenience embedLogo function exported Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migration 002_add_logo_and_shapes.sql: - logo_url, logo_aspect_ratio, error_correction_before_logo columns - corner_shape, dot_shape, eye_color columns - Updates plugin version to 1.1.0 Types updates: - QRCode interface: logoUrl, logoAspectRatio, errorCorrectionBeforeLogo - CreateQRCodeInput: logoUrl, logoAspectRatio - UpdateQRCodeInput: logoUrl, logoAspectRatio - QRCodeGenerateOptions: logoUrl, logoAspectRatio Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ervice QRService updates: - Import and use SvgCustomizer for shape customization - Import and use LogoEmbedder for logo embedding - generate() uses join:false when shapes/eyeColor needed - generate() forces Level H when logo is present (STYLE-04) - create() stores error_correction_before_logo when logo added - update() restores error correction when logo removed - mapRowToQRCode includes all Phase 2 fields - Updated SQL queries for Phase 2 columns Requirements implemented: - STYLE-03: Logo embedding via LogoEmbedder - STYLE-04: Automatic Level H with logo, restoration on removal - STYLE-05: Corner shape customization - STYLE-06: Dot shape customization - STYLE-07: Eye color customization Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add @cf-wasm/resvg for edge-compatible SVG-to-PNG conversion - Create PngExporter class with export() method - Support DPI options: 72 (web), 150 (screen), 300 (print) - Support transparent background option - Include size estimation and warning utilities - Export convenience exportPng function
- Add DpiOption type (72 | 150 | 300)
- Add ExportFormat type ('svg' | 'png')
- Add PngExportOptions interface with dpi and transparent options
- Add PngExportResult interface with buffer, dimensions, size
- Update QRCodeGenerateOptions with exportFormat and pngOptions
- Update QRCodeGenerateResult with optional png field
- Import PngExporter and PNG export types - Add private pngExporter instance - Add generatePng() for direct PNG generation with DPI options - Add generateForRecordAsPng() for PNG from stored QR code - Add estimatePngSize() for size warnings in UI - Support transparent background option - Size warning for files over 5MB
- Add RedirectIntegration class for QR-redirect module communication
- getSourcePath() builds /qr/{shortCode} redirect paths
- getScanCount() queries redirect_analytics for scan tracking
- redirectExists() validates short code collision checking
- invalidateCache() wraps redirect cache invalidation
- Update create() to atomically insert QR code + redirect via D1 batch()
- Generate unique short code and create redirect with /qr/{code} path
- Update update() to atomically update redirect when destination changes
- Update delete() to atomically soft-delete QR code and redirect
- Add short_code to all SELECT queries and mapRowToQRCode
- Invalidate redirect cache after all redirect modifications
- Add RedirectIntegration instance for facade methods
- Create qr-redirect.ts with GET /qr/:code handler - Return 302 redirect for active QR codes - Return 410 Gone with branded expired page for deleted/inactive codes - Register route in plugin index.ts with public access Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add optional scanCount field to QRCode interface - Update list() to JOIN with redirects and redirect_analytics - Update getById() to include scan count from analytics - Map scan_count column to scanCount in mapRowToQRCode() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tasks completed: 2/2 - QR redirect route handler with expired page - Scan count integration in QR listing SUMMARY: .planning/phases/03-redirect-integration/03-03-SUMMARY.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create routes/admin.ts with GET / handler for list page - Add placeholder routes for /new, /:id/edit, POST /, PUT /:id - Implement DELETE /:id handler for QR code deletion - Register admin routes at /admin/qr-codes in index.ts - Add QR Codes menu item with order 86 in admin sidebar Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create qr-list.template.ts with QRListPageData interface - Render table with Preview, Name, URL, Scans, Created, Actions columns - Add HTMX search input with debounced filtering (300ms delay) - Add scan count badges with color coding (gray/blue/green/purple) - Add relative time formatting for created dates - Add delete confirmation dialog with scan count warning - Add pagination controls for multi-page results - Add empty state with contextual messaging Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create qr-preview.template.ts with renderQRPreview function - Display QR code SVG in centered container with shadow - Show short URL with copy-friendly code styling - Add download buttons for SVG and PNG formats - Include DPI selector for existing QR codes (72/150/300) - Add renderQRPreviewLoading and renderQRPreviewError helpers - Support exactOptionalPropertyTypes with explicit undefined types Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- GET /new renders create form with default settings and initial preview - GET /:id/edit renders edit form with QR code data and current preview - POST /preview returns preview partial HTML for HTMX updates - Import renderQRFormPage and renderQRPreview from templates
- POST / creates QR code via QRService.create() and redirects to list - PUT /:id updates QR code via QRService.update() and redirects to list - DELETE /:id soft-deletes QR code via QRService.delete() and returns JSON - GET /:id/preview returns SVG thumbnail for list view - GET /:id/download/png returns PNG file with specified DPI - All routes have proper error handling and logging
Added QR Codes navigation item to both admin-layout-catalyst and admin-layout-v2 templates, positioned after Redirects.
- Add custom settings page with file upload for default logo - Fix SVG preview for eye color and shape customization - Fix responsive preview sizing (280x280) - Reduce logo size to 5% area coverage (~22% width) - Encode short URL in QR codes for redirect tracking - Pre-provision short codes for new QR codes - Add redirect-management as plugin dependency - Update plugin author to ahaas Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Pass defaultSettings to form template when creating new QR codes - Form values now properly initialize from plugin settings - Default logo from settings is pre-populated in the form - Fix settings form to use proper <form> element for FormData - Preview endpoint uses plugin settings for fallback defaults Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Features
Test plan
🤖 Generated with Claude Code