diff --git a/web/components/contract-search.tsx b/web/components/contract-search.tsx
index e4b7f9cf..5bd69057 100644
--- a/web/components/contract-search.tsx
+++ b/web/components/contract-search.tsx
@@ -200,7 +200,7 @@ export function ContractSearch(props: {
}
return (
-
+
void
+ submitLabel: (length: number) => string
+ onSubmit: (contracts: Contract[]) => void | Promise
+ contractSearchOptions?: Partial[0]>
+}) {
+ const {
+ title,
+ description,
+ open,
+ setOpen,
+ submitLabel,
+ onSubmit,
+ contractSearchOptions,
+ } = props
+
+ const [contracts, setContracts] = useState([])
+ const [loading, setLoading] = useState(false)
+
+ async function addContract(contract: Contract) {
+ if (contracts.map((c) => c.id).includes(contract.id)) {
+ setContracts(contracts.filter((c) => c.id !== contract.id))
+ } else setContracts([...contracts, contract])
+ }
+
+ async function onFinish() {
+ setLoading(true)
+ await onSubmit(contracts)
+ setLoading(false)
+ setOpen(false)
+ setContracts([])
+ }
+
+ return (
+
+
+
+
+ {title}
+
+ {!loading && (
+
+ {contracts.length > 0 && (
+
+ )}
+
+
+ )}
+
+ {description}
+
+
+ {loading && (
+
+
+
+ )}
+
+
+ c.id),
+ highlightClassName:
+ '!bg-indigo-100 outline outline-2 outline-indigo-300',
+ }}
+ additionalFilter={{}} /* hide pills */
+ headerClassName="bg-white"
+ {...contractSearchOptions}
+ />
+
+
+
+ )
+}
diff --git a/web/components/editor/market-modal.tsx b/web/components/editor/market-modal.tsx
index 31c437b1..1e2c1482 100644
--- a/web/components/editor/market-modal.tsx
+++ b/web/components/editor/market-modal.tsx
@@ -1,12 +1,6 @@
import { Editor } from '@tiptap/react'
import { Contract } from 'common/contract'
-import { useState } from 'react'
-import { Button } from '../button'
-import { ContractSearch } from '../contract-search'
-import { Col } from '../layout/col'
-import { Modal } from '../layout/modal'
-import { Row } from '../layout/row'
-import { LoadingIndicator } from '../loading-indicator'
+import { SelectMarketsModal } from '../contract-select-modal'
import { embedContractCode, embedContractGridCode } from '../share-embed-button'
import { insertContent } from './utils'
@@ -17,83 +11,23 @@ export function MarketModal(props: {
}) {
const { editor, open, setOpen } = props
- const [contracts, setContracts] = useState([])
- const [loading, setLoading] = useState(false)
-
- async function addContract(contract: Contract) {
- if (contracts.map((c) => c.id).includes(contract.id)) {
- setContracts(contracts.filter((c) => c.id !== contract.id))
- } else setContracts([...contracts, contract])
- }
-
- async function doneAddingContracts() {
- setLoading(true)
+ function onSubmit(contracts: Contract[]) {
if (contracts.length == 1) {
insertContent(editor, embedContractCode(contracts[0]))
} else if (contracts.length > 1) {
insertContent(editor, embedContractGridCode(contracts))
}
- setLoading(false)
- setOpen(false)
- setContracts([])
}
return (
-
-
-
- Embed a market
-
- {!loading && (
-
- {contracts.length == 1 && (
-
- )}
- {contracts.length > 1 && (
-
- )}
-
-
- )}
-
-
- {loading && (
-
-
-
- )}
-
-
- c.id),
- highlightClassName:
- '!bg-indigo-100 outline outline-2 outline-indigo-300',
- }}
- additionalFilter={{}} /* hide pills */
- headerClassName="bg-white"
- />
-
-
-
+
+ len == 1 ? 'Embed 1 question' : `Embed grid of ${len} questions`
+ }
+ onSubmit={onSubmit}
+ />
)
}
diff --git a/web/pages/group/[...slugs]/index.tsx b/web/pages/group/[...slugs]/index.tsx
index f124e225..f1521b42 100644
--- a/web/pages/group/[...slugs]/index.tsx
+++ b/web/pages/group/[...slugs]/index.tsx
@@ -31,8 +31,6 @@ import { SEO } from 'web/components/SEO'
import { Linkify } from 'web/components/linkify'
import { fromPropz, usePropz } from 'web/hooks/use-propz'
import { Tabs } from 'web/components/layout/tabs'
-import { LoadingIndicator } from 'web/components/loading-indicator'
-import { Modal } from 'web/components/layout/modal'
import { ChoicesToggleGroup } from 'web/components/choices-toggle-group'
import { ContractSearch } from 'web/components/contract-search'
import { JoinOrLeaveGroupButton } from 'web/components/groups/groups-button'
@@ -51,6 +49,7 @@ import { Spacer } from 'web/components/layout/spacer'
import { usePost } from 'web/hooks/use-post'
import { useAdmin } from 'web/hooks/use-admin'
import { track } from '@amplitude/analytics-browser'
+import { SelectMarketsModal } from 'web/components/contract-select-modal'
export const getStaticProps = fromPropz(getStaticPropz)
export async function getStaticPropz(props: { params: { slugs: string[] } }) {
@@ -401,27 +400,12 @@ function GroupLeaderboard(props: {
function AddContractButton(props: { group: Group; user: User }) {
const { group, user } = props
const [open, setOpen] = useState(false)
- const [contracts, setContracts] = useState([])
- const [loading, setLoading] = useState(false)
const groupContractIds = useGroupContractIds(group.id)
- async function addContractToCurrentGroup(contract: Contract) {
- if (contracts.map((c) => c.id).includes(contract.id)) {
- setContracts(contracts.filter((c) => c.id !== contract.id))
- } else setContracts([...contracts, contract])
- }
-
- async function doneAddingContracts() {
- Promise.all(
- contracts.map(async (contract) => {
- setLoading(true)
- await addContractToGroup(group, contract, user.id)
- })
- ).then(() => {
- setLoading(false)
- setOpen(false)
- setContracts([])
- })
+ async function onSubmit(contracts: Contract[]) {
+ await Promise.all(
+ contracts.map((contract) => addContractToGroup(group, contract, user.id))
+ )
}
return (
@@ -437,71 +421,27 @@ function AddContractButton(props: { group: Group; user: User }) {
-
-
-
- Add markets
-
-
- Add pre-existing markets to this group, or{' '}
-
-
- create a new one
-
-
- .
-
-
- {contracts.length > 0 && (
-
- {!loading ? (
-
-
-
-
- ) : (
-
-
-
- )}
-
- )}
-
-
-
-
c.id),
- highlightClassName: '!bg-indigo-100 border-indigo-100 border-2',
- }}
- />
+ title="Add markets"
+ description={
+
+ Add pre-existing markets to this group, or{' '}
+
+
+ create a new one
+
+
+ .
-
-
+ }
+ submitLabel={(len) => `Add ${len} question${len !== 1 ? 's' : ''}`}
+ onSubmit={onSubmit}
+ contractSearchOptions={{
+ additionalFilter: { excludeContractIds: groupContractIds },
+ }}
+ />
>
)
}