import AccordianItem from './accordian-item' import { Col, InputGroup, Row, Form as BootstrapForm, Badge } from 'react-bootstrap' import { Checkbox, CheckboxGroup, Form, Input, MarkdownInput } from './form' import FeeButton, { FeeButtonProvider } from './fee-button' import { gql, useApolloClient, useLazyQuery } from '@apollo/client' import { useCallback, useMemo, useState } from 'react' import { useRouter } from 'next/router' import { MAX_TERRITORY_DESC_LENGTH, POST_TYPES, TERRITORY_BILLING_OPTIONS, TERRITORY_PERIOD_COST } from '@/lib/constants' import { territorySchema } from '@/lib/validate' import { useMe } from './me' import Info from './info' import { abbrNum } from '@/lib/format' import { purchasedType } from '@/lib/territory' import { SUB } from '@/fragments/subs' import { usePaidMutation } from './use-paid-mutation' import { UNARCHIVE_TERRITORY, UPSERT_SUB } from '@/fragments/paidAction' export default function TerritoryForm ({ sub }) { const router = useRouter() const client = useApolloClient() const { me } = useMe() const [upsertSub] = usePaidMutation(UPSERT_SUB) const [unarchiveTerritory] = usePaidMutation(UNARCHIVE_TERRITORY) const schema = territorySchema({ client, me, sub }) const [fetchSub] = useLazyQuery(SUB) const [archived, setArchived] = useState(false) const onNameChange = useCallback(async (formik, e) => { // never show "territory archived" warning during edits if (sub) return const name = e.target.value const { data } = await fetchSub({ variables: { sub: name } }) setArchived(data?.sub?.status === 'STOPPED') }, [fetchSub, setArchived]) const onSubmit = useCallback( async ({ ...variables }) => { const { error, payError } = archived ? await unarchiveTerritory({ variables }) : await upsertSub({ variables: { oldName: sub?.name, ...variables } }) if (error) throw error if (payError) return // modify graphql cache to include new sub client.cache.modify({ fields: { subs (existing = [], { readField }) { const newSubRef = client.cache.writeFragment({ data: { __typename: 'Sub', name: variables.name }, fragment: gql` fragment SubSubmitFragment on Sub { name }` }) if (existing.some(ref => readField('name', ref) === variables.name)) { return existing } return [...existing, newSubRef] } } }) await router.push(`/~${variables.name}`) }, [client, upsertSub, unarchiveTerritory, router, archived] ) const [billing, setBilling] = useState((sub?.billingType || 'MONTHLY').toLowerCase()) const lineItems = useMemo(() => { const lines = { territory: TERRITORY_BILLING_OPTIONS('first')[billing] } if (!sub) return lines // we are changing billing type so prorate the change if (sub?.billingType?.toLowerCase() !== billing) { const alreadyBilled = TERRITORY_PERIOD_COST(purchasedType(sub)) lines.paid = { term: `- ${abbrNum(alreadyBilled)} sats`, label: 'already paid', op: '-', modifier: cost => cost - alreadyBilled } return lines } }, [sub, billing]) return (
~} onChange={onNameChange} warn={archived && (
this territory is archived
  • This territory got archived because the previous founder did not pay for the upkeep
  • You can proceed but will inherit the old content
)} /> sats} /> {sub?.billingType !== 'ONCE' && <> billing {sub && sub.billingType !== 'ONCE' && You will be credited what you paid for your current billing period when you change your billing period to a longer duration. If you change from yearly to monthly, when your year ends, your monthly billing will begin. } } name='billing' groupClassName={billing !== 'once' ? 'mb-0' : ''} > checked && setBilling('monthly')} groupClassName='ms-1 mb-0' /> checked && setBilling('yearly')} groupClassName='ms-1 mb-0' /> checked && setBilling('once')} groupClassName='ms-1 mb-0' /> {billing !== 'once' && } } options} body={ <> moderation enable moderation
  1. Outlaw posts and comments with a click
  2. Your territory will get a moderated badge
} name='moderated' groupClassName='ms-1' /> nsfw mark as nsfw
  1. Let stackers know that your territory may contain explicit content
  2. Your territory will get a nsfw badge
} name='nsfw' groupClassName='ms-1' /> } />
) }