import { Checkbox, Form, Input, MarkdownInput, SubmitButton } from './form' import TextareaAutosize from 'react-textarea-autosize' import { InputGroup, Form as BForm, Col, Image } from 'react-bootstrap' import * as Yup from 'yup' import { useEffect, useState } from 'react' import Info from './info' import AccordianItem from './accordian-item' import styles from '../styles/post.module.css' import { useLazyQuery, gql, useMutation } from '@apollo/client' import { useRouter } from 'next/router' import Link from 'next/link' import { CURRENCY_SYMBOLS, usePrice } from './price' import Avatar from './avatar' import BootstrapForm from 'react-bootstrap/Form' import Alert from 'react-bootstrap/Alert' import { useMe } from './me' import ActionTooltip from './action-tooltip' Yup.addMethod(Yup.string, 'or', function (schemas, msg) { return this.test({ name: 'or', message: msg, test: value => { if (Array.isArray(schemas) && schemas.length > 1) { const resee = schemas.map(schema => schema.isValidSync(value)) return resee.some(res => res) } else { throw new TypeError('Schemas is not correct array schema') } }, exclusive: false }) }) function satsMin2Mo (minute) { return minute * 30 * 24 * 60 } function PriceHint ({ monthly }) { const me = useMe() const price = usePrice() const fiatSymbol = CURRENCY_SYMBOLS[me?.fiatCurrency || 'USD'] if (!price || !monthly) { return null } const fixed = (n, f) => Number.parseFloat(n).toFixed(f) const fiat = fixed((price / 100000000) * monthly, 0) return {monthly} sats/mo which is {fiatSymbol}{fiat}/mo } // need to recent list items export default function JobForm ({ item, sub }) { const storageKeyPrefix = item ? undefined : `${sub.name}-job` const router = useRouter() const [logoId, setLogoId] = useState(item?.uploadId) const [upsertJob] = useMutation(gql` mutation upsertJob($id: ID, $title: String!, $company: String!, $location: String, $remote: Boolean, $text: String!, $url: String!, $maxBid: Int!, $status: String, $logo: Int) { upsertJob(sub: "${sub.name}", id: $id, title: $title, company: $company, location: $location, remote: $remote, text: $text, url: $url, maxBid: $maxBid, status: $status, logo: $logo) { id } }` ) const JobSchema = Yup.object({ title: Yup.string().required('required').trim(), company: Yup.string().required('required').trim(), text: Yup.string().required('required').trim(), url: Yup.string() .or([Yup.string().email(), Yup.string().url()], 'invalid url or email') .required('required'), maxBid: Yup.number().typeError('must be a number') .integer('must be whole').min(0, 'must be positive') .required('required'), location: Yup.string().test( 'no-remote', "don't write remote, just check the box", v => !v?.match(/\bremote\b/gi)) .when('remote', { is: (value) => !value, then: Yup.string().required('required').trim() }) }) return ( <>
{ let status if (start) { status = 'ACTIVE' } else if (stop) { status = 'STOPPED' } const { error } = await upsertJob({ variables: { id: item?.id, sub: sub.name, maxBid: Number(maxBid), status, logo: Number(logoId), ...values } }) if (error) { throw new Error({ message: error.toString() }) } if (item) { await router.push(`/items/${item.id}`) } else { await router.push(`/~${sub.name}/recent`) } })} >
remote} name='remote' hiddenLabel groupClassName={styles.inlineCheckGroup} /> how to apply url or email address} name='url' required clear /> {item && }
{item ? save : ( post 1000 sats )}
) } function PromoteJob ({ item, sub, storageKeyPrefix }) { const [monthly, setMonthly] = useState(satsMin2Mo(item?.maxBid || 0)) const [getAuctionPosition, { data }] = useLazyQuery(gql` query AuctionPosition($id: ID, $bid: Int!) { auctionPosition(sub: "${sub.name}", id: $id, bid: $bid) }`, { fetchPolicy: 'network-only' }) const position = data?.auctionPosition useEffect(() => { const initialMaxBid = Number(item?.maxBid || localStorage.getItem(storageKeyPrefix + '-maxBid')) || 0 getAuctionPosition({ variables: { id: item?.id, bid: initialMaxBid } }) setMonthly(satsMin2Mo(initialMaxBid)) }, []) return ( 0} header={
promote
} body={ <> bid
  1. The higher your bid the higher your job will rank
  2. You can increase, decrease, or remove your bid at anytime
  3. You can edit or stop your job at anytime
  4. If you run out of sats, your job will stop being promoted until you fill your wallet again
optional } name='maxBid' onChange={async (formik, e) => { if (e.target.value >= 0 && e.target.value <= 100000000) { setMonthly(satsMin2Mo(e.target.value)) getAuctionPosition({ variables: { id: item?.id, bid: Number(e.target.value) } }) } else { setMonthly(satsMin2Mo(0)) } }} append={sats/min} hint={} storageKeyPrefix={storageKeyPrefix} /> <>
This bid puts your job in position: {position}
} /> ) } function StatusControl ({ item }) { let StatusComp if (item.status !== 'STOPPED') { StatusComp = () => { return ( <> I want to stop my job} headerColor='var(--danger)' body={ stop my job} name='stop' inline /> } /> ) } } else if (item.status === 'STOPPED') { StatusComp = () => { return ( I want to resume my job} headerColor='var(--success)' body={ resume my job} name='start' inline /> } /> ) } } return (
job control {item.status === 'NOSATS' && your promotion ran out of sats. fund your wallet or reduce bid to continue promoting your job}
) }