Skip to content

Commit

Permalink
chore: further changes
Browse files Browse the repository at this point in the history
  • Loading branch information
im-adithya committed Jul 11, 2024
1 parent d4974cf commit 70183e4
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 112 deletions.
3 changes: 1 addition & 2 deletions frontend/src/components/BudgetAmountSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ function BudgetAmountSelect({
className={cn(
"cursor-pointer rounded text-nowrap border-2 text-center p-4 dark:text-white",
!customBudget &&
(Number.isNaN(value) ? 100000 : value) ==
budgetOptions[budget]
(Number.isNaN(value) ? 0 : value) == budgetOptions[budget]
? "border-primary"
: "border-muted"
)}
Expand Down
247 changes: 139 additions & 108 deletions frontend/src/components/Permissions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PlusCircle } from "lucide-react";
import React, { useState } from "react";
import React from "react";
import BudgetAmountSelect from "src/components/BudgetAmountSelect";
import BudgetRenewalSelect from "src/components/BudgetRenewalSelect";
import ExpirySelect from "src/components/ExpirySelect";
Expand All @@ -20,7 +20,7 @@ interface PermissionsProps {
capabilities: WalletCapabilities;
initialPermissions: AppPermissions;
onPermissionsChange: (permissions: AppPermissions) => void;
canEditPermissions: boolean;
canEditPermissions?: boolean;
budgetUsage?: number;
isNewConnection?: boolean;
}
Expand All @@ -34,118 +34,135 @@ const Permissions: React.FC<PermissionsProps> = ({
budgetUsage,
}) => {
const [permissions, setPermissions] = React.useState(initialPermissions);
const [budgetOption, setBudgetOption] = useState(
isNewConnection ? !!permissions.maxAmount : true
);
const [expireOption, setExpireOption] = useState(
isNewConnection ? !!permissions.expiresAt : true
);

// this is triggered when edit mode is cancelled in show app
React.useEffect(() => {
setPermissions(initialPermissions);
}, [initialPermissions]);

const handlePermissionsChange = (
changedPermissions: Partial<AppPermissions>
) => {
const updatedPermissions = { ...permissions, ...changedPermissions };
setPermissions(updatedPermissions);
onPermissionsChange(updatedPermissions);
};
const canEditBudgetAmount = isNewConnection
? Number.isNaN(permissions.maxAmount)
: canEditPermissions;
const canEditExpiry = isNewConnection
? !permissions.expiresAt
: canEditPermissions;
const [showBudgetOptions, setShowBudgetOptions] = React.useState(
isNewConnection ? !!permissions.maxAmount : true
);
const [showExpiryOptions, setShowExpiryOptions] = React.useState(
isNewConnection ? !!permissions.expiresAt : true
);

const handleScopeChange = (scopes: Set<Scope>) => {
handlePermissionsChange({ scopes });
};
const handlePermissionsChange = React.useCallback(
(changedPermissions: Partial<AppPermissions>) => {
const updatedPermissions = { ...permissions, ...changedPermissions };
setPermissions(updatedPermissions);
onPermissionsChange(updatedPermissions);
},
[permissions, onPermissionsChange]
);

const handleBudgetMaxAmountChange = (amount: number) => {
handlePermissionsChange({ maxAmount: amount });
};
const handleScopeChange = React.useCallback(
(scopes: Set<Scope>) => {
handlePermissionsChange({ scopes });
},
[handlePermissionsChange]
);

const handleBudgetRenewalChange = (value: string) => {
handlePermissionsChange({ budgetRenewal: value as BudgetRenewalType });
};
const handleBudgetMaxAmountChange = React.useCallback(
(amount: number) => {
handlePermissionsChange({ maxAmount: amount });
},
[handlePermissionsChange]
);

const handleExpiryDaysChange = (expiryDays: number) => {
if (!expiryDays) {
handlePermissionsChange({ expiresAt: undefined });
return;
}
const currentDate = new Date();
currentDate.setDate(currentDate.getUTCDate() + expiryDays);
currentDate.setHours(23, 59, 59);
handlePermissionsChange({ expiresAt: currentDate });
};
const handleBudgetRenewalChange = React.useCallback(
(value: string) => {
handlePermissionsChange({ budgetRenewal: value as BudgetRenewalType });
},
[handlePermissionsChange]
);

return !canEditPermissions ? (
<>
<p className="text-sm font-medium mb-2">Scopes</p>
<div className="flex flex-col gap-1">
{[...initialPermissions.scopes].map((rm, index) => {
const PermissionIcon = iconMap[rm];
return (
<div
key={index}
className={cn(
"flex items-center mb-2",
rm == NIP_47_PAY_INVOICE_METHOD && "order-last"
)}
>
<PermissionIcon className="mr-2 w-4 h-4" />
<p className="text-sm">{scopeDescriptions[rm]}</p>
</div>
);
})}
</div>
{permissions.scopes.has(NIP_47_PAY_INVOICE_METHOD) && (
<div className="pt-2 pl-4 ml-2 border-l-2 border-l-primary">
<div className="flex flex-col gap-2 text-muted-foreground mb-3 text-sm">
<p className="capitalize">
Budget Renewal: {permissions.budgetRenewal || "Never"}
</p>
<p>
Budget Amount:{" "}
{permissions.maxAmount
? new Intl.NumberFormat().format(permissions.maxAmount)
: "∞"}
{" sats "}
{`(${new Intl.NumberFormat().format(budgetUsage || 0)} sats used)`}
</p>
const handleExpiryDaysChange = React.useCallback(
(expiryDays: number) => {
if (!expiryDays) {
handlePermissionsChange({ expiresAt: undefined });
return;
}
const currentDate = new Date();
currentDate.setDate(currentDate.getUTCDate() + expiryDays);
currentDate.setHours(23, 59, 59);
handlePermissionsChange({ expiresAt: currentDate });
},
[handlePermissionsChange]
);

return (
<div className="max-w-lg">
{canEditPermissions ? (
<Scopes
capabilities={capabilities}
scopes={permissions.scopes}
onScopeChange={handleScopeChange}
/>
) : (
<>
<p className="text-sm font-medium mb-2">Scopes</p>
<div className="flex flex-col gap-1">
{[...initialPermissions.scopes].map((rm) => {
const PermissionIcon = iconMap[rm];
return (
<div
key={rm}
className={cn(
"flex items-center mb-2",
rm == NIP_47_PAY_INVOICE_METHOD && "order-last"
)}
>
<PermissionIcon className="mr-2 w-4 h-4" />
<p className="text-sm">{scopeDescriptions[rm]}</p>
</div>
);
})}
</div>
</div>
</>
)}
<div className="mt-4">
<p className="text-sm font-medium mb-2">Connection expiry</p>
<p className="text-muted-foreground text-sm">
{permissions.expiresAt &&
new Date(permissions.expiresAt).getFullYear() !== 1
? new Date(permissions.expiresAt).toString()
: "This app will never expire"}
</p>
</div>
</>
) : (
<div className="max-w-lg">
<Scopes
capabilities={capabilities}
scopes={permissions.scopes}
onScopeChange={handleScopeChange}
/>

{capabilities.scopes.includes(NIP_47_PAY_INVOICE_METHOD) &&
permissions.scopes.has(NIP_47_PAY_INVOICE_METHOD) && (
permissions.scopes.has(NIP_47_PAY_INVOICE_METHOD) &&
(!canEditBudgetAmount ? (
<div className="pt-2 pl-4 ml-2 border-l-2 border-l-primary">
<div className="flex flex-col gap-2 text-muted-foreground mb-3 text-sm">
<p className="capitalize">
Budget Renewal: {permissions.budgetRenewal || "Never"}
</p>
<p>
Budget Amount:{" "}
{permissions.maxAmount
? new Intl.NumberFormat().format(permissions.maxAmount)
: "∞"}
{" sats "}
{!isNewConnection &&
`(${new Intl.NumberFormat().format(budgetUsage || 0)} sats used)`}
</p>
</div>
</div>
) : (
<>
{!budgetOption && (
{!showBudgetOptions && (
<Button
type="button"
variant="secondary"
onClick={() => setBudgetOption(true)}
onClick={() => {
setShowBudgetOptions(true);
handleBudgetMaxAmountChange(100000);
}}
className="mb-4 mr-4"
>
<PlusCircle className="w-4 h-4 mr-2" />
Set budget renewal
</Button>
)}
{budgetOption && (
{showBudgetOptions && (
<>
<p className="font-medium text-sm mb-2">Budget Renewal</p>
<div className="flex gap-2 items-center text-muted-foreground mb-4 text-sm">
Expand All @@ -162,25 +179,39 @@ const Permissions: React.FC<PermissionsProps> = ({
</>
)}
</>
)}
))}

{!expireOption && (
<Button
type="button"
variant="secondary"
onClick={() => setExpireOption(true)}
className="mb-6"
>
<PlusCircle className="w-4 h-4 mr-2" />
Set expiration time
</Button>
)}
{!canEditExpiry ? (
<div className="mt-4">
<p className="text-sm font-medium mb-2">Connection expiry</p>
<p className="text-muted-foreground text-sm">
{permissions.expiresAt &&
new Date(permissions.expiresAt).getFullYear() !== 1
? new Date(permissions.expiresAt).toString()
: "This app will never expire"}
</p>
</div>
) : (
<>
{!showExpiryOptions && (
<Button
type="button"
variant="secondary"
onClick={() => setShowExpiryOptions(true)}
className="mb-6"
>
<PlusCircle className="w-4 h-4 mr-2" />
Set expiration time
</Button>
)}

{expireOption && (
<ExpirySelect
value={permissions.expiresAt}
onChange={handleExpiryDaysChange}
/>
{showExpiryOptions && (
<ExpirySelect
value={permissions.expiresAt}
onChange={handleExpiryDaysChange}
/>
)}
</>
)}
</div>
);
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/screens/apps/NewApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ const NewAppInternal = ({ capabilities }: NewAppInternalProps) => {
const parseExpiresParam = (expiresParam: string): Date | undefined => {
const expiresParamTimestamp = parseInt(expiresParam);
if (!isNaN(expiresParamTimestamp)) {
return new Date(expiresParamTimestamp * 1000);
const expiry = new Date(expiresParamTimestamp * 1000);
expiry.setHours(23, 59, 59);
return expiry;
}
return undefined;
};
Expand Down Expand Up @@ -271,7 +273,7 @@ const NewAppInternal = ({ capabilities }: NewAppInternalProps) => {
capabilities={capabilities}
initialPermissions={permissions}
onPermissionsChange={setPermissions}
canEditPermissions={!reqMethodsParam}
canEditPermissions
isNewConnection
/>
</div>
Expand Down

0 comments on commit 70183e4

Please sign in to comment.