import React from 'react'
import { router, usePage } from '@inertiajs/react'
import CollectionCard from '../../components/profile/collections/CollectionCard'
import SeoHead from '../../components/seo/SeoHead'
import NovaSelect from '../../components/ui/NovaSelect'
const SEARCH_SELECT_OPTIONS = {
type: [
{ value: 'personal', label: 'Personal' },
{ value: 'community', label: 'Community' },
{ value: 'editorial', label: 'Editorial' },
],
mode: [
{ value: 'manual', label: 'Manual' },
{ value: 'smart', label: 'Smart' },
],
lifecycle_state: [
{ value: 'published', label: 'Published' },
{ value: 'featured', label: 'Featured' },
{ value: 'archived', label: 'Archived' },
],
health_state: [
{ value: 'healthy', label: 'Healthy' },
{ value: 'needs_metadata', label: 'Needs metadata' },
{ value: 'stale', label: 'Stale' },
{ value: 'low_content', label: 'Low content' },
{ value: 'broken_items', label: 'Broken items' },
{ value: 'weak_cover', label: 'Weak cover' },
{ value: 'low_engagement', label: 'Low engagement' },
{ value: 'duplicate_risk', label: 'Duplicate risk' },
{ value: 'merge_candidate', label: 'Merge candidate' },
],
sort: [
{ value: 'trending', label: 'Trending' },
{ value: 'recent', label: 'Recent' },
{ value: 'quality', label: 'Quality' },
{ value: 'evergreen', label: 'Evergreen' },
],
}
function humanizeToken(value) {
return String(value || '')
.replaceAll('_', ' ')
.replaceAll('-', ' ')
.replace(/\b\w/g, (match) => match.toUpperCase())
}
function searchChipLabel(key, value) {
if (!value) return null
const option = SEARCH_SELECT_OPTIONS[key]?.find((item) => item.value === value)
const displayValue = option?.label || humanizeToken(value)
return key === 'q'
? `Query: ${value}`
: key === 'campaign_key'
? `Campaign: ${displayValue}`
: key === 'program_key'
? `Program: ${displayValue}`
: key === 'quality_tier'
? `Quality Tier: ${displayValue}`
: key === 'sort'
? `Sort: ${displayValue}`
: `${humanizeToken(key)}: ${displayValue}`
}
function buildSearchHref(filters, omitKey = null) {
const params = new URLSearchParams()
Object.entries(filters || {}).forEach(([key, value]) => {
if (key === omitKey) return
if (value === null || value === undefined || value === '') return
params.set(key, value)
})
const query = params.toString()
return query ? `/collections/search?${query}` : '/collections/search'
}
function activeSearchChips(filters) {
return Object.entries(filters || {})
.filter(([, value]) => value !== null && value !== undefined && value !== '')
.map(([key, value]) => ({
key,
label: searchChipLabel(key, value),
href: buildSearchHref(filters, key),
}))
.filter((chip) => chip.label)
}
function primarySaveContext({ search, campaign, program, title, eyebrow }) {
if (search) {
return {
context: 'collection_search',
meta: {
query: search?.filters?.q || null,
surface_label: 'collection search',
},
}
}
if (campaign) {
return {
context: 'campaign_landing',
meta: {
campaign_key: campaign.key,
campaign_label: campaign.label,
surface_label: campaign.label || 'campaign landing',
},
}
}
if (program) {
return {
context: 'program_landing',
meta: {
program_key: program.key,
program_label: program.label,
surface_label: program.label || 'program landing',
},
}
}
if (eyebrow === 'Trending') return { context: 'trending_landing', meta: { surface_label: 'trending collections' } }
if (eyebrow === 'Editorial') return { context: 'editorial_landing', meta: { surface_label: 'editorial collections' } }
if (eyebrow === 'Community') return { context: 'community_landing', meta: { surface_label: 'community collections' } }
if (eyebrow === 'Seasonal') return { context: 'seasonal_landing', meta: { surface_label: 'seasonal collections' } }
if (title === 'Recommended collections' || title === 'Collections worth exploring') return { context: 'recommended_landing', meta: { surface_label: 'recommended collections' } }
return {
context: 'featured_landing',
meta: { surface_label: 'featured collections' },
}
}
function HeroStat({ icon, label, value }) {
return (
)
}
function EmptyState() {
return (
No featured collections yet
Featured placement is reserved for public collections with a strong visual point of view. Check back once creators start pinning their best showcases.
)
}
function SearchPanel({ search }) {
if (!search) return null
const filters = search.filters || {}
const options = search.options || {}
const chips = activeSearchChips(filters)
const [localFilters, setLocalFilters] = React.useState({
q: filters.q || '',
type: filters.type || '',
sort: filters.sort || 'trending',
category: filters.category || '',
mode: filters.mode || '',
style: filters.style || '',
lifecycle_state: filters.lifecycle_state || '',
theme: filters.theme || '',
health_state: filters.health_state || '',
color: filters.color || '',
campaign_key: filters.campaign_key || '',
program_key: filters.program_key || '',
quality_tier: filters.quality_tier || '',
})
function updateFilter(key, val) {
setLocalFilters((curr) => ({ ...curr, [key]: val }))
}
function handleSubmit(event) {
event.preventDefault()
const params = {}
Object.entries(localFilters).forEach(([k, v]) => { if (v) params[k] = v })
router.get('/collections/search', params)
}
return (
Filters
Search collections
{search?.meta?.total ?? 0} results
{chips.length ? (
) : null}
{(search?.links?.prev || search?.links?.next) ? (
{search.links.prev ?
Previous : null}
{search.links.next ?
Next : null}
) : null}
)
}
export default function CollectionFeaturedIndex() {
const { props } = usePage()
const seo = props.seo || {}
const eyebrow = props.eyebrow || 'Discovery'
const title = props.title || 'Featured collections'
const description = props.description || 'A rotating set of standout galleries from across Skinbase. Some are meticulously hand-sequenced. Others are smart collections that stay fresh as the creator publishes new work.'
const collections = Array.isArray(props.collections) ? props.collections : []
const communityCollections = Array.isArray(props.communityCollections) ? props.communityCollections : []
const editorialCollections = Array.isArray(props.editorialCollections) ? props.editorialCollections : []
const recentCollections = Array.isArray(props.recentCollections) ? props.recentCollections : []
const trendingCollections = Array.isArray(props.trendingCollections) ? props.trendingCollections : []
const seasonalCollections = Array.isArray(props.seasonalCollections) ? props.seasonalCollections : []
const campaign = props.campaign || null
const program = props.program || null
const search = props.search || null
const smartCount = collections.filter((collection) => collection?.mode === 'smart').length
const totalArtworks = collections.reduce((sum, collection) => sum + (collection?.artworks_count || 0), 0)
const mainSave = primarySaveContext({ search, campaign, program, title, eyebrow })
const listSchema = seo?.canonical ? {
'@context': 'https://schema.org',
'@type': 'CollectionPage',
name: title,
description,
url: seo.canonical,
mainEntity: {
'@type': 'ItemList',
numberOfItems: collections.length,
itemListElement: collections.slice(0, 18).map((collection, index) => ({
'@type': 'ListItem',
position: index + 1,
url: collection.url,
name: collection.title,
})),
},
} : null
return (
<>
{eyebrow}
{title}
{campaign?.badge_label ? (
{campaign.badge_label}
) : program?.promotion_tier ? (
Promotion tier: {program.promotion_tier}
) : null}
{description}
{campaign ? (
Campaign key: {campaign.key}
{campaign.event_label ? Event: {campaign.event_label} : null}
{campaign.season_key ? Season: {campaign.season_key} : null}
{Array.isArray(campaign.active_surface_keys) && campaign.active_surface_keys.length ? Surfaces: {campaign.active_surface_keys.join(', ')} : null}
) : program ? (
Program key: {program.key}
Collections: {program.collections_count ?? collections.length}
{program.trust_tier ? Trust: {program.trust_tier} : null}
{Array.isArray(program.partner_labels) && program.partner_labels.length ? Partners: {program.partner_labels.join(', ')} : null}
{Array.isArray(program.sponsorship_labels) && program.sponsorship_labels.length ? Sponsors: {program.sponsorship_labels.join(', ')} : null}
) : null}
{collections.length ? (
{collections.map((collection) => (
))}
) : (
)}
{communityCollections.length ? (
Community
Collaborative picks
{communityCollections.map((collection) => (
))}
) : null}
{trendingCollections.length ? (
Trending
Momentum right now
{trendingCollections.map((collection) => (
))}
) : null}
{editorialCollections.length ? (
Editorial
Staff and campaign collections
{editorialCollections.map((collection) => (
))}
) : null}
{seasonalCollections.length ? (
Seasonal
Campaign and event spotlights
{seasonalCollections.map((collection) => (
))}
) : null}
{recentCollections.length ? (
Recent
Freshly published collections
{recentCollections.map((collection) => (
))}
) : null}
>
)
}