174 lines
6.6 KiB
Plaintext
174 lines
6.6 KiB
Plaintext
---
|
|
import { Icon } from 'astro-icon/components'
|
|
import { actions } from 'astro:actions'
|
|
|
|
import { cn } from '../lib/cn'
|
|
import { makeLoginUrl } from '../lib/redirectUrls'
|
|
|
|
import Button from './Button.astro'
|
|
import FormTimeTrap from './FormTimeTrap.astro'
|
|
import InputHoneypotTrap from './InputHoneypotTrap.astro'
|
|
import InputRating from './InputRating.astro'
|
|
import InputText from './InputText.astro'
|
|
import InputWrapper from './InputWrapper.astro'
|
|
import UserBadge from './UserBadge.astro'
|
|
|
|
import type { Prisma } from '@prisma/client'
|
|
import type { HTMLAttributes } from 'astro/types'
|
|
|
|
type Props = Omit<HTMLAttributes<'form'>, 'action' | 'enctype' | 'method'> & {
|
|
serviceId: number
|
|
parentId?: number
|
|
commentId?: number
|
|
activeRatingComment?: Prisma.CommentGetPayload<{
|
|
select: {
|
|
id: true
|
|
rating: true
|
|
}
|
|
}> | null
|
|
}
|
|
|
|
const { serviceId, parentId, commentId, activeRatingComment, class: className, ...htmlProps } = Astro.props
|
|
|
|
const MIN_COMMENT_LENGTH = parentId ? 10 : 30
|
|
|
|
const user = Astro.locals.user
|
|
const userCommentsDisabled = user ? user.karmaUnlocks.commentsDisabled : false
|
|
---
|
|
|
|
<form
|
|
method="POST"
|
|
action={actions.comment.create}
|
|
enctype="application/x-www-form-urlencoded"
|
|
class={cn(className)}
|
|
{...htmlProps}
|
|
>
|
|
<FormTimeTrap />
|
|
<input type="hidden" name="serviceId" value={serviceId} />
|
|
{parentId && <input type="hidden" name="parentId" value={parentId} />}
|
|
|
|
<div class="space-y-1.5">
|
|
<input
|
|
type="checkbox"
|
|
id={`use-form-secret-token-${String(commentId ?? 'new')}`}
|
|
name="useFormUserSecretToken"
|
|
checked={!user}
|
|
class="peer/use-form-secret-token hidden"
|
|
/>
|
|
|
|
{
|
|
user ? (
|
|
userCommentsDisabled ? (
|
|
<div class="rounded-md border border-red-500/30 bg-red-500/10 px-3 py-2 text-center text-sm text-red-400">
|
|
<Icon name="ri:forbid-line" class="mr-1 inline h-4 w-4 align-[-0.2em]" />
|
|
You cannot comment due to low karma.
|
|
</div>
|
|
) : (
|
|
<>
|
|
<div class="text-day-400 flex items-center gap-2 text-xs peer-checked/use-form-secret-token:hidden">
|
|
<Icon name="ri:user-line" class="size-3.5" />
|
|
<span>
|
|
Commenting as: <UserBadge user={user} size="sm" class="text-green-400" />
|
|
</span>
|
|
</div>
|
|
|
|
<InputHoneypotTrap name="message" />
|
|
|
|
<div>
|
|
<textarea
|
|
id={`comment-${String(commentId ?? 'new')}`}
|
|
name="content"
|
|
required
|
|
minlength={MIN_COMMENT_LENGTH}
|
|
maxlength={2000}
|
|
rows="4"
|
|
placeholder="Write your comment..."
|
|
class="placeholder:text-day-500 focus:ring-day-500 border-night-500 bg-night-800 focus:border-night-600 max-h-128 min-h-16 w-full resize-y rounded-lg border px-2.5 py-2 text-sm focus:ring-1 focus:outline-hidden"
|
|
/>
|
|
</div>
|
|
|
|
{!parentId ? (
|
|
<div class="[&:has(input[name='rating'][value='']:checked)_[data-show-if-rating]]:hidden">
|
|
<div class="flex flex-wrap gap-4">
|
|
<InputRating name="rating" label="Rating" />
|
|
|
|
<InputWrapper label="Tags" name="tags">
|
|
<label class="flex cursor-pointer items-center gap-2">
|
|
<input type="checkbox" name="issueKycRequested" class="text-red-400" />
|
|
<span class="flex items-center gap-1 text-xs text-red-400">
|
|
<Icon name="ri:user-forbid-fill" class="size-3" />
|
|
KYC Issue
|
|
</span>
|
|
</label>
|
|
|
|
<label class="flex cursor-pointer items-center gap-2">
|
|
<input type="checkbox" name="issueFundsBlocked" class="text-orange-400" />
|
|
<span class="flex items-center gap-1 text-xs text-orange-400">
|
|
<Icon name="ri:wallet-3-fill" class="size-3" />
|
|
Funds Blocked
|
|
</span>
|
|
</label>
|
|
</InputWrapper>
|
|
|
|
<InputText
|
|
label="Order ID"
|
|
name="orderId"
|
|
inputProps={{
|
|
maxlength: 100,
|
|
placeholder: 'Order ID / URL / Proof',
|
|
class: 'bg-night-800',
|
|
}}
|
|
descriptionLabel="Only visible to admins, to verify your comment"
|
|
class="grow"
|
|
/>
|
|
</div>
|
|
|
|
<div class="mt-4 flex items-start justify-end gap-2">
|
|
{!!activeRatingComment?.rating && (
|
|
<div
|
|
class="rounded-sm bg-yellow-500/10 px-2 py-1.5 text-xs text-yellow-400"
|
|
data-show-if-rating
|
|
>
|
|
<Icon name="ri:information-line" class="mr-1 inline size-3.5" />
|
|
<a
|
|
href={`${Astro.url.origin}${Astro.url.pathname}#comment-${activeRatingComment.id}`}
|
|
class="inline-flex items-center gap-1 underline"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
Your previous rating
|
|
<Icon name="ri:external-link-line" class="inline size-2.5 align-[-0.1em]" />
|
|
</a>
|
|
of
|
|
{[
|
|
activeRatingComment.rating.toLocaleString(),
|
|
<Icon name="ri:star-fill" class="inline size-3 align-[-0.1em]" />,
|
|
]}
|
|
won't count for the total.
|
|
</div>
|
|
)}
|
|
|
|
<Button type="submit" label="Send" icon="ri:send-plane-2-line" />
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div class="flex items-center justify-end gap-2">
|
|
<Button type="submit" label="Reply" icon="ri:reply-line" />
|
|
</div>
|
|
)}
|
|
</>
|
|
)
|
|
) : (
|
|
<a
|
|
href={makeLoginUrl(Astro.url, { message: 'Login to comment' })}
|
|
data-astro-reload
|
|
class="font-title mb-4 inline-flex w-full items-center justify-center gap-1.5 rounded-md border border-blue-500/30 bg-blue-500/10 px-3 py-1.5 text-xs text-blue-400 shadow-xs transition-colors duration-200 hover:bg-blue-500/20 focus:ring-1 focus:ring-blue-500 focus:outline-hidden"
|
|
>
|
|
<Icon name="ri:login-box-line" class="size-3.5" />
|
|
Login to comment
|
|
</a>
|
|
)
|
|
}
|
|
</div>
|
|
</form>
|