mirror of
https://github.com/Kareadita/Kavita.git
synced 2026-01-07 12:40:22 -05:00
212 lines
9.4 KiB
HTML
212 lines
9.4 KiB
HTML
<ng-container *transloco="let t; prefix: 'license'">
|
|
|
|
<div class="position-relative">
|
|
<a class="position-absolute custom-position btn btn-outline-primary" [href]="WikiLink.KavitaPlusFAQ" target="_blank" rel="noreferrer nofollow">{{t('faq-title')}}</a>
|
|
</div>
|
|
|
|
<div>
|
|
<p>{{t('kavita+-desc-part-1')}} <a [href]="WikiLink.KavitaPlus" target="_blank" rel="noreferrer nofollow">{{t('kavita+-desc-part-2')}}</a> {{t('kavita+-desc-part-3')}}</p>
|
|
|
|
<p>{{t('kavita+-warning')}}</p>
|
|
|
|
<form [formGroup]="formGroup">
|
|
<div class="mt-2">
|
|
<app-setting-item [title]="t('title')" (editMode)="updateEditMode($event)" [isEditMode]="!isViewMode()" [showEdit]="hasLicense()" [fixedExtras]="true">
|
|
<ng-template #titleExtra>
|
|
<button class="btn btn-icon btn-sm" (click)="loadLicenseInfo(true)">
|
|
@if (isChecking()) {
|
|
<app-loading [loading]="isChecking()" size="spinner-border-sm"></app-loading>
|
|
} @else if (hasLicense()) {
|
|
<span>
|
|
<i class="fa-solid fa-refresh" tabindex="0" [ngbTooltip]="t('check')"></i>
|
|
</span>
|
|
}
|
|
</button>
|
|
</ng-template>
|
|
<ng-template #view>
|
|
@if (hasLicense()) {
|
|
<span class="me-1">*********</span>
|
|
|
|
@if (isChecking()) {
|
|
<div class="spinner-border spinner-border-sm text-primary" role="status">
|
|
<span class="visually-hidden">{{t('loading')}}</span>
|
|
</div>
|
|
} @else {
|
|
@if (licenseInfo()?.isActive) {
|
|
<i [ngbTooltip]="t('license-valid')" class="fa-solid fa-check-circle successful-validation ms-1">
|
|
<span class="visually-hidden">{{t('license-valid')}}</span>
|
|
</i>
|
|
} @else {
|
|
<i class="error fa-solid fa-exclamation-circle ms-1" [ngbTooltip]="t('license-not-valid')">
|
|
<span class="visually-hidden">{{t('license-not-valid')}}</span>
|
|
</i>
|
|
}
|
|
}
|
|
@if (!isChecking() && hasLicense() && !licenseInfo) {
|
|
<div><span class="error">{{t('license-mismatch')}}</span></div>
|
|
}
|
|
|
|
} @else {
|
|
{{t('no-license-key')}}
|
|
}
|
|
</ng-template>
|
|
|
|
<ng-template #edit>
|
|
<div class="form-group mb-3">
|
|
<label for="license-key">{{t('activate-license-label')}}</label>
|
|
<input id="license-key" type="text" class="form-control" formControlName="licenseKey" autocomplete="off"/>
|
|
</div>
|
|
<div class="form-group mb-3">
|
|
<label for="email">{{t('activate-email-label')}}</label>
|
|
<input id="email" type="email" class="form-control" formControlName="email" autocomplete="off"/>
|
|
</div>
|
|
<div class="form-group mb-3">
|
|
<label for="discordId">{{t('activate-discordId-label')}}</label>
|
|
<i class="fa fa-circle-info ms-1" aria-hidden="true" [ngbTooltip]="t('activate-discordId-tooltip')"></i>
|
|
<a class="ms-1" [href]="WikiLink.KavitaPlusDiscordId" target="_blank" rel="noopener noreferrer">{{t('help-label')}}</a>
|
|
<input id="discordId" type="text" class="form-control" formControlName="discordId" autocomplete="off" [class.is-invalid]="formGroup.get('discordId')?.invalid && formGroup.get('discordId')?.touched"/>
|
|
@if (formGroup.dirty || !formGroup.untouched) {
|
|
<div id="inviteForm-validations" class="invalid-feedback">
|
|
@if (formGroup.get('discordId')?.errors?.pattern) {
|
|
<div>
|
|
{{t('discord-validation')}}
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<div class="col-auto d-flex d-md-block justify-content-sm-center text-md-end mb-3">
|
|
<button type="button" class="flex-fill btn btn-danger me-1" aria-describedby="license-key-header"
|
|
(click)="deleteLicense()">
|
|
{{t('activate-delete')}}
|
|
</button>
|
|
<button type="button" class="flex-fill btn btn-danger me-1" aria-describedby="license-key-header"
|
|
[ngbTooltip]="t('activate-reset-tooltip')"
|
|
[disabled]="!formGroup.get('email')?.value || !formGroup.get('licenseKey')?.value" (click)="resetLicense()">
|
|
{{t('activate-reset')}}
|
|
</button>
|
|
<button type="submit" class="flex-fill btn btn-primary" aria-describedby="license-key-header"
|
|
[disabled]="!formGroup.get('email')?.value || !formGroup.get('licenseKey')?.value" (click)="saveForm()">
|
|
@if (!isSaving()) {
|
|
<span>{{t('activate-save')}}</span>
|
|
}
|
|
|
|
<app-loading [loading]="isSaving()" size="spinner-border-sm"></app-loading>
|
|
</button>
|
|
</div>
|
|
|
|
</ng-template>
|
|
|
|
<ng-template #titleActions>
|
|
@if (hasLicense()) {
|
|
@if (licenseInfo()?.isActive) {
|
|
<a class="btn btn-outline-primary btn-sm me-1" [href]="manageLink()" target="_blank" rel="noreferrer nofollow">{{t('manage')}}</a>
|
|
} @else {
|
|
<a class="btn btn-outline-primary btn-sm me-1"
|
|
[ngbTooltip]="t('invalid-license-tooltip')"
|
|
href="mailto:kavitareader@gmail.com?subject=Kavita%20Subscription%20Renewal&body=Description%3A%0D%0A%0D%0ALicense%20Key%3A%0D%0A%0D%0AYour%20Email%3A"
|
|
>{{t('renew')}}</a>
|
|
}
|
|
} @else {
|
|
<a class="btn btn-secondary btn-sm me-1" [href]="buyLink" target="_blank" rel="noreferrer nofollow">{{t('buy')}}</a>
|
|
<button class="btn btn-primary btn-sm" (click)="toggleViewMode()">{{isViewMode() ? t('activate') : t('cancel')}}</button>
|
|
}
|
|
</ng-template>
|
|
</app-setting-item>
|
|
</div>
|
|
</form>
|
|
|
|
|
|
@let licInfo = licenseInfo();
|
|
@if (hasLicense() && licInfo) {
|
|
|
|
<div class="setting-section-break"></div>
|
|
|
|
<div class="row g-0 mt-3">
|
|
<h3>{{t('info-title')}}</h3>
|
|
<div class="mb-2 col-md-6 col-sm-12">
|
|
<app-setting-item [canEdit]="false" [showEdit]="false" [title]="t('license-active-label')">
|
|
<ng-template #view>
|
|
@if (isChecking()) {
|
|
{{null | defaultValue}}
|
|
} @else {
|
|
<i class="fas {{licInfo.isActive ? 'fa-check-circle' : 'fa-circle-xmark error'}}">
|
|
<span class="visually-hidden">{{licInfo.isActive ? t('valid') : t('invalid')}]</span>
|
|
</i>
|
|
}
|
|
</ng-template>
|
|
</app-setting-item>
|
|
</div>
|
|
|
|
<div class="mb-2 col-md-6 col-sm-12">
|
|
<app-setting-item [canEdit]="false" [showEdit]="false" [title]="t('supported-version-label')">
|
|
<ng-template #view>
|
|
<i class="fas {{licInfo.isValidVersion ? 'fa-check-circle' : 'fa-circle-xmark error'}}">
|
|
<span class="visually-hidden">{{isValidVersion ? t('valid') : t('invalid')}]</span>
|
|
</i>
|
|
</ng-template>
|
|
</app-setting-item>
|
|
</div>
|
|
|
|
<div class="mb-2 col-md-6 col-sm-12">
|
|
<app-setting-item [canEdit]="false" [showEdit]="false" [title]="t('expiration-label')">
|
|
<ng-template #view>
|
|
{{licInfo.expirationDate | utcToLocalTime | defaultValue}}
|
|
</ng-template>
|
|
</app-setting-item>
|
|
</div>
|
|
|
|
<div class="mb-2 col-md-6 col-sm-12">
|
|
<app-setting-item [canEdit]="false" [showEdit]="false" [title]="t('total-subbed-months-label')">
|
|
<ng-template #view>
|
|
{{licInfo.totalMonthsSubbed | number}}
|
|
</ng-template>
|
|
</app-setting-item>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-sm-12">
|
|
<app-setting-item [canEdit]="false" [showEdit]="false" [title]="t('email-label')">
|
|
<ng-template #view>
|
|
<span (click)="toggleEmailShow()" class="col-12 clickable">
|
|
@if (showEmail()) {
|
|
{{licInfo.registeredEmail}}
|
|
} @else {
|
|
***************
|
|
}
|
|
</span>
|
|
</ng-template>
|
|
</app-setting-item>
|
|
</div>
|
|
|
|
<div class="setting-section-break"></div>
|
|
|
|
<!-- Actions around license -->
|
|
<h3>{{t('actions-title')}}</h3>
|
|
|
|
<div class="mt-2 mb-2">
|
|
<app-setting-button [subtitle]="t('cancel-tooltip')">
|
|
<a class="btn btn-danger btn-sm mt-1" [href]="manageLink()" target="_blank" rel="noreferrer nofollow">{{t('cancel-label')}}</a>
|
|
</app-setting-button>
|
|
</div>
|
|
|
|
<div class="mt-2 mb-2">
|
|
<app-setting-button [subtitle]="t('delete-tooltip')">
|
|
<button type="button" class="flex-fill btn btn-danger btn-sm mt-1" aria-describedby="license-key-header" (click)="deleteLicense()">
|
|
{{t('activate-delete')}}
|
|
</button>
|
|
</app-setting-button>
|
|
</div>
|
|
|
|
<div class="mt-2 mb-2">
|
|
<app-setting-button [subtitle]="t('manage-tooltip')">
|
|
<a class="btn btn-primary btn-sm mt-1" [href]="manageLink()" target="_blank" rel="noreferrer nofollow">{{t('manage')}}</a>
|
|
</app-setting-button>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
|
|
</ng-container>
|