From 81232875ac790df33d280b39b346e5e8fa2a78c7 Mon Sep 17 00:00:00 2001 From: Colin Regourd Date: Tue, 16 Jan 2024 17:19:35 +0100 Subject: [PATCH 1/4] Change versions of next-admin --- package.json | 2 +- .../(admin)/admin/[[...nextadmin]]/page.tsx | 113 +++++------------- src/components/admin/Dashboard.tsx | 65 ++++++++++ src/utils/nextadmin.ts | 59 ++++++++- tailwind.admin.config.js | 2 +- yarn.lock | 56 +++++++-- 6 files changed, 197 insertions(+), 100 deletions(-) create mode 100644 src/components/admin/Dashboard.tsx diff --git a/package.json b/package.json index 8f285a5..0d3c2ff 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@heroicons/react": "^2.0.16", "@next-auth/prisma-adapter": "^1.0.5", "@postlight/parser": "^2.2.3", - "@premieroctet/next-admin": "^3.0.0", + "@premieroctet/next-admin": "^3.2.0", "@prisma/client": "^4.11.0", "@radix-ui/react-dialog": "^1.0.3", "@radix-ui/react-navigation-menu": "^1.1.2", diff --git a/src/app/(admin)/admin/[[...nextadmin]]/page.tsx b/src/app/(admin)/admin/[[...nextadmin]]/page.tsx index b6494ce..d026b70 100644 --- a/src/app/(admin)/admin/[[...nextadmin]]/page.tsx +++ b/src/app/(admin)/admin/[[...nextadmin]]/page.tsx @@ -1,35 +1,22 @@ -import { authOptions } from '@/pages/api/auth/[...nextauth]'; -import client from '@/lib/db'; -import { getServerSession } from 'next-auth'; -import { redirect } from 'next/navigation'; -import { NextAdmin } from '@premieroctet/next-admin'; -import { getPropsFromParams } from '@premieroctet/next-admin/dist/appRouter'; -import '@/theme/admin.css'; -import '@premieroctet/next-admin/dist/styles.css'; -import schema from '../../../../../prisma/json-schema/json-schema.json'; -import { options } from '@/utils/nextadmin'; import { submitFormAction } from '@/actions/nextadmin'; +import Dashboard, { DashboardProps } from '@/components/admin/Dashboard'; import { linksByDay, linksByDomain, newDigestByMonth, newUsersByMonth, } from '@/lib/adminQueries'; -import { Digest, Team } from '@prisma/client'; -import { Card, Col, Grid, Metric, Text } from '@tremor/react'; -import DataOverTime from '@/components/admin/widgets/DataOverTime'; -import LinksByWebsite from '@/components/admin/widgets/LinksByWebsite'; -import LinksOverTime from '@/components/admin/widgets/LinksOverTime'; +import client from '@/lib/db'; +import { authOptions } from '@/pages/api/auth/[...nextauth]'; +import '@/theme/admin.css'; +import '@premieroctet/next-admin/dist/styles.css'; +import { options } from '@/utils/nextadmin'; +import { NextAdmin } from '@premieroctet/next-admin'; +import { getPropsFromParams } from '@premieroctet/next-admin/dist/appRouter'; +import { getServerSession } from 'next-auth'; +import { redirect } from 'next/navigation'; +import schema from '../../../../../prisma/json-schema/json-schema.json'; -type DashboardProps = { - newUsersByMonth: Awaited>; - newDigestByMonth: Awaited>; - linksByDomain: Awaited>; - linksCount: number; - latestTeam: Team | null; - latestDigest: Digest | null; - linksByDay: Awaited>; -}; export default async function AdminPage({ params, @@ -56,72 +43,28 @@ export default async function AdminPage({ const dashboardProps: DashboardProps | undefined = !params.nextadmin ? { - newUsersByMonth: await newUsersByMonth(), - newDigestByMonth: await newDigestByMonth(), - linksByDomain: await linksByDomain(), - linksByDay: await linksByDay(), - linksCount: await client.link.count(), - latestDigest: await client.digest.findFirst({ - where: { publishedAt: { not: null } }, - orderBy: { createdAt: 'desc' }, - include: { - team: true, - }, - }), - latestTeam: await client.team.findFirst({ - orderBy: { createdAt: 'desc' }, - }), - } + newUsersByMonth: await newUsersByMonth(), + newDigestByMonth: await newDigestByMonth(), + linksByDomain: await linksByDomain(), + linksByDay: await linksByDay(), + linksCount: await client.link.count(), + latestDigest: await client.digest.findFirst({ + where: { publishedAt: { not: null } }, + orderBy: { createdAt: 'desc' }, + include: { + team: true, + }, + }), + latestTeam: await client.team.findFirst({ + orderBy: { createdAt: 'desc' }, + }), + } : undefined; return ( - - - - - - - Dernier digest publié - - - {dashboardProps.latestDigest?.title} par {/* @ts-ignore */} - {dashboardProps.latestDigest?.team.name} - - - - - - Dernière team créée - - - {dashboardProps.latestTeam?.name} - - - - - Total des liens - {dashboardProps?.linksCount} - - - - - - ) - } + dashboard={dashboardProps && } /> ); } diff --git a/src/components/admin/Dashboard.tsx b/src/components/admin/Dashboard.tsx new file mode 100644 index 0000000..fa99877 --- /dev/null +++ b/src/components/admin/Dashboard.tsx @@ -0,0 +1,65 @@ +import { linksByDay, linksByDomain, newDigestByMonth, newUsersByMonth } from "@/lib/adminQueries"; +import { Digest, Team } from "@prisma/client"; +import { Card, Col, Grid, Metric, Text } from "@tremor/react"; +import DataOverTime from "./widgets/DataOverTime"; +import LinksByWebsite from "./widgets/LinksByWebsite"; +import LinksOverTime from "./widgets/LinksOverTime"; + + +export type DashboardProps = { + newUsersByMonth: Awaited>; + newDigestByMonth: Awaited>; + linksByDomain: Awaited>; + linksCount: number; + latestTeam: Team | null; + latestDigest: Digest | null; + linksByDay: Awaited>; +}; + +const Dashboard = (dashboardProps: DashboardProps) => { + return ( + + + + + + + + Dernier digest publié + + + {dashboardProps.latestDigest?.title} par {/* @ts-ignore */} + {dashboardProps.latestDigest?.team.name} + + + + + + Dernière team créée + + + {dashboardProps.latestTeam?.name} + + + + + Total des liens + {dashboardProps?.linksCount} + + + + + + ) +} + +export default Dashboard \ No newline at end of file diff --git a/src/utils/nextadmin.ts b/src/utils/nextadmin.ts index d0221a3..d805048 100644 --- a/src/utils/nextadmin.ts +++ b/src/utils/nextadmin.ts @@ -7,13 +7,44 @@ export const options: NextAdminOptions = { toString: (user) => user.email ?? user.id, list: { display: ['id', 'email', 'name', 'role', 'createdAt'], - search: ['email', 'name'], + search: ['id', 'email', 'name'], + fields: { + createdAt: { + formatter: (date) => new Date(date).toLocaleString('fr'), + }, + } + }, + edit: { + display: ['id', 'createdAt', 'email', 'name', 'emailVerified', 'accounts', 'role', 'defaultTeam'], + fields: { + defaultTeam: { + optionFormatter: (team) => team?.name! + }, + }, }, }, Team: { list: { display: ['id', 'name', 'memberships', 'createdAt'], search: ['name'], + fields: { + createdAt: { + formatter: (date) => new Date(date).toLocaleString('fr'), + } + } + }, + edit: { + fields: { + memberships: { + optionFormatter: (membership) => `User ${membership?.userId?.slice(0, 5)}...` + }, + bookmarks: { + optionFormatter: (bookmark) => `Bookmark ${bookmark?.id?.slice(0, 5)}...` + }, + color: { + format: 'color' + } + } }, }, Link: { @@ -21,11 +52,37 @@ export const options: NextAdminOptions = { display: ['id', 'title', 'description', 'url'], search: ['url'], }, + edit: { + fields: { + url: { + format: 'uri' + }, + image: { + format: 'file' + }, + bookmark: { + optionFormatter: (bookmark) => `Bookmark ${bookmark?.id?.slice(0, 5)}...` + }, + } + }, }, Digest: { + toString: (digest) => digest.title ?? digest.id, list: { display: ['id', 'title', 'description', 'isFeatured', 'createdAt'], + fields: { + createdAt: { + formatter: (date) => new Date(date).toLocaleString('fr'), + } + } }, + edit: { + fields: { + team: { + optionFormatter: (team) => team?.name! + }, + } + } }, }, }; diff --git a/tailwind.admin.config.js b/tailwind.admin.config.js index a653de1..98044d5 100644 --- a/tailwind.admin.config.js +++ b/tailwind.admin.config.js @@ -2,7 +2,7 @@ module.exports = { content: [ - './node_modules/@premieroctet/next-admin/src/**/*.{js,ts,jsx,tsx}', + './node_modules/@premieroctet/next-admin/dist/**/*.{js,ts,jsx,tsx}', './node_modules/@tremor/**/*.{js,ts,jsx,tsx}', './src/components/admin/**/*.{js,ts,jsx,tsx}', ], diff --git a/yarn.lock b/yarn.lock index 1262fe3..e75d2fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1591,14 +1591,15 @@ dependencies: safe-buffer "^5.0.1" -"@premieroctet/next-admin@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@premieroctet/next-admin/-/next-admin-3.0.0.tgz#379f6362b5087cec4517405662eab11b8c2a409d" - integrity sha512-u/Q5iOT+UPEg5TcKEtsqtZo+hNxbFhSNxDz/oayxqUTSel+FIrUNZGMvM5fymy3hUD+LeIxkGKD0BeYWp+Rpnw== +"@premieroctet/next-admin@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@premieroctet/next-admin/-/next-admin-3.2.0.tgz#3ca3d8db760950972e479d1c8d5f5b9734f2c7c9" + integrity sha512-v1A90UWs4YE5MGACgO+Xr8FdbOqvzioK+CL37npkhDoq1Tjw1g8oJcFDjePydnGHrl9RTR5PXrENanmtJuV3Yg== dependencies: "@headlessui/react" "^1.7.13" "@heroicons/react" "^2.0.18" "@picocss/pico" "^1.5.7" + "@radix-ui/react-dropdown-menu" "^2.0.6" "@radix-ui/react-select" "^1.2.2" "@rjsf/core" "^5.3.0" "@rjsf/utils" "^5.3.0" @@ -1606,7 +1607,6 @@ "@tanstack/react-table" "^8.9.2" "@types/formidable" "^3.4.5" "@types/node" "^18.15.3" - "@types/react-dom" "18.0.11" body-parser "^1.20.2" class-variance-authority "^0.6.0" clsx "^1.2.1" @@ -1943,6 +1943,20 @@ "@radix-ui/react-use-callback-ref" "1.0.1" "@radix-ui/react-use-escape-keydown" "1.0.3" +"@radix-ui/react-dropdown-menu@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz#cdf13c956c5e263afe4e5f3587b3071a25755b63" + integrity sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-menu" "2.0.6" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-focus-guards@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz#339c1c69c41628c1a5e655f15f7020bf11aa01fa" @@ -2003,6 +2017,31 @@ "@babel/runtime" "^7.13.10" "@radix-ui/react-use-layout-effect" "1.0.1" +"@radix-ui/react-menu@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.0.6.tgz#2c9e093c1a5d5daa87304b2a2f884e32288ae79e" + integrity sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.4" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.3" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-roving-focus" "1.0.4" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-callback-ref" "1.0.1" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + "@radix-ui/react-navigation-menu@^1.1.2": version "1.1.4" resolved "https://registry.yarnpkg.com/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz#654151310c3f9a29afd19fb60ddc7977e54b8a3d" @@ -3137,13 +3176,6 @@ dependencies: "@types/react" "*" -"@types/react-dom@18.0.11": - version "18.0.11" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33" - integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw== - dependencies: - "@types/react" "*" - "@types/react-dom@^18": version "18.2.14" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.14.tgz#c01ba40e5bb57fc1dc41569bb3ccdb19eab1c539" From be57cc650b6259a38b9be481b132e3c028518da8 Mon Sep 17 00:00:00 2001 From: Colin Regourd Date: Tue, 16 Jan 2024 19:35:00 +0100 Subject: [PATCH 2/4] Upgrade next-admin to 3.2.1 with parse patch --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0d3c2ff..b1d901c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@heroicons/react": "^2.0.16", "@next-auth/prisma-adapter": "^1.0.5", "@postlight/parser": "^2.2.3", - "@premieroctet/next-admin": "^3.2.0", + "@premieroctet/next-admin": "^3.2.1", "@prisma/client": "^4.11.0", "@radix-ui/react-dialog": "^1.0.3", "@radix-ui/react-navigation-menu": "^1.1.2", diff --git a/yarn.lock b/yarn.lock index e75d2fb..8b210e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1591,10 +1591,10 @@ dependencies: safe-buffer "^5.0.1" -"@premieroctet/next-admin@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@premieroctet/next-admin/-/next-admin-3.2.0.tgz#3ca3d8db760950972e479d1c8d5f5b9734f2c7c9" - integrity sha512-v1A90UWs4YE5MGACgO+Xr8FdbOqvzioK+CL37npkhDoq1Tjw1g8oJcFDjePydnGHrl9RTR5PXrENanmtJuV3Yg== +"@premieroctet/next-admin@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@premieroctet/next-admin/-/next-admin-3.2.1.tgz#35aa53a681a14a9e4dc46d52209404187ef2c24b" + integrity sha512-fcEVWBgXp+/77H1g8vaPj8DseE7rvVW35eG13YtcCqEXR6OEdjANREPfdFW3Z504TE22+aDhyVgQMO2CJ/p5Og== dependencies: "@headlessui/react" "^1.7.13" "@heroicons/react" "^2.0.18" From df10d6f680a7d45b6cc74b2874543bf225b36799 Mon Sep 17 00:00:00 2001 From: Colin Regourd Date: Tue, 23 Jan 2024 16:49:27 +0100 Subject: [PATCH 3/4] Fix delete and set image as text field --- src/actions/nextadmin.ts | 11 +++++++++-- src/app/(admin)/admin/[[...nextadmin]]/page.tsx | 5 +++-- src/utils/nextadmin.ts | 3 --- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/actions/nextadmin.ts b/src/actions/nextadmin.ts index 2b4d30c..e610f0e 100644 --- a/src/actions/nextadmin.ts +++ b/src/actions/nextadmin.ts @@ -1,8 +1,8 @@ 'use server'; import client from '@/lib/db'; import { options } from '@/utils/nextadmin'; -import { ActionParams } from '@premieroctet/next-admin'; -import { submitForm } from '@premieroctet/next-admin/dist/actions'; +import { ActionParams, ModelName } from '@premieroctet/next-admin'; +import { deleteResourceItems, submitForm } from '@premieroctet/next-admin/dist/actions'; export const submitFormAction = async ( params: ActionParams, @@ -10,3 +10,10 @@ export const submitFormAction = async ( ) => { return submitForm({ ...params, options, prisma: client }, formData); }; + +export const deleteItem = async ( + model: ModelName, + ids: string[] | number[] +) => { + return deleteResourceItems(client, model, ids); +}; diff --git a/src/app/(admin)/admin/[[...nextadmin]]/page.tsx b/src/app/(admin)/admin/[[...nextadmin]]/page.tsx index d026b70..cb2b823 100644 --- a/src/app/(admin)/admin/[[...nextadmin]]/page.tsx +++ b/src/app/(admin)/admin/[[...nextadmin]]/page.tsx @@ -1,4 +1,4 @@ -import { submitFormAction } from '@/actions/nextadmin'; +import { deleteItem, submitFormAction } from '@/actions/nextadmin'; import Dashboard, { DashboardProps } from '@/components/admin/Dashboard'; import { linksByDay, @@ -9,10 +9,10 @@ import { import client from '@/lib/db'; import { authOptions } from '@/pages/api/auth/[...nextauth]'; import '@/theme/admin.css'; -import '@premieroctet/next-admin/dist/styles.css'; import { options } from '@/utils/nextadmin'; import { NextAdmin } from '@premieroctet/next-admin'; import { getPropsFromParams } from '@premieroctet/next-admin/dist/appRouter'; +import '@premieroctet/next-admin/dist/styles.css'; import { getServerSession } from 'next-auth'; import { redirect } from 'next/navigation'; import schema from '../../../../../prisma/json-schema/json-schema.json'; @@ -39,6 +39,7 @@ export default async function AdminPage({ prisma: client, schema, action: submitFormAction, + deleteAction: deleteItem }); const dashboardProps: DashboardProps | undefined = !params.nextadmin diff --git a/src/utils/nextadmin.ts b/src/utils/nextadmin.ts index d805048..38ade4e 100644 --- a/src/utils/nextadmin.ts +++ b/src/utils/nextadmin.ts @@ -57,9 +57,6 @@ export const options: NextAdminOptions = { url: { format: 'uri' }, - image: { - format: 'file' - }, bookmark: { optionFormatter: (bookmark) => `Bookmark ${bookmark?.id?.slice(0, 5)}...` }, From a109c94bf53fd0a567ab5043b6614e8aa8da28d5 Mon Sep 17 00:00:00 2001 From: Colin Regourd Date: Wed, 31 Jan 2024 17:27:23 +0100 Subject: [PATCH 4/4] Upgrade next-admin 3.2.5 --- package.json | 2 +- src/utils/nextadmin.ts | 29 ++++++++++++++++++++++++++--- yarn.lock | 8 ++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index b1d901c..1d4c300 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@heroicons/react": "^2.0.16", "@next-auth/prisma-adapter": "^1.0.5", "@postlight/parser": "^2.2.3", - "@premieroctet/next-admin": "^3.2.1", + "@premieroctet/next-admin": "^3.2.5", "@prisma/client": "^4.11.0", "@radix-ui/react-dialog": "^1.0.3", "@radix-ui/react-navigation-menu": "^1.1.2", diff --git a/src/utils/nextadmin.ts b/src/utils/nextadmin.ts index 38ade4e..b48c34b 100644 --- a/src/utils/nextadmin.ts +++ b/src/utils/nextadmin.ts @@ -4,6 +4,10 @@ export const options: NextAdminOptions = { basePath: '/admin', model: { User: { + aliases: { + emailVerified: 'Email verified date', + defaultTeam: 'Default team', + }, toString: (user) => user.email ?? user.id, list: { display: ['id', 'email', 'name', 'role', 'createdAt'], @@ -24,6 +28,16 @@ export const options: NextAdminOptions = { }, }, Team: { + aliases: { + bookmarks: 'Links', + createdAt: 'Created at', + slackToken: 'Slack token', + slackTeamId: 'Slack team', + typefullyToken: 'Typefully token', + apiKey: 'API key', + nextSuggestedDigestTitle: 'Next suggested digest title', + subscriptionId: 'Subscription', + }, list: { display: ['id', 'name', 'memberships', 'createdAt'], search: ['name'], @@ -36,18 +50,24 @@ export const options: NextAdminOptions = { edit: { fields: { memberships: { - optionFormatter: (membership) => `User ${membership?.userId?.slice(0, 5)}...` + optionFormatter: (membership) => membership?.user?.email ?? `User ${membership?.user?.id?.slice(0, 5)}...` }, bookmarks: { - optionFormatter: (bookmark) => `Bookmark ${bookmark?.id?.slice(0, 5)}...` + optionFormatter: (bookmark) => bookmark.link.title ?? `Bookmark ${bookmark?.id?.slice(0, 5)}...` }, color: { format: 'color' + }, + apiKey: { + format: 'password' } } }, }, Link: { + aliases: { + bookmark: 'Teams', + }, list: { display: ['id', 'title', 'description', 'url'], search: ['url'], @@ -58,7 +78,7 @@ export const options: NextAdminOptions = { format: 'uri' }, bookmark: { - optionFormatter: (bookmark) => `Bookmark ${bookmark?.id?.slice(0, 5)}...` + optionFormatter: (bookmark) => bookmark.team.name ?? `Bookmark ${bookmark?.id?.slice(0, 5)}...` }, } }, @@ -78,6 +98,9 @@ export const options: NextAdminOptions = { team: { optionFormatter: (team) => team?.name! }, + digestBlocks: { + optionFormatter: (digestBlock) => digestBlock.title ?? `DigestBlock ${digestBlock?.id?.slice(0, 5)}...` + }, } } }, diff --git a/yarn.lock b/yarn.lock index 8b210e6..c80dffc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1591,10 +1591,10 @@ dependencies: safe-buffer "^5.0.1" -"@premieroctet/next-admin@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@premieroctet/next-admin/-/next-admin-3.2.1.tgz#35aa53a681a14a9e4dc46d52209404187ef2c24b" - integrity sha512-fcEVWBgXp+/77H1g8vaPj8DseE7rvVW35eG13YtcCqEXR6OEdjANREPfdFW3Z504TE22+aDhyVgQMO2CJ/p5Og== +"@premieroctet/next-admin@^3.2.5": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@premieroctet/next-admin/-/next-admin-3.2.5.tgz#9f67e2b3e87c0f9e50b74cb041878841dd97d3ba" + integrity sha512-RrGNy8NAtFB0KN/U2Bz3WCgaY1jbPvsDHBnN2kf2v9IxSelSmGp7YEXzjvLtD0/ol7yqy80nsnZeN1KeSjqXJw== dependencies: "@headlessui/react" "^1.7.13" "@heroicons/react" "^2.0.18"