Projects
2025
Enterprise CRM Platform for Advertising Sales

Enterprise CRM Platform for Advertising Sales

Mission-critical platform serving 15+ sales team members. Built complex dashboards, filtering systems, and PDF generation. My biggest technical challenge: delivering enterprise features under tight deadlines.

Vue.jsNuxt.jsPiniaTailwind CSSAPI integration

THE CONTEXT

Summit Media's advertising sales team was managing campaigns across 20+ industries using spreadsheets and a legacy platform. Creating proposals, tracking versions, and generating reports was manual and error-prone.

The stakes: Ad sales is revenue. Slow tools slow down the entire sales process.


THE CHALLENGE (And Why It Was Brutal)

This was my biggest technical challenge to date:

  • ⏰ Tight deadlines - Fast-paced, production-critical
  • 🎯 Solo frontend dev - I was responsible for implementing most of the UI/UX, translating provided mockups into a functional system
  • πŸ†• First-time everything - Most patterns were new to me
  • 🎨 Complex UI - 20+ industry filters, dynamic tables, conditional actions
  • πŸ”— Heavy API integration - Real-time data syncing

Translation: I had to learn while building, fast.


WHAT I BUILT

Core Features:

1. Campaign Management System

  • Create, track, and manage campaigns across multiple industries
  • Real-time cost estimation and proposal generation
  • Version control for proposals (sales teams iterate constantly)

2. Advanced Filtering System

  • 20+ industry categories with nested filters
  • Search across campaigns, proposals, and cost estimation
  • Instant results with performance optimization

3. Dynamic Table System with Smart Actions

This was the heart of the CRM and my proudest technical achievement:

The Challenge: Different campaign statuses require different actions. A draft proposal needs "Create Proposal," an approved proposal needs "Create CE," a completed campaign needs "Create Job Order"β€”and the UI had to make this intuitive.

What I Built:

  • Multiple interconnected tables (Campaigns, Proposals, Cost Estimate, Job Orders)
  • Status-driven action system - buttons and options that dynamically change based on campaign state
  • Complex conditional logic determining what actions are available
  • Real-time status updates reflected across all related tables

Example Flow:

Draft β†’ [Edit | Create Proposal]
  ↓
Proposal β†’ [Create another version | Create CE | Edit | Generate PDF]
  ↓
Cost Estimate β†’ [Create another version | Create Job Order | Generate PDF]
  ↓
Job Order β†’ [Publish | Add Notes | Start Campaign | Stop Campaign]
  ↓
Completed β†’ [Generate Invoice | Archive | View Report]

Each status transition triggered different API calls, updated multiple tables, and recalculated related data in real-time.

Technical Complexity:

  • Conditional rendering based on user permissions AND campaign status
  • Optimistic UI updates (show changes immediately, sync with backend)
  • Cascading updates (changing one campaign affects related proposals, job orders)
  • State synchronization across multiple table views

4. PDF Generation

  • One-click proposal and invoice exports
  • Professional formatting with company branding
  • Dynamic content based on campaign configuration

THE TECHNICAL DEEP DIVE

My Responsibilities:

βœ… Frontend Architecture - Component structure and routing
βœ… UI/UX Implementation - Pixel-perfect from Figma designs
βœ… API Integration - RESTful endpoints, state synchronization
βœ… Business Logic - Calculations, validations, conditional flows
βœ… State Management - Pinia for complex, multi-view data

Hardest Technical Problems:

Problem 1: Status-Dependent Action System

The most complex part was managing actions that depend on:

  • Campaign status (Draft, In Progress, For Proposal, Proposal Sent, etc)
  • Related data state (Does this campaign have a proposal? cost estimate?)

I built a computed action system that evaluates all conditions and renders only valid actions:

// Simplified example of the pattern I used
const availableActions = computed(() => {
  const actions = [];

  if (campaign.status === "draft" && hasPermission("edit")) {
    actions.push({ label: "Edit", handler: editCampaign });
  }

  if (campaign.status === "approved" && !campaign.hasJobOrder) {
    actions.push({ label: "Create Job Order", handler: createJobOrder });
  }

  // ... many more conditions
  return actions;
});

This kept the UI clean while handling incredibly complex business logic.

Problem 2: Real-Time Data Synchronization

Multiple users editing campaigns simultaneously required:

  • Optimistic updates (show changes immediately)
  • Conflict resolution when data changes server-side
  • Automatic table refreshes without losing user context (filters, sort, pagination)

Solution: Built a smart polling system that checks for updates without disrupting user workflow.

Problem 3: Performance with Large Datasets

Rendering 100+ campaigns with filters, search, and dynamic actions without lag required:

  • Virtual scrolling for large tables
  • Debounced search inputs (wait 300ms after typing stops)
  • Optimized computed properties (cache results, only recalculate when dependencies change)
  • Lazy loading related data (load job orders only when row is expanded)

Problem 4: Complex Form Validation

Campaign creation had interdependent fields:

  • Industry selection β†’ determines available ad types
  • Location selection β†’ determines pricing structure
  • Pricing changes β†’ recalculates total cost in real-time

All while maintaining a smooth UX and clear error messages.


THE IMPACT

For the Sales Team:

  • βœ… Faster proposal creation (estimated 60% time savings)
  • βœ… Better version tracking (no more "Final_v3_REAL_Final.xlsx")
  • βœ… Clear action visibility - always know what you can do next
  • βœ… Professional PDF exports for clients
  • βœ… Real-time pipeline visibility across all campaigns

For Me:

This project leveled me up as a developer:

  • Learned to work under pressure without sacrificing quality
  • Gained confidence in complex state management (Pinia for multi-view data)
  • Mastered conditional logic at scale (status-driven UIs are everywhere now)
  • Understood how frontend decisions impact business (slow CRM = lost revenue)
  • Discovered I thrive in fast-paced environments (tight deadlines became my fuel)

TECH STACK

  • Frontend: Vue 3 (Composition API), Nuxt 3
  • State Management: Pinia
  • UI: Tailwind CSS
  • Tables: Custom-built with virtual scrolling
  • PDF: API-generated PDFs with in-app modal viewer
  • API: RESTful integration with Node.js backend

WHAT THIS TAUGHT ME

1. You Don't Need to Know Everything to Start

Most patterns were new to me:

  • Complex state management across multiple views
  • Conditional action systems
  • Virtual scrolling for performance
  • Real-time data synchronization

I used AI tools (Claude, ChatGPT) to accelerate learning, but I made sure to understand every solution, not just copy-paste. I'd ask "Why does this pattern work?" not just "Give me the code."

2. Clean Code Under Pressure is Possible

Even with tight deadlines, I prioritized:

  • Meaningful component names (CampaignActionButton not Button2)
  • Clear state structure (organized Pinia stores by feature)
  • Comments on complex logic (especially the status-action mapping)

Why? Other devs need to maintain this. Rushing today creates problems tomorrow. Plus, clean code is faster to debug when (not if) bugs appear.

3. Frontend Impacts Revenue

A slow, buggy CRM doesn't just annoy usersβ€”it costs money:

  • Slow filters = sales team wastes time
  • Broken action buttons = proposals don't get sent
  • Confusing UI = mistakes in pricing

This shifted how I think about performance and UX as business priorities, not just nice-to-haves.

4. Complex UIs Need Simple Patterns

The status-action system could have been a nightmare of nested if statements. Instead, I built a declarative pattern that made adding new statuses or actions predictable and safe.

Key principle: Make the complex logic look simple in the code.


THE BIGGER PICTURE

This CRM manages 100+ campaigns for 15+ sales team members across 20+ industries.

But more than that, it taught me:

  • How to deliver under pressure
  • How to learn while building
  • How frontend choices impact real business outcomes
  • That I love complex, high-stakes projects

This is the project that made me want to learn backendβ€”because I kept thinking, "How does the API handle this? Could I build a better sync system?"

Now I'm learning Node.js, Express, and database design to answer those questions.


2026