Files
kycnotme/web/src/pages/service-suggestion/[id].astro
2025-05-21 07:03:39 +00:00

173 lines
4.8 KiB
Plaintext

---
import { Icon } from 'astro-icon/components'
import { actions } from 'astro:actions'
import AdminOnly from '../../components/AdminOnly.astro'
import Chat from '../../components/Chat.astro'
import ServiceCard from '../../components/ServiceCard.astro'
import { getServiceSuggestionStatusInfo } from '../../constants/serviceSuggestionStatus'
import BaseLayout from '../../layouts/BaseLayout.astro'
import { cn } from '../../lib/cn'
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,
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,
categories: {
select: {
name: true,
icon: true,
},
},
},
},
messages: {
select: {
id: true,
content: true,
createdAt: true,
user: {
select: {
id: true,
name: 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)
---
<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`,
},
]}
>
<h1 class="font-title mt-12 mb-6 text-center text-3xl font-bold">Edit service</h1>
<AdminOnly>
<a
href={`/admin/service-suggestions/${serviceSuggestionIdRaw}`}
class="border-day-500/30 bg-day-500/10 text-day-400 hover:bg-day-500/20 focus:ring-day-500 inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm shadow-xs transition-colors duration-200 focus:ring-2 focus:ring-offset-2 focus:ring-offset-black focus:outline-hidden"
>
<Icon name="ri:lock-line" class="size-4" />
View in admin
</a>
</AdminOnly>
<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 grid grid-cols-2 gap-6 text-sm">
<div class="flex flex-wrap items-center gap-2">
<span>Status:</span>
<span
class={cn(
'border-night-500 bg-night-800 box-content inline-flex h-8 items-center justify-center gap-1 rounded-full border px-2',
statusInfo.iconClass
)}
>
<Icon name={statusInfo.icon} class="size-4" />
{statusInfo.label}
</span>
</div>
<div class="flex flex-wrap items-center gap-2">
<span>Submitted:</span>
<span>
{
formatDateShort(serviceSuggestion.createdAt, {
prefix: false,
hourPrecision: true,
caseType: 'sentence',
})
}
</span>
</div>
</div>
<div class="mt-6">
<div class="text-day-200 mb-2 text-sm">Notes for moderators:</div>
{
serviceSuggestion.notes ? (
<div class="text-sm wrap-anywhere whitespace-pre-wrap" set:text={serviceSuggestion.notes} />
) : (
<span class="text-sm italic">Empty</span>
)
}
</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>