Skip to content

Instantly share code, notes, and snippets.

@vibegui
Created December 2, 2024 22:23
Show Gist options
  • Select an option

  • Save vibegui/dacf5f3939339efef9872edd999612fa to your computer and use it in GitHub Desktop.

Select an option

Save vibegui/dacf5f3939339efef9872edd999612fa to your computer and use it in GitHub Desktop.

Revisions

  1. vibegui created this gist Dec 2, 2024.
    181 changes: 181 additions & 0 deletions startup-offer-generator.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,181 @@
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Startup Offer Generator</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script type="module">
    import { getSDK } from "https://webdraw.ai/webdraw-sdk";

    const sdk = await getSDK();
    const form = document.getElementById('offerForm');
    const input = document.getElementById('offerInput');
    const table = document.getElementById('compensationTable');
    const submitBtn = document.getElementById('submitBtn');
    const spinner = document.getElementById('spinner');
    const errorMsg = document.getElementById('errorMsg');

    form.addEventListener('submit', async (e) => {
    e.preventDefault();
    const userInput = input.value.trim();
    if (!userInput) {
    showError('Please enter a description of the offer.');
    return;
    }

    // Show loading state
    submitBtn.disabled = true;
    spinner.classList.remove('hidden');
    table.classList.add('opacity-50');
    hideError();

    try {
    const response = await sdk.ai.message({
    messages: [{ role: 'user', content: userInput }],
    system: `You are a compensation calculator assistant. For the input text, analyze and project company growth with these requirements:
    - Project valuations for up to 5 years
    - Target reaching $1B valuation within 5 years if reasonable based on input
    - Return a JSON object with this exact structure:
    {
    "company_data": {
    "initial_shares": 10000000,
    "rounds": [{
    "year": number,
    "valuation": number,
    "dilution_percentage": number
    }]
    },
    "compensation_package": {
    "base_salary": number,
    "stock_options": {
    "shares": number
    }
    }
    }`,
    });

    let data;
    try {
    const content = response.content[0].text;
    // Find the JSON object in the response
    const jsonMatch = content.match(/\{[\s\S]*\}/);
    if (!jsonMatch) {
    throw new Error('No valid JSON found in response');
    }
    data = JSON.parse(jsonMatch[0]);
    updateTable(data);
    } catch (e) {
    showError('Unable to process the AI response. Please try rephrasing your input.');
    console.error('Parse error:', e);
    }
    } catch (error) {
    showError('Failed to generate offer. Please try again.');
    console.error('API error:', error);
    }

    // Hide loading state
    submitBtn.disabled = false;
    spinner.classList.add('hidden');
    table.classList.remove('opacity-50');
    });

    function showError(message) {
    errorMsg.textContent = message;
    errorMsg.classList.remove('hidden');
    }

    function hideError() {
    errorMsg.classList.add('hidden');
    }

    function updateTable(data) {
    let currentTotalShares = data.company_data.initial_shares;
    const years = data.company_data.rounds.map(round => {
    const stockOptions = data.compensation_package.stock_options.shares;
    currentTotalShares = currentTotalShares * (1 + round.dilution_percentage / 100);
    const equityPercentage = (stockOptions / currentTotalShares) * 100;
    const equityValue = (equityPercentage / 100) * round.valuation;

    return {
    year: round.year,
    companyValuation: round.valuation,
    dilutionPercentage: round.dilution_percentage,
    totalShares: Math.round(currentTotalShares),
    stockOptions: stockOptions,
    equityPercentage: equityPercentage,
    equityValue: equityValue,
    salary: data.compensation_package.base_salary,
    totalCompensation: data.compensation_package.base_salary + equityValue
    };
    });

    const tbody = document.querySelector('#compensationTable tbody');
    tbody.innerHTML = '';

    years.forEach(year => {
    const row = document.createElement('tr');
    row.innerHTML = `
    <td class="border px-4 py-2">${year.year}</td>
    <td class="border px-4 py-2">$${year.companyValuation.toLocaleString()}</td>
    <td class="border px-4 py-2">${year.dilutionPercentage}%</td>
    <td class="border px-4 py-2">${Math.round(year.totalShares).toLocaleString()}</td>
    <td class="border px-4 py-2">${year.stockOptions.toLocaleString()}</td>
    <td class="border px-4 py-2">${year.equityPercentage.toFixed(4)}%</td>
    <td class="border px-4 py-2">$${Math.round(year.equityValue).toLocaleString()}</td>
    <td class="border px-4 py-2">$${year.salary.toLocaleString()}</td>
    <td class="border px-4 py-2">$${Math.round(year.totalCompensation).toLocaleString()}</td>
    `;
    tbody.appendChild(row);
    });
    }
    </script>
    </head>
    <body class="bg-gray-100 min-h-screen p-8">
    <div class="max-w-7xl mx-auto bg-white rounded-lg shadow-lg p-6">
    <h1 class="text-3xl font-bold mb-8 text-center">Startup Offer Generator</h1>

    <!-- Input Form -->
    <div class="max-w-2xl mx-auto mb-8">
    <form id="offerForm" class="space-y-4">
    <textarea
    id="offerInput"
    class="w-full h-32 p-4 border rounded"
    placeholder="Describe the valuation story, expected valuations, salary, stock options, and total company shares. The AI will project growth for up to 5 years targeting $1B valuation if feasible."
    ></textarea>
    <div id="errorMsg" class="hidden text-red-500 text-center mb-4"></div>
    <div class="flex justify-center">
    <button
    id="submitBtn"
    type="submit"
    class="bg-blue-500 text-white px-6 py-2 rounded hover:bg-blue-600 flex items-center space-x-2"
    >
    <span>Generate Offer</span>
    <div id="spinner" class="hidden animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
    </button>
    </div>
    </form>
    </div>

    <!-- Compensation Table -->
    <div class="overflow-x-auto">
    <table id="compensationTable" class="w-full table-auto">
    <thead>
    <tr class="bg-gray-100">
    <th class="border px-4 py-2">Year</th>
    <th class="border px-4 py-2">Company Valuation</th>
    <th class="border px-4 py-2">Dilution %</th>
    <th class="border px-4 py-2">Total Shares</th>
    <th class="border px-4 py-2">Stock Options</th>
    <th class="border px-4 py-2">Equity %</th>
    <th class="border px-4 py-2">Equity Value</th>
    <th class="border px-4 py-2">Salary</th>
    <th class="border px-4 py-2">Total Compensation</th>
    </tr>
    </thead>
    <tbody></tbody>
    </table>
    </div>
    </div>
    </body>
    </html>