Add unlisted event status: hidden from listings but accessible by URL
- Backend: add 'unlisted' to schema enum and Zod validation; allow booking for unlisted events - Frontend: Event type and guards updated; unlisted events bookable, excluded from public listing/sitemap - Admin: badge, status dropdown, Make Unlisted / Make Public / Unpublish actions; scanner/emails/tickets include unlisted Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -10,7 +10,7 @@ import Button from '@/components/ui/Button';
|
||||
import Input from '@/components/ui/Input';
|
||||
import MediaPicker from '@/components/MediaPicker';
|
||||
import { MoreMenu, DropdownItem, AdminMobileStyles } from '@/components/admin/MobileComponents';
|
||||
import { PlusIcon, PencilIcon, TrashIcon, EyeIcon, PhotoIcon, DocumentDuplicateIcon, ArchiveBoxIcon, StarIcon, XMarkIcon } from '@heroicons/react/24/outline';
|
||||
import { PlusIcon, PencilIcon, TrashIcon, EyeIcon, PhotoIcon, DocumentDuplicateIcon, ArchiveBoxIcon, StarIcon, XMarkIcon, LinkIcon } from '@heroicons/react/24/outline';
|
||||
import { StarIcon as StarIconSolid } from '@heroicons/react/24/solid';
|
||||
import toast from 'react-hot-toast';
|
||||
import clsx from 'clsx';
|
||||
@@ -40,7 +40,7 @@ export default function AdminEventsPage() {
|
||||
price: number;
|
||||
currency: string;
|
||||
capacity: number;
|
||||
status: 'draft' | 'published' | 'cancelled' | 'completed' | 'archived';
|
||||
status: 'draft' | 'published' | 'unlisted' | 'cancelled' | 'completed' | 'archived';
|
||||
bannerUrl: string;
|
||||
externalBookingEnabled: boolean;
|
||||
externalBookingUrl: string;
|
||||
@@ -225,8 +225,8 @@ export default function AdminEventsPage() {
|
||||
|
||||
const getStatusBadge = (status: string) => {
|
||||
const styles: Record<string, string> = {
|
||||
draft: 'badge-gray', published: 'badge-success', cancelled: 'badge-danger',
|
||||
completed: 'badge-info', archived: 'badge-gray',
|
||||
draft: 'badge-gray', published: 'badge-success', unlisted: 'badge-warning',
|
||||
cancelled: 'badge-danger', completed: 'badge-info', archived: 'badge-gray',
|
||||
};
|
||||
return <span className={`badge ${styles[status] || 'badge-gray'}`}>{status}</span>;
|
||||
};
|
||||
@@ -359,6 +359,7 @@ export default function AdminEventsPage() {
|
||||
className="w-full px-4 py-3 rounded-btn border border-secondary-light-gray">
|
||||
<option value="draft">Draft</option>
|
||||
<option value="published">Published</option>
|
||||
<option value="unlisted">Unlisted</option>
|
||||
<option value="cancelled">Cancelled</option>
|
||||
<option value="completed">Completed</option>
|
||||
<option value="archived">Archived</option>
|
||||
@@ -515,6 +516,21 @@ export default function AdminEventsPage() {
|
||||
<PencilIcon className="w-4 h-4" />
|
||||
</button>
|
||||
<MoreMenu>
|
||||
{(event.status === 'draft' || event.status === 'published') && (
|
||||
<DropdownItem onClick={() => handleStatusChange(event, 'unlisted')}>
|
||||
<LinkIcon className="w-4 h-4 mr-2" /> Make Unlisted
|
||||
</DropdownItem>
|
||||
)}
|
||||
{event.status === 'unlisted' && (
|
||||
<DropdownItem onClick={() => handleStatusChange(event, 'published')}>
|
||||
Make Public
|
||||
</DropdownItem>
|
||||
)}
|
||||
{(event.status === 'published' || event.status === 'unlisted') && (
|
||||
<DropdownItem onClick={() => handleStatusChange(event, 'draft')}>
|
||||
Unpublish
|
||||
</DropdownItem>
|
||||
)}
|
||||
<DropdownItem onClick={() => handleDuplicate(event)}>
|
||||
<DocumentDuplicateIcon className="w-4 h-4 mr-2" /> Duplicate
|
||||
</DropdownItem>
|
||||
@@ -588,6 +604,21 @@ export default function AdminEventsPage() {
|
||||
Publish
|
||||
</DropdownItem>
|
||||
)}
|
||||
{(event.status === 'draft' || event.status === 'published') && (
|
||||
<DropdownItem onClick={() => handleStatusChange(event, 'unlisted')}>
|
||||
<LinkIcon className="w-4 h-4 mr-2" /> Make Unlisted
|
||||
</DropdownItem>
|
||||
)}
|
||||
{event.status === 'unlisted' && (
|
||||
<DropdownItem onClick={() => handleStatusChange(event, 'published')}>
|
||||
Make Public
|
||||
</DropdownItem>
|
||||
)}
|
||||
{(event.status === 'published' || event.status === 'unlisted') && (
|
||||
<DropdownItem onClick={() => handleStatusChange(event, 'draft')}>
|
||||
Unpublish
|
||||
</DropdownItem>
|
||||
)}
|
||||
{event.status === 'published' && (
|
||||
<DropdownItem onClick={() => handleSetFeatured(featuredEventId === event.id ? null : event.id)}>
|
||||
<StarIcon className="w-4 h-4 mr-2" />
|
||||
|
||||
Reference in New Issue
Block a user