mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-09 12:16:36 +00:00
add admin/license i18n
This commit is contained in:
@@ -57,6 +57,7 @@ import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
|
||||
import { SitePriceCalculator } from "./components/SitePriceCalculator";
|
||||
import Link from "next/link";
|
||||
import { Checkbox } from "@app/components/ui/checkbox";
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
const formSchema = z.object({
|
||||
licenseKey: z
|
||||
@@ -77,6 +78,7 @@ function obfuscateLicenseKey(key: string): string {
|
||||
|
||||
export default function LicensePage() {
|
||||
const api = createApiClient(useEnvContext());
|
||||
const t = useTranslations();
|
||||
const [rows, setRows] = useState<LicenseKeyCache[]>([]);
|
||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
@@ -129,11 +131,8 @@ export default function LicensePage() {
|
||||
}
|
||||
} catch (e) {
|
||||
toast({
|
||||
title: "Failed to load license keys",
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred loading license keys"
|
||||
)
|
||||
title: t('licenseErrorKeyLoad'),
|
||||
description: formatAxiosError(e, t('licenseErrorKeyLoadDescription'))
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -148,17 +147,14 @@ export default function LicensePage() {
|
||||
}
|
||||
await loadLicenseKeys();
|
||||
toast({
|
||||
title: "License key deleted",
|
||||
description: "The license key has been deleted"
|
||||
title: t('licenseKeyDeleted'),
|
||||
description: t('licenseKeyDeletedDescription')
|
||||
});
|
||||
setIsDeleteModalOpen(false);
|
||||
} catch (e) {
|
||||
toast({
|
||||
title: "Failed to delete license key",
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred deleting license key"
|
||||
)
|
||||
title: t('licenseErrorKeyDelete'),
|
||||
description: formatAxiosError(e, t('licenseErrorKeyDeleteDescription'))
|
||||
});
|
||||
} finally {
|
||||
setIsDeletingLicense(false);
|
||||
@@ -174,16 +170,13 @@ export default function LicensePage() {
|
||||
}
|
||||
await loadLicenseKeys();
|
||||
toast({
|
||||
title: "License keys rechecked",
|
||||
description: "All license keys have been rechecked"
|
||||
title: t('licenseErrorKeyRechecked'),
|
||||
description: t('licenseErrorKeyRecheckedDescription')
|
||||
});
|
||||
} catch (e) {
|
||||
toast({
|
||||
title: "Failed to recheck license keys",
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred rechecking license keys"
|
||||
)
|
||||
title: t('licenseErrorKeyRecheck'),
|
||||
description: formatAxiosError(e, t('licenseErrorKeyRecheckDescription'))
|
||||
});
|
||||
} finally {
|
||||
setIsRecheckingLicense(false);
|
||||
@@ -201,8 +194,8 @@ export default function LicensePage() {
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "License key activated",
|
||||
description: "The license key has been successfully activated."
|
||||
title: t('licenseKeyActivated'),
|
||||
description: t('licenseKeyActivatedDescription')
|
||||
});
|
||||
|
||||
setIsCreateModalOpen(false);
|
||||
@@ -211,11 +204,8 @@ export default function LicensePage() {
|
||||
} catch (e) {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to activate license key",
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred while activating the license key."
|
||||
)
|
||||
title: t('licenseErrorKeyActivate'),
|
||||
description: formatAxiosError(e, t('licenseErrorKeyActivateDescription'))
|
||||
});
|
||||
} finally {
|
||||
setIsActivatingLicense(false);
|
||||
@@ -245,9 +235,9 @@ export default function LicensePage() {
|
||||
>
|
||||
<CredenzaContent>
|
||||
<CredenzaHeader>
|
||||
<CredenzaTitle>Activate License Key</CredenzaTitle>
|
||||
<CredenzaTitle>{t('licenseActivateKey')}</CredenzaTitle>
|
||||
<CredenzaDescription>
|
||||
Enter a license key to activate it.
|
||||
{t('licenseActivateKeyDescription')}
|
||||
</CredenzaDescription>
|
||||
</CredenzaHeader>
|
||||
<CredenzaBody>
|
||||
@@ -262,7 +252,7 @@ export default function LicensePage() {
|
||||
name="licenseKey"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>License Key</FormLabel>
|
||||
<FormLabel>{t('licenseKey')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
@@ -285,12 +275,7 @@ export default function LicensePage() {
|
||||
</FormControl>
|
||||
<div className="space-y-1 leading-none">
|
||||
<FormLabel>
|
||||
By checking this box, you
|
||||
confirm that you have read
|
||||
and agree to the license
|
||||
terms corresponding to the
|
||||
tier associated with your
|
||||
license key.
|
||||
{t('licenseAgreement')}
|
||||
<br />
|
||||
<Link
|
||||
href="https://fossorial.io/license.html"
|
||||
@@ -298,9 +283,7 @@ export default function LicensePage() {
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary hover:underline"
|
||||
>
|
||||
View Fossorial
|
||||
Commercial License &
|
||||
Subscription Terms
|
||||
{t('fossorialLicense')}
|
||||
</Link>
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
@@ -313,7 +296,7 @@ export default function LicensePage() {
|
||||
</CredenzaBody>
|
||||
<CredenzaFooter>
|
||||
<CredenzaClose asChild>
|
||||
<Button variant="outline">Close</Button>
|
||||
<Button variant="outline">{t('close')}</Button>
|
||||
</CredenzaClose>
|
||||
<Button
|
||||
type="submit"
|
||||
@@ -321,7 +304,7 @@ export default function LicensePage() {
|
||||
loading={isActivatingLicense}
|
||||
disabled={isActivatingLicense}
|
||||
>
|
||||
Activate License
|
||||
{t('licenseActivate')}
|
||||
</Button>
|
||||
</CredenzaFooter>
|
||||
</CredenzaContent>
|
||||
@@ -336,47 +319,40 @@ export default function LicensePage() {
|
||||
}}
|
||||
dialog={
|
||||
<div className="space-y-4">
|
||||
<p>
|
||||
Are you sure you want to delete the license key{" "}
|
||||
<b>
|
||||
{obfuscateLicenseKey(
|
||||
selectedLicenseKey.licenseKey
|
||||
)}
|
||||
</b>
|
||||
?
|
||||
<p>
|
||||
{t('licenseQuestionRemove', {selectedKey: obfuscateLicenseKey(selectedLicenseKey.licenseKey)})}
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
This will remove the license key and all
|
||||
associated permissions granted by it.
|
||||
{t('licenseMessageRemove')}
|
||||
</b>
|
||||
</p>
|
||||
<p>
|
||||
To confirm, please type the license key below.
|
||||
{t('licenseMessageConfirm')}
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
buttonText="Confirm Delete License Key"
|
||||
buttonText={t('licenseKeyDeleteConfirm')}
|
||||
onConfirm={async () =>
|
||||
deleteLicenseKey(selectedLicenseKey.licenseKeyEncrypted)
|
||||
}
|
||||
string={selectedLicenseKey.licenseKey}
|
||||
title="Delete License Key"
|
||||
title={t('licenseKeyDelete')}
|
||||
/>
|
||||
)}
|
||||
|
||||
<SettingsSectionTitle
|
||||
title="Manage License Status"
|
||||
description="View and manage license keys in the system"
|
||||
title={t('licenseTitle')}
|
||||
description={t('licenseTitleDescription')}
|
||||
/>
|
||||
|
||||
<SettingsContainer>
|
||||
<SettingsSectionGrid cols={2}>
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SSTitle>Host License</SSTitle>
|
||||
<SSTitle>{t('licenseHost')}</SSTitle>
|
||||
<SettingsSectionDescription>
|
||||
Manage the main license key for the host.
|
||||
{t('licenseHostDescription')}
|
||||
</SettingsSectionDescription>
|
||||
</SettingsSectionHeader>
|
||||
<div className="space-y-4">
|
||||
@@ -397,7 +373,7 @@ export default function LicensePage() {
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<div className="text-2xl">
|
||||
Not Licensed
|
||||
{t('notLicensed')}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -405,7 +381,7 @@ export default function LicensePage() {
|
||||
{licenseStatus?.hostId && (
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm font-medium">
|
||||
Host ID
|
||||
{t('hostId')}
|
||||
</div>
|
||||
<CopyTextBox text={licenseStatus.hostId} />
|
||||
</div>
|
||||
@@ -413,7 +389,7 @@ export default function LicensePage() {
|
||||
{hostLicense && (
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm font-medium">
|
||||
License Key
|
||||
{t('licenseKey')}
|
||||
</div>
|
||||
<CopyTextBox
|
||||
text={hostLicense}
|
||||
@@ -431,39 +407,33 @@ export default function LicensePage() {
|
||||
disabled={isRecheckingLicense}
|
||||
loading={isRecheckingLicense}
|
||||
>
|
||||
Recheck All Keys
|
||||
{t('licenseReckeckAll')}
|
||||
</Button>
|
||||
</SettingsSectionFooter>
|
||||
</SettingsSection>
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SSTitle>Sites Usage</SSTitle>
|
||||
<SSTitle>{t('licenseSiteUsage')}</SSTitle>
|
||||
<SettingsSectionDescription>
|
||||
View the number of sites using this license.
|
||||
{t('licenseSiteUsageDecsription')}
|
||||
</SettingsSectionDescription>
|
||||
</SettingsSectionHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-2xl">
|
||||
{licenseStatus?.usedSites || 0}{" "}
|
||||
{licenseStatus?.usedSites === 1
|
||||
? "site"
|
||||
: "sites"}{" "}
|
||||
in system
|
||||
{t('licenseSitesUsed', {count: licenseStatus?.usedSites || 0})}
|
||||
</div>
|
||||
</div>
|
||||
{!licenseStatus?.isHostLicensed && (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
There is no limit on the number of sites
|
||||
using an unlicensed host.
|
||||
{t('licenseNoSiteLimit')}
|
||||
</p>
|
||||
)}
|
||||
{licenseStatus?.maxSites && (
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-muted-foreground">
|
||||
{licenseStatus.usedSites || 0} of{" "}
|
||||
{licenseStatus.maxSites} sites used
|
||||
{t('licenseSitesUsedMax', {usedSites: licenseStatus.usedSites || 0, maxSites: licenseStatus.maxSites})}
|
||||
</span>
|
||||
<span className="text-muted-foreground">
|
||||
{Math.round(
|
||||
@@ -495,7 +465,7 @@ export default function LicensePage() {
|
||||
setIsPurchaseModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Purchase License
|
||||
{t('licensePurchase')}
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
@@ -507,7 +477,7 @@ export default function LicensePage() {
|
||||
setIsPurchaseModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Purchase Additional Sites
|
||||
{t('licensePurchaseSites')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user