481 lines
15 KiB
Cheetah
481 lines
15 KiB
Cheetah
{{define "onboarding-details"}}
|
||
<div class="onboarding-container">
|
||
<div class="onboarding-card">
|
||
<!-- Progress -->
|
||
<div class="onboarding-progress">
|
||
<div class="progress-step completed clickable" onclick="goToStep('/onboarding/product')">
|
||
<div class="progress-box">✓</div>
|
||
<span class="progress-label">Product</span>
|
||
</div>
|
||
<div class="progress-line completed"></div>
|
||
<div class="progress-step completed clickable" onclick="goToStep('/onboarding/login')">
|
||
<div class="progress-box">✓</div>
|
||
<span class="progress-label">Account</span>
|
||
</div>
|
||
<div class="progress-line completed"></div>
|
||
<div class="progress-step active">
|
||
<div class="progress-box">3</div>
|
||
<span class="progress-label">Details</span>
|
||
</div>
|
||
<div class="progress-line"></div>
|
||
<div class="progress-step">
|
||
<div class="progress-box">4</div>
|
||
<span class="progress-label">Terms</span>
|
||
</div>
|
||
<div class="progress-line"></div>
|
||
<div class="progress-step">
|
||
<div class="progress-box">5</div>
|
||
<span class="progress-label">Payment</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Header -->
|
||
<div class="onboarding-header">
|
||
<p class="label accent mb-3">Step 3 of 5</p>
|
||
<h1 class="mb-4">Your details</h1>
|
||
<p class="lead">We need this for billing and compliance. Exact match with Paddle requirements.</p>
|
||
</div>
|
||
|
||
<!-- Form -->
|
||
<form id="detailsForm" onsubmit="return saveDetails(event)">
|
||
<!-- Personal -->
|
||
<div class="form-section">
|
||
<h3 class="form-section-title">Personal</h3>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group half">
|
||
<label class="form-label">First name <span class="required">*</span></label>
|
||
<input type="text" class="form-input" name="firstName" required placeholder="Jane">
|
||
</div>
|
||
<div class="form-group half">
|
||
<label class="form-label">Last name <span class="required">*</span></label>
|
||
<input type="text" class="form-input" name="lastName" required placeholder="Doe">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Company (optional but recommended) -->
|
||
<div class="form-section">
|
||
<h3 class="form-section-title">Organization</h3>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Company name</label>
|
||
<input type="text" class="form-input" name="companyName" placeholder="Acme Inc. (optional)">
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<!--
|
||
NOTE FOR NEXT AGENT: Tax ID/VAT field visibility by country.
|
||
Per Paddle requirements: Show for EU countries (VAT reverse charge),
|
||
AU (GST), NZ, NO, CH. Check Paddle docs for latest list.
|
||
Mandatory for business customers in these regions when B2B.
|
||
-->
|
||
<div class="form-group half" id="taxIdGroup">
|
||
<label class="form-label">Tax ID / VAT number</label>
|
||
<input type="text" class="form-input" name="taxId" placeholder="EU123456789 (if applicable)">
|
||
</div>
|
||
<div class="form-group half">
|
||
<label class="form-label">Company size</label>
|
||
<select class="form-input form-select" name="companySize">
|
||
<option value="">Select...</option>
|
||
<option value="1">Just me</option>
|
||
<option value="2-10">2–10 people</option>
|
||
<option value="11-50">11–50 people</option>
|
||
<option value="51-200">51–200 people</option>
|
||
<option value="201+">201+ people</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Billing Address (Paddle required) -->
|
||
<div class="form-section">
|
||
<h3 class="form-section-title">Billing address <span class="required">*</span></h3>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Street address <span class="required">*</span></label>
|
||
<input type="text" class="form-input" name="addressLine1" required placeholder="123 Main Street">
|
||
<input type="text" class="form-input mt-2" name="addressLine2" placeholder="Suite 100, Floor 2 (optional)">
|
||
</div>
|
||
|
||
<div class="form-row three-col">
|
||
<div class="form-group">
|
||
<label class="form-label">City <span class="required">*</span></label>
|
||
<input type="text" class="form-input" name="city" required placeholder="Zürich">
|
||
</div>
|
||
<!--
|
||
NOTE FOR NEXT AGENT: State field mandatory for US, CA, AU.
|
||
Per Paddle: Required for tax calculation in these countries.
|
||
Show as required (*) when country is US/CA/AU.
|
||
-->
|
||
<div class="form-group" id="stateGroup">
|
||
<label class="form-label">State / Province <span id="stateRequired" class="required hidden">*</span></label>
|
||
<input type="text" class="form-input" name="state" placeholder="ZH (if applicable)">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">ZIP / Postal code <span class="required">*</span></label>
|
||
<input type="text" class="form-input" name="postalCode" required placeholder="8001">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Country <span class="required">*</span></label>
|
||
<select class="form-input form-select" name="country" required id="countrySelect">
|
||
<option value="">Select country...</option>
|
||
<option value="CH" selected>Switzerland</option>
|
||
<option value="US">United States</option>
|
||
<option value="DE">Germany</option>
|
||
<option value="GB">United Kingdom</option>
|
||
<option value="FR">France</option>
|
||
<option value="NL">Netherlands</option>
|
||
<option value="AT">Austria</option>
|
||
<option value="IT">Italy</option>
|
||
<option value="ES">Spain</option>
|
||
<option value="CA">Canada</option>
|
||
<option value="AU">Australia</option>
|
||
<option value="JP">Japan</option>
|
||
<option value="SG">Singapore</option>
|
||
<!-- Full list would be here -->
|
||
</select>
|
||
</div>
|
||
|
||
<div class="vat-info" id="vatInfo">
|
||
<div class="info-box">
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
|
||
<span>VAT will be calculated based on your country. Businesses in EU can enter VAT ID for reverse charge.</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Actions -->
|
||
<div class="form-actions">
|
||
<button type="button" class="btn btn-ghost" onclick="history.back()">Back</button>
|
||
<button type="submit" class="btn btn-primary">Continue →</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
.onboarding-container {
|
||
min-height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
padding: 48px 24px;
|
||
background: linear-gradient(180deg, #fafafa 0%, #f5f5f5 100%);
|
||
}
|
||
|
||
.onboarding-container::after {
|
||
content: '';
|
||
flex: 1;
|
||
min-height: 24px;
|
||
}
|
||
|
||
.onboarding-card {
|
||
width: 100%;
|
||
max-width: 520px;
|
||
background: white;
|
||
border-radius: 16px;
|
||
padding: 48px;
|
||
box-shadow: 0 4px 24px rgba(0,0,0,0.06);
|
||
border: 1px solid var(--border);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.onboarding-progress {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 48px;
|
||
}
|
||
|
||
.progress-step {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.progress-step.active .progress-dot {
|
||
background: var(--brand-black);
|
||
color: white;
|
||
}
|
||
|
||
.progress-step.completed .progress-dot {
|
||
background: var(--success);
|
||
color: white;
|
||
}
|
||
|
||
.progress-box {
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: 6px;
|
||
background: var(--bg-secondary);
|
||
color: var(--text-tertiary);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
transition: all 0.2s ease;
|
||
border: 1px solid var(--border);
|
||
}
|
||
|
||
.progress-step.active .progress-box {
|
||
background: var(--brand-black);
|
||
color: white;
|
||
border-color: var(--brand-black);
|
||
}
|
||
|
||
.progress-step.completed .progress-box {
|
||
background: var(--success);
|
||
color: white;
|
||
border-color: var(--success);
|
||
}
|
||
|
||
.progress-step.clickable {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.progress-step.clickable:hover .progress-box {
|
||
border-color: var(--brand-black);
|
||
color: var(--text);
|
||
}
|
||
|
||
.progress-step.clickable:hover .progress-label {
|
||
color: var(--text);
|
||
}
|
||
|
||
.progress-label {
|
||
font-size: 11px;
|
||
font-weight: 500;
|
||
color: var(--text-tertiary);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
}
|
||
|
||
.progress-step.active .progress-label {
|
||
color: var(--text);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.progress-step.completed .progress-label {
|
||
color: var(--success);
|
||
}
|
||
|
||
.progress-line {
|
||
width: 40px;
|
||
height: 2px;
|
||
background: var(--border);
|
||
margin: 0 8px;
|
||
margin-bottom: 24px;
|
||
transition: background 0.2s;
|
||
}
|
||
|
||
.progress-line.completed {
|
||
background: var(--success);
|
||
}
|
||
|
||
.onboarding-header {
|
||
text-align: center;
|
||
margin-bottom: 40px;
|
||
}
|
||
|
||
.form-section {
|
||
margin-bottom: 40px;
|
||
padding-bottom: 32px;
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
|
||
.form-section:last-of-type {
|
||
border-bottom: none;
|
||
padding-bottom: 0;
|
||
}
|
||
|
||
.form-section-title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: var(--text);
|
||
margin-bottom: 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.required {
|
||
color: var(--brand-red);
|
||
}
|
||
|
||
.form-row {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 16px;
|
||
}
|
||
|
||
.form-row.three-col {
|
||
grid-template-columns: 2fr 1fr 1fr;
|
||
}
|
||
|
||
.form-group {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.form-group:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.form-label {
|
||
display: block;
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: var(--text);
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.form-input {
|
||
width: 100%;
|
||
padding: 10px 12px;
|
||
border-radius: 8px;
|
||
border: 1px solid var(--border);
|
||
font-size: 15px;
|
||
font-family: inherit;
|
||
transition: border-color 0.15s, box-shadow 0.15s;
|
||
background: white;
|
||
}
|
||
|
||
.hidden {
|
||
display: none;
|
||
}
|
||
|
||
.form-input:focus {
|
||
outline: none;
|
||
border-color: var(--brand-black);
|
||
box-shadow: 0 0 0 3px rgba(10,10,10,0.04);
|
||
}
|
||
|
||
.form-input::placeholder {
|
||
color: var(--text-tertiary);
|
||
opacity: 0.6;
|
||
}
|
||
|
||
.form-select {
|
||
appearance: none;
|
||
background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23737373' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
||
background-repeat: no-repeat;
|
||
background-position: right 14px center;
|
||
padding-right: 40px;
|
||
}
|
||
|
||
.form-input.mt-2 {
|
||
margin-top: 12px;
|
||
}
|
||
|
||
.vat-info {
|
||
margin-top: 16px;
|
||
}
|
||
|
||
.info-box {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 12px;
|
||
padding: 16px;
|
||
background: var(--bg-secondary);
|
||
border-radius: 10px;
|
||
border: 1px solid var(--border);
|
||
font-size: 14px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.info-box svg {
|
||
flex-shrink: 0;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.form-actions {
|
||
display: flex;
|
||
gap: 16px;
|
||
margin-top: 32px;
|
||
}
|
||
|
||
.form-actions .btn {
|
||
flex: 1;
|
||
justify-content: center;
|
||
height: 48px;
|
||
}
|
||
|
||
@media (max-width: 640px) {
|
||
.onboarding-card {
|
||
padding: 32px 24px;
|
||
border-radius: 0;
|
||
border: none;
|
||
box-shadow: none;
|
||
max-width: 100%;
|
||
}
|
||
|
||
.onboarding-container {
|
||
padding: 0;
|
||
background: white;
|
||
}
|
||
|
||
.form-row,
|
||
.form-row.three-col {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.progress-line {
|
||
width: 24px;
|
||
}
|
||
|
||
.form-actions {
|
||
flex-direction: column-reverse;
|
||
}
|
||
|
||
.form-actions .btn:first-child {
|
||
margin-top: 8px;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
// Country-specific VAT logic
|
||
document.getElementById('countrySelect').addEventListener('change', function(e) {
|
||
const euCountries = ['DE', 'FR', 'IT', 'ES', 'NL', 'AT', 'BE', 'DK', 'FI', 'SE', 'PL', 'CZ', 'HU', 'RO', 'BG', 'HR', 'SI', 'SK', 'LT', 'LV', 'EE', 'IE', 'PT', 'GR', 'CY', 'MT', 'LU'];
|
||
|
||
const isEU = euCountries.includes(e.target.value);
|
||
const vatInfo = document.getElementById('vatInfo');
|
||
|
||
if (isEU) {
|
||
vatInfo.querySelector('span').textContent = 'VAT will be added at checkout. If you have a valid VAT ID, enter it above for reverse charge.';
|
||
} else if (e.target.value === 'CH') {
|
||
vatInfo.querySelector('span').textContent = 'Swiss VAT (8.1%) will be added at checkout.';
|
||
} else if (e.target.value === 'US') {
|
||
vatInfo.querySelector('span').textContent = 'Sales tax will be calculated based on your state.';
|
||
} else {
|
||
vatInfo.querySelector('span').textContent = 'Local taxes may apply based on your jurisdiction.';
|
||
}
|
||
});
|
||
|
||
function goToStep(url) {
|
||
window.location.href = url;
|
||
}
|
||
|
||
function saveDetails(e) {
|
||
e.preventDefault();
|
||
|
||
const formData = new FormData(e.target);
|
||
const data = Object.fromEntries(formData);
|
||
|
||
// Store in session/localStorage or send to API
|
||
console.log('Saving details:', data);
|
||
|
||
// Navigate to next step (terms)
|
||
window.location.href = '/onboarding/terms';
|
||
|
||
return false;
|
||
}
|
||
</script>
|
||
{{end}}
|