mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-22 20:16:57 +00:00
Avatar with drop down menu for accessing zones and signing out
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@auth/mongodb-adapter": "^2.5.0",
|
"@auth/mongodb-adapter": "^2.5.0",
|
||||||
|
"@headlessui-float/react": "^0.13.3",
|
||||||
"@headlessui/react": "^1.7.18",
|
"@headlessui/react": "^1.7.18",
|
||||||
"@headlessui/tailwindcss": "^0.2.0",
|
"@headlessui/tailwindcss": "^0.2.0",
|
||||||
"@hookform/resolvers": "^3.3.3",
|
"@hookform/resolvers": "^3.3.3",
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ import { useTranslations } from "next-intl";
|
|||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import { burgerMenuIsOpenAtom } from "@/atoms";
|
import { burgerMenuIsOpenAtom } from "@/atoms";
|
||||||
|
import { useAuthMenuOptions } from "@/hooks/useAuthMenuOptions";
|
||||||
import { Link } from "@/utils/navigation";
|
import { Link } from "@/utils/navigation";
|
||||||
|
|
||||||
const HamburgerMenu = () => {
|
const HamburgerMenu = () => {
|
||||||
const t = useTranslations("Nav");
|
const t = useTranslations("Nav");
|
||||||
const [burgerMenuIsOpen, setBurgerMenuIsOpen] = useAtom(burgerMenuIsOpenAtom);
|
const [burgerMenuIsOpen, setBurgerMenuIsOpen] = useAtom(burgerMenuIsOpenAtom);
|
||||||
|
const menuItems = useAuthMenuOptions();
|
||||||
|
|
||||||
const closeMenu = () => setBurgerMenuIsOpen(false);
|
const closeMenu = () => setBurgerMenuIsOpen(false);
|
||||||
|
|
||||||
@@ -20,35 +22,41 @@ const HamburgerMenu = () => {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<ul className="list-reset text-white">
|
<ul className="list-reset text-white">
|
||||||
<li className="py-5 text-center text-xl">
|
<li className="py-3 text-center text-xl">
|
||||||
<Link
|
<Link onClick={closeMenu} href="/tournaments">
|
||||||
onClick={closeMenu}
|
|
||||||
href="/tournaments"
|
|
||||||
className="border-b-2 border-transparent transition-all duration-300 ease-in-out hover:border-white"
|
|
||||||
>
|
|
||||||
{t("tournaments")}
|
{t("tournaments")}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li className="py-5 text-center text-xl">
|
<li className="py-3 text-center text-xl">
|
||||||
<Link
|
<Link onClick={closeMenu} href="/clubs">
|
||||||
onClick={closeMenu}
|
|
||||||
href="/clubs"
|
|
||||||
className="border-b-2 border-transparent transition-all duration-300 ease-in-out hover:border-white"
|
|
||||||
>
|
|
||||||
{t("clubs")}
|
{t("clubs")}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li className="py-5 text-center text-xl">
|
<li className="py-3 text-center text-xl">
|
||||||
<Link
|
<Link onClick={closeMenu} href="/elo">
|
||||||
onClick={closeMenu}
|
|
||||||
href="/elo"
|
|
||||||
className="border-b-2 border-transparent transition-all duration-300 ease-in-out hover:border-white"
|
|
||||||
>
|
|
||||||
{t("elo")}
|
{t("elo")}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<hr className="my-5" />
|
||||||
|
|
||||||
|
{menuItems.map(({ title, onClick, className, disabled }, i) => (
|
||||||
|
<li key={i} className="py-3 text-center text-xl">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={disabled}
|
||||||
|
className={className}
|
||||||
|
onClick={() => {
|
||||||
|
onClick();
|
||||||
|
closeMenu();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,10 +15,7 @@ export default function Navbar() {
|
|||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav
|
<nav className="relative mt-0 h-16 w-full overflow-x-clip border-b-[1px] bg-white px-5 dark:border-gray-700 dark:bg-gray-800">
|
||||||
className="relative mt-0 h-16 w-full overflow-x-clip border-b-[1px] bg-white px-5 dark:border-gray-700 dark:bg-gray-800"
|
|
||||||
data-test="navbar"
|
|
||||||
>
|
|
||||||
<div className="container mx-auto flex h-full items-center justify-between">
|
<div className="container mx-auto flex h-full items-center justify-between">
|
||||||
<Link
|
<Link
|
||||||
className="font-extrabold text-gray-900 no-underline hover:no-underline dark:text-white"
|
className="font-extrabold text-gray-900 no-underline hover:no-underline dark:text-white"
|
||||||
@@ -33,10 +30,7 @@ export default function Navbar() {
|
|||||||
<Hamburger />
|
<Hamburger />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div className="hidden h-full justify-center md:flex md:w-1/2 md:justify-end">
|
||||||
className="hidden h-full justify-center md:flex md:w-1/2 md:justify-end"
|
|
||||||
data-test="desktop-menu"
|
|
||||||
>
|
|
||||||
<ul className="list-reset flex h-full flex-1 items-center gap-14 text-gray-900 no-underline dark:text-white md:flex-none">
|
<ul className="list-reset flex h-full flex-1 items-center gap-14 text-gray-900 no-underline dark:text-white md:flex-none">
|
||||||
{links.map(({ title, route }) => (
|
{links.map(({ title, route }) => (
|
||||||
<li key={route} className="h-full">
|
<li key={route} className="h-full">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export default function Contact() {
|
|||||||
const t = useTranslations("Contact");
|
const t = useTranslations("Contact");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="grid place-items-center bg-white pb-20 dark:bg-gray-800">
|
<section className="bg-white pb-20 dark:bg-gray-800">
|
||||||
<div className="mx-auto max-w-screen-md px-4 py-8 lg:py-16">
|
<div className="mx-auto max-w-screen-md px-4 py-8 lg:py-16">
|
||||||
<h2
|
<h2
|
||||||
className="mb-4 text-center text-4xl font-extrabold tracking-tight text-gray-900 dark:text-white"
|
className="mb-4 text-center text-4xl font-extrabold tracking-tight text-gray-900 dark:text-white"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import "leaflet-defaulticon-compatibility";
|
|||||||
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
|
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
|
||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
import { FeatureGroup, GeoJSON, MapContainer, TileLayer } from "react-leaflet";
|
import { FeatureGroup, GeoJSON, MapContainer, TileLayer } from "react-leaflet";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import { MapEvents } from "@/components/MapEvents";
|
import { MapEvents } from "@/components/MapEvents";
|
||||||
import type { ZoneModel } from "@/server/models/zoneModel";
|
import type { ZoneModel } from "@/server/models/zoneModel";
|
||||||
@@ -13,10 +14,10 @@ const center: LatLngLiteral = { lat: 47.0844, lng: 2.3964 };
|
|||||||
|
|
||||||
export type ZoneThumbnailProps = {
|
export type ZoneThumbnailProps = {
|
||||||
features: ZoneModel["features"];
|
features: ZoneModel["features"];
|
||||||
size: number;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ZoneThumbnail = ({ features, size }: ZoneThumbnailProps) => {
|
export const ZoneThumbnail = ({ features, className }: ZoneThumbnailProps) => {
|
||||||
return (
|
return (
|
||||||
<MapContainer
|
<MapContainer
|
||||||
center={center}
|
center={center}
|
||||||
@@ -24,7 +25,7 @@ export const ZoneThumbnail = ({ features, size }: ZoneThumbnailProps) => {
|
|||||||
zoomControl={false}
|
zoomControl={false}
|
||||||
scrollWheelZoom={false}
|
scrollWheelZoom={false}
|
||||||
dragging={false}
|
dragging={false}
|
||||||
style={{ height: size, width: size }}
|
className={twMerge("h-[200px] w-auto md:w-[200px]", className)}
|
||||||
attributionControl={false}
|
attributionControl={false}
|
||||||
>
|
>
|
||||||
<MapEvents bounds={L.geoJson(features).getBounds()} />
|
<MapEvents bounds={L.geoJson(features).getBounds()} />
|
||||||
|
|||||||
@@ -20,25 +20,27 @@ export default function ZonesLayout({ children }: { children: ReactNode }) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto max-w-screen-md px-4 py-8 lg:py-16">
|
<section className="bg-white pb-20 dark:bg-gray-800">
|
||||||
{!sessionData ? (
|
<div className="mx-auto max-w-screen-md px-4 py-8 lg:py-16">
|
||||||
<div>
|
{!sessionData ? (
|
||||||
<h2
|
<div>
|
||||||
className="mb-4 text-center text-4xl font-extrabold tracking-tight text-gray-900 dark:text-white"
|
<h2
|
||||||
data-test="header2"
|
className="mb-4 text-center text-4xl font-extrabold tracking-tight text-gray-900 dark:text-white"
|
||||||
>
|
data-test="header2"
|
||||||
{t("title")}
|
>
|
||||||
</h2>
|
{t("title")}
|
||||||
|
</h2>
|
||||||
|
|
||||||
<p className="mb-8 text-center font-light text-gray-500 dark:text-gray-400 sm:text-xl lg:mb-16">
|
<p className="mb-8 text-center font-light text-gray-500 dark:text-gray-400 sm:text-xl lg:mb-16">
|
||||||
{t("logonRequired")}
|
{t("logonRequired")}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<SignInForm />
|
<SignInForm />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
children
|
children
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,12 +86,17 @@ const Zones = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="flex gap-4 text-gray-900 dark:text-white"
|
className="flex flex-col gap-4 text-gray-900 dark:text-white md:flex-row"
|
||||||
key={zone.id}
|
key={zone.id}
|
||||||
>
|
>
|
||||||
<ZoneThumbnail features={zone.features} size={200} />
|
<h3 className="text-xl font-semibold text-gray-900 dark:text-white md:hidden">
|
||||||
<div className="flex flex-1 flex-col justify-between">
|
{zone.name}
|
||||||
<h3 className="text-xl font-semibold text-gray-900 dark:text-white">
|
</h3>
|
||||||
|
|
||||||
|
<ZoneThumbnail features={zone.features} />
|
||||||
|
|
||||||
|
<div className="flex flex-1 flex-col justify-between gap-4">
|
||||||
|
<h3 className="hidden text-xl font-semibold text-gray-900 dark:text-white md:block">
|
||||||
{zone.name}
|
{zone.name}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
|||||||
@@ -2,31 +2,36 @@
|
|||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
|
import { Menu } from "@headlessui/react";
|
||||||
import { signIn, signOut, useSession } from "next-auth/react";
|
import { signIn, signOut, useSession } from "next-auth/react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { RxAvatar } from "react-icons/rx";
|
||||||
|
|
||||||
|
import { useAuthMenuOptions } from "@/hooks/useAuthMenuOptions";
|
||||||
|
|
||||||
|
import { DropdownMenu } from "./DropdownMenu";
|
||||||
|
|
||||||
const AuthButton = () => {
|
const AuthButton = () => {
|
||||||
const t = useTranslations("Nav");
|
const t = useTranslations("Nav");
|
||||||
const router = useRouter();
|
const { data: sessionData, status } = useSession();
|
||||||
const [signingOut, setSigningOut] = useState(false);
|
const menuItems = useAuthMenuOptions();
|
||||||
const { data: sessionData } = useSession();
|
|
||||||
|
|
||||||
const handleSignOut = async () => {
|
if (status === "loading") {
|
||||||
setSigningOut(true);
|
return null;
|
||||||
try {
|
}
|
||||||
await signOut({ redirect: false });
|
|
||||||
router.push("/");
|
|
||||||
} finally {
|
|
||||||
setSigningOut(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (sessionData) {
|
if (sessionData) {
|
||||||
return (
|
return (
|
||||||
<button disabled={signingOut} onClick={handleSignOut}>
|
<DropdownMenu
|
||||||
{t("signOut")}
|
items={menuItems}
|
||||||
</button>
|
containerClassName="flex items-center justify-center"
|
||||||
|
buttonComponent={
|
||||||
|
<Menu.Button>
|
||||||
|
<RxAvatar className="h-6 w-6" />
|
||||||
|
</Menu.Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { Float } from "@headlessui-float/react";
|
||||||
|
import { Menu } from "@headlessui/react";
|
||||||
|
import { IoMdMore } from "react-icons/io";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
export type DropdownMenuItem = {
|
||||||
|
title: React.ReactNode;
|
||||||
|
disabled?: boolean;
|
||||||
|
onClick: () => void;
|
||||||
|
className?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DropdownMenuProps = {
|
||||||
|
items: DropdownMenuItem[];
|
||||||
|
buttonComponent?: React.ReactElement;
|
||||||
|
containerClassName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DropdownMenu = ({
|
||||||
|
items,
|
||||||
|
buttonComponent,
|
||||||
|
containerClassName,
|
||||||
|
}: DropdownMenuProps) => {
|
||||||
|
return (
|
||||||
|
<Menu as="div" className={twMerge("relative", containerClassName)}>
|
||||||
|
<Float
|
||||||
|
portal
|
||||||
|
placement="bottom-end"
|
||||||
|
offset={15}
|
||||||
|
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"
|
||||||
|
>
|
||||||
|
{buttonComponent ?? (
|
||||||
|
<Menu.Button>
|
||||||
|
<IoMdMore />
|
||||||
|
</Menu.Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Menu.Items className="z-20 flex w-auto items-start overflow-hidden rounded-md bg-neutral-200 focus:outline-none dark:bg-neutral-600">
|
||||||
|
<div className="flex flex-col px-1 py-1">
|
||||||
|
{items.map(({ title, onClick, className, disabled }, i) => (
|
||||||
|
<Menu.Item key={i}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={twMerge(
|
||||||
|
"w-full whitespace-nowrap rounded-md px-2.5 py-2 text-left text-sm text-black dark:text-white",
|
||||||
|
!disabled && "hover:bg-white dark:hover:bg-neutral-700",
|
||||||
|
disabled && "text-neutral-500 dark:text-neutral-500",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
disabled={disabled ?? false}
|
||||||
|
onClick={() => {
|
||||||
|
if (!disabled) onClick();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</button>
|
||||||
|
</Menu.Item>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Menu.Items>
|
||||||
|
</Float>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
|
import { Spinner } from "./Spinner";
|
||||||
|
|
||||||
const LoadingMap = () => {
|
const LoadingMap = () => {
|
||||||
const t = useTranslations("Tournaments");
|
const t = useTranslations("Tournaments");
|
||||||
return (
|
return (
|
||||||
<div className="grid h-content place-self-center bg-white text-center text-gray-900 dark:bg-gray-800 dark:text-white">
|
<div className="mt-20 flex h-content justify-center bg-white pt-20 text-center text-gray-900 dark:bg-gray-800 dark:text-white">
|
||||||
<p>{t("loading")}</p>
|
<Spinner />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
import { signIn, signOut, useSession } from "next-auth/react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
|
import { DropdownMenuItem } from "@/components/DropdownMenu";
|
||||||
|
|
||||||
|
export const useAuthMenuOptions = () => {
|
||||||
|
const t = useTranslations("Nav");
|
||||||
|
const router = useRouter();
|
||||||
|
const [signingOut, setSigningOut] = useState(false);
|
||||||
|
const { data: sessionData, status } = useSession();
|
||||||
|
|
||||||
|
const handleSignOut = async () => {
|
||||||
|
setSigningOut(true);
|
||||||
|
try {
|
||||||
|
await signOut({ redirect: false });
|
||||||
|
router.push("/");
|
||||||
|
} finally {
|
||||||
|
setSigningOut(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (status === "loading") {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sessionData) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: t("signIn"),
|
||||||
|
onClick: () => signIn(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: DropdownMenuItem[] = [
|
||||||
|
{
|
||||||
|
title: t("myZones"),
|
||||||
|
onClick: () => router.push("/zones"),
|
||||||
|
disabled: signingOut,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// title: t("deleteAccount"),
|
||||||
|
// onClick: handleSignOut,
|
||||||
|
// disabled: signingOut,
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
title: t("signOut"),
|
||||||
|
onClick: handleSignOut,
|
||||||
|
disabled: signingOut,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
@@ -35,7 +35,9 @@
|
|||||||
"clubs": "Clubs",
|
"clubs": "Clubs",
|
||||||
"elo": "Elo Calculator",
|
"elo": "Elo Calculator",
|
||||||
"signIn": "Sign In",
|
"signIn": "Sign In",
|
||||||
"signOut": "Sign Out"
|
"signOut": "Sign Out",
|
||||||
|
"myZones": "My Zones",
|
||||||
|
"deleteAccount": "Delete my Account"
|
||||||
},
|
},
|
||||||
|
|
||||||
"Footer": {
|
"Footer": {
|
||||||
|
|||||||
@@ -35,7 +35,9 @@
|
|||||||
"clubs": "Clubs",
|
"clubs": "Clubs",
|
||||||
"elo": "Calculette Elo",
|
"elo": "Calculette Elo",
|
||||||
"signIn": "Se connecter",
|
"signIn": "Se connecter",
|
||||||
"signOut": "Se déconnecter"
|
"signOut": "Se déconnecter",
|
||||||
|
"myZones": "Mes Régions",
|
||||||
|
"deleteAccount": "Supprimer le compte"
|
||||||
},
|
},
|
||||||
|
|
||||||
"Footer": {
|
"Footer": {
|
||||||
|
|||||||
@@ -1178,14 +1178,14 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f"
|
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f"
|
||||||
integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==
|
integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==
|
||||||
|
|
||||||
"@floating-ui/core@^1.0.0":
|
"@floating-ui/core@^1.0.0", "@floating-ui/core@^1.5.3":
|
||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1"
|
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1"
|
||||||
integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==
|
integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@floating-ui/utils" "^0.2.1"
|
"@floating-ui/utils" "^0.2.1"
|
||||||
|
|
||||||
"@floating-ui/dom@^1.0.1", "@floating-ui/dom@^1.6.1":
|
"@floating-ui/dom@^1.0.1", "@floating-ui/dom@^1.5.4", "@floating-ui/dom@^1.6.1":
|
||||||
version "1.6.3"
|
version "1.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef"
|
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef"
|
||||||
integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==
|
integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==
|
||||||
@@ -1193,6 +1193,22 @@
|
|||||||
"@floating-ui/core" "^1.0.0"
|
"@floating-ui/core" "^1.0.0"
|
||||||
"@floating-ui/utils" "^0.2.0"
|
"@floating-ui/utils" "^0.2.0"
|
||||||
|
|
||||||
|
"@floating-ui/react-dom@^2.0.0":
|
||||||
|
version "2.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.8.tgz#afc24f9756d1b433e1fe0d047c24bd4d9cefaa5d"
|
||||||
|
integrity sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/dom" "^1.6.1"
|
||||||
|
|
||||||
|
"@floating-ui/react@^0.26.5":
|
||||||
|
version "0.26.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.12.tgz#6908f774d8e3167d89b37fd83be975c7e5d8be99"
|
||||||
|
integrity sha512-D09o62HrWdIkstF2kGekIKAC0/N/Dl6wo3CQsnLcOmO3LkW6Ik8uIb3kw8JYkwxNCcg+uJ2bpWUiIijTBep05w==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/react-dom" "^2.0.0"
|
||||||
|
"@floating-ui/utils" "^0.2.0"
|
||||||
|
tabbable "^6.0.0"
|
||||||
|
|
||||||
"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1":
|
"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1":
|
||||||
version "0.2.1"
|
version "0.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2"
|
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2"
|
||||||
@@ -1259,6 +1275,15 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
|
|
||||||
|
"@headlessui-float/react@^0.13.3":
|
||||||
|
version "0.13.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@headlessui-float/react/-/react-0.13.3.tgz#700ac6cfe56a264dcdc4c6486253dd7573b1b970"
|
||||||
|
integrity sha512-wApuiUu2zcuETftdEJupEUG3XP6AUpwNN+kb6rrBadMf/jpOt1rVBjurgL+peKSW9AfxpNT7uqlL4se6u/epqw==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/core" "^1.5.3"
|
||||||
|
"@floating-ui/dom" "^1.5.4"
|
||||||
|
"@floating-ui/react" "^0.26.5"
|
||||||
|
|
||||||
"@headlessui/react@^1.7.18":
|
"@headlessui/react@^1.7.18":
|
||||||
version "1.7.18"
|
version "1.7.18"
|
||||||
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.18.tgz#30af4634d2215b2ca1aa29d07f33d02bea82d9d7"
|
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.18.tgz#30af4634d2215b2ca1aa29d07f33d02bea82d9d7"
|
||||||
@@ -5516,6 +5541,11 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||||
|
|
||||||
|
tabbable@^6.0.0:
|
||||||
|
version "6.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
|
||||||
|
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
|
||||||
|
|
||||||
tailwind-merge@^2.0.0:
|
tailwind-merge@^2.0.0:
|
||||||
version "2.2.2"
|
version "2.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.2.tgz#87341e7604f0e20499939e152cd2841f41f7a3df"
|
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.2.tgz#87341e7604f0e20499939e152cd2841f41f7a3df"
|
||||||
|
|||||||
Reference in New Issue
Block a user