--- import { Icon } from 'astro-icon/components' import { actions, isInputError } from 'astro:actions' import { orderBy } from 'lodash-es' import { SUGGESTION_DESCRIPTION_MAX_LENGTH, SUGGESTION_NAME_MAX_LENGTH, SUGGESTION_NOTES_MAX_LENGTH, SUGGESTION_SLUG_MAX_LENGTH, } from '../../actions/serviceSuggestion' import Captcha from '../../components/Captcha.astro' import InputCardGroup from '../../components/InputCardGroup.astro' import InputCheckbox from '../../components/InputCheckbox.astro' import InputCheckboxGroup from '../../components/InputCheckboxGroup.astro' import InputHoneypotTrap from '../../components/InputHoneypotTrap.astro' import InputImageFile from '../../components/InputImageFile.astro' import InputSubmitButton from '../../components/InputSubmitButton.astro' import InputText from '../../components/InputText.astro' import InputTextArea from '../../components/InputTextArea.astro' import { getAttributeCategoryInfo } from '../../constants/attributeCategories' import { getAttributeTypeInfo } from '../../constants/attributeTypes' import { contactMethodUrlTypes } from '../../constants/contactMethods' import { currencies } from '../../constants/currencies' import { kycLevelClarifications } from '../../constants/kycLevelClarifications' import { kycLevels } from '../../constants/kycLevels' import BaseLayout from '../../layouts/BaseLayout.astro' import { prisma } from '../../lib/prisma' import { makeLoginUrl } from '../../lib/redirectUrls' const user = Astro.locals.user if (!user) { return Astro.redirect(makeLoginUrl(Astro.url, { message: 'Login to suggest a new service' })) } const result = Astro.getActionResult(actions.serviceSuggestion.createService) if (result && !result.error && !result.data.hasDuplicates) { return Astro.redirect(`/service-suggestion/${result.data.serviceSuggestion.id}`) } const inputErrors = isInputError(result?.error) ? result.error.fields : {} const [categories, attributes] = await Astro.locals.banners.tryMany([ [ 'Failed to fetch categories', () => prisma.category.findMany({ orderBy: { name: 'asc' }, select: { id: true, name: true, icon: true, }, }), [], ], [ 'Failed to fetch attributes', () => prisma.attribute.findMany({ orderBy: { category: 'asc' }, select: { id: true, title: true, category: true, type: true, }, }), [], ], ]) ---

Service suggestion

Suggestions are reviewed by moderators before being public.

{ result?.data?.hasDuplicates && ( <>

Possible duplicates found

Is your service already listed below?

{result.data.possibleDuplicates.map((duplicate) => { const editServiceUrl = new URL('/service-suggestion/edit', Astro.url) editServiceUrl.searchParams.set('serviceId', duplicate.id.toString()) if (result.data.extraNotes) { editServiceUrl.searchParams.set('notes', result.data.extraNotes) } return (

{duplicate.name}

{duplicate.description}

) })}

Review your suggestion

) }
type.labelPlural).join(', ')}`, ].join('\n')} name="contactMethods" inputProps={{ placeholder: 'contact@example.com\nt.me/example\n+123 456 7890', class: 'h-full', }} class="flex flex-col self-stretch" error={inputErrors.contactMethods} />
).operatingSince} /> ({ label: kycLevel.name, value: kycLevel.id.toString(), icon: kycLevel.icon, description: `${kycLevel.description}\n\n_KYC Level ${kycLevel.value}/4_`, }))} iconSize="md" cardSize="md" required error={inputErrors.kycLevel} /> ({ label: clarification.label, value: clarification.value, icon: clarification.icon, description: clarification.description, }))} selectedValue="NONE" iconSize="sm" cardSize="sm" error={inputErrors.kycLevelClarification} />
({ label: category.name, value: category.id.toString(), icon: category.icon, }))} size="lg" error={inputErrors.categories} class="min-w-auto" /> ({ ...attribute, categoryInfo: getAttributeCategoryInfo(attribute.category), typeInfo: getAttributeTypeInfo(attribute.type), })), ['categoryInfo.order', 'typeInfo.order'] ).map((attribute) => ({ label: attribute.title, value: attribute.id.toString(), icon: [attribute.categoryInfo.icon, attribute.typeInfo.icon], iconClassName: [attribute.categoryInfo.classNames.icon, attribute.typeInfo.classNames.icon], }))} error={inputErrors.attributes} size="lg" />
({ label: currency.name, value: currency.id, icon: currency.icon, }))} error={inputErrors.acceptedCurrencies} required multiple /> I understand the suggestion rules and process