Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
# Checkout the actual branch, not a specific commit
ref: ${{ github.head_ref || github.ref_name }}
# Fetch the full history to avoid shallow clone issues
fetch-depth: 0

- name: Run Laravel Pint
uses: aglipanci/laravel-pint-action@latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}

- name: Validate composer.json and composer.lock
run: composer validate --strict
Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"spatie/laravel-package-tools": "^1.19"
},
"require-dev": {
"eclipsephp/catalogue-plugin": "dev-main",
"laravel/pint": "^1.21",
"orchestra/testbench": "^10.1",
"pestphp/pest": "^3.7",
Expand Down
124 changes: 124 additions & 0 deletions resources/dist/slider-column.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
[x-cloak] { display: none !important; }

.image-preview-lightbox-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999 !important;
background-color: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(10px);
display: flex;
align-items: center;
justify-content: center;
padding: 80px;
}

.image-preview-lightbox-container {
position: relative;
max-width: 90vw;
max-height: 90vh;
display: flex;
align-items: center;
justify-content: center;
z-index: 9999 !important;
}

.image-preview-lightbox-close {
position: absolute;
top: -50px;
right: 0;
color: white;
background: none;
border: none;
cursor: pointer;
padding: 10px;
opacity: 0.8;
transition: opacity 0.2s;
}

.image-preview-lightbox-close:hover {
opacity: 1;
}

.image-preview-lightbox-close svg {
width: 32px;
height: 32px;
}

.image-preview-lightbox-image-wrapper {
position: relative;
display: flex;
align-items: center;
justify-content: center;
background-color: #1f2937;
border-radius: 8px;
overflow: hidden;
max-width: 90vw;
max-height: 85vh;
}

.image-preview-lightbox-image {
max-width: 100%;
max-height: 85vh;
width: auto;
height: auto;
object-fit: contain;
display: block;
}

.image-preview-lightbox-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(255, 255, 255, 0.1);
color: white;
border: none;
border-radius: 50%;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: background-color 0.2s;
}

.image-preview-lightbox-nav:hover {
background-color: rgba(255, 255, 255, 0.2);
}

.image-preview-lightbox-nav.prev {
left: -60px;
}

.image-preview-lightbox-nav.next {
right: -60px;
}

.image-preview-lightbox-nav svg {
width: 24px;
height: 24px;
}

.image-preview-lightbox-info {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(to top, rgba(0, 0, 0, 0.9), transparent);
padding: 24px;
color: white;
border-radius: 0 0 8px 8px;
}

.image-preview-lightbox-title {
font-size: 18px;
font-weight: 600;
margin: 0 0 8px 0;
}

.image-preview-lightbox-link {
margin: 8px 0 0 0;
}
155 changes: 155 additions & 0 deletions resources/dist/slider-column.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
window.imagePreviewLightbox = function() {
return {
isOpen: false,
currentIndex: 0,
images: [],
currentImage: {
url: '',
title: '',
link: '',
filename: ''
},

getDisplayName() {
return this.currentImage.title || this.currentImage.filename || '';
},

init() {
const self = this;
document.addEventListener('click', function(e) {
if (e.target.classList.contains('image-preview-trigger')) {
e.preventDefault();
e.stopPropagation();
self.openFromTable(e.target);
}
}, true);
document.addEventListener('keydown', (e) => {
if (this.isOpen) {
if (e.key === 'ArrowLeft') {
e.preventDefault();
this.previous();
} else if (e.key === 'ArrowRight') {
e.preventDefault();
this.next();
}
}
});
},

openFromTable(imageElement) {
const allRows = document.querySelectorAll('tbody tr');
this.images = [];
let clickedIndex = 0;

const imageGrid = [];
let maxColumns = 0;

allRows.forEach((row) => {
const rowImages = row.querySelectorAll('.fi-ta-image .image-preview-trigger');
const rowImageArray = Array.from(rowImages);
imageGrid.push(rowImageArray);
maxColumns = Math.max(maxColumns, rowImageArray.length);
});

let clickedRowIndex = -1;
let clickedColIndex = -1;

imageGrid.forEach((rowImages, rowIndex) => {
rowImages.forEach((img, colIndex) => {
if (img === imageElement) {
clickedRowIndex = rowIndex;
clickedColIndex = colIndex;
}
});
});

imageGrid.forEach((rowImages, rowIndex) => {
rowImages.forEach((img, colIndex) => {
this.addImageToCollection(img, imageElement, () => {
if (rowIndex === clickedRowIndex && colIndex === clickedColIndex) {
clickedIndex = this.images.length - 1;
}
});
});
});

if (this.images.length > 0) {
this.currentIndex = clickedIndex;
this.updateCurrentImage();
this.open();
}
},

addImageToCollection(img, imageElement, onMatch) {
const configData = img.dataset.lightboxConfig;

if (configData) {
try {
const lightboxData = JSON.parse(configData);
const matchingImageData = lightboxData.find(data =>
img.src.includes(data.url) || data.url.includes(img.src) || data.url === img.src
);

if (matchingImageData) {
this.images.push({
url: img.src,
title: matchingImageData.title || '',
link: matchingImageData.link || '',
filename: img.alt || ''
});

if (img === imageElement) {
onMatch();
}
return;
}
} catch (e) {
console.error('Error parsing lightbox config:', e);
}
}

const imageData = {
url: img.src,
title: '',
link: '',
filename: img.alt || ''
};

this.images.push(imageData);

if (img === imageElement) {
onMatch();
}
},

open() {
this.isOpen = true;
document.body.style.overflow = 'hidden';
},

close() {
this.isOpen = false;
document.body.style.overflow = '';
},

next() {
if (this.images.length > 0) {
this.currentIndex = (this.currentIndex + 1) % this.images.length;
this.updateCurrentImage();
}
},

previous() {
if (this.images.length > 0) {
this.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length;
this.updateCurrentImage();
}
},

updateCurrentImage() {
if (this.images[this.currentIndex]) {
this.currentImage = this.images[this.currentIndex];
}
}
};
};
36 changes: 36 additions & 0 deletions resources/views/components/placeholder-image.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@php
$centerX = $width / 2;
$centerY = $height / 2;
$area = $width * $height;
$averageDimension = sqrt($area);
$fontSize = max(20, min(64, $averageDimension / 2.5));
$aspectRatio = max($width, $height) / min($width, $height);
if ($aspectRatio > 3) {
$fontSize *= 0.9;
}

$fontSize = round($fontSize, 1);
@endphp
<svg width="{{ $width }}px" height="{{ $height }}px" viewBox="0 0 {{ $width }} {{ $height }}"
fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="{{ $width }}" height="{{ $height }}" fill="#EFF1F3" />
@if ($text)
<text x="{{ $centerX }}" y="{{ $centerY }}" text-anchor="middle" dominant-baseline="central"
fill="#687787" font-family="Arial, sans-serif" font-size="{{ $fontSize }}" font-weight="400">
{{ $text }}
</text>
@else
@php
$scale = min($width, $height) / 120;
$iconWidth = 120 * $scale;
$iconHeight = 120 * $scale;
$offsetX = ($width - $iconWidth) / 2;
$offsetY = ($height - $iconHeight) / 2;
@endphp
<g transform="translate({{ $offsetX }}, {{ $offsetY }}) scale({{ $scale }})">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M33.2503 38.4816C33.2603 37.0472 34.4199 35.8864 35.8543 35.875H83.1463C84.5848 35.875 85.7503 37.0431 85.7503 38.4816V80.5184C85.7403 81.9528 84.5807 83.1136 83.1463 83.125H35.8543C34.4158 83.1236 33.2503 81.957 33.2503 80.5184V38.4816ZM80.5006 41.1251H38.5006V77.8751L62.8921 53.4783C63.9172 52.4536 65.5788 52.4536 66.6039 53.4783L80.5006 67.4013V41.1251ZM43.75 51.6249C43.75 54.5244 46.1005 56.8749 49 56.8749C51.8995 56.8749 54.25 54.5244 54.25 51.6249C54.25 48.7254 51.8995 46.3749 49 46.3749C46.1005 46.3749 43.75 48.7254 43.75 51.6249Z"
fill="#687787" />
</g>
@endif
</svg>
45 changes: 45 additions & 0 deletions resources/views/components/slider-column-lightbox.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<div x-data="imagePreviewLightbox()" x-init="init()">
<div x-show="isOpen"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
@click="close()"
@keydown.escape.window="close()"
class="image-preview-lightbox-overlay"
x-cloak>

<div class="image-preview-lightbox-container" @click.stop>
<button type="button" @click.stop="close()" class="image-preview-lightbox-close">
<x-filament::icon icon="heroicon-o-x-mark" />
</button>

<div class="image-preview-lightbox-image-wrapper">
<img :src="currentImage.url"
:alt="getDisplayName()"
class="image-preview-lightbox-image">
<div class="image-preview-lightbox-info" x-show="currentImage.title || currentImage.link">
<p class="image-preview-lightbox-title" x-text="currentImage.title" x-show="currentImage.title"></p>
<p class="image-preview-lightbox-link" x-show="currentImage.link">
<a :href="currentImage.link" target="_blank" class="text-blue-400 hover:text-blue-300">
<x-filament::icon icon="heroicon-o-arrow-top-right-on-square" class="w-5 h-5" />
</a>
</p>
</div>
</div>
<template x-if="images && images.length > 1">
<div>
<button type="button" @click.stop.prevent="previous()" class="image-preview-lightbox-nav prev">
<x-filament::icon icon="heroicon-o-chevron-left" />
</button>

<button type="button" @click.stop.prevent="next()" class="image-preview-lightbox-nav next">
<x-filament::icon icon="heroicon-o-chevron-right" />
</button>
</div>
</template>
</div>
</div>
</div>
Loading