calcom/apps/web/ee/components/apiKeys/ApiKeyListItem.tsx
Leo Giovanetti 1a79e0624c
Recurring Events (#2562)
* Init dev

* UI changes for recurring event + prisma

* Revisiting schema + changes WIP

* UI done, BE WIP

* Feature completion

* Unused query param removed

* Invalid comment removed

* Removed unused translation

* Update apps/web/public/static/locales/en/common.json

Thanks!

Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* Success page changes

* More progress

* Email text tweaks + test + seed

* Tweaking emails + Cal Apps support WIP

* No app integration for now
Final email and pages tweaks to avoid recurring info showed

* Missing comment for clarity

* Yet again, comment

* Last minute fix

* Missing tooltip for upcoming bookings

* Fixing seed

* Fixing import

* Increasing timeout for e2e

* Fixing any

* Apply suggestions from code review

Co-authored-by: Omar López <zomars@me.com>

* Update apps/web/pages/d/[link]/book.tsx

Co-authored-by: Omar López <zomars@me.com>

* Code improvements

* More code improvements

* Reverting back number input arrows

* Update BookingPage.tsx

* Update BookingPage.tsx

* Adds fallback for sendOrganizerPaymentRefundFailedEmail

* Type overkill

* Type fixes

* Type fixes

* Nitpicks

* Update success.tsx

* Update success.tsx

* Update success.tsx

* Fixing types

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Omar López <zomars@me.com>
2022-05-05 18:16:25 -03:00

107 lines
3.8 KiB
TypeScript

import { PencilAltIcon, TrashIcon } from "@heroicons/react/outline";
import { ExclamationIcon } from "@heroicons/react/solid";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import Button from "@calcom/ui/Button";
import { Dialog, DialogTrigger } from "@calcom/ui/Dialog";
import { Tooltip } from "@calcom/ui/Tooltip";
import { inferQueryOutput, trpc } from "@lib/trpc";
import { ListItem } from "@components/List";
import ConfirmationDialogContent from "@components/dialog/ConfirmationDialogContent";
import Badge from "@components/ui/Badge";
dayjs.extend(relativeTime);
export type TApiKeys = inferQueryOutput<"viewer.apiKeys.list">[number];
export default function ApiKeyListItem(props: { apiKey: TApiKeys; onEditApiKey: () => void }) {
const { t } = useLocale();
const utils = trpc.useContext();
const isExpired = props?.apiKey?.expiresAt ? props.apiKey.expiresAt < new Date() : null;
const neverExpires = props?.apiKey?.expiresAt === null;
const deleteApiKey = trpc.useMutation("viewer.apiKeys.delete", {
async onSuccess() {
await utils.invalidateQueries(["viewer.apiKeys.list"]);
},
});
return (
<ListItem className="-mt-px flex w-full p-4">
<div className="flex w-full justify-between">
<div className="flex max-w-full flex-col truncate">
<div className="flex space-x-2">
<span className="text-gray-900">
{props?.apiKey?.note ? props.apiKey.note : t("api_key_no_note")}
</span>
{!neverExpires && isExpired && (
<Badge className="-p-2" variant="default">
{t("expired")}
</Badge>
)}
</div>
<div className="mt-2 flex">
<span
className={classNames(
"flex flex-col space-x-2 space-y-1 text-xs sm:flex-row sm:space-y-0 sm:rtl:space-x-reverse",
isExpired ? "text-red-600" : "text-gray-500",
neverExpires ? "text-yellow-600" : ""
)}>
{neverExpires ? (
<div className="flex flex-row space-x-3 text-gray-500">
<ExclamationIcon className="w-4" />
{t("api_key_never_expires")}
</div>
) : (
`${isExpired ? t("expired") : t("expires")} ${dayjs(
props?.apiKey?.expiresAt?.toString()
).fromNow()}`
)}
</span>
</div>
</div>
<div className="flex">
<Tooltip content={t("edit_api_key")}>
<Button
onClick={() => props.onEditApiKey()}
color="minimal"
size="icon"
StartIcon={PencilAltIcon}
className="ml-4 w-full self-center p-2"
/>
</Tooltip>
<Dialog>
<Tooltip content={t("delete_api_key")}>
<DialogTrigger asChild>
<Button
onClick={(e) => {
e.stopPropagation();
}}
color="minimal"
size="icon"
StartIcon={TrashIcon}
className="ml-2 w-full self-center p-2"
/>
</DialogTrigger>
</Tooltip>
<ConfirmationDialogContent
variety="danger"
title={t("confirm_delete_api_key")}
confirmBtnText={t("revoke_api_key")}
cancelBtnText={t("cancel")}
onConfirm={() =>
deleteApiKey.mutate({
id: props.apiKey.id,
})
}>
{t("delete_api_key_confirm_title")}
</ConfirmationDialogContent>
</Dialog>
</div>
</div>
</ListItem>
);
}