Add Portfolio and Bookshop QR types with tailored landing pages.
Deploy Ladill QR Plus / deploy (push) Successful in 58s

Portfolio showcases freelancer work projects; Bookshop lists author titles with multi-platform purchase links. Includes create/edit forms, public assets, and tests.
This commit is contained in:
isaacclad
2026-07-16 20:56:52 +00:00
parent 95d73d1367
commit d83a314bee
13 changed files with 989 additions and 1 deletions
@@ -329,6 +329,51 @@ class QrScanController extends Controller
return Storage::disk('qr')->response($path);
}
public function portfolioAvatar(string $shortCode): StreamedResponse
{
return $this->serveContentImage($shortCode, QrCode::TYPE_PORTFOLIO, 'avatar_path');
}
public function portfolioCover(string $shortCode): StreamedResponse
{
return $this->serveContentImage($shortCode, QrCode::TYPE_PORTFOLIO, 'cover_path');
}
public function portfolioProjectImage(string $shortCode, int $index): StreamedResponse
{
return $this->serveListImage($shortCode, QrCode::TYPE_PORTFOLIO, 'projects', $index, 'image_path');
}
public function bookshopAvatar(string $shortCode): StreamedResponse
{
return $this->serveContentImage($shortCode, QrCode::TYPE_BOOKSHOP, 'avatar_path');
}
public function bookshopCover(string $shortCode): StreamedResponse
{
return $this->serveContentImage($shortCode, QrCode::TYPE_BOOKSHOP, 'cover_path');
}
public function bookshopBookCover(string $shortCode, int $index): StreamedResponse
{
return $this->serveListImage($shortCode, QrCode::TYPE_BOOKSHOP, 'books', $index, 'cover_path');
}
private function serveListImage(string $shortCode, string $type, string $listKey, int $index, string $pathKey): StreamedResponse
{
$qrCode = QrCode::query()
->where('short_code', $shortCode)
->where('is_active', true)
->firstOrFail();
abort_unless($qrCode->type === $type, 404);
$path = $qrCode->content()[$listKey][$index][$pathKey] ?? null;
abort_unless($path && Storage::disk('qr')->exists($path), 404);
return Storage::disk('qr')->response($path);
}
private function escapeVcard(string $value): string
{
return str_replace(["\n", "\r", ',', ';'], [' ', ' ', '\\,', '\\;'], $value);