Created
December 2, 2024 22:23
-
-
Save drawveloper/dacf5f3939339efef9872edd999612fa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment