This commit is contained in:
2026-01-22 16:40:16 +01:00
parent 5cffab48c7
commit 7b21581108
10 changed files with 445 additions and 148 deletions
+160 -72
View File
@@ -238,65 +238,22 @@ endblock %}
<p class="page-subtitle">Pay only for what you use. No hidden fees, no surprises.</p>
<div class="pricing-hero">
<h2 style="font-size: 2rem; margin: 0;">Pay-As-You-Go Storage</h2>
<div class="pricing-hero-amount">$5/TB</div>
<p class="pricing-hero-description">Plus 15GB free tier included</p>
<h2 style="font-size: 2rem; margin: 0;">Simple Cloud Storage Pricing</h2>
<div class="pricing-hero-amount">$3-$5/TB</div>
<p class="pricing-hero-description">Pay only for what you use. No hidden features, just storage.</p>
</div>
<div class="pricing-grid">
<div class="pricing-grid" id="pricing-plans">
<!-- Plans will be loaded dynamically from API -->
<div class="pricing-card">
<div class="pricing-tier">Free Tier</div>
<div class="pricing-amount">$0</div>
<div class="pricing-period">First 15GB included</div>
<div class="pricing-tier">Loading...</div>
<div class="pricing-amount">$-</div>
<div class="pricing-period">Loading plans...</div>
<ul class="pricing-features">
<li>15GB storage included</li>
<li>15GB bandwidth per month</li>
<li>All core features</li>
<li>WebDAV support</li>
<li>File versioning</li>
<li>Two-factor authentication</li>
<li>EU data residency</li>
<li>Loading subscription plans...</li>
</ul>
<div class="pricing-cta">
<a href="/app" class="btn btn-secondary" style="width: 100%;">Get Started Free</a>
</div>
</div>
<div class="pricing-card featured">
<div class="pricing-tier">Pay-As-You-Go</div>
<div class="pricing-amount">$5/TB</div>
<div class="pricing-period">Billed monthly</div>
<ul class="pricing-features">
<li>$0.0045 per GB per month storage</li>
<li>$0.009 per GB egress bandwidth</li>
<li>Free ingress bandwidth</li>
<li>All premium features</li>
<li>99.9% uptime SLA</li>
<li>24/7 support</li>
<li>API access</li>
<li>Priority support</li>
</ul>
<div class="pricing-cta">
<a href="/app" class="btn btn-primary" style="width: 100%;">Start Using</a>
</div>
</div>
<div class="pricing-card">
<div class="pricing-tier">Enterprise</div>
<div class="pricing-amount">Custom</div>
<div class="pricing-period">Contact us for pricing</div>
<ul class="pricing-features">
<li>Volume discounts available</li>
<li>Dedicated account manager</li>
<li>Custom SLA options</li>
<li>Priority support 24/7</li>
<li>Custom integrations</li>
<li>Training and onboarding</li>
<li>Compliance assistance</li>
<li>Secure infrastructure</li>
</ul>
<div class="pricing-cta">
<a href="/support" class="btn btn-secondary" style="width: 100%;">Contact Sales</a>
<button class="btn btn-secondary" style="width: 100%;" disabled>Loading...</button>
</div>
</div>
</div>
@@ -327,60 +284,191 @@ endblock %}
<div class="faq-item">
<div class="faq-question">How is storage calculated?</div>
<div class="faq-answer">Storage is calculated based on your average daily usage throughout the month. You're
charged $0.0045 per GB per month ($5 per TB). The first 15GB is always free.</div>
charged per GB per month starting from the first GB. No free tiers or hidden limits.</div>
</div>
<div class="faq-item">
<div class="faq-question">What is bandwidth egress?</div>
<div class="faq-answer">Bandwidth egress is data transferred out of MyWebdav (downloads). You're charged
$0.009 per GB. The first 15GB per month is free. Uploads (ingress) are always free.</div>
per GB for downloads. Uploads (ingress) are always free.</div>
</div>
<div class="faq-item">
<div class="faq-question">Are there any hidden fees?</div>
<div class="faq-answer">No. We believe in transparent pricing. You only pay for storage and egress bandwidth
as shown. There are no setup fees, minimum charges, or surprise costs.</div>
<div class="faq-answer">No. You only pay for storage usage and download bandwidth. No setup fees,
no minimum charges, no surprise costs. The price you see is what you pay.</div>
</div>
<div class="faq-item">
<div class="faq-question">Can I cancel anytime?</div>
<div class="faq-answer">Yes. There are no long-term contracts or commitments. You can delete your account at
any time and will only be charged for usage up to that point.</div>
<div class="faq-answer">Yes. There are no long-term contracts or commitments. You can close your account at
any time and will only be charged for actual usage up to that point.</div>
</div>
<div class="faq-item">
<div class="faq-question">What payment methods do you accept?</div>
<div class="faq-answer">We accept all major credit cards (Visa, Mastercard, American Express) and SEPA
direct debit through our payment processor Stripe.</div>
<div class="faq-answer">We accept all major credit cards through our payment processor Stripe.</div>
</div>
<div class="faq-item">
<div class="faq-question">Do you offer volume discounts?</div>
<div class="faq-answer">Yes. For storage over 10TB or bandwidth over 5TB per month, please contact our sales
team for custom pricing.</div>
<div class="faq-answer">Yes. Our Enterprise tier offers lower rates for high volume usage (10TB+).
Contact us for details on volume pricing.</div>
</div>
</div>
</div>
<script>
async function loadSubscriptionPlans() {
try {
const response = await fetch('/api/billing/plans');
if (!response.ok) throw new Error('Failed to load plans');
const plans = await response.json();
const plansContainer = document.getElementById('pricing-plans');
plansContainer.innerHTML = plans.map(plan => {
const isFeatured = plan.name === 'professional';
// Set pricing based on plan name
let storagePrice, bandwidthPrice, ctaText, ctaAction, features;
if (plan.name === 'starter') {
storagePrice = '$0.005/GB';
bandwidthPrice = '$0.008/GB';
ctaText = 'Get Started';
ctaAction = () => subscribeToPlan('starter');
features = [
'Cloud storage for individuals',
'Storage: ' + storagePrice,
'Bandwidth: ' + bandwidthPrice,
'Free uploads (ingress)',
'WebDAV access',
'SFTP access',
'API access',
'File versioning',
'99.9% uptime SLA',
'Email support'
];
} else if (plan.name === 'professional') {
storagePrice = '$0.004/GB';
bandwidthPrice = '$0.007/GB';
ctaText = 'Choose Plan';
ctaAction = () => subscribeToPlan('professional');
features = [
'Cloud storage for professionals',
'Storage: ' + storagePrice,
'Bandwidth: ' + bandwidthPrice,
'Free uploads (ingress)',
'WebDAV access',
'SFTP access',
'API access',
'File versioning',
'99.9% uptime SLA',
'Priority email support'
];
} else if (plan.name === 'enterprise') {
storagePrice = '$0.003/GB (10TB+)';
bandwidthPrice = '$0.005/GB';
ctaText = 'Contact Sales';
ctaAction = () => window.location.href = '/support';
features = [
'Cloud storage for enterprises',
'Storage: ' + storagePrice,
'Bandwidth: ' + bandwidthPrice,
'Free uploads (ingress)',
'WebDAV access',
'SFTP access',
'API access',
'File versioning',
'99.9% uptime SLA',
'Priority email support',
'Volume discounts available'
];
}
return `
<div class="pricing-card ${isFeatured ? 'featured' : ''}">
<div class="pricing-tier">${plan.display_name}</div>
<div class="pricing-amount">${plan.price_monthly > 0 ? '$' + plan.price_monthly : 'Usage-based'}</div>
<div class="pricing-period">Billed monthly based on usage</div>
<ul class="pricing-features">
${features.map(feature => `<li>${feature}</li>`).join('')}
</ul>
<div class="pricing-cta">
<button class="btn ${isFeatured ? 'btn-primary' : 'btn-secondary'}"
style="width: 100%;"
onclick="(${ctaAction})()">
${ctaText}
</button>
</div>
</div>
`;
}).join('');
} catch (error) {
console.error('Error loading plans:', error);
document.getElementById('pricing-plans').innerHTML = `
<div class="pricing-card">
<div class="pricing-tier">Error</div>
<div class="pricing-amount">-</div>
<div class="pricing-period">Failed to load plans</div>
<ul class="pricing-features">
<li>Please refresh the page and try again</li>
</ul>
</div>
`;
}
}
async function subscribeToPlan(planName) {
try {
// Check if user is logged in
const response = await fetch('/api/auth/me');
if (!response.ok) {
// User not logged in, redirect to login
window.location.href = '/app#login';
return;
}
const subscribeResponse = await fetch('/api/billing/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ plan_name: planName })
});
if (!subscribeResponse.ok) {
const error = await subscribeResponse.json();
throw new Error(error.detail || 'Failed to subscribe');
}
const result = await subscribeResponse.json();
alert(result.message);
} catch (error) {
console.error('Subscription error:', error);
alert(error.message || 'Failed to subscribe. Please try again.');
}
}
function calculatePrice() {
const storage = parseFloat(document.getElementById('storage').value) || 0;
const bandwidth = parseFloat(document.getElementById('bandwidth').value) || 0;
const freeStorage = 15;
const freeBandwidth = 15;
const billableStorage = Math.max(0, storage - freeStorage);
const billableBandwidth = Math.max(0, bandwidth - freeBandwidth);
const storageCost = billableStorage * 0.0045;
const bandwidthCost = billableBandwidth * 0.009;
// Professional tier pricing (featured)
const storageCost = storage * 0.004;
const bandwidthCost = bandwidth * 0.007;
const total = storageCost + bandwidthCost;
document.getElementById('result').textContent = '$' + total.toFixed(2);
}
calculatePrice();
// Load plans when page loads
document.addEventListener('DOMContentLoaded', function() {
loadSubscriptionPlans();
calculatePrice();
});
</script>
{% endblock %}