PlanTempusApp/PlanTempus.Application/Features/Accounts/Pages/Payment.cshtml
Janus C. H. Knudsen 217a9cd95c Adds authentication and pricing pages for user onboarding
Introduces comprehensive user authentication flow with plan selection and registration

Includes:
- Pricing page with plan details and selection
- Payment page with plan summary and card information
- Signup page for different plan tiers
- Shared authentication layout and design system improvements

Enhances user onboarding experience with clear plan information and streamlined signup process
2026-01-11 01:38:14 +01:00

219 lines
8.2 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@page "/payment"
@model PlanTempus.Application.Features.Accounts.Pages.PaymentModel
@{
ViewData["Title"] = "Betaling";
Layout = "/Features/_Shared/Pages/_AuthLayout.cshtml";
var plan = Model.SelectedPlan;
}
<swp-auth-layout>
<!-- Order Summary Panel -->
<swp-auth-plan-panel>
<swp-auth-logo>
<i class="ph ph-calendar-check"></i>
<span>PlanTempus</span>
</swp-auth-logo>
<swp-selected-plan-header>Din ordre</swp-selected-plan-header>
<swp-plan-card class="selected">
<swp-plan-badge class="@plan.BadgeClass">
<i class="ph @plan.BadgeIcon"></i>
@plan.BadgeText
</swp-plan-badge>
<swp-plan-name>@plan.Name</swp-plan-name>
<swp-plan-users>@plan.UserRange</swp-plan-users>
@if (plan.PricePerMonth.HasValue)
{
<swp-plan-price>
<swp-plan-price-amount>@plan.PriceDisplay</swp-plan-price-amount>
<swp-plan-price-period>kr/md</swp-plan-price-period>
</swp-plan-price>
}
<swp-plan-features>
@foreach (var feature in plan.Features)
{
<swp-plan-feature>
<i class="ph ph-check-circle"></i>
@feature
</swp-plan-feature>
}
</swp-plan-features>
<swp-order-summary>
<swp-order-line>
<span>@plan.Name abonnement</span>
<span>@(plan.PricePerMonth.HasValue ? $"{plan.PriceDisplay} kr" : "")</span>
</swp-order-line>
<swp-order-line class="discount">
<span>14 dages gratis prøve</span>
<span>-@(plan.PricePerMonth.HasValue ? $"{plan.PriceDisplay} kr" : "")</span>
</swp-order-line>
<swp-order-divider></swp-order-divider>
<swp-order-line class="total">
<span>At betale i dag</span>
<span>0 kr</span>
</swp-order-line>
</swp-order-summary>
</swp-plan-card>
<swp-change-plan-link>
<a href="/pricing">
<i class="ph ph-arrow-left"></i>
Skift abonnement
</a>
</swp-change-plan-link>
</swp-auth-plan-panel>
<!-- Payment Form Panel -->
<swp-auth-form-panel>
<swp-auth-form-container>
<swp-auth-header>
<swp-auth-title>Betalingsoplysninger</swp-auth-title>
<swp-auth-description>Dit kort debiteres først efter prøveperioden</swp-auth-description>
</swp-auth-header>
<swp-auth-form id="paymentForm">
<swp-form-group>
<swp-form-label>Kortnummer</swp-form-label>
<swp-form-input class="has-icon">
<input type="text"
id="cardNumber"
placeholder="1234 5678 9012 3456"
maxlength="19"
autocomplete="cc-number" />
<span class="input-icon">
<i class="ph ph-credit-card"></i>
</span>
</swp-form-input>
</swp-form-group>
<swp-form-row>
<swp-form-group>
<swp-form-label>Udløbsdato</swp-form-label>
<swp-form-input>
<input type="text"
id="expiry"
placeholder="MM/ÅÅ"
maxlength="5"
autocomplete="cc-exp" />
</swp-form-input>
</swp-form-group>
<swp-form-group>
<swp-form-label>CVV</swp-form-label>
<swp-form-input>
<input type="text"
id="cvv"
placeholder="123"
maxlength="4"
autocomplete="cc-csc" />
</swp-form-input>
</swp-form-group>
</swp-form-row>
<swp-form-group>
<swp-form-label>Navn på kort</swp-form-label>
<swp-form-input>
<input type="text"
id="cardName"
placeholder="Som det står på kortet"
autocomplete="cc-name" />
</swp-form-input>
</swp-form-group>
<swp-payment-secure>
<i class="ph ph-lock"></i>
<span>Sikker betaling med SSL-kryptering</span>
</swp-payment-secure>
<swp-btn class="primary full-width lg" id="submitPayment">
<span>Start gratis prøveperiode</span>
<i class="ph ph-arrow-right"></i>
</swp-btn>
</swp-auth-form>
<!-- Processing State -->
<swp-payment-processing id="processingState" style="display: none;">
<swp-spinner></swp-spinner>
<swp-processing-text>Behandler betaling...</swp-processing-text>
</swp-payment-processing>
<!-- Success State -->
<swp-payment-success id="successState" style="display: none;">
<swp-success-icon>
<i class="ph ph-check-circle"></i>
</swp-success-icon>
<swp-success-title>Betaling godkendt!</swp-success-title>
<swp-success-text>Omdirigerer til oprettelse af konto...</swp-success-text>
</swp-payment-success>
<swp-auth-footer>
<swp-auth-footer-text>
Ved at fortsætte accepterer du vores <a href="/terms">vilkår</a>
</swp-auth-footer-text>
</swp-auth-footer>
</swp-auth-form-container>
</swp-auth-form-panel>
</swp-auth-layout>
@section Scripts {
<script>
// Format card number with spaces
const cardNumber = document.getElementById('cardNumber');
cardNumber.addEventListener('input', function(e) {
let value = e.target.value.replace(/\s/g, '').replace(/\D/g, '');
let formatted = value.match(/.{1,4}/g)?.join(' ') || '';
e.target.value = formatted;
});
// Format expiry date
const expiry = document.getElementById('expiry');
expiry.addEventListener('input', function(e) {
let value = e.target.value.replace(/\D/g, '');
if (value.length >= 2) {
value = value.substring(0, 2) + '/' + value.substring(2, 4);
}
e.target.value = value;
});
// CVV - numbers only
const cvv = document.getElementById('cvv');
cvv.addEventListener('input', function(e) {
e.target.value = e.target.value.replace(/\D/g, '');
});
// Simulate payment processing
const submitBtn = document.getElementById('submitPayment');
const form = document.getElementById('paymentForm');
const processingState = document.getElementById('processingState');
const successState = document.getElementById('successState');
submitBtn.addEventListener('click', function(e) {
e.preventDefault();
// Simple validation
if (!cardNumber.value || !expiry.value || !cvv.value || !document.getElementById('cardName').value) {
alert('Udfyld venligst alle felter');
return;
}
// Show processing
form.style.display = 'none';
processingState.style.display = 'flex';
// Simulate processing delay
setTimeout(function() {
processingState.style.display = 'none';
successState.style.display = 'flex';
// Redirect to signup after success
setTimeout(function() {
window.location.href = '/signup?plan=@Model.SelectedPlan.Key&payment=complete';
}, 1500);
}, 2000);
});
</script>
}