Add Portfolio and Bookshop QR types with tailored landing pages.
Deploy Ladill QR Plus / deploy (push) Successful in 58s
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:
@@ -103,6 +103,38 @@ class QrCodeManagerService
|
||||
}
|
||||
}
|
||||
|
||||
if ($type === QrCode::TYPE_PORTFOLIO) {
|
||||
if (($data['portfolio_avatar'] ?? null) instanceof UploadedFile) {
|
||||
$content['avatar_path'] = $this->storeMenuBrandImage($user, $data['portfolio_avatar'], 'portfolio-avatars');
|
||||
}
|
||||
if (($data['portfolio_cover'] ?? null) instanceof UploadedFile) {
|
||||
$content['cover_path'] = $this->storeMenuBrandImage($user, $data['portfolio_cover'], 'portfolio-covers');
|
||||
}
|
||||
$content['projects'] = $this->injectListImages(
|
||||
$user,
|
||||
$content['projects'] ?? [],
|
||||
$data['project_images'] ?? [],
|
||||
'portfolio-projects',
|
||||
'image_path',
|
||||
);
|
||||
}
|
||||
|
||||
if ($type === QrCode::TYPE_BOOKSHOP) {
|
||||
if (($data['bookshop_avatar'] ?? null) instanceof UploadedFile) {
|
||||
$content['avatar_path'] = $this->storeMenuBrandImage($user, $data['bookshop_avatar'], 'bookshop-avatars');
|
||||
}
|
||||
if (($data['bookshop_cover'] ?? null) instanceof UploadedFile) {
|
||||
$content['cover_path'] = $this->storeMenuBrandImage($user, $data['bookshop_cover'], 'bookshop-covers');
|
||||
}
|
||||
$content['books'] = $this->injectListImages(
|
||||
$user,
|
||||
$content['books'] ?? [],
|
||||
$data['book_covers'] ?? [],
|
||||
'bookshop-books',
|
||||
'cover_path',
|
||||
);
|
||||
}
|
||||
|
||||
if ($type === QrCode::TYPE_CHURCH) {
|
||||
if (($data['church_logo'] ?? null) instanceof UploadedFile) {
|
||||
$content['logo_path'] = $this->storeMenuBrandImage($user, $data['church_logo'], 'church-logos');
|
||||
@@ -245,6 +277,38 @@ class QrCodeManagerService
|
||||
}
|
||||
}
|
||||
|
||||
if ($qrCode->type === QrCode::TYPE_PORTFOLIO) {
|
||||
if (($data['portfolio_avatar'] ?? null) instanceof UploadedFile) {
|
||||
$content['avatar_path'] = $this->storeMenuBrandImage($qrCode->user, $data['portfolio_avatar'], 'portfolio-avatars');
|
||||
}
|
||||
if (($data['portfolio_cover'] ?? null) instanceof UploadedFile) {
|
||||
$content['cover_path'] = $this->storeMenuBrandImage($qrCode->user, $data['portfolio_cover'], 'portfolio-covers');
|
||||
}
|
||||
$content['projects'] = $this->injectListImages(
|
||||
$qrCode->user,
|
||||
$content['projects'] ?? [],
|
||||
$data['project_images'] ?? [],
|
||||
'portfolio-projects',
|
||||
'image_path',
|
||||
);
|
||||
}
|
||||
|
||||
if ($qrCode->type === QrCode::TYPE_BOOKSHOP) {
|
||||
if (($data['bookshop_avatar'] ?? null) instanceof UploadedFile) {
|
||||
$content['avatar_path'] = $this->storeMenuBrandImage($qrCode->user, $data['bookshop_avatar'], 'bookshop-avatars');
|
||||
}
|
||||
if (($data['bookshop_cover'] ?? null) instanceof UploadedFile) {
|
||||
$content['cover_path'] = $this->storeMenuBrandImage($qrCode->user, $data['bookshop_cover'], 'bookshop-covers');
|
||||
}
|
||||
$content['books'] = $this->injectListImages(
|
||||
$qrCode->user,
|
||||
$content['books'] ?? [],
|
||||
$data['book_covers'] ?? [],
|
||||
'bookshop-books',
|
||||
'cover_path',
|
||||
);
|
||||
}
|
||||
|
||||
if ($qrCode->type === QrCode::TYPE_CHURCH) {
|
||||
if (($data['church_logo'] ?? null) instanceof UploadedFile) {
|
||||
$content['logo_path'] = $this->storeMenuBrandImage($qrCode->user, $data['church_logo'], 'church-logos');
|
||||
@@ -354,6 +418,8 @@ class QrCodeManagerService
|
||||
QrCode::TYPE_SHOP => ['shop_title', 'sections', 'currency', 'accepts_payment', 'brand_color', 'shipping_type', 'shipping_fee', 'free_shipping_above'],
|
||||
QrCode::TYPE_APP => ['app_name', 'ios_url', 'android_url', 'web_url', 'app_icon'],
|
||||
QrCode::TYPE_BOOK => ['book_title', 'author', 'description', 'price_ghs'],
|
||||
QrCode::TYPE_PORTFOLIO => ['name', 'role', 'bio', 'email', 'phone', 'website', 'brand_color', 'projects', 'social'],
|
||||
QrCode::TYPE_BOOKSHOP => ['author_name', 'tagline', 'bio', 'email', 'website', 'brand_color', 'books', 'social'],
|
||||
QrCode::TYPE_WIFI => ['ssid', 'password', 'encryption', 'hidden'],
|
||||
default => [],
|
||||
};
|
||||
@@ -480,6 +546,36 @@ class QrCodeManagerService
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject uploaded list images (project images / book covers) into a flat list.
|
||||
*
|
||||
* @param array<int, mixed> $items
|
||||
* @param array<int, mixed> $uploads
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
private function injectListImages(User $user, array $items, array $uploads, string $subdir, string $pathKey): array
|
||||
{
|
||||
if ($uploads === []) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
foreach ($uploads as $index => $file) {
|
||||
if (! ($file instanceof UploadedFile) || ! isset($items[$index])) {
|
||||
continue;
|
||||
}
|
||||
$mime = $file->getMimeType() ?: '';
|
||||
if (! str_starts_with($mime, 'image/')) {
|
||||
continue;
|
||||
}
|
||||
$ext = $file->getClientOriginalExtension() ?: 'jpg';
|
||||
$path = $user->id.'/'.$subdir.'/'.Str::uuid()->toString().'.'.$ext;
|
||||
$file->storeAs('', $path, 'qr');
|
||||
$items[$index][$pathKey] = $path;
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
private function storeBookCover(User $user, UploadedFile $file): string
|
||||
{
|
||||
$mime = $file->getMimeType() ?: '';
|
||||
|
||||
Reference in New Issue
Block a user