added tab management

This commit is contained in:
chark1es 2025-02-21 02:17:11 -08:00
parent fd5af1e2fa
commit ec0478f77f

View file

@ -2,6 +2,7 @@
import { Authentication } from "../../scripts/pocketbase/Authentication";
import { Update } from "../../scripts/pocketbase/Update";
import { FileManager } from "../../scripts/pocketbase/FileManager";
import { Get } from "../../scripts/pocketbase/Get";
// Form sections
import PRSection from "./Officer_EventRequestForm/PRSection";
@ -9,9 +10,48 @@ import EventDetailsSection from "./Officer_EventRequestForm/EventDetailsSection"
import TAPSection from "./Officer_EventRequestForm/TAPSection";
import ASFundingSection from "./Officer_EventRequestForm/ASFundingSection";
interface EventRequest {
id: string;
created: string;
event_name: string;
event_description: string;
location: string;
start_date: string;
end_date: string;
status: 'draft' | 'pending' | 'approved' | 'rejected';
has_food: boolean;
[key: string]: any; // For other fields we might need
}
interface ListResponse<T> {
page: number;
perPage: number;
totalItems: number;
totalPages: number;
items: T[];
}
const auth = Authentication.getInstance();
const update = Update.getInstance();
const fileManager = FileManager.getInstance();
const get = Get.getInstance();
// Get user's submitted event requests
let userEventRequests: ListResponse<EventRequest> = {
page: 1,
perPage: 50,
totalItems: 0,
totalPages: 0,
items: []
};
if (auth.isAuthenticated()) {
try {
userEventRequests = await get.getList<EventRequest>("event_request", 1, 50, `requested_user = "${auth.getUserId()}"`, "-created");
} catch (error) {
console.error("Failed to fetch event requests:", error);
}
}
---
<div class="w-full max-w-4xl mx-auto p-6">
@ -21,6 +61,38 @@ const fileManager = FileManager.getInstance();
Event Request Form
</h1>
<div class="tabs-container">
<!-- Tab Navigation -->
<div class="tabs tabs-boxed bg-base-200/50 backdrop-blur-sm p-1 rounded-lg mb-6">
<input type="radio" name="form_tabs" id="new-request-tab" class="tab-toggle" checked />
<input type="radio" name="form_tabs" id="my-requests-tab" class="tab-toggle" />
<div class="w-full flex">
<label for="new-request-tab" class="tab flex-1 tab-lg transition-all duration-200">
<div class="flex items-center justify-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd" />
</svg>
New Request
</div>
</label>
<label for="my-requests-tab" class="tab flex-1 tab-lg transition-all duration-200">
<div class="flex items-center justify-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z" />
<path fill-rule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm3 4a1 1 0 000 2h.01a1 1 0 100-2H7zm3 0a1 1 0 000 2h3a1 1 0 100-2h-3zm-3 4a1 1 0 100 2h.01a1 1 0 100-2H7zm3 0a1 1 0 100 2h3a1 1 0 100-2h-3z" clip-rule="evenodd" />
</svg>
My Requests
{userEventRequests.items.length > 0 && (
<span class="badge badge-primary badge-sm">{userEventRequests.items.length}</span>
)}
</div>
</label>
</div>
<!-- Tab Content -->
<div class="tab-panels mt-6">
<div class="tab-panel" id="new-request-panel">
<form id="eventRequestForm" class="space-y-8">
<div class="card bg-base-100/95 backdrop-blur-md shadow-lg">
<div class="card-body">
@ -102,10 +174,140 @@ const fileManager = FileManager.getInstance();
</form>
</div>
<div class="tab-panel hidden" id="my-requests-panel">
<div class="space-y-4">
{userEventRequests.items.length === 0 ? (
<div class="text-center py-8 text-base-content/70">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-12 w-12 mx-auto mb-4 opacity-50"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M5 3a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2V5a2 2 0 00-2-2H5zm0 2h10v7h-2l-1 2H8l-1-2H5V5z"
clip-rule="evenodd"
/>
</svg>
<p>No event requests found</p>
</div>
) : (
<div class="grid gap-4">
{userEventRequests.items.map((request) => (
<div class="card bg-base-100/95 backdrop-blur-md shadow-lg">
<div class="card-body">
<h3 class="card-title text-lg">
{request.event_name || "Untitled Event"}
{request.status === "draft" && (
<span class="badge badge-outline">Draft</span>
)}
{request.status === "pending" && (
<span class="badge badge-warning">Pending</span>
)}
{request.status === "approved" && (
<span class="badge badge-success">Approved</span>
)}
{request.status === "rejected" && (
<span class="badge badge-error">Rejected</span>
)}
</h3>
<p class="text-sm opacity-70">
Submitted: {new Date(request.created).toLocaleDateString()}
</p>
<div class="flex gap-2 mt-4">
<button class="btn btn-sm btn-outline" onclick=`editRequest('${request.id}')`>
Edit
</button>
<button class="btn btn-sm btn-ghost" onclick=`viewRequest('${request.id}')`>
View Details
</button>
</div>
</div>
</div>
))}
</div>
)}
</div>
</div>
</div>
</div>
</div>
</div>
<style>
/* Hide radio inputs but keep them functional */
.tab-toggle {
position: absolute;
opacity: 0;
pointer-events: none;
}
/* Style tabs */
.tab {
@apply text-base-content/70 hover:text-base-content;
}
/* Active tab styles */
#new-request-tab:checked ~ .w-full label[for="new-request-tab"],
#my-requests-tab:checked ~ .w-full label[for="my-requests-tab"] {
@apply bg-base-100 text-primary tab-active shadow-sm;
}
/* Show/hide panels based on radio selection */
#new-request-tab:checked ~ .tab-panels #new-request-panel {
display: block;
}
#my-requests-tab:checked ~ .tab-panels #my-requests-panel {
display: block;
}
.tab-panel {
display: none;
}
.tab-panels {
min-height: 300px;
}
/* Smooth transitions */
.tab {
transition: all 0.2s ease-in-out;
}
.badge {
transition: all 0.2s ease-in-out;
}
</style>
<script>
import { Authentication } from "../../scripts/pocketbase/Authentication";
import { Update } from "../../scripts/pocketbase/Update";
import { FileManager } from "../../scripts/pocketbase/FileManager";
import { Get } from "../../scripts/pocketbase/Get";
// Add TypeScript interfaces
interface EventRequest {
id: string;
created: string;
event_name: string;
event_description: string;
location: string;
start_date: string;
end_date: string;
status: 'draft' | 'pending' | 'approved' | 'rejected';
has_food: boolean;
[key: string]: any; // For other fields we might need
}
// Extend Window interface
declare global {
interface Window {
editRequest: (requestId: string) => void;
viewRequest: (requestId: string) => void;
}
}
// Form visibility logic
const form = document.getElementById("eventRequestForm") as HTMLFormElement;
@ -271,4 +473,90 @@ const fileManager = FileManager.getInstance();
setTimeout(() => toast.remove(), 3000);
}
});
// Remove the old tab switching logic and add new event listeners for the radio buttons
const tabToggles = document.querySelectorAll('.tab-toggle');
const tabPanels = document.querySelectorAll('.tab-panel');
tabToggles.forEach(toggle => {
toggle.addEventListener('change', (e) => {
const target = e.target as HTMLInputElement;
const panelId = target.id.replace('-tab', '-panel');
// Hide all panels
tabPanels.forEach(panel => {
panel.classList.add('hidden');
});
// Show selected panel
const selectedPanel = document.getElementById(panelId);
if (selectedPanel) {
selectedPanel.classList.remove('hidden');
}
});
});
// Edit request handler
window.editRequest = (requestId: string) => {
// Load the request data into the form
const get = Get.getInstance();
get.getOne<EventRequest>("event_request", requestId)
.then((request: EventRequest) => {
// Populate form fields with request data
const form = document.getElementById('eventRequestForm');
if (form) {
for (const [key, value] of Object.entries(request)) {
const input = form.querySelector(`[name="${key}"]`) as HTMLInputElement | null;
if (input) {
input.value = value;
}
}
// Switch to the form tab
const newRequestTab = document.querySelector('[data-tab="new-request"]') as HTMLElement;
if (newRequestTab) {
newRequestTab.click();
}
}
})
.catch((error: Error) => {
console.error("Failed to load request:", error);
alert("Failed to load request. Please try again.");
});
};
// View request handler
window.viewRequest = (requestId: string) => {
// Open a modal with request details
const get = Get.getInstance();
get.getOne<EventRequest>("event_request", requestId)
.then((request: EventRequest) => {
const modal = document.createElement('dialog');
modal.className = 'modal';
modal.innerHTML = `
<div class="modal-box">
<h3 class="font-bold text-lg">${request.event_name || "Untitled Event"}</h3>
<div class="py-4 space-y-2">
<p><strong>Status:</strong> ${request.status}</p>
<p><strong>Description:</strong> ${request.event_description || "No description"}</p>
<p><strong>Location:</strong> ${request.location || "No location"}</p>
<p><strong>Start Date:</strong> ${new Date(request.start_date).toLocaleString()}</p>
<p><strong>End Date:</strong> ${new Date(request.end_date).toLocaleString()}</p>
${request.has_food ? '<p><strong>Food:</strong> Yes</p>' : ''}
</div>
<div class="modal-action">
<form method="dialog">
<button class="btn">Close</button>
</form>
</div>
</div>
`;
document.body.appendChild(modal);
modal.showModal();
})
.catch((error: Error) => {
console.error("Failed to load request:", error);
alert("Failed to load request details. Please try again.");
});
};
</script>