fix button popup for files and datetime
This commit is contained in:
parent
022f730ae9
commit
fc39192f61
2 changed files with 136 additions and 17 deletions
|
@ -412,15 +412,35 @@ export class EventAuth {
|
||||||
|
|
||||||
private splitDateTime(dateTimeStr: string): { date: string; time: string } {
|
private splitDateTime(dateTimeStr: string): { date: string; time: string } {
|
||||||
if (!dateTimeStr) return { date: "", time: "" };
|
if (!dateTimeStr) return { date: "", time: "" };
|
||||||
|
|
||||||
|
// Create a date object in local timezone
|
||||||
const dateTime = new Date(dateTimeStr);
|
const dateTime = new Date(dateTimeStr);
|
||||||
const date = dateTime.toISOString().split('T')[0];
|
|
||||||
const time = dateTime.toTimeString().split(' ')[0].slice(0, 5);
|
// Format date as YYYY-MM-DD
|
||||||
|
const date = dateTime.toLocaleDateString('en-CA'); // en-CA gives YYYY-MM-DD format
|
||||||
|
|
||||||
|
// Format time as HH:mm
|
||||||
|
const time = dateTime.toLocaleTimeString('en-US', {
|
||||||
|
hour12: false,
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
});
|
||||||
|
|
||||||
return { date, time };
|
return { date, time };
|
||||||
}
|
}
|
||||||
|
|
||||||
private combineDateTime(date: string, time: string): string {
|
private combineDateTime(date: string, time: string): string {
|
||||||
if (!date || !time) return "";
|
if (!date || !time) return "";
|
||||||
return `${date}T${time}:00`;
|
|
||||||
|
// Create a new Date object from the date and time strings
|
||||||
|
const [year, month, day] = date.split('-').map(Number);
|
||||||
|
const [hours, minutes] = time.split(':').map(Number);
|
||||||
|
|
||||||
|
// Create date in local timezone
|
||||||
|
const dateTime = new Date(year, month - 1, day, hours, minutes);
|
||||||
|
|
||||||
|
// Format the date to ISO string with timezone offset
|
||||||
|
return dateTime.toISOString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getFileNameFromUrl(url: string): string {
|
private getFileNameFromUrl(url: string): string {
|
||||||
|
|
|
@ -141,7 +141,7 @@
|
||||||
d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"
|
d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"
|
||||||
></path>
|
></path>
|
||||||
<path
|
<path
|
||||||
d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z"
|
d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5z"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
Open in New Tab
|
Open in New Tab
|
||||||
|
@ -163,6 +163,27 @@
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
|
<!-- File Viewer Modal -->
|
||||||
|
<dialog id="fileViewer" class="modal">
|
||||||
|
<div class="modal-box w-11/12 max-w-5xl">
|
||||||
|
<div class="flex justify-between items-center mb-4">
|
||||||
|
<h3 class="font-bold text-lg" id="fileViewerTitle">Event Files</h3>
|
||||||
|
<form method="dialog">
|
||||||
|
<button class="btn btn-sm btn-circle btn-ghost">✕</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="fileViewerContent"
|
||||||
|
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
|
||||||
|
>
|
||||||
|
<!-- Files will be dynamically inserted here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form method="dialog" class="modal-backdrop">
|
||||||
|
<button>close</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { StoreAuth } from "../auth/StoreAuth";
|
import { StoreAuth } from "../auth/StoreAuth";
|
||||||
import { EventCheckIn } from "../auth/EventCheckIn";
|
import { EventCheckIn } from "../auth/EventCheckIn";
|
||||||
|
@ -310,11 +331,10 @@
|
||||||
hasFiles && isPastEvent
|
hasFiles && isPastEvent
|
||||||
? `
|
? `
|
||||||
<button
|
<button
|
||||||
class="btn btn-ghost btn-xs view-files"
|
class="btn btn-ghost btn-xs gap-2"
|
||||||
data-event-id="${event.id}"
|
onclick="document.getElementById('fileViewer').showModal(); document.dispatchEvent(new CustomEvent('viewEventFiles', { detail: { eventId: '${event.id}' } }))"
|
||||||
onclick="document.dispatchEvent(new CustomEvent('viewEventFiles', { detail: { eventId: '${event.id}' } }))"
|
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" viewBox="0 0 20 20" fill="currentColor">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
|
||||||
<path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4z" clip-rule="evenodd" />
|
<path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4z" clip-rule="evenodd" />
|
||||||
</svg>
|
</svg>
|
||||||
${event.files.length} File${event.files.length > 1 ? "s" : ""}
|
${event.files.length} File${event.files.length > 1 ? "s" : ""}
|
||||||
|
@ -480,26 +500,105 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add event listener for viewing files
|
// Add event listener for viewing files
|
||||||
const handleViewFiles = (e: Event) => {
|
interface ViewEventFilesEvent extends CustomEvent {
|
||||||
|
detail: {
|
||||||
|
eventId: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("viewEventFiles", ((e: Event) => {
|
||||||
if (e instanceof CustomEvent && "eventId" in e.detail) {
|
if (e instanceof CustomEvent && "eventId" in e.detail) {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const event = await pb
|
const event = await pb
|
||||||
.collection("events")
|
.collection("events")
|
||||||
.getOne(e.detail.eventId);
|
.getOne(e.detail.eventId);
|
||||||
document.dispatchEvent(
|
const fileViewerContent =
|
||||||
new CustomEvent("showEventFiles", {
|
document.getElementById("fileViewerContent");
|
||||||
detail: { event },
|
const fileViewerTitle =
|
||||||
})
|
document.getElementById("fileViewerTitle");
|
||||||
);
|
|
||||||
|
if (fileViewerContent && fileViewerTitle) {
|
||||||
|
fileViewerTitle.textContent = `Files - ${event.event_name}`;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!event.files ||
|
||||||
|
!Array.isArray(event.files) ||
|
||||||
|
event.files.length === 0
|
||||||
|
) {
|
||||||
|
fileViewerContent.innerHTML = `
|
||||||
|
<div class="col-span-full text-center py-4 opacity-70">
|
||||||
|
No files available
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileViewerContent.innerHTML = event.files
|
||||||
|
.map((file) => {
|
||||||
|
const fileUrl = pb.files.getURL(event, file);
|
||||||
|
const fileName =
|
||||||
|
file.split("/").pop() || "File";
|
||||||
|
const fileExt =
|
||||||
|
fileName.split(".").pop()?.toLowerCase() ||
|
||||||
|
"";
|
||||||
|
|
||||||
|
let preview = "";
|
||||||
|
if (
|
||||||
|
["jpg", "jpeg", "png", "gif"].includes(
|
||||||
|
fileExt
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
preview = `
|
||||||
|
<div class="aspect-video bg-base-300 rounded-t-lg overflow-hidden">
|
||||||
|
<img src="${fileUrl}" alt="${fileName}" class="w-full h-full object-contain">
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
preview = `
|
||||||
|
<div class="aspect-video bg-base-300 rounded-t-lg flex items-center justify-center">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 opacity-50" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="card bg-base-200">
|
||||||
|
${preview}
|
||||||
|
<div class="card-body p-4">
|
||||||
|
<h3 class="card-title text-sm truncate" title="${fileName}">${fileName}</h3>
|
||||||
|
<div class="card-actions justify-end">
|
||||||
|
<a href="${fileUrl}" target="_blank" class="btn btn-ghost btn-sm gap-2">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z" />
|
||||||
|
<path d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z" />
|
||||||
|
</svg>
|
||||||
|
Open
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.join("");
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to load event files:", err);
|
console.error("Failed to load event files:", err);
|
||||||
|
const fileViewerContent =
|
||||||
|
document.getElementById("fileViewerContent");
|
||||||
|
if (fileViewerContent) {
|
||||||
|
fileViewerContent.innerHTML = `
|
||||||
|
<div class="col-span-full text-center py-4 text-error">
|
||||||
|
Failed to load files. Please try again.
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
};
|
}) as unknown as EventListener);
|
||||||
|
|
||||||
document.addEventListener("viewEventFiles", handleViewFiles);
|
|
||||||
|
|
||||||
// Initial render
|
// Initial render
|
||||||
renderEvents();
|
renderEvents();
|
||||||
|
|
Loading…
Reference in a new issue