clean up ui pass 1

This commit is contained in:
miloschwartz
2025-06-30 09:33:48 -07:00
parent 3b6a44e683
commit a0381eb2c6
82 changed files with 17618 additions and 17258 deletions

View File

@@ -46,11 +46,14 @@ export default function ApiKeysTable({ apiKeys }: ApiKeyTableProps) {
const deleteSite = (apiKeyId: string) => {
api.delete(`/api-key/${apiKeyId}`)
.catch((e) => {
console.error(t('apiKeysErrorDelete'), e);
console.error(t("apiKeysErrorDelete"), e);
toast({
variant: "destructive",
title: t('apiKeysErrorDelete'),
description: formatAxiosError(e, t('apiKeysErrorDeleteMessage'))
title: t("apiKeysErrorDelete"),
description: formatAxiosError(
e,
t("apiKeysErrorDeleteMessage")
)
});
})
.then(() => {
@@ -64,41 +67,6 @@ export default function ApiKeysTable({ apiKeys }: ApiKeyTableProps) {
};
const columns: ColumnDef<ApiKeyRow>[] = [
{
id: "dots",
cell: ({ row }) => {
const apiKeyROw = row.original;
const router = useRouter();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
<span className="sr-only">{t('openMenu')}</span>
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
onClick={() => {
setSelected(apiKeyROw);
}}
>
<span>{t('viewSettings')}</span>
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
setSelected(apiKeyROw);
setIsDeleteModalOpen(true);
}}
>
<span className="text-red-500">{t('delete')}</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
},
{
accessorKey: "name",
header: ({ column }) => {
@@ -109,7 +77,7 @@ export default function ApiKeysTable({ apiKeys }: ApiKeyTableProps) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
{t('name')}
{t("name")}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@@ -117,7 +85,7 @@ export default function ApiKeysTable({ apiKeys }: ApiKeyTableProps) {
},
{
accessorKey: "key",
header: t('key'),
header: t("key"),
cell: ({ row }) => {
const r = row.original;
return <span className="font-mono">{r.key}</span>;
@@ -125,7 +93,7 @@ export default function ApiKeysTable({ apiKeys }: ApiKeyTableProps) {
},
{
accessorKey: "createdAt",
header: t('createdAt'),
header: t("createdAt"),
cell: ({ row }) => {
const r = row.original;
return <span>{moment(r.createdAt).format("lll")} </span>;
@@ -136,13 +104,44 @@ export default function ApiKeysTable({ apiKeys }: ApiKeyTableProps) {
cell: ({ row }) => {
const r = row.original;
return (
<div className="flex items-center justify-end">
<Link href={`/admin/api-keys/${r.id}`}>
<Button variant={"outlinePrimary"} className="ml-2">
{t('edit')}
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
</Link>
<div className="flex items-center justify-end gap-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
<span className="sr-only">
{t("openMenu")}
</span>
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
onClick={() => {
setSelected(r);
}}
>
<span>{t("viewSettings")}</span>
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
setSelected(r);
setIsDeleteModalOpen(true);
}}
>
<span className="text-red-500">
{t("delete")}
</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<div className="flex items-center justify-end">
<Link href={`/admin/api-keys/${r.id}`}>
<Button variant={"secondary"} className="ml-2" size="sm">
{t("edit")}
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
</Link>
</div>
</div>
);
}
@@ -161,24 +160,23 @@ export default function ApiKeysTable({ apiKeys }: ApiKeyTableProps) {
dialog={
<div className="space-y-4">
<p>
{t('apiKeysQuestionRemove', {selectedApiKey: selected?.name || selected?.id})}
{t("apiKeysQuestionRemove", {
selectedApiKey:
selected?.name || selected?.id
})}
</p>
<p>
<b>
{t('apiKeysMessageRemove')}
</b>
<b>{t("apiKeysMessageRemove")}</b>
</p>
<p>
{t('apiKeysMessageConfirm')}
</p>
<p>{t("apiKeysMessageConfirm")}</p>
</div>
}
buttonText={t('apiKeysDeleteConfirm')}
buttonText={t("apiKeysDeleteConfirm")}
onConfirm={async () => deleteSite(selected!.id)}
string={selected.name}
title={t('apiKeysDelete')}
title={t("apiKeysDelete")}
/>
)}

View File

@@ -2,16 +2,7 @@ import { internal } from "@app/lib/api";
import { AxiosResponse } from "axios";
import { redirect } from "next/navigation";
import { authCookieHeader } from "@app/lib/api/cookies";
import { SidebarSettings } from "@app/components/SidebarSettings";
import Link from "next/link";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator
} from "@app/components/ui/breadcrumb";
import { GetApiKeyResponse } from "@server/routers/apiKeys";
import ApiKeyProvider from "@app/providers/ApiKeyProvider";
import { HorizontalTabs } from "@app/components/HorizontalTabs";

View File

@@ -25,21 +25,12 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { Input } from "@app/components/ui/input";
import { InfoIcon } from "lucide-react";
import { Button } from "@app/components/ui/button";
import { Checkbox, CheckboxWithLabel } from "@app/components/ui/checkbox";
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
import { createApiClient, formatAxiosError } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { toast } from "@app/hooks/useToast";
import { AxiosResponse } from "axios";
import { useParams, useRouter } from "next/navigation";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator
} from "@app/components/ui/breadcrumb";
import Link from "next/link";
import { useRouter } from "next/navigation";
import {
CreateOrgApiKeyBody,
CreateOrgApiKeyResponse
@@ -108,7 +99,7 @@ export default function Page() {
const copiedForm = useForm<CopiedFormValues>({
resolver: zodResolver(copiedFormSchema),
defaultValues: {
copied: false
copied: true
}
});
@@ -299,54 +290,54 @@ export default function Page() {
</AlertDescription>
</Alert>
<h4 className="font-semibold">
{t('apiKeysInfo')}
</h4>
{/* <h4 className="font-semibold"> */}
{/* {t('apiKeysInfo')} */}
{/* </h4> */}
<CopyTextBox
text={`${apiKey.apiKeyId}.${apiKey.apiKey}`}
/>
<Form {...copiedForm}>
<form
className="space-y-4"
id="copied-form"
>
<FormField
control={copiedForm.control}
name="copied"
render={({ field }) => (
<FormItem>
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
defaultChecked={
copiedForm.getValues(
"copied"
) as boolean
}
onCheckedChange={(
e
) => {
copiedForm.setValue(
"copied",
e as boolean
);
}}
/>
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
{t('apiKeysConfirmCopy')}
</label>
</div>
<FormMessage />
</FormItem>
)}
/>
</form>
</Form>
{/* <Form {...copiedForm}> */}
{/* <form */}
{/* className="space-y-4" */}
{/* id="copied-form" */}
{/* > */}
{/* <FormField */}
{/* control={copiedForm.control} */}
{/* name="copied" */}
{/* render={({ field }) => ( */}
{/* <FormItem> */}
{/* <div className="flex items-center space-x-2"> */}
{/* <Checkbox */}
{/* id="terms" */}
{/* defaultChecked={ */}
{/* copiedForm.getValues( */}
{/* "copied" */}
{/* ) as boolean */}
{/* } */}
{/* onCheckedChange={( */}
{/* e */}
{/* ) => { */}
{/* copiedForm.setValue( */}
{/* "copied", */}
{/* e as boolean */}
{/* ); */}
{/* }} */}
{/* /> */}
{/* <label */}
{/* htmlFor="terms" */}
{/* className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" */}
{/* > */}
{/* {t('apiKeysConfirmCopy')} */}
{/* </label> */}
{/* </div> */}
{/* <FormMessage /> */}
{/* </FormItem> */}
{/* )} */}
{/* /> */}
{/* </form> */}
{/* </Form> */}
</SettingsSectionBody>
</SettingsSection>
)}

View File

@@ -43,14 +43,14 @@ export default function IdpTable({ idps }: Props) {
try {
await api.delete(`/idp/${idpId}`);
toast({
title: t('success'),
description: t('idpDeletedDescription')
title: t("success"),
description: t("idpDeletedDescription")
});
setIsDeleteModalOpen(false);
router.refresh();
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -67,41 +67,6 @@ export default function IdpTable({ idps }: Props) {
};
const columns: ColumnDef<IdpRow>[] = [
{
id: "dots",
cell: ({ row }) => {
const r = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
<span className="sr-only">{t('openMenu')}</span>
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<Link
className="block w-full"
href={`/admin/idp/${r.idpId}/general`}
>
<DropdownMenuItem>
{t('viewSettings')}
</DropdownMenuItem>
</Link>
<DropdownMenuItem
onClick={() => {
setSelectedIdp(r);
setIsDeleteModalOpen(true);
}}
>
<span className="text-red-500">{t('delete')}</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
},
{
accessorKey: "idpId",
header: ({ column }) => {
@@ -128,7 +93,7 @@ export default function IdpTable({ idps }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
{t('name')}
{t("name")}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@@ -144,7 +109,7 @@ export default function IdpTable({ idps }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
{t('type')}
{t("type")}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@@ -162,9 +127,43 @@ export default function IdpTable({ idps }: Props) {
const siteRow = row.original;
return (
<div className="flex items-center justify-end">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
<span className="sr-only">
{t("openMenu")}
</span>
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<Link
className="block w-full"
href={`/admin/idp/${siteRow.idpId}/general`}
>
<DropdownMenuItem>
{t("viewSettings")}
</DropdownMenuItem>
</Link>
<DropdownMenuItem
onClick={() => {
setSelectedIdp(siteRow);
setIsDeleteModalOpen(true);
}}
>
<span className="text-red-500">
{t("delete")}
</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Link href={`/admin/idp/${siteRow.idpId}/general`}>
<Button variant={"outlinePrimary"} className="ml-2">
{t('edit')}
<Button
variant={"secondary"}
className="ml-2"
size="sm"
>
{t("edit")}
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
</Link>
@@ -186,22 +185,20 @@ export default function IdpTable({ idps }: Props) {
dialog={
<div className="space-y-4">
<p>
{t('idpQuestionRemove', {name: selectedIdp.name})}
{t("idpQuestionRemove", {
name: selectedIdp.name
})}
</p>
<p>
<b>
{t('idpMessageRemove')}
</b>
</p>
<p>
{t('idpMessageConfirm')}
<b>{t("idpMessageRemove")}</b>
</p>
<p>{t("idpMessageConfirm")}</p>
</div>
}
buttonText={t('idpConfirmDelete')}
buttonText={t("idpConfirmDelete")}
onConfirm={async () => deleteIdp(selectedIdp.idpId)}
string={selectedIdp.name}
title={t('idpDelete')}
title={t("idpDelete")}
/>
)}

View File

@@ -4,17 +4,7 @@ import { AxiosResponse } from "axios";
import { redirect } from "next/navigation";
import { authCookieHeader } from "@app/lib/api/cookies";
import { HorizontalTabs } from "@app/components/HorizontalTabs";
import { ProfessionalContentOverlay } from "@app/components/ProfessionalContentOverlay";
import Link from "next/link";
import { ArrowLeft } from "lucide-react";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator
} from "@app/components/ui/breadcrumb";
import { getTranslations } from "next-intl/server";
interface SettingsLayoutProps {

View File

@@ -140,7 +140,7 @@ export default function PolicyTable({ policies, onDelete, onAdd, onEdit }: Props
return (
<div className="flex items-center justify-end">
<Button
variant={"outlinePrimary"}
variant={"secondary"}
className="ml-2"
onClick={() => onEdit(policy)}
>

View File

@@ -9,7 +9,7 @@ import { internal } from "@app/lib/api";
import { AxiosResponse } from "axios";
import { authCookieHeader } from "@app/lib/api/cookies";
import { Layout } from "@app/components/Layout";
import { adminNavItems } from "../navigation";
import { adminNavSections } from "../navigation";
export const dynamic = "force-dynamic";
@@ -47,7 +47,7 @@ export default async function AdminLayout(props: LayoutProps) {
return (
<UserProvider user={user}>
<Layout orgs={orgs} navItems={adminNavItems}>
<Layout orgs={orgs} navItems={adminNavSections}>
{props.children}
</Layout>
</UserProvider>

View File

@@ -122,7 +122,7 @@ export function LicenseKeysDataTable({
cell: ({ row }) => (
<div className="flex items-center justify-end space-x-2">
<Button
variant="outlinePrimary"
variant="secondary"
onClick={() => onDelete(row.original)}
>
{t('delete')}

View File

@@ -41,11 +41,11 @@ export default function UsersTable({ users }: Props) {
const deleteUser = (id: string) => {
api.delete(`/user/${id}`)
.catch((e) => {
console.error(t('userErrorDelete'), e);
console.error(t("userErrorDelete"), e);
toast({
variant: "destructive",
title: t('userErrorDelete'),
description: formatAxiosError(e, t('userErrorDelete'))
title: t("userErrorDelete"),
description: formatAxiosError(e, t("userErrorDelete"))
});
})
.then(() => {
@@ -84,7 +84,7 @@ export default function UsersTable({ users }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
{t('username')}
{t("username")}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@@ -100,7 +100,7 @@ export default function UsersTable({ users }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
{t('email')}
{t("email")}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@@ -116,7 +116,7 @@ export default function UsersTable({ users }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
{t('name')}
{t("name")}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@@ -132,7 +132,7 @@ export default function UsersTable({ users }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
{t('identityProvider')}
{t("identityProvider")}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@@ -146,14 +146,15 @@ export default function UsersTable({ users }: Props) {
<>
<div className="flex items-center justify-end">
<Button
variant={"outlinePrimary"}
variant={"secondary"}
size="sm"
className="ml-2"
onClick={() => {
setSelected(r);
setIsDeleteModalOpen(true);
}}
>
{t('delete')}
{t("delete")}
</Button>
</div>
</>
@@ -174,26 +175,27 @@ export default function UsersTable({ users }: Props) {
dialog={
<div className="space-y-4">
<p>
{t('userQuestionRemove', {selectedUser: selected?.email || selected?.name || selected?.username})}
{t("userQuestionRemove", {
selectedUser:
selected?.email ||
selected?.name ||
selected?.username
})}
</p>
<p>
<b>
{t('userMessageRemove')}
</b>
<b>{t("userMessageRemove")}</b>
</p>
<p>
{t('userMessageConfirm')}
</p>
<p>{t("userMessageConfirm")}</p>
</div>
}
buttonText={t('userDeleteConfirm')}
buttonText={t("userDeleteConfirm")}
onConfirm={async () => deleteUser(selected!.id)}
string={
selected.email || selected.name || selected.username
}
title={t('userDeleteServer')}
title={t("userDeleteServer")}
/>
)}