--- import { Icon } from 'astro-icon/components' import { actions } from 'astro:actions' import { z } from 'astro:content' import { orderBy as lodashOrderBy } from 'lodash-es' import SortArrowIcon from '../../../components/SortArrowIcon.astro' import TimeFormatted from '../../../components/TimeFormatted.astro' import UserBadge from '../../../components/UserBadge.astro' import { getServiceSuggestionStatusInfo, serviceSuggestionStatuses, } from '../../../constants/serviceSuggestionStatus' import BaseLayout from '../../../layouts/BaseLayout.astro' import { zodParseQueryParamsStoringErrors } from '../../../lib/parseUrlFilters' import { prisma } from '../../../lib/prisma' import { makeLoginUrl } from '../../../lib/redirectUrls' import type { Prisma, ServiceSuggestionStatus } from '@prisma/client' const user = Astro.locals.user if (!user?.admin) { return Astro.redirect(makeLoginUrl(Astro.url, { message: 'Admin access required' })) } const search = Astro.url.searchParams.get('search') ?? '' const statusEnumValues = serviceSuggestionStatuses.map((s) => s.value) as [string, ...string[]] const statusParam = Astro.url.searchParams.get('status') const statusFilter = z .enum(statusEnumValues) .nullable() .parse(statusParam === '' ? null : statusParam) as ServiceSuggestionStatus | null const { data: filters } = zodParseQueryParamsStoringErrors( { 'sort-by': z.enum(['service', 'status', 'user', 'createdAt', 'messageCount']).default('createdAt'), 'sort-order': z.enum(['asc', 'desc']).default('desc'), }, Astro ) const sortBy = filters['sort-by'] const sortOrder = filters['sort-order'] let prismaOrderBy: Prisma.ServiceSuggestionOrderByWithRelationInput = { createdAt: 'desc' } if (sortBy === 'createdAt') { prismaOrderBy = { createdAt: sortOrder } } let suggestions = await prisma.serviceSuggestion.findMany({ where: { ...(search ? { OR: [ { service: { name: { contains: search, mode: 'insensitive' } } }, { user: { name: { contains: search, mode: 'insensitive' } } }, { notes: { contains: search, mode: 'insensitive' } }, ], } : {}), status: statusFilter ?? undefined, }, orderBy: prismaOrderBy, select: { id: true, status: true, notes: true, createdAt: true, user: { select: { displayName: true, name: true, picture: true, }, }, service: { select: { id: true, name: true, slug: true, description: true, imageUrl: true, verificationStatus: true, categories: { select: { name: true, icon: true, }, }, }, }, messages: { select: { id: true, content: true, createdAt: true, user: { select: { id: true, name: true, }, }, }, orderBy: { createdAt: 'desc', }, take: 1, }, _count: { select: { messages: true, }, }, }, }) let suggestionsWithDetails = suggestions.map((s) => ({ ...s, statusInfo: getServiceSuggestionStatusInfo(s.status), messageCount: s._count.messages, lastMessage: s.messages[0], })) if (sortBy === 'service') { suggestionsWithDetails = lodashOrderBy( suggestionsWithDetails, [(s) => s.service.name.toLowerCase()], [sortOrder] ) } else if (sortBy === 'status') { suggestionsWithDetails = lodashOrderBy(suggestionsWithDetails, [(s) => s.statusInfo.label], [sortOrder]) } else if (sortBy === 'user') { suggestionsWithDetails = lodashOrderBy( suggestionsWithDetails, [(s) => s.user.name.toLowerCase()], [sortOrder] ) } else if (sortBy === 'messageCount') { suggestionsWithDetails = lodashOrderBy(suggestionsWithDetails, ['messageCount'], [sortOrder]) } const suggestionCount = suggestionsWithDetails.length const makeSortUrl = (slug: string) => { const currentSortBy = filters['sort-by'] const currentSortOrder = filters['sort-order'] const newSortOrder = currentSortBy === slug && currentSortOrder === 'asc' ? 'desc' : 'asc' const searchParams = new URLSearchParams(Astro.url.search) searchParams.set('sort-by', slug) searchParams.set('sort-order', newSortOrder) return `/admin/service-suggestions?${searchParams.toString()}` } ---

Service Suggestions

{suggestionCount} suggestions

Suggestions List

Scroll horizontally to see more →
{ suggestionsWithDetails.map((suggestion) => ( )) }
Service User Status Created Messages Actions
{suggestion.service.description}
{suggestion.messageCount}