ironservices-maui/Controls/LicenseActivationView.xaml.cs

289 lines
7.7 KiB
C#

using IronLicensing.Client;
using IronLicensing.Client.Models;
namespace IronServices.Maui.Controls;
/// <summary>
/// A reusable license activation view for IronLicensing.
/// </summary>
public partial class LicenseActivationView : ContentView
{
private ILicenseManager? _licenseManager;
public LicenseActivationView()
{
InitializeComponent();
}
#region Bindable Properties
/// <summary>
/// The ILicenseManager to use for license validation.
/// </summary>
public static readonly BindableProperty LicenseManagerProperty = BindableProperty.Create(
nameof(LicenseManager),
typeof(ILicenseManager),
typeof(LicenseActivationView),
null,
propertyChanged: (b, o, n) => ((LicenseActivationView)b)._licenseManager = n as ILicenseManager);
public ILicenseManager? LicenseManager
{
get => (ILicenseManager?)GetValue(LicenseManagerProperty);
set => SetValue(LicenseManagerProperty, value);
}
/// <summary>
/// The title text.
/// </summary>
public static readonly BindableProperty TitleProperty = BindableProperty.Create(
nameof(Title),
typeof(string),
typeof(LicenseActivationView),
"Activate License",
propertyChanged: (b, o, n) => ((LicenseActivationView)b).TitleLabel.Text = n as string);
public string Title
{
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
/// <summary>
/// The subtitle text.
/// </summary>
public static readonly BindableProperty SubtitleProperty = BindableProperty.Create(
nameof(Subtitle),
typeof(string),
typeof(LicenseActivationView),
"Enter your license key to activate",
propertyChanged: (b, o, n) => ((LicenseActivationView)b).SubtitleLabel.Text = n as string);
public string Subtitle
{
get => (string)GetValue(SubtitleProperty);
set => SetValue(SubtitleProperty, value);
}
/// <summary>
/// Pre-filled license key.
/// </summary>
public static readonly BindableProperty LicenseKeyProperty = BindableProperty.Create(
nameof(LicenseKey),
typeof(string),
typeof(LicenseActivationView),
null,
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((LicenseActivationView)b).LicenseKeyEntry.Text = n as string);
public string? LicenseKey
{
get => (string?)GetValue(LicenseKeyProperty);
set => SetValue(LicenseKeyProperty, value);
}
/// <summary>
/// Whether to show the help link.
/// </summary>
public static readonly BindableProperty ShowHelpLinkProperty = BindableProperty.Create(
nameof(ShowHelpLink),
typeof(bool),
typeof(LicenseActivationView),
true,
propertyChanged: (b, o, n) => ((LicenseActivationView)b).HelpLink.IsVisible = (bool)n);
public bool ShowHelpLink
{
get => (bool)GetValue(ShowHelpLinkProperty);
set => SetValue(ShowHelpLinkProperty, value);
}
/// <summary>
/// URL to open when help link is tapped.
/// </summary>
public static readonly BindableProperty HelpUrlProperty = BindableProperty.Create(
nameof(HelpUrl),
typeof(string),
typeof(LicenseActivationView),
"https://ironservices.io/docs/licensing");
public string HelpUrl
{
get => (string)GetValue(HelpUrlProperty);
set => SetValue(HelpUrlProperty, value);
}
#endregion
#region Events
/// <summary>
/// Raised when license activation is successful.
/// </summary>
public event EventHandler<LicenseActivatedEventArgs>? LicenseActivated;
/// <summary>
/// Raised when license activation fails.
/// </summary>
public event EventHandler<LicenseActivationFailedEventArgs>? ActivationFailed;
/// <summary>
/// Raised when help link is tapped.
/// </summary>
public event EventHandler? HelpRequested;
#endregion
#region Event Handlers
private async void OnActivateClicked(object sender, EventArgs e)
{
if (_licenseManager == null)
{
ShowError("License manager not configured");
return;
}
var licenseKey = LicenseKeyEntry.Text?.Trim();
if (string.IsNullOrEmpty(licenseKey))
{
ShowError("Please enter a license key");
return;
}
SetLoading(true);
HideError();
HideStatus();
try
{
var result = await _licenseManager.ActivateAsync(licenseKey);
if (result.Success)
{
ShowStatus(true, "License activated successfully!");
LicenseActivated?.Invoke(this, new LicenseActivatedEventArgs(result));
}
else
{
ShowError(result.ErrorMessage ?? "Invalid license key");
ActivationFailed?.Invoke(this, new LicenseActivationFailedEventArgs(result.ErrorMessage ?? "Invalid license key"));
}
}
catch (Exception ex)
{
ShowError($"Error: {ex.Message}");
ActivationFailed?.Invoke(this, new LicenseActivationFailedEventArgs(ex.Message));
}
finally
{
SetLoading(false);
}
}
private async void OnHelpTapped(object sender, EventArgs e)
{
HelpRequested?.Invoke(this, EventArgs.Empty);
try
{
await Browser.OpenAsync(HelpUrl, BrowserLaunchMode.SystemPreferred);
}
catch
{
// Ignore if can't open browser
}
}
#endregion
#region Helper Methods
private void SetLoading(bool isLoading)
{
ActivateButton.IsEnabled = !isLoading;
ActivateButton.IsVisible = !isLoading;
LoadingIndicator.IsRunning = isLoading;
LoadingIndicator.IsVisible = isLoading;
LicenseKeyEntry.IsEnabled = !isLoading;
}
private void ShowError(string message)
{
ErrorLabel.Text = message;
ErrorLabel.IsVisible = true;
}
private void HideError()
{
ErrorLabel.IsVisible = false;
}
private void ShowStatus(bool success, string message)
{
StatusFrame.IsVisible = true;
StatusFrame.BackgroundColor = success
? Color.FromArgb("#D1FAE5") // Green background
: Color.FromArgb("#FEE2E2"); // Red background
StatusIcon.Text = success ? "✓" : "✗";
StatusIcon.TextColor = success ? Colors.Green : Colors.Red;
StatusLabel.Text = message;
StatusLabel.TextColor = success ? Colors.Green : Colors.Red;
}
private void HideStatus()
{
StatusFrame.IsVisible = false;
}
/// <summary>
/// Validates the current license without activating a new one.
/// </summary>
public async Task<bool> ValidateAsync()
{
if (_licenseManager == null) return false;
var licenseKey = LicenseKeyEntry.Text?.Trim();
try
{
var result = await _licenseManager.ValidateAsync(licenseKey);
return result.Success;
}
catch
{
return false;
}
}
#endregion
}
/// <summary>
/// Event args for successful license activation.
/// </summary>
public class LicenseActivatedEventArgs : EventArgs
{
public LicenseResult Result { get; }
public LicenseInfo? License => Result.License;
public LicenseActivatedEventArgs(LicenseResult result)
{
Result = result;
}
}
/// <summary>
/// Event args for failed license activation.
/// </summary>
public class LicenseActivationFailedEventArgs : EventArgs
{
public string Error { get; }
public LicenseActivationFailedEventArgs(string error)
{
Error = error;
}
}