Sales
Pipeline
Track opportunities. Close deals. Own your data.
Sign in with Microsoft
Sales
Pipeline
Win Rate
Pipeline
Avg Deal
Active
Board
List
New
Sign Out
All Stages
Prospect
Qualified
Proposal Sent
Negotiation
Closed Won
Closed Lost
All Types
New Business
Upsell
Cross Sell
Renewal
Other
Recurrent
Clear
Opportunity
Company
Stage
Type
Amount
Expected Close
Source
No opportunities yet. Create your first one.
Name
Company
Amount
Expected Close
Contact
Email
Type
New Business
Upsell
Cross Sell
Renewal
Other
Source
Referral
Inbound
Outbound
Event
Partner
Website
Social Media
Other
Notes
{ editing = false; $store.notifications.add('Updated','success'); })" class="btn btn-primary" style="width:100%;"> Save Changes
{$store.kanban.load();$store.notifications.add('Qualified','success');})" class="btn btn-primary btn-sm">Qualify
{$store.kanban.load();$store.notifications.add('Moved to Proposal Sent','success');})" class="btn btn-primary btn-sm">Send Proposal
{$store.kanban.load();$store.notifications.add('In Negotiation','success');})" class="btn btn-primary btn-sm">Begin Negotiation
Close Won
Close Lost
Proposals
Upload
No proposals uploaded yet.
Audit Trail
{$store.kanban.load();$store.notifications.add('Deleted','info');})}" class="btn btn-ghost btn-sm" style="color:var(--red);font-size:12px;"> Delete Opportunity
New Opportunity
Name *
Company *
Amount (cents)
Expected Close
Business Type
New Business
Upsell
Cross Sell
Renewal
Other
Source Channel
Referral
Inbound
Outbound
Event
Partner
Website
Social Media
Other
Contact Name
Contact Email
Recurrent deal
Recurrence Interval
Monthly
Quarterly
Semi-Annual
Annual
Notes
Cancel
{ open=false; submitting=false; $store.kanban.load(); $store.kpi.load(); $store.notifications.add('Opportunity created','success'); }).catch(()=>{ submitting=false; $store.notifications.add('Failed to create','error'); })" class="btn btn-primary" :disabled="!form.name || !form.company || submitting" x-text="submitting ? 'Creating...' : 'Create Opportunity'">
Reason *
Competitor (optional)
Final Amount (cents)
Notes
Cancel
{ open=false; submitting=false; $store.kanban.load(); $store.kpi.load(); $store.notifications.add(outcome==='won'?'Deal won!':'Deal closed as lost','success'); }).catch((e)=>{ submitting=false; $store.notifications.add(e.response?.data?.error||'Failed','error'); })" class="btn" :class="outcome==='won' ? 'btn-primary' : 'btn-danger'" style="min-width:100px;" :disabled="!form.reason || submitting" x-text="submitting ? 'Closing...' : (outcome==='won' ? 'Confirm Won' : 'Confirm Lost')">
Upload Proposal
File
Notes (optional)
Cancel
r.json()).then(async (data) => { await fetch(data.uploadUrl, { method: 'PUT', body: file, headers: { 'Content-Type': file.type } }); await fetch('/api/opportunities/' + oppId + '/proposals/complete', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem('sales_token') }, body: JSON.stringify({ proposalId: data.proposalId, version: data.version, fileName: file.name, fileType: file.type, fileSize: file.size, s3Key: data.s3Key, notes }) }); $store.opportunities.loadOne(oppId); open = false; uploading = false; $store.notifications.add('Proposal uploaded', 'success'); }).catch(() => { uploading = false; $store.notifications.add('Upload failed', 'error'); }); " class="btn btn-primary" :disabled="!file || uploading" x-text="uploading ? 'Uploading...' : 'Upload'">