Skip to content
This repository has been archived by the owner on Apr 7, 2024. It is now read-only.

Pro 133/api key delete #82

Merged
merged 3 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ export const rollKey = async (name: string, workspaceId: string) => {
});
});

revalidatePath(`/floe`);
revalidatePath(`/${workspaceId}/developers`);

return token;
};

export const deleteKey = async (slug: string, workspaceId: string) => {
await db.encryptedKey.delete({
where: {
workspaceId_slug: {
slug,
workspaceId,
},
},
});

revalidatePath(`/${workspaceId}/developers`);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Pill } from "@floe/ui";
import type { Prisma } from "@floe/db";
import { KeyIcon } from "@heroicons/react/24/solid";
import { KeyIcon, EllipsisVerticalIcon } from "@heroicons/react/24/solid";
import { TrashIcon } from "@heroicons/react/20/solid";
import { Menu, Transition } from "@headlessui/react";
import { Fragment } from "react";
import { deleteKey } from "./actions";

export function Table({
workspace,
Expand All @@ -27,53 +31,92 @@ export function Table({
}

return (
<table className="min-w-full divide-y divide-gray-300 table-fixed">
<table className="min-w-full divide-y table-fixed divide-zinc-300">
<thead>
<tr>
<th
className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-0"
className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-zinc-900 sm:pl-0"
scope="col"
>
Name
</th>
<th
className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-0"
className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-zinc-900 sm:pl-0"
scope="col"
>
Slug
</th>
<th
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
className="px-3 py-3.5 text-left text-sm font-semibold text-zinc-900"
scope="col"
>
Token
</th>
<th
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
className="px-3 py-3.5 text-left text-sm font-semibold text-zinc-900"
scope="col"
>
Created
</th>
<th />
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tbody className="divide-y divide-zinc-200">
{workspace.encrytpedKeys.map((key) => (
<tr key={key.slug}>
<td className="py-4 pl-4 pr-3 text-sm font-medium text-gray-900 whitespace-nowrap sm:pl-0">
<td className="py-4 pl-4 pr-3 text-sm font-medium text-zinc-900 whitespace-nowrap sm:pl-0">
{key.name}
</td>
<td className="py-4 pl-4 pr-3 text-sm font-medium text-gray-900 whitespace-nowrap sm:pl-0">
<td className="py-4 pl-4 pr-3 text-sm font-medium text-zinc-900 whitespace-nowrap sm:pl-0">
<Pill color="gray" fontStlye="mono" text={workspace.slug} />
</td>
<td className="px-3 py-4 text-sm text-gray-500 whitespace-nowrap">
<td className="px-3 py-4 text-sm text-zinc-500 whitespace-nowrap">
<Pill
color="gray"
fontStlye="mono"
text={`secret_••••••••••••••••${key.slug}`}
/>
</td>
<td className="flex items-center gap-1 px-3 py-4 text-sm text-gray-500 whitespace-nowrap">
{new Date(key.createdAt).toLocaleDateString()}
<td className="flex items-center gap-1 px-3 py-4 text-sm text-zinc-500 whitespace-nowrap">
<time
className="mt-2 nx-text-gray-500 dark:nx-text-gray-400"
dateTime={new Date(key.createdAt).toLocaleDateString()}
suppressHydrationWarning
>
{new Date(key.createdAt).toLocaleDateString("en-US", {
day: "numeric",
month: "long",
year: "numeric",
})}
</time>
</td>
<td>
<Menu as="div" className="relative text-right">
<Menu.Button className="p-1 rounded-full hover:bg-zinc-100 focus:outline-none">
<EllipsisVerticalIcon className="w-5 h-5 text-zinc-900" />
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute bottom-full right-0 z-10 mb-2.5 min-w-[150px] rounded-md bg-white py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-none">
<Menu.Item>
<button
className="flex items-center w-full gap-2 px-3 py-1 text-sm leading-6 text-left text-zinc-900 hover:bg-zinc-50"
onClick={() => deleteKey(key.slug, workspace.id)}
type="button"
>
<TrashIcon className="h-5" /> Delete key
</button>
</Menu.Item>
</Menu.Items>
</Transition>
</Menu>
</td>
</tr>
))}
Expand Down
20 changes: 15 additions & 5 deletions apps/app/src/app/signin/form.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
"use client";

import { useState } from "react";
import { signIn } from "next-auth/react";
import { Button, Input } from "@floe/ui";
import Image from "next/image";
import type { FormEvent } from "react";
import { Spinner } from "@floe/ui";
import { useSearchParams } from "next/navigation";
import logo from "public/logo.png";

function Form() {
const searchParams = useSearchParams();
const [loading, setLoading] = useState(false);
const callbackUrl = searchParams.get("callbackUrl") || "/";

function handleSubmit(event: FormEvent<HTMLFormElement>) {
async function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();

if (loading) {
return;
}

const email = event.currentTarget.email.value;
void signIn("sendgrid", { email, callbackUrl });
setLoading(true);
await signIn("sendgrid", { email, callbackUrl }).finally(() => {
setLoading(false);
});
}

return (
Expand All @@ -39,8 +49,8 @@ function Form() {
type="email"
/>
</div>
<Button className="w-full" type="submit">
Continue with email
<Button className="w-full" disabled={loading} type="submit">
{loading ? <Spinner /> : "Continue with email"}
</Button>
</form>
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/action-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function ActionCard({
</div>
</div>
</div>
<div className="px-6 py-5">{children}</div>
<div className="px-6 py-5 overflow-x-auto">{children}</div>
{bottomActions?.length ? (
<div className="px-6 py-3 border-t rounded-b-xl bg-zinc-100 border-zinc-200">
<div className="flex items-center justify-between -mt-2 -ml-4 flex-nowrap">
Expand Down