Loading...
Notifications
No notifications yet
{{ new Date(n.timestamp).toLocaleString() }}
Notification Settings

{{ showRegisterForm ? 'Sign Up' : 'Login' }}

{{ loginError }}
Or continue with
Loading...

Authentication Required

Please log in to access SideKick

{{ formatQuoteNumber(currentQuote) }} - {{ currentQuote.client_name }}

Total: ${{ currentQuote.total }}
Status: {{ currentQuote.status || 'pending' }}
Address: {{ currentQuote.job_address }}

Dashboard

Overview of your contractor business

Last updated

{{ new Date().toLocaleDateString() }}

Total Quotes

{{ quotes.length }}

${{ quotes.reduce((sum, q) => sum + parseFloat(q.total || 0), 0).toFixed(2) }} total value

Active Jobs

{{ jobs.filter(j => j.status === 'active').length }}

{{ jobs.filter(j => j.status === 'pending').length }} pending

Materials

{{ materials.length }}

Inventory ready

Today's Schedule

{{ job.client_name }}

{{ job.address }}

{{ formatTime(job.scheduled_date) || 'No time set' }}

{{ job.status }}

No jobs scheduled for today

Recent Activity

{{ formatQuoteNumber(quote) }} - {{ quote.client_name }} ({{ quote.job_address.split(',')[0] }})
${{ quote.total }}

No quotes yet. Create your first quote to get started!

Quotes & Estimates

๐Ÿ“ Organize by Folder

๐Ÿ“… Auto-organized by month
{{ getCurrentFolder().icon }} {{ getCurrentFolder().name }} {{ getCurrentFolder().description }}
{{ getCurrentFolder().quote_count || 0 }} quotes โ€ข ${{ getCurrentFolder().total_value || 0 }}

{{ editingQuote ? 'Edit Quote' : 'New Quote' }}

Create a professional estimate for your client

Client Information

Leave blank for automatic monthly organization

Project Details

Line Items

Item Quantity Unit Price Total
${{ getItemPrice(item).toFixed(2) }} ${{ (getItemPrice(item) * (parseFloat(item.quantity) || 0)).toFixed(2) }}
No items added. Click "Add Item" to get started.

Labor & Pricing

$

Quote Summary

Materials Subtotal ${{ (typeof materialsSubtotal === 'number' ? materialsSubtotal : 0).toFixed(2) }}
Labor Subtotal ${{ (typeof laborSubtotal === 'number' ? laborSubtotal : 0).toFixed(2) }}
Total ${{ (currentQuote.total && parseFloat(currentQuote.total) > 0) ? parseFloat(currentQuote.total).toFixed(2) : quoteTotal }}

Price Validation Issues Detected

  • โ€ข {{ issue.message }}
Saved Total: ${{ (priceValidation && typeof priceValidation.saved_total === 'number' ? priceValidation.saved_total : 0).toFixed(2) }}
Calculated: ${{ (priceValidation && typeof priceValidation.calculated_total === 'number' ? priceValidation.calculated_total : 0).toFixed(2) }}
Materials: ${{ (priceValidation && typeof priceValidation.materials_subtotal === 'number' ? priceValidation.materials_subtotal : 0).toFixed(2) }}
Labor: ${{ (priceValidation && typeof priceValidation.labor_subtotal === 'number' ? priceValidation.labor_subtotal : 0).toFixed(2) }}
Difference: ${{ (typeof priceValidation.difference === 'number' ? priceValidation.difference : 0).toFixed(2) }}

All Prices Verified โœ“

Calculations match saved values

"Verify & Log Prices" creates a detailed log file comparing quote prices with materials library

AI-Generated Estimate

This quote was generated using AI with industry standards and current market pricing. Prices and quantities are estimates based on best practices. Please verify against retailer prices and project dimensions. AI can make mistakes - always double-check critical calculations.

Prices are averaged from multiple retailers (Lowe's, Home Depot, Menards) when available. Quantities calculated using industry-standard formulas.

๐Ÿค–

Need help with materials and pricing?

Let AI generate a complete quote based on your job description using industry standards

๐Ÿค– Generate Quote with AI

The more details you provide, the more accurate the AI estimate will be.

AI is analyzing your job description and generating an estimate...

Today's Reminders

No reminders for today

All caught up! No quotes need follow-up today.

{{ reminder.quote_number || 'Quote #' + reminder.id }} {{ reminder.status || 'pending' }}

{{ reminder.client_name }}

{{ reminder.client_email }}

{{ reminder.client_phone }}

{{ reminder.description }}

Total: ${{ reminder.total }} Follow-up: {{ reminder.follow_up_date }}

No quotes in this folder

Create a new quote or move existing quotes here

Quote # Client Total Status Folder Date Actions
{{ formatQuoteNumber(quote) }}
{{ quote.client_name }} ${{ quote.total }} {{ quote.status || 'pending' }}
{{ quote.folder_icon }} {{ quote.folder_name }}
No Folder
{{ formatDate(quote.created_at) }}

No quotes in this folder

Create a new quote or move existing quotes here

{{ formatQuoteNumber(quote) }}
{{ quote.client_name }}
{{ quote.status || 'pending' }}
Total ${{ quote.total }}
Date {{ formatDate(quote.created_at) }}
Page {{ quotePage }} / {{ quotesTotalPages }}

Manage Estimate Folders

{{ folder.icon }}

{{ folder.name }}

{{ folder.description }}

{{ folder.quote_count || 0 }} quotes ${{ folder.total_value || 0 }}
Drop quotes here to organize
๐Ÿ“‹

No Folder

Unorganized quotes

{{ quotes.filter(q => !q.folder_id).length }} quotes ${{ quotes.filter(q => !q.folder_id).reduce((sum, q) => sum + parseFloat(q.total || 0), 0).toFixed(2) }}
Drop quotes here to remove from folders

{{ editingFolder ? 'Edit Folder' : 'New Folder' }}

Jobs

{{ editingJob ? 'Edit Job' : 'New Job' }}

๐Ÿ“ Job Locations

Pending
Active
Complete

Interactive Job Map

Map will show job locations with real addresses

Current Jobs ({{ jobs.length }})

{{ job.client_name }}
No address

Map Setup

Add full addresses to jobs to enable interactive Google Maps with pins and route optimization

๐Ÿš— Route Optimization

Today's Route

{{ todaysJobs.length }} jobs scheduled

Estimated Travel

Calculating...

Distance: --

Proximity Alerts

{{ nearbyJobsCount }} nearby jobs

{{ job.client_name }}

{{ formatDate(job.scheduled_date) }}

{{ job.status }}

{{ job.address }}

{{ job.description }}

No jobs yet

Create your first job or convert a quote to get started!

Invoices

{{ formatInvoiceNumber(invoice) }}

{{ invoice.client_name }}

{{ invoice.status }}

Amount: ${{ invoice.total }}

Date: {{ formatDate(invoice.invoice_date) }}

Due: {{ formatDate(invoice.due_date) }}

Address: {{ invoice.job_address }}

No invoices yet

Complete jobs to generate invoices automatically

{{ editingInvoice ? 'Edit Invoice' : 'New Invoice' }}

๐Ÿ“ Original Quote Items

โž• Add-ons & Extra Charges

No add-ons or extra charges. Original quote items only.
Original Quote: ${{ calculateOriginalTotal() }}
Add-ons & Extras: +${{ calculateAddonsTotal() }}

Final Total: ${{ calculateInvoiceTotal() }}

Materials

{{ editingMaterial ? 'Edit Material' : 'New Material' }}

Name Description Price Unit Actions
{{ material.name }} {{ material.description }} ${{ material.price }} {{ material.unit }}
{{ material.name }}
{{ material.description }}
Price ${{ material.price }}
Unit {{ material.unit }}

๐Ÿ“ฅ Import Quote from File

1
Upload File
2
Extract Data
3
Review & Save

Drop your quote file here

or click to browse

Supports PDF, PNG, JPG files up to 10MB

{{ selectedFile.name }}

{{ formatFileSize(selectedFile.size) }} โ€ข {{ selectedFile.type }}

Processing your file...

{{ processingMessage }}

๐Ÿ“„ Smart Data Extraction

We've highlighted key information from your file. Click any highlighted item to populate the form below.

๐Ÿ“‹ Key Information Found

Client Details
Name: {{ cleanData.client_name }}
Email: {{ cleanData.client_email }}
Phone: {{ cleanData.client_phone }}
Address: {{ cleanData.job_address }}
No client info found
Quote Details
Total: ${{ cleanData.total }}
Service: {{ cleanData.service_description }}
No quote details found

๐Ÿ” Raw Extracted Text

{{ extractedText }}

Use this text to manually copy/paste any missed information

Materials

Total: ${{ calculateImportQuoteTotal() }}

Manage your clients

Clients

{{ client.name.charAt(0).toUpperCase() }}

{{ client.name }}

{{ client.email }}
{{ client.phone }}
{{ client.address }}

{{ client.notes }}

No clients yet

Add your first client to get started with repeat customer management!

Page {{ clientPage }} / {{ clientTotalPages }}

๐Ÿ“ธ {{ cameraMode === 'quote' ? 'Scan Quote' : 'Job Site Photo' }}

๐Ÿ“ท Captured Photos

๐Ÿ“ {{ photo.location || 'No GPS' }}
โœ๏ธ Annotated

โœ๏ธ Digital Signature

Please sign below:

๐Ÿ–ผ๏ธ Annotate Photo

Tool:
Color:
Size: {{ annotationSize }}px

๐Ÿ’ณ Payment Processing

Total Amount

${{ paymentData.amount }}

Payment Processing - Coming Soon!

Stripe integration in development. Full payment processing will be available soon.

Credit/Debit Card
QR Code Payment

๐Ÿงพ Service Pricebook

{{ item.name }}

{{ item.category }}

{{ formatCurrency(item.price) }}/{{ item.unit }}

Tax: {{ (item.tax_rate * 100) }}%

No services found in this category

Let's get started!

Welcome! This guided setup will walk you through adding your first client, creating a quote, scheduling a job, sending an invoice, and logging a payment. Onboarding will finish after your first workflow is complete.

Client added!

Ready to create a quote for them?

Quote created!

Ready to schedule a job for this quote?

Job scheduled!

Ready to create and send an invoice?

Invoice sent!

Ready to log a payment for this invoice?

You're all set!

Onboarding is complete. You can now use all features of SideKick. Need help? Access tips anytime from the help menu.

{{ modalData.title }}

{{ modalData.message }}

{{ modalData.title }}

On mobile, this will open your SMS app. For desktop, copy or email the link:

Copied!

{{ modalData.message }}

{{ modalData.title }}

{{ modalData.message }}

{{ option.label }}

{{ option.description }}

New Material

Uncheck to add as a one-off item just for this quote.