feat(ui): changed back to relative time distance with tooltip of detailed time

This commit is contained in:
Akhil Mohan
2024-03-29 22:36:46 +05:30
parent 31ad6b0c86
commit 00f2d40803
6 changed files with 184 additions and 106 deletions
@@ -49,6 +49,7 @@ const MAX_ROLES_TO_BE_SHOWN_IN_TABLE = 2;
const formatRoleName = (role: string, customRoleName?: string) => { const formatRoleName = (role: string, customRoleName?: string) => {
if (role === ProjectMembershipRole.Custom) return customRoleName; if (role === ProjectMembershipRole.Custom) return customRoleName;
if (role === ProjectMembershipRole.Member) return "Developer"; if (role === ProjectMembershipRole.Member) return "Developer";
if (role === ProjectMembershipRole.NoAccess) return "No access";
return role; return role;
}; };
export const IdentityTab = withProjectPermission( export const IdentityTab = withProjectPermission(
@@ -173,7 +174,9 @@ export const IdentityTab = withProjectPermission(
return ( return (
<Tag key={roleId}> <Tag key={roleId}>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<div>{formatRoleName(role, customRoleName)}</div> <div className="capitalize">
{formatRoleName(role, customRoleName)}
</div>
{isTemporary && ( {isTemporary && (
<div> <div>
<Tooltip <Tooltip
@@ -1,8 +1,9 @@
/* eslint-disable no-nested-ternary */
import { Controller, useFieldArray, useForm } from "react-hook-form"; import { Controller, useFieldArray, useForm } from "react-hook-form";
import { faCaretDown, faClock, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons"; import { faCaretDown, faClock, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { format } from "date-fns"; import { format, formatDistance } from "date-fns";
import ms from "ms"; import ms from "ms";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { z } from "zod"; import { z } from "zod";
@@ -21,7 +22,8 @@ import {
Select, Select,
SelectItem, SelectItem,
Spinner, Spinner,
Tag Tag,
Tooltip
} from "@app/components/v2"; } from "@app/components/v2";
import { import {
ProjectPermissionActions, ProjectPermissionActions,
@@ -182,24 +184,41 @@ export const IdentityRbacSection = ({ identityProjectMember, onOpenUpgradeModal
/> />
<Popover> <Popover>
<PopoverTrigger disabled={isMemberEditDisabled}> <PopoverTrigger disabled={isMemberEditDisabled}>
<Button <div>
variant="outline_bg" <Tooltip
leftIcon={isTemporary ? <FontAwesomeIcon icon={faClock} /> : undefined} content={
rightIcon={<FontAwesomeIcon icon={faCaretDown} className="ml-2" />} temporaryAccess?.isTemporary
isDisabled={isMemberEditDisabled} ? isExpired
className={twMerge( ? "Timed Access Expired"
"border-none bg-mineshaft-600 hover:bg-mineshaft-500 py-2.5 capitalize text-xs", : `Until ${format(
isTemporary && "text-primary", new Date(temporaryAccess.temporaryAccessEndTime || ""),
isExpired && "text-red-600" "yyyy-MM-dd HH:mm:ss"
)} )}`
> : "Non expiry access"
{!temporaryAccess?.isTemporary }
? "Permanent" >
: `Expires at ${format( <Button
new Date(temporaryAccess.temporaryAccessEndTime || ""), variant="outline_bg"
"yyyy-MM-dd HH:mm:ss" leftIcon={isTemporary ? <FontAwesomeIcon icon={faClock} /> : undefined}
)}`} rightIcon={<FontAwesomeIcon icon={faCaretDown} className="ml-2" />}
</Button> isDisabled={isMemberEditDisabled}
className={twMerge(
"border-none bg-mineshaft-600 py-2.5 text-xs capitalize hover:bg-mineshaft-500",
isTemporary && "text-primary",
isExpired && "text-red-600"
)}
>
{temporaryAccess?.isTemporary
? isExpired
? "Access Expired"
: formatDistance(
new Date(temporaryAccess.temporaryAccessEndTime || ""),
new Date()
)
: "Permanent"}
</Button>
</Tooltip>
</div>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent <PopoverContent
arrowClassName="fill-gray-600" arrowClassName="fill-gray-600"
@@ -279,7 +298,7 @@ export const IdentityRbacSection = ({ identityProjectMember, onOpenUpgradeModal
</Popover> </Popover>
<IconButton <IconButton
variant="outline_bg" variant="outline_bg"
className="border border-mineshaft-500 bg-mineshaft-600 hover:bg-red/20 hover:border-red/70 py-3" className="border border-mineshaft-500 bg-mineshaft-600 py-3 hover:border-red/70 hover:bg-red/20"
ariaLabel="delete-role" ariaLabel="delete-role"
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
onClick={() => { onClick={() => {
@@ -324,7 +343,7 @@ export const IdentityRbacSection = ({ identityProjectMember, onOpenUpgradeModal
)} )}
isLoading={roleForm.formState.isSubmitting} isLoading={roleForm.formState.isSubmitting}
> >
Save Roles Save Roles
</Button> </Button>
</div> </div>
</form> </form>
@@ -1,8 +1,15 @@
import { Controller, useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
import { faArrowRotateLeft, faCaretDown, faCheck, faClock, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons"; import {
faArrowRotateLeft,
faCaretDown,
faCheck,
faClock,
faPlus,
faTrash
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { format } from "date-fns"; import { format, formatDistance } from "date-fns";
import ms from "ms"; import ms from "ms";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { z } from "zod"; import { z } from "zod";
@@ -173,10 +180,15 @@ const SpecificPrivilegeSecretForm = ({
} }
}; };
const getAccessLabel = () => { const getAccessLabel = (exactTime = false) => {
if (isExpired) return "Access expired"; if (isExpired) return "Access expired";
if (!temporaryAccessField?.isTemporary) return "Permanent"; if (!temporaryAccessField?.isTemporary) return "Permanent";
return `Until ${format(new Date(temporaryAccessField.temporaryAccessEndTime || ""), "yyyy-MM-dd HH:mm:ss")}`; if (exactTime)
return `Until ${format(
new Date(temporaryAccessField.temporaryAccessEndTime || ""),
"yyyy-MM-dd HH:mm:ss"
)}`;
return formatDistance(new Date(temporaryAccessField.temporaryAccessEndTime || ""), new Date());
}; };
return ( return (
@@ -281,24 +293,23 @@ const SpecificPrivilegeSecretForm = ({
<div className="mt-7 flex items-center space-x-2"> <div className="mt-7 flex items-center space-x-2">
<Popover> <Popover>
<PopoverTrigger disabled={isMemberEditDisabled}> <PopoverTrigger disabled={isMemberEditDisabled}>
<Tooltip <div>
asChild <Tooltip content={getAccessLabel(true)}>
content={isExpired ? "Timed access expired" : "Grant timed access"} <Button
> variant="outline_bg"
<Button leftIcon={isTemporary ? <FontAwesomeIcon icon={faClock} /> : undefined}
variant="outline_bg" rightIcon={<FontAwesomeIcon icon={faCaretDown} className="ml-2" />}
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
leftIcon={isTemporary ? <FontAwesomeIcon icon={faClock} /> : undefined} className={twMerge(
rightIcon={<FontAwesomeIcon icon={faCaretDown} className="ml-2" />} "border-none bg-mineshaft-600 py-2.5 text-xs capitalize hover:bg-mineshaft-500",
className={twMerge( isTemporary && "text-primary",
"border-none py-2.5 capitalize text-xs hover:bg-mineshaft-500", isExpired && "text-red-600"
isTemporary && "text-primary", )}
isExpired && "text-red-600" >
)} {getAccessLabel()}
> </Button>
{getAccessLabel()} </Tooltip>
</Button> </div>
</Tooltip>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent <PopoverContent
arrowClassName="fill-gray-600" arrowClassName="fill-gray-600"
@@ -381,7 +392,7 @@ const SpecificPrivilegeSecretForm = ({
<Tooltip content="Cancel" className="mr-4"> <Tooltip content="Cancel" className="mr-4">
<IconButton <IconButton
variant="outline_bg" variant="outline_bg"
className="border border-mineshaft-500 bg-mineshaft-600 hover:bg-red/20 hover:border-red/70 py-2.5" className="border border-mineshaft-500 bg-mineshaft-600 py-2.5 hover:border-red/70 hover:bg-red/20"
ariaLabel="delete-privilege" ariaLabel="delete-privilege"
isDisabled={privilegeForm.formState.isSubmitting} isDisabled={privilegeForm.formState.isSubmitting}
onClick={() => privilegeForm.reset()} onClick={() => privilegeForm.reset()}
@@ -389,7 +400,10 @@ const SpecificPrivilegeSecretForm = ({
<FontAwesomeIcon icon={faArrowRotateLeft} className="py-0.5" /> <FontAwesomeIcon icon={faArrowRotateLeft} className="py-0.5" />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Tooltip content={isMemberEditDisabled ? "Access restricted" : "Save"} className="mr-4"> <Tooltip
content={isMemberEditDisabled ? "Access restricted" : "Save"}
className="mr-4"
>
<IconButton <IconButton
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
className="border-none py-3" className="border-none py-3"
@@ -397,19 +411,22 @@ const SpecificPrivilegeSecretForm = ({
type="submit" type="submit"
> >
{privilegeForm.formState.isSubmitting ? ( {privilegeForm.formState.isSubmitting ? (
<Spinner size="xs" className="m-0 text-slate-500 w-3 h-3" /> <Spinner size="xs" className="m-0 h-3 w-3 text-slate-500" />
) : ( ) : (
<FontAwesomeIcon icon={faCheck} className="px-0.5"/> <FontAwesomeIcon icon={faCheck} className="px-0.5" />
)} )}
</IconButton> </IconButton>
</Tooltip> </Tooltip>
</> </>
) : ( ) : (
<Tooltip content={isMemberEditDisabled ? "Access restricted" : "Delete"} className="mr-4"> <Tooltip
content={isMemberEditDisabled ? "Access restricted" : "Delete"}
className="mr-4"
>
<IconButton <IconButton
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
variant="outline_bg" variant="outline_bg"
className="border border-mineshaft-500 bg-mineshaft-600 hover:bg-red/20 hover:border-red/70 py-3" className="border border-mineshaft-500 bg-mineshaft-600 py-3 hover:border-red/70 hover:bg-red/20"
ariaLabel="delete-privilege" ariaLabel="delete-privilege"
onClick={() => handlePopUpOpen("deletePrivilege")} onClick={() => handlePopUpOpen("deletePrivilege")}
> >
@@ -480,7 +497,7 @@ export const SpecificPrivilegeSection = ({ identityId }: Props) => {
Additional Privileges Additional Privileges
{isLoading && <Spinner size="xs" />} {isLoading && <Spinner size="xs" />}
</div> </div>
<p className="text-sm text-mineshaft-400 mt-0.5"> <p className="mt-0.5 text-sm text-mineshaft-400">
Select individual privileges to associate with the identity. Select individual privileges to associate with the identity.
</p> </p>
<div> <div>
@@ -76,6 +76,7 @@ const MAX_ROLES_TO_BE_SHOWN_IN_TABLE = 2;
const formatRoleName = (role: string, customRoleName?: string) => { const formatRoleName = (role: string, customRoleName?: string) => {
if (role === ProjectMembershipRole.Custom) return customRoleName; if (role === ProjectMembershipRole.Custom) return customRoleName;
if (role === ProjectMembershipRole.Member) return "Developer"; if (role === ProjectMembershipRole.Member) return "Developer";
if (role === ProjectMembershipRole.NoAccess) return "No access";
return role; return role;
}; };
@@ -279,7 +280,9 @@ export const MemberListTab = () => {
return ( return (
<Tag key={id}> <Tag key={id}>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<div>{formatRoleName(role, customRoleName)}</div> <div className="capitalize">
{formatRoleName(role, customRoleName)}
</div>
{isTemporary && ( {isTemporary && (
<div> <div>
<Tooltip <Tooltip
@@ -1,8 +1,9 @@
/* eslint-disable no-nested-ternary */
import { Controller, useFieldArray, useForm } from "react-hook-form"; import { Controller, useFieldArray, useForm } from "react-hook-form";
import { faCaretDown, faClock, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons"; import { faCaretDown, faClock, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { format } from "date-fns"; import { format, formatDistance } from "date-fns";
import ms from "ms"; import ms from "ms";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { z } from "zod"; import { z } from "zod";
@@ -21,7 +22,8 @@ import {
Select, Select,
SelectItem, SelectItem,
Spinner, Spinner,
Tag Tag,
Tooltip
} from "@app/components/v2"; } from "@app/components/v2";
import { import {
ProjectPermissionActions, ProjectPermissionActions,
@@ -170,7 +172,7 @@ export const MemberRbacSection = ({ projectMember, onOpenUpgradeModal }: Props)
{...field} {...field}
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
onValueChange={(e) => onChange(e)} onValueChange={(e) => onChange(e)}
className="w-full bg-mineshaft-600 hover:bg-mineshaft-500 duration-200" className="w-full bg-mineshaft-600 duration-200 hover:bg-mineshaft-500"
> >
{projectRoles?.map(({ name, slug, id: projectRoleId }) => ( {projectRoles?.map(({ name, slug, id: projectRoleId }) => (
<SelectItem value={slug} key={projectRoleId}> <SelectItem value={slug} key={projectRoleId}>
@@ -181,25 +183,42 @@ export const MemberRbacSection = ({ projectMember, onOpenUpgradeModal }: Props)
)} )}
/> />
<Popover> <Popover>
<PopoverTrigger disabled={isMemberEditDisabled}> <PopoverTrigger disabled={isMemberEditDisabled} asChild>
<Button <div>
variant="outline_bg" <Tooltip
leftIcon={isTemporary ? <FontAwesomeIcon icon={faClock} /> : undefined} content={
rightIcon={<FontAwesomeIcon icon={faCaretDown} className="ml-2" />} temporaryAccess?.isTemporary
isDisabled={isMemberEditDisabled} ? isExpired
className={twMerge( ? "Timed Access Expired"
"border-none bg-mineshaft-600 hover:bg-mineshaft-500 py-2.5 capitalize text-xs", : `Until ${format(
isTemporary && "text-primary", new Date(temporaryAccess.temporaryAccessEndTime || ""),
isExpired && "text-red-600" "yyyy-MM-dd HH:mm:ss"
)} )}`
> : "Non expiry access"
{!temporaryAccess?.isTemporary }
? "Permanent" >
: `Until ${format( <Button
new Date(temporaryAccess.temporaryAccessEndTime || ""), variant="outline_bg"
"yyyy-MM-dd HH:mm:ss" leftIcon={isTemporary ? <FontAwesomeIcon icon={faClock} /> : undefined}
)}`} rightIcon={<FontAwesomeIcon icon={faCaretDown} className="ml-2" />}
</Button> isDisabled={isMemberEditDisabled}
className={twMerge(
"border-none bg-mineshaft-600 py-2.5 text-xs capitalize hover:bg-mineshaft-500",
isTemporary && "text-primary",
isExpired && "text-red-600"
)}
>
{temporaryAccess?.isTemporary
? isExpired
? "Access Expired"
: formatDistance(
new Date(temporaryAccess.temporaryAccessEndTime || ""),
new Date()
)
: "Permanent"}
</Button>
</Tooltip>
</div>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent <PopoverContent
arrowClassName="fill-gray-600" arrowClassName="fill-gray-600"
@@ -279,7 +298,7 @@ export const MemberRbacSection = ({ projectMember, onOpenUpgradeModal }: Props)
</Popover> </Popover>
<IconButton <IconButton
variant="outline_bg" variant="outline_bg"
className="border border-mineshaft-500 bg-mineshaft-600 hover:bg-red/20 hover:border-red/70 py-3" className="border border-mineshaft-500 bg-mineshaft-600 py-3 hover:border-red/70 hover:bg-red/20"
ariaLabel="delete-role" ariaLabel="delete-role"
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
onClick={() => { onClick={() => {
@@ -321,7 +340,7 @@ export const MemberRbacSection = ({ projectMember, onOpenUpgradeModal }: Props)
)} )}
isLoading={roleForm.formState.isSubmitting} isLoading={roleForm.formState.isSubmitting}
> >
Save Roles Save Roles
</Button> </Button>
</div> </div>
</form> </form>
@@ -1,8 +1,15 @@
import { Controller, useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
import { faArrowRotateLeft, faCaretDown, faCheck, faClock, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons"; import {
faArrowRotateLeft,
faCaretDown,
faCheck,
faClock,
faPlus,
faTrash
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { format } from "date-fns"; import { format, formatDistance } from "date-fns";
import ms from "ms"; import ms from "ms";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { z } from "zod"; import { z } from "zod";
@@ -161,10 +168,15 @@ const SpecificPrivilegeSecretForm = ({ privilege }: { privilege: TProjectUserPri
} }
}; };
const getAccessLabel = () => { const getAccessLabel = (exactTime = false) => {
if (isExpired) return "Access expired"; if (isExpired) return "Access expired";
if (!temporaryAccessField?.isTemporary) return "Permanent"; if (!temporaryAccessField?.isTemporary) return "Permanent";
return `Until ${format(new Date(temporaryAccessField.temporaryAccessEndTime || ""), "yyyy-MM-dd HH:mm:ss")}`; if (exactTime)
return `Until ${format(
new Date(temporaryAccessField.temporaryAccessEndTime || ""),
"yyyy-MM-dd HH:mm:ss"
)}`;
return formatDistance(new Date(temporaryAccessField.temporaryAccessEndTime || ""), new Date());
}; };
return ( return (
@@ -269,24 +281,23 @@ const SpecificPrivilegeSecretForm = ({ privilege }: { privilege: TProjectUserPri
<div className="mt-7 flex items-center space-x-2"> <div className="mt-7 flex items-center space-x-2">
<Popover> <Popover>
<PopoverTrigger disabled={isMemberEditDisabled}> <PopoverTrigger disabled={isMemberEditDisabled}>
<Tooltip <div>
asChild <Tooltip content={getAccessLabel(true)}>
content={isExpired ? "Timed access expired" : "Grant timed access"} <Button
> variant="outline_bg"
<Button leftIcon={isTemporary ? <FontAwesomeIcon icon={faClock} /> : undefined}
variant="outline_bg" rightIcon={<FontAwesomeIcon icon={faCaretDown} className="ml-2" />}
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
leftIcon={isTemporary ? <FontAwesomeIcon icon={faClock} /> : undefined} className={twMerge(
rightIcon={<FontAwesomeIcon icon={faCaretDown} className="ml-2" />} "border-none bg-mineshaft-600 py-2.5 text-xs capitalize hover:bg-mineshaft-500",
className={twMerge( isTemporary && "text-primary",
"border-none py-2.5 capitalize text-xs hover:bg-mineshaft-500", isExpired && "text-red-600"
isTemporary && "text-primary", )}
isExpired && "text-red-600" >
)} {getAccessLabel()}
> </Button>
{getAccessLabel()} </Tooltip>
</Button> </div>
</Tooltip>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent <PopoverContent
arrowClassName="fill-gray-600" arrowClassName="fill-gray-600"
@@ -369,7 +380,7 @@ const SpecificPrivilegeSecretForm = ({ privilege }: { privilege: TProjectUserPri
<Tooltip content="Cancel" className="mr-4"> <Tooltip content="Cancel" className="mr-4">
<IconButton <IconButton
variant="outline_bg" variant="outline_bg"
className="border border-mineshaft-500 bg-mineshaft-600 hover:bg-red/20 hover:border-red/70 py-2.5" className="border border-mineshaft-500 bg-mineshaft-600 py-2.5 hover:border-red/70 hover:bg-red/20"
ariaLabel="delete-privilege" ariaLabel="delete-privilege"
isDisabled={privilegeForm.formState.isSubmitting} isDisabled={privilegeForm.formState.isSubmitting}
onClick={() => privilegeForm.reset()} onClick={() => privilegeForm.reset()}
@@ -377,7 +388,10 @@ const SpecificPrivilegeSecretForm = ({ privilege }: { privilege: TProjectUserPri
<FontAwesomeIcon icon={faArrowRotateLeft} className="py-0.5" /> <FontAwesomeIcon icon={faArrowRotateLeft} className="py-0.5" />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Tooltip content={isMemberEditDisabled ? "Access restricted" : "Save"} className="mr-4"> <Tooltip
content={isMemberEditDisabled ? "Access restricted" : "Save"}
className="mr-4"
>
<IconButton <IconButton
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
className="border-none py-3" className="border-none py-3"
@@ -385,19 +399,22 @@ const SpecificPrivilegeSecretForm = ({ privilege }: { privilege: TProjectUserPri
type="submit" type="submit"
> >
{privilegeForm.formState.isSubmitting ? ( {privilegeForm.formState.isSubmitting ? (
<Spinner size="xs" className="m-0 text-slate-500 w-3 h-3" /> <Spinner size="xs" className="m-0 h-3 w-3 text-slate-500" />
) : ( ) : (
<FontAwesomeIcon icon={faCheck} className="px-0.5"/> <FontAwesomeIcon icon={faCheck} className="px-0.5" />
)} )}
</IconButton> </IconButton>
</Tooltip> </Tooltip>
</> </>
) : ( ) : (
<Tooltip content={isMemberEditDisabled ? "Access restricted" : "Delete"} className="mr-4"> <Tooltip
content={isMemberEditDisabled ? "Access restricted" : "Delete"}
className="mr-4"
>
<IconButton <IconButton
isDisabled={isMemberEditDisabled} isDisabled={isMemberEditDisabled}
variant="outline_bg" variant="outline_bg"
className="border border-mineshaft-500 bg-mineshaft-600 hover:bg-red/20 hover:border-red/70 py-3" className="border border-mineshaft-500 bg-mineshaft-600 py-3 hover:border-red/70 hover:bg-red/20"
ariaLabel="delete-privilege" ariaLabel="delete-privilege"
onClick={() => handlePopUpOpen("deletePrivilege")} onClick={() => handlePopUpOpen("deletePrivilege")}
> >
@@ -463,7 +480,7 @@ export const SpecificPrivilegeSection = ({ membershipId }: Props) => {
Additional Privileges Additional Privileges
{isLoading && <Spinner size="xs" />} {isLoading && <Spinner size="xs" />}
</div> </div>
<p className="text-sm text-mineshaft-400 mt-0.5"> <p className="mt-0.5 text-sm text-mineshaft-400">
Select individual privileges to associate with the user. Select individual privileges to associate with the user.
</p> </p>
<div> <div>