Complete homeowner journey from selecting a job type through bid acceptance. 10 screens covering creation, posting, dashboard, and bid review.
Select a saved property or add a new one.
Need a new kitchen faucet installed in our 1920s Akron home. The current Moen fixture is corroded at the base and leaking under the sink. Would prefer a pull-down sprayer style.
$200 – $500
Contractors in the Akron area are being notified. You'll receive bids soon.
Side-by-side comparison of your top bids
jobs
posterId, propertyId, jobTypeId, categoryId
title, description, status, address, city
state, zipCode, jobDetails { budget, timeline }
photos[], bidMode, biddingPreference
jobBids
jobId, contractorId, bidType, bidAmount
bidMinAmount, bidMaxAmount, bidExplanation
estimatedDays, includesMaterials, includesPermits
status, warrantyDetails
posterProperties
posterId, nickname, address, city, state
zipCode, propertyType, squareFootage
jobTypes
jobTypeId, name, categoryId, subcategoryId
description, isActive
Job Status
draft → open → pending_contract
→ pending_funding → in_progress
→ pending_completion → completed
Bid Status
pending → accepted | rejected
Escrow
pending → hold_period → funded
→ first_payout_sent → released
Hooks
useCreateJob()
usePosterProperties()
useQuery(api.jobs.jobTypes.list)
useQuery(api.jobs.bids.listForJob)
useQuery(api.jobs.bids.get)
useMutation(api.poster.jobs.acceptBid)
useMutation(api.poster.jobs.rejectBid)
Custom Hooks
useJobDetail(jobId)
useBidComparison(jobId)
api.jobs.jobs.create
title, description, jobTypeId, propertyId
address, city, state, zipCode, budget
timeline, photos[], bidMode
api.jobs.jobs.update
jobId + partial fields
api.jobs.jobs.publish
jobId → status: draft → open
api.poster.jobs.acceptBid
jobId, bidId → generates contract
api.poster.jobs.rejectBid
bidId → status: rejected