add admin/license i18n

This commit is contained in:
Lokowitz
2025-05-06 09:41:44 +00:00
parent 4dd9f4736d
commit 1e72b0f854
4 changed files with 124 additions and 98 deletions

View File

@@ -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>
</>
)}