186 lines
5.5 KiB
Plaintext
186 lines
5.5 KiB
Plaintext
---
|
|
import { Icon } from 'astro-icon/components'
|
|
import { actions } from 'astro:actions'
|
|
|
|
import AdminOnly from '../../components/AdminOnly.astro'
|
|
import BadgeSmall from '../../components/BadgeSmall.astro'
|
|
import Button from '../../components/Button.astro'
|
|
import Chat from '../../components/Chat.astro'
|
|
import ServiceCard from '../../components/ServiceCard.astro'
|
|
import { getServiceSuggestionStatusInfo } from '../../constants/serviceSuggestionStatus'
|
|
import { getServiceSuggestionTypeInfo } from '../../constants/serviceSuggestionType'
|
|
import BaseLayout from '../../layouts/BaseLayout.astro'
|
|
import { parseIntWithFallback } from '../../lib/numbers'
|
|
import { prisma } from '../../lib/prisma'
|
|
import { makeLoginUrl } from '../../lib/redirectUrls'
|
|
import { formatDateShort } from '../../lib/timeAgo'
|
|
|
|
const user = Astro.locals.user
|
|
if (!user) {
|
|
return Astro.redirect(makeLoginUrl(Astro.url, { message: 'Login to view service suggestion' }))
|
|
}
|
|
|
|
const { id: serviceSuggestionIdRaw } = Astro.params
|
|
const serviceSuggestionId = parseIntWithFallback(serviceSuggestionIdRaw)
|
|
if (!serviceSuggestionId) {
|
|
return Astro.rewrite('/404')
|
|
}
|
|
|
|
const serviceSuggestion = await Astro.locals.banners.try('Error fetching service suggestion', async () =>
|
|
prisma.serviceSuggestion.findUnique({
|
|
select: {
|
|
id: true,
|
|
type: true,
|
|
status: true,
|
|
notes: true,
|
|
createdAt: true,
|
|
service: {
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
slug: true,
|
|
description: true,
|
|
overallScore: true,
|
|
kycLevel: true,
|
|
imageUrl: true,
|
|
verificationStatus: true,
|
|
acceptedCurrencies: true,
|
|
serviceVisibility: true,
|
|
categories: {
|
|
select: {
|
|
name: true,
|
|
icon: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
messages: {
|
|
select: {
|
|
id: true,
|
|
content: true,
|
|
createdAt: true,
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
displayName: true,
|
|
picture: true,
|
|
},
|
|
},
|
|
},
|
|
orderBy: {
|
|
createdAt: 'desc',
|
|
},
|
|
},
|
|
},
|
|
where: {
|
|
id: serviceSuggestionId,
|
|
userId: user.id,
|
|
},
|
|
})
|
|
)
|
|
|
|
if (!serviceSuggestion) {
|
|
if (user.admin) return Astro.redirect(`/admin/service-suggestions/${serviceSuggestionIdRaw}`)
|
|
return Astro.rewrite('/404')
|
|
}
|
|
|
|
const statusInfo = getServiceSuggestionStatusInfo(serviceSuggestion.status)
|
|
const typeInfo = getServiceSuggestionTypeInfo(serviceSuggestion.type)
|
|
---
|
|
|
|
<BaseLayout
|
|
pageTitle={`${serviceSuggestion.service.name} | Service suggestion`}
|
|
description="View your service suggestion"
|
|
ogImage={{
|
|
template: 'generic',
|
|
title: 'My service suggestions',
|
|
description: 'View and manage your service suggestion',
|
|
icon: 'ri:service-line',
|
|
}}
|
|
widthClassName="max-w-screen-md"
|
|
htmx
|
|
breadcrumbs={[
|
|
{
|
|
name: 'Service suggestions',
|
|
url: '/service-suggestion',
|
|
},
|
|
{
|
|
name: `${serviceSuggestion.service.name} | Service suggestion`,
|
|
},
|
|
]}
|
|
>
|
|
<div class="mt-12 mb-6 text-center">
|
|
<h1 class="font-title text-center text-3xl font-bold">Service suggestion</h1>
|
|
<div class="flex items-center justify-center gap-2">
|
|
<AdminOnly>
|
|
<Button
|
|
as="a"
|
|
href={`/admin/service-suggestions/${serviceSuggestionIdRaw}`}
|
|
size="sm"
|
|
icon="ri:lock-line"
|
|
label="View in admin"
|
|
/>
|
|
</AdminOnly>
|
|
</div>
|
|
</div>
|
|
|
|
<ServiceCard service={serviceSuggestion.service} class="mb-6" />
|
|
|
|
<section class="border-night-400 bg-night-600 rounded-lg border p-6">
|
|
<div class="text-day-200 xs:grid-cols-2 grid gap-2 text-sm">
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<span class="font-title font-bold">Status:</span>
|
|
<BadgeSmall color={statusInfo.color} text={statusInfo.label} icon={statusInfo.icon} />
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<span class="font-title font-bold">Type:</span>
|
|
<BadgeSmall color={typeInfo.color} text={typeInfo.label} icon={typeInfo.icon} />
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<span class="font-title font-bold">Submitted:</span>
|
|
<span>
|
|
{
|
|
formatDateShort(serviceSuggestion.createdAt, {
|
|
prefix: false,
|
|
hourPrecision: true,
|
|
caseType: 'sentence',
|
|
})
|
|
}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<span class="font-title font-bold">Service:</span>
|
|
<a href={`/service/${serviceSuggestion.service.slug}`} class="hover:text-day-200 text-green-400">
|
|
Open <Icon name="ri:external-link-line" class="ml-0.5 inline-block size-3 align-[-0.05em]" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-night-700 -mx-2 mt-4 rounded-lg p-2 text-sm">
|
|
<span class="font-title block font-bold">Notes for moderators:</span>
|
|
{
|
|
serviceSuggestion.notes ? (
|
|
<div class="mt-1 text-sm wrap-anywhere whitespace-pre-wrap" set:text={serviceSuggestion.notes} />
|
|
) : (
|
|
<div class="text-day-400 my-4 text-center text-sm italic">Empty</div>
|
|
)
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<Chat
|
|
messages={serviceSuggestion.messages}
|
|
title="Chat with moderators"
|
|
userId={user.id}
|
|
action={actions.serviceSuggestion.message}
|
|
formData={{
|
|
suggestionId: serviceSuggestion.id,
|
|
}}
|
|
class="mt-12"
|
|
/>
|
|
</BaseLayout>
|