From e61957b5e921c765f0c06b89e6b3dbf838b18e90 Mon Sep 17 00:00:00 2001 From: Randa Firman Putra Date: Thu, 26 Jun 2025 13:03:15 +0700 Subject: [PATCH] Change Dashboard Sidebar --- app/layout.tsx | 27 +- app/mahasiswa/profile/page.tsx | 306 +--------------- app/page.tsx | 2 +- components/ClientLayout.tsx | 50 +++ components/ui/Navbar.tsx | 362 ++----------------- components/ui/Sidebar.tsx | 14 +- components/ui/SidebarContent.tsx | 2 +- package-lock.json | 593 ++++++++++++++++++++++++++++++- package.json | 6 +- 9 files changed, 676 insertions(+), 686 deletions(-) create mode 100644 components/ClientLayout.tsx diff --git a/app/layout.tsx b/app/layout.tsx index 8e3df99..54bf9bd 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,10 +1,7 @@ import type { Metadata } from 'next'; import { Geist, Geist_Mono } from 'next/font/google'; import './globals.css'; -import Navbar from '@/components/ui/Navbar'; -import Sidebar from '@/components/ui/Sidebar'; -import { ThemeProvider } from '@/components/theme-provider'; -import { Toaster } from '@/components/ui/toaster'; +import ClientLayout from '../components/ClientLayout'; const geistSans = Geist({ variable: '--font-geist-sans', @@ -21,28 +18,6 @@ export const metadata: Metadata = { description: 'Admin Dashboard', }; -function ClientLayout({ children }: { children: React.ReactNode }) { - return ( - -
- -
- -
- {children} -
-
-
- -
- ); -} - export default function RootLayout({ children, }: Readonly<{ diff --git a/app/mahasiswa/profile/page.tsx b/app/mahasiswa/profile/page.tsx index 08288bf..1741e35 100644 --- a/app/mahasiswa/profile/page.tsx +++ b/app/mahasiswa/profile/page.tsx @@ -1,309 +1,11 @@ 'use client'; -import { useEffect, useState } from 'react'; -import { useRouter } from 'next/navigation'; -import { useToast } from '@/components/ui/use-toast'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { Skeleton } from '@/components/ui/skeleton'; -import { User, Trophy, Award } from 'lucide-react'; -import { useTheme } from 'next-themes'; - -interface PrestasiMahasiswa { - nama_prestasi: string; - jenis_prestasi: string; - tingkat_prestasi: string; - peringkat: string; - tanggal_prestasi: string; -} - -interface BeasiswaMahasiswa { - nama_beasiswa: string; - sumber_beasiswa: string; - jenis_beasiswa: string; - beasiswa_status: string; -} - -interface MahasiswaProfile { - // Data Mahasiswa - nama: string; - nim: string; - tahun_angkatan: string; - jk: 'Pria' | 'Wanita'; - jenis_pendaftaran: string; - ipk: number | null; - agama: string; - kabupaten: string; - provinsi: string; - - // Status Mahasiswa - status_kuliah: string; - semester: string; - - // Prestasi Mahasiswa - prestasi: PrestasiMahasiswa[]; - - // Beasiswa Mahasiswa - beasiswa: BeasiswaMahasiswa[]; -} - export default function ProfilePage() { - const [profile, setProfile] = useState(null); - const [loading, setLoading] = useState(true); - const { toast } = useToast(); - const router = useRouter(); - const { theme } = useTheme(); - - useEffect(() => { - const fetchProfile = async () => { - try { - console.log('Fetching profile data...'); - const response = await fetch('/api/mahasiswa/profile'); - console.log('Profile response status:', response.status); - - if (response.status === 401) { - toast({ - variant: "destructive", - title: "Akses Ditolak", - description: "Silakan login terlebih dahulu untuk mengakses halaman ini.", - }); - router.push('/'); - return; - } - - if (!response.ok) { - const errorData = await response.json(); - throw new Error(errorData.error || 'Failed to fetch profile data'); - } - - const data = await response.json(); - console.log('Profile data received:', data); - setProfile(data); - } catch (error) { - console.error('Error fetching profile:', error); - toast({ - variant: "destructive", - title: "Error", - description: error instanceof Error ? error.message : "Gagal memuat data profil. Silakan coba lagi nanti.", - }); - } finally { - setLoading(false); - } - }; - - fetchProfile(); - }, [toast, router]); - - if (loading) { - return ( -
- {[...Array(3)].map((_, i) => ( - - - - - -
- {[...Array(8)].map((_, j) => ( -
- - -
- ))} -
-
-
- ))} -
- ); - } - - if (!profile) { - return ( -
- - - Profil Mahasiswa - - -
- Data profil tidak tersedia -
-
-
-
- ); - } - - // Format IPK value - const formatIPK = (ipk: number | null): string => { - if (ipk === null || ipk === undefined) return '-'; - return Number(ipk).toFixed(2); - }; - - // Get first prestasi or create empty object - const firstPrestasi = profile.prestasi.length > 0 ? profile.prestasi[0] : { - nama_prestasi: '-', - jenis_prestasi: '-', - tingkat_prestasi: '-', - peringkat: '-', - tanggal_prestasi: '-' - }; - - // Get first beasiswa or create empty object - const firstBeasiswa = profile.beasiswa.length > 0 ? profile.beasiswa[0] : { - nama_beasiswa: '-', - sumber_beasiswa: '-', - jenis_beasiswa: '-', - beasiswa_status: '-' - }; - return ( -
- {/* Data Mahasiswa */} - - -
-
- -
-
- Data Mahasiswa -
-
-
- -
-
-
-
Nama Lengkap
-
{profile.nama}
-
-
-
NIM
-
{profile.nim}
-
-
-
Status Kuliah
-
{profile.status_kuliah}
-
-
-
Semester
-
{profile.semester}
-
-
-
Tahun Angkatan
-
{profile.tahun_angkatan}
-
-
-
Jenis Kelamin
-
{profile.jk}
-
-
-
-
-
Jenis Pendaftaran
-
{profile.jenis_pendaftaran}
-
-
-
IPK
-
{formatIPK(profile.ipk)}
-
-
-
Agama
-
{profile.agama}
-
-
-
Kabupaten
-
{profile.kabupaten}
-
-
-
Provinsi
-
{profile.provinsi}
-
-
-
-
-
- - {/* Prestasi Mahasiswa */} - - -
-
- -
-
- Prestasi Mahasiswa -
-
-
- -
-
-
-
Nama Prestasi
-
{firstPrestasi.nama_prestasi}
-
-
-
Jenis Prestasi
-
{firstPrestasi.jenis_prestasi}
-
-
-
Tingkat Prestasi
-
{firstPrestasi.tingkat_prestasi}
-
-
-
-
-
Peringkat
-
{firstPrestasi.peringkat}
-
-
-
Tanggal Prestasi
-
{firstPrestasi.tanggal_prestasi}
-
-
-
-
-
- - {/* Beasiswa Mahasiswa */} - - -
-
- -
-
- Beasiswa Mahasiswa -
-
-
- -
-
-
-
Nama Beasiswa
-
{firstBeasiswa.nama_beasiswa}
-
-
-
Sumber Beasiswa
-
{firstBeasiswa.sumber_beasiswa}
-
-
-
-
-
Jenis Beasiswa
-
{firstBeasiswa.jenis_beasiswa}
-
-
-
Status Beasiswa
-
{firstBeasiswa.beasiswa_status}
-
-
-
-
-
+
+
+ Sedang dalam pengembangan :) +
); } diff --git a/app/page.tsx b/app/page.tsx index b848205..ebc3c71 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -128,7 +128,7 @@ export default function HomePage() {
) : ( <> -
+
{/* Kartu Total Mahasiswa */} diff --git a/components/ClientLayout.tsx b/components/ClientLayout.tsx new file mode 100644 index 0000000..ec52303 --- /dev/null +++ b/components/ClientLayout.tsx @@ -0,0 +1,50 @@ +"use client"; + +import { useState, useEffect } from 'react'; +import Navbar from '@/components/ui/Navbar'; +import Sidebar from '@/components/ui/Sidebar'; +import { ThemeProvider } from '@/components/theme-provider'; +import { Toaster } from '@/components/ui/toaster'; + +interface ClientLayoutProps { + children: React.ReactNode; +} + +export default function ClientLayout({ children }: ClientLayoutProps) { + const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false); + + // Load sidebar state from localStorage on mount + useEffect(() => { + const savedState = localStorage.getItem('sidebarCollapsed'); + if (savedState !== null) { + setIsSidebarCollapsed(JSON.parse(savedState)); + } + }, []); + + // Save sidebar state to localStorage when it changes + useEffect(() => { + localStorage.setItem('sidebarCollapsed', JSON.stringify(isSidebarCollapsed)); + }, [isSidebarCollapsed]); + + return ( + +
+ +
+ setIsSidebarCollapsed(!isSidebarCollapsed)} isSidebarCollapsed={isSidebarCollapsed} /> +
+ {children} +
+
+
+ +
+ ); +} \ No newline at end of file diff --git a/components/ui/Navbar.tsx b/components/ui/Navbar.tsx index fecd190..6764fcc 100644 --- a/components/ui/Navbar.tsx +++ b/components/ui/Navbar.tsx @@ -1,245 +1,20 @@ 'use client'; -import { useState, useEffect } from 'react'; -import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog'; -import { Input } from '@/components/ui/input'; -import { Button } from '@/components/ui/button'; -import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { ThemeToggle } from '@/components/theme-toggle'; -import { Menu, User } from 'lucide-react'; +import { Menu, PanelLeftClose, PanelLeft } from 'lucide-react'; +import { Button } from '@/components/ui/button'; import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet'; import SidebarContent from '@/components/ui/SidebarContent'; -import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu'; -import { useToast } from '@/components/ui/use-toast'; import Link from 'next/link'; -import { useRouter } from 'next/navigation'; -const Navbar = () => { - const [isLoggedIn, setIsLoggedIn] = useState(false); - const [dialogOpen, setDialogOpen] = useState(false); - const [loginData, setLoginData] = useState({ nim: '', password: '' }); - const [registerData, setRegisterData] = useState({ username: '', nim: '', password: '', confirmPassword: '' }); - const [userData, setUserData] = useState(null); - const { toast } = useToast(); - const router = useRouter(); - - // Check login status on component mount and when route changes - useEffect(() => { - const checkAuth = async () => { - try { - const response = await fetch('/api/auth/check'); - const data = await response.json(); - - if (response.ok && data.user) { - setUserData(data.user); - setIsLoggedIn(true); - } else { - setUserData(null); - setIsLoggedIn(false); - } - } catch (error) { - console.error('Auth check failed:', error); - setUserData(null); - setIsLoggedIn(false); - } - }; - - checkAuth(); - }, [router]); - - const handleLogin = async (e: React.FormEvent) => { - e.preventDefault(); - - // Validate input - if (!loginData.nim || !loginData.password) { - toast({ - variant: "destructive", - title: "Login gagal", - description: "NIM dan password harus diisi", - }); - return; - } - - console.log('Login attempt with data:', { - nim: loginData.nim, - password: '***' - }); - - try { - const response = await fetch('/api/auth/login', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - nim: loginData.nim.trim(), - password: loginData.password - }), - }); - - console.log('Login response status:', response.status); - const data = await response.json(); - console.log('Login response data:', data); - - if (!response.ok) { - throw new Error(data.error || 'Login gagal'); - } - - toast({ - title: "Login berhasil", - description: "Selamat datang kembali!", - }); - - setUserData(data.user); - setIsLoggedIn(true); - setDialogOpen(false); - router.refresh(); - } catch (error) { - console.error('Login error:', error); - toast({ - variant: "destructive", - title: "Login gagal", - description: error instanceof Error ? error.message : 'Terjadi kesalahan saat login', - }); - } - }; - - const handleRegister = async (e: React.FormEvent) => { - e.preventDefault(); - - // Validate passwords match - if (registerData.password !== registerData.confirmPassword) { - toast({ - variant: "destructive", - title: "Registrasi gagal", - description: "Password dan konfirmasi password tidak cocok", - }); - return; - } - - try { - const response = await fetch('/api/auth/register', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - username: registerData.username, - nim: registerData.nim, - password: registerData.password, - }), - }); - - const data = await response.json(); - - if (!response.ok) { - throw new Error(data.error || 'Registrasi gagal'); - } - - toast({ - title: "Registrasi berhasil", - description: "Silakan login dengan akun Anda", - }); - - // Reset form and switch to login tab - setRegisterData({ username: '', nim: '', password: '', confirmPassword: '' }); - const tabsList = document.querySelector('[role="tablist"]'); - if (tabsList) { - const loginTab = tabsList.querySelector('[value="login"]'); - if (loginTab) { - (loginTab as HTMLElement).click(); - } - } - } catch (error) { - toast({ - variant: "destructive", - title: "Registrasi gagal", - description: error instanceof Error ? error.message : 'Terjadi kesalahan saat registrasi', - }); - } - }; - - const handleLogout = async () => { - try { - const response = await fetch('/api/auth/logout', { - method: 'POST', - }); - - if (!response.ok) { - throw new Error('Logout gagal'); - } - - toast({ - title: "Logout berhasil", - description: "Sampai jumpa lagi!", - }); - - setUserData(null); - setIsLoggedIn(false); - router.push('/'); - router.refresh(); - } catch (error) { - toast({ - variant: "destructive", - title: "Logout gagal", - description: error instanceof Error ? error.message : 'Terjadi kesalahan saat logout', - }); - } - }; - - const handleProfileClick = async () => { - try { - const response = await fetch('/api/auth/check'); - const data = await response.json(); - - if (response.ok && data.user) { - router.push('/mahasiswa/profile'); - } else { - toast({ - variant: "destructive", - title: "Akses Ditolak", - description: "Silakan login terlebih dahulu untuk mengakses profil", - }); - setDialogOpen(true); - router.push('/'); // Redirect to home if not logged in - } - } catch (error) { - console.error('Error checking auth status:', error); - toast({ - variant: "destructive", - title: "Error", - description: "Terjadi kesalahan saat memeriksa status login", - }); - router.push('/'); - } - }; - - const handleInputChange = (e: React.ChangeEvent) => { - const { name, value } = e.target; - if (name.startsWith('login')) { - const loginField = name.replace('login', '').toLowerCase(); - setLoginData(prev => ({ - ...prev, - [loginField]: value - })); - } else { - setRegisterData(prev => ({ - ...prev, - [name]: value - })); - } - }; +interface NavbarProps { + onSidebarToggle: () => void; + isSidebarCollapsed: boolean; +} +const Navbar = ({ onSidebarToggle, isSidebarCollapsed }: NavbarProps) => { return ( -
+
{/* Mobile Menu Button */}
@@ -251,11 +26,28 @@ const Navbar = () => { - Menu Navigasi
+ + {/* Desktop Sidebar Toggle Button */} +
+ +
+ PODIF Logo PODIF @@ -263,108 +55,6 @@ const Navbar = () => {
- {isLoggedIn ? ( - - - - - - - - - - - My Account - - - Profile - - Logout - - - ) : ( - - - - - - - Portal Data Informatika - Masuk atau daftar untuk mengakses portal - - - - Login - Register - - -
- - - -
-
- -
- - - - - -
-
-
-
-
- )}
diff --git a/components/ui/Sidebar.tsx b/components/ui/Sidebar.tsx index 2dac4ad..e8de52f 100644 --- a/components/ui/Sidebar.tsx +++ b/components/ui/Sidebar.tsx @@ -2,10 +2,18 @@ import SidebarContent from './SidebarContent'; -const Sidebar = () => { +interface SidebarProps { + isCollapsed?: boolean; +} + +const Sidebar = ({ isCollapsed = false }: SidebarProps) => { return ( -
- +
+
+ +
); }; diff --git a/components/ui/SidebarContent.tsx b/components/ui/SidebarContent.tsx index f903c3b..7155aa6 100644 --- a/components/ui/SidebarContent.tsx +++ b/components/ui/SidebarContent.tsx @@ -24,7 +24,7 @@ import { School, Settings, User, GraduationCap, Award, Users, Clock, BookOpen, H const SidebarContent = () => { return ( - + diff --git a/package-lock.json b/package-lock.json index 0380979..c9f366e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,13 +10,15 @@ "dependencies": { "@radix-ui/react-accordion": "^1.2.4", "@radix-ui/react-avatar": "^1.1.4", - "@radix-ui/react-dialog": "^1.1.7", + "@radix-ui/react-dialog": "^1.1.14", "@radix-ui/react-dropdown-menu": "^2.1.7", "@radix-ui/react-label": "^2.1.4", "@radix-ui/react-select": "^2.2.2", - "@radix-ui/react-slot": "^1.2.0", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.7", "@radix-ui/react-toast": "^1.2.10", + "@radix-ui/react-tooltip": "^1.2.7", "@supabase/supabase-js": "^2.50.0", "@types/bcryptjs": "^2.4.6", "@types/jsonwebtoken": "^9.0.9", @@ -790,6 +792,24 @@ } } }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -821,23 +841,23 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.7.tgz", - "integrity": "sha512-EIdma8C0C/I6kL6sO02avaCRqi3fmWJpxH6mqbVScorW6nNktzKJT/le7VPho3o/7wCsyRg3z0+Q+Obr0Gy/VQ==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", + "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.6", + "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-portal": "1.1.5", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-slot": "1.2.0", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, @@ -856,6 +876,148 @@ } } }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-direction": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", @@ -1031,6 +1193,24 @@ } } }, + "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-menu": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.7.tgz", @@ -1071,6 +1251,24 @@ } } }, + "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.3.tgz", @@ -1174,6 +1372,24 @@ } } }, + "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.3.tgz", @@ -1428,6 +1644,24 @@ } } }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-controllable-state": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", @@ -1447,10 +1681,56 @@ } } }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", - "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -1575,6 +1855,24 @@ } } }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-use-controllable-state": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", @@ -1728,6 +2026,24 @@ } } }, + "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-use-controllable-state": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", @@ -1747,6 +2063,235 @@ } } }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz", + "integrity": "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", + "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-presence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", @@ -1928,6 +2473,24 @@ } } }, + "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/rect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", diff --git a/package.json b/package.json index 2e9d2f3..8c06296 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,15 @@ "dependencies": { "@radix-ui/react-accordion": "^1.2.4", "@radix-ui/react-avatar": "^1.1.4", - "@radix-ui/react-dialog": "^1.1.7", + "@radix-ui/react-dialog": "^1.1.14", "@radix-ui/react-dropdown-menu": "^2.1.7", "@radix-ui/react-label": "^2.1.4", "@radix-ui/react-select": "^2.2.2", - "@radix-ui/react-slot": "^1.2.0", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.7", "@radix-ui/react-toast": "^1.2.10", + "@radix-ui/react-tooltip": "^1.2.7", "@supabase/supabase-js": "^2.50.0", "@types/bcryptjs": "^2.4.6", "@types/jsonwebtoken": "^9.0.9",