feat:用户登录功能

This commit is contained in:
hzm
2026-02-07 13:19:26 +08:00
parent 1b14faf73b
commit 01cd491f5e
4 changed files with 490 additions and 16 deletions

View File

@@ -1166,8 +1166,8 @@ input[type="number"] {
}
.user-menu-trigger.logged-in {
border-color: var(--primary);
background: rgba(34, 211, 238, 0.1);
/*border-color: var(--primary);*/
/*background: rgba(34, 211, 238, 0.1);*/
}
.user-avatar-small {

View File

@@ -2,6 +2,8 @@
import { useEffect, useRef, useState, useMemo, useLayoutEffect } from 'react';
import { motion, AnimatePresence, Reorder } from 'framer-motion';
import { createAvatar } from '@dicebear/core';
import { glass } from '@dicebear/collection';
import Announcement from "./components/Announcement";
import zhifubaoImg from "./assets/zhifubao.jpg";
import weixinImg from "./assets/weixin.jpg";
@@ -1788,6 +1790,14 @@ export default function HomePage() {
const [loginSuccess, setLoginSuccess] = useState('');
const [loginOtp, setLoginOtp] = useState('');
const userAvatar = useMemo(() => {
if (!user?.id) return '';
return createAvatar(glass, {
seed: user.id,
size: 80
}).toDataUri();
}, [user?.id]);
// 反馈弹窗状态
const [feedbackOpen, setFeedbackOpen] = useState(false);
const [feedbackNonce, setFeedbackNonce] = useState(0);
@@ -2454,6 +2464,13 @@ export default function HomePage() {
// 登出
const handleLogout = async () => {
try {
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
await supabase.auth.signOut({ scope: 'local' });
setUserMenuOpen(false);
setUser(null);
return;
}
const { error } = await supabase.auth.signOut();
if (error?.code === 'session_not_found') {
await supabase.auth.signOut({ scope: 'local' });
@@ -3477,17 +3494,8 @@ export default function HomePage() {
>
<RefreshIcon className={refreshing ? 'spin' : ''} width="18" height="18" />
</button>
<button
className="icon-button"
aria-label="打开设置"
onClick={() => setSettingsOpen(true)}
title="设置"
>
<SettingsIcon width="18" height="18" />
</button>
{/* 临时隐藏用户菜单入口 */}
<div className="user-menu-container" ref={userMenuRef} hidden>
{/* 用户菜单 */}
<div className="user-menu-container" ref={userMenuRef}>
<button
className={`icon-button user-menu-trigger ${user ? 'logged-in' : ''}`}
aria-label={user ? '用户菜单' : '登录'}
@@ -3496,7 +3504,15 @@ export default function HomePage() {
>
{user ? (
<div className="user-avatar-small">
{user.email?.charAt(0).toUpperCase() || 'U'}
{userAvatar ? (
<img
src={userAvatar}
alt="用户头像"
style={{ width: '100%', height: '100%', borderRadius: '50%' }}
/>
) : (
(user.email?.charAt(0).toUpperCase() || 'U')
)}
</div>
) : (
<UserIcon width="18" height="18" />
@@ -3517,7 +3533,15 @@ export default function HomePage() {
<>
<div className="user-menu-header">
<div className="user-avatar-large">
{user.email?.charAt(0).toUpperCase() || 'U'}
{userAvatar ? (
<img
src={userAvatar}
alt="用户头像"
style={{ width: '100%', height: '100%', borderRadius: '50%' }}
/>
) : (
(user.email?.charAt(0).toUpperCase() || 'U')
)}
</div>
<div className="user-info">
<span className="user-email">{user.email}</span>
@@ -3609,7 +3633,12 @@ export default function HomePage() {
/>
{isSearching && <div className="search-spinner" />}
</div>
<button className="button" type="submit" disabled={loading}>
<button
className="button"
type="submit"
disabled={loading || refreshing}
style={{pointerEvents: refreshing ? 'none' : 'auto', opacity: refreshing ? 0.6 : 1}}
>
{loading ? '添加中…' : '添加'}
</button>
</form>

440
package-lock.json generated
View File

@@ -8,11 +8,445 @@
"name": "real-time-fund",
"version": "0.1.0",
"dependencies": {
"@dicebear/collection": "^9.3.1",
"@dicebear/core": "^9.3.1",
"@supabase/supabase-js": "^2.78.0",
"framer-motion": "^12.29.2",
"next": "^16.1.5",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"engines": {
"node": ">=20.9.0"
}
},
"node_modules/@dicebear/adventurer": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/adventurer/-/adventurer-9.3.1.tgz",
"integrity": "sha512-MBCA8QtRC4mWbYncFDxI67LxxXMccsORqJS8osD4F/MgOPMJsdoN9QrRfsY/MjO+4NbTSxsVzOhn2nf1WzoLbA==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/adventurer-neutral": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/adventurer-neutral/-/adventurer-neutral-9.3.1.tgz",
"integrity": "sha512-MKrzLkAGx0cdBVD+XJu6ERhdJjWsjoFS+0nF9MZT17h/m/Q12FSoj+ACoKTEXBS/LBQfQqjA9HstBlSxMzmBdw==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/avataaars": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/avataaars/-/avataaars-9.3.1.tgz",
"integrity": "sha512-gQwtaTfPVwNAvVktdTjyhGnQtt5ifeE/6XyMX/fUJTTo/uI2NLy4LedzjsibA/DW8xi+TbgUyXlyTaJs0H6MGA==",
"license": "See LICENSE file",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/avataaars-neutral": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/avataaars-neutral/-/avataaars-neutral-9.3.1.tgz",
"integrity": "sha512-d9enbUJcRfMui0ZESJ9ofJXKJPdqrzKgqefT9fcC8EfOvP0WqVtsUzcPj9l6FYhG1fMDdTsx+A8e//1lCynbQQ==",
"license": "See LICENSE file",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/big-ears": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/big-ears/-/big-ears-9.3.1.tgz",
"integrity": "sha512-JN2ZlrSvpKJNyRAFzyeg+Y5wBG0EZQc8Ds5bZIHkf2/uaLUQIeDT1At2Sr7hSJDKSYZ8z83H6ckbzpDl5b9MzQ==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/big-ears-neutral": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/big-ears-neutral/-/big-ears-neutral-9.3.1.tgz",
"integrity": "sha512-Fvw/GoT+3q77zwUbHOujGujQ4oVgtoOXE7ByfxcPeVcaUUTRARpWXlNwUBg0zt+o/Dfv875awpt3sIgKuecGsw==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/big-smile": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/big-smile/-/big-smile-9.3.1.tgz",
"integrity": "sha512-c5USb4n3Zw32WIJUZqc2+mCe3vbN6XJtZjKtFbisFujMAX6I3avRf6S1JBbm5oT86ynGH6P1/EZ2K7WkThfEBg==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/bottts": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/bottts/-/bottts-9.3.1.tgz",
"integrity": "sha512-qIPokserYLIwpScbsvFADwspBfa1Mg8JFEtYcXYcbPLnNek8bZiAhpQSc1bHSqHjm10bFEjvTr0opSNr72CBzw==",
"license": "See LICENSE file",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/bottts-neutral": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/bottts-neutral/-/bottts-neutral-9.3.1.tgz",
"integrity": "sha512-Ea3dZ7/absDmedpFIZp+yoeS6Dq0sZ8W87xw39SS45Mr1s3i4lVd/0XWc9U5QBl0XrP4CQKB7b2QpcSY4tIYtg==",
"license": "See LICENSE file",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/collection": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/collection/-/collection-9.3.1.tgz",
"integrity": "sha512-3hDYu9K4quu9jiXQTno2e0AyBzmrqm1PE6Mw7u2gYOZZ5GsSqrDdNHQODShyzqDF1LuyypZY4XN4YjFJ6fWqig==",
"license": "MIT",
"dependencies": {
"@dicebear/adventurer": "9.3.1",
"@dicebear/adventurer-neutral": "9.3.1",
"@dicebear/avataaars": "9.3.1",
"@dicebear/avataaars-neutral": "9.3.1",
"@dicebear/big-ears": "9.3.1",
"@dicebear/big-ears-neutral": "9.3.1",
"@dicebear/big-smile": "9.3.1",
"@dicebear/bottts": "9.3.1",
"@dicebear/bottts-neutral": "9.3.1",
"@dicebear/croodles": "9.3.1",
"@dicebear/croodles-neutral": "9.3.1",
"@dicebear/dylan": "9.3.1",
"@dicebear/fun-emoji": "9.3.1",
"@dicebear/glass": "9.3.1",
"@dicebear/icons": "9.3.1",
"@dicebear/identicon": "9.3.1",
"@dicebear/initials": "9.3.1",
"@dicebear/lorelei": "9.3.1",
"@dicebear/lorelei-neutral": "9.3.1",
"@dicebear/micah": "9.3.1",
"@dicebear/miniavs": "9.3.1",
"@dicebear/notionists": "9.3.1",
"@dicebear/notionists-neutral": "9.3.1",
"@dicebear/open-peeps": "9.3.1",
"@dicebear/personas": "9.3.1",
"@dicebear/pixel-art": "9.3.1",
"@dicebear/pixel-art-neutral": "9.3.1",
"@dicebear/rings": "9.3.1",
"@dicebear/shapes": "9.3.1",
"@dicebear/thumbs": "9.3.1",
"@dicebear/toon-head": "9.3.1"
},
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/core": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/core/-/core-9.3.1.tgz",
"integrity": "sha512-N6Gl9z3SxYp1OVtOzQegtURFqr0D62l3QcXgvshDAVXDNjkziZ5gWj//JxYJRWldNZfVp9/pm97V3ExKI5AXPg==",
"license": "MIT",
"dependencies": {
"@types/json-schema": "^7.0.11"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@dicebear/croodles": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/croodles/-/croodles-9.3.1.tgz",
"integrity": "sha512-p40OXll38AYpWh7vOVuapv6ClQuzaMh77e++QJjJGNr6n1OE6YmmQbp6XzE7iELzz2yGoCPIm/FjI+zcH0aAwA==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/croodles-neutral": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/croodles-neutral/-/croodles-neutral-9.3.1.tgz",
"integrity": "sha512-NEOV/j+pqxhFmxSC4EFjPgjbTsnOXkX3WgLLVz0PZBpVpS2kPOwBQXZT2fUGZIq7zHucWWatnMaKBvd2LYmFhA==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/dylan": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/dylan/-/dylan-9.3.1.tgz",
"integrity": "sha512-CWP8S9heivya/KSSF72IJ6QKE5bUsoxKSlnLD21uO+NAm5Mzkw00PM0cgA4RvnPNf0Et7HmoJXrrvOBavWE65A==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/fun-emoji": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/fun-emoji/-/fun-emoji-9.3.1.tgz",
"integrity": "sha512-oSJPxHvAnORxa3FJYwYGQcUuP5LIFRKzMJJ9RP4D5GTYmpjsdG0K895eo4vKkXrY/BVNVROBlfK0KcTX1xOU8g==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/glass": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/glass/-/glass-9.3.1.tgz",
"integrity": "sha512-yNxDgIE9A+/n5VgOMH8P0qb1EGsMhMSSrl0s6ZnTBpHLGwRv1iGXezJaZrkx/ZSPsp8KlOOfTodeqi2vkVdFHg==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/icons": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/icons/-/icons-9.3.1.tgz",
"integrity": "sha512-p8BrJ/6C2smLKU8vFFu+B54zD/GFbdjumVubzcURjvbOh1YOWU2CD4TruSBZ4d2zbAwgJIAjE+5oANB0a1gfdg==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/identicon": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/identicon/-/identicon-9.3.1.tgz",
"integrity": "sha512-P3TmN7pRqlS8S9/1E+lGEMrBbQvjjXGNgXnw+Okviq+41172iLVg6Wv0nbNsOyF9QjRTjrJMq4VT3XgOuU4JAg==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/initials": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/initials/-/initials-9.3.1.tgz",
"integrity": "sha512-1O61oYxKVeeGL6QcNCcxH7zsqbp37NmHbR/Y5CVqr6AVv0bBswvCzVzUv/Zmmsp70DoYQB+lbX+oNIdcqUWAaw==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/lorelei": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/lorelei/-/lorelei-9.3.1.tgz",
"integrity": "sha512-4btARyv+ITuL3GWKA68/h6hAPL52lN1034JHx+dJCjy7zXrsXvFKkQj62LbCkQKHQOihTkAW1dfccVQ7mlGn4w==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/lorelei-neutral": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/lorelei-neutral/-/lorelei-neutral-9.3.1.tgz",
"integrity": "sha512-GP2EX3w8Di4b3XN0uM7lARbg1iZ9r0zaZHlUbCE2CzFy3xxrKSrRDYf2BvVt7x76doijXR5SLm4DMbEA9ARJWA==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/micah": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/micah/-/micah-9.3.1.tgz",
"integrity": "sha512-LAPY6Zlw/nh0Xts4aIY5d0hlaJEfSah+M5GoBRzKFKlieYdee7hvE8gsCE+OZ4pZUc98Dh7h0XXqVt/ojYW3jw==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/miniavs": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/miniavs/-/miniavs-9.3.1.tgz",
"integrity": "sha512-LRLKxDAIk8fW/88YB0vbYiJ850FaO2EcdznOfyW0izDp0ghTGZXsO5B5RUiLTunH8ZCnDdA+DtaugaFTdvOx/Q==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/notionists": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/notionists/-/notionists-9.3.1.tgz",
"integrity": "sha512-xSukD2J+iKaKq/kEOZ6svwon9sQYRpgIeNC7Gfskb7uyC+iUHQmCy6hSxLFGIOFVqEbw6Ow8uNpn9NqaFpQA4w==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/notionists-neutral": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/notionists-neutral/-/notionists-neutral-9.3.1.tgz",
"integrity": "sha512-Z9dikJjibAc94EtFnHQb1+ADMISLedgLls5+ARiKwKjPcYZcuRm4U8kR9tMLmqggro10uJlT7YrLSCC/5abUXA==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/open-peeps": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/open-peeps/-/open-peeps-9.3.1.tgz",
"integrity": "sha512-g4A3XcLrKPy44ajlhWfmGXYUDzXfogzB/H7Z46k+mxvrhVSF0jsmReYjX80jqHNeEZ9ikIpR5g4Hbo6vmOmjGQ==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/personas": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/personas/-/personas-9.3.1.tgz",
"integrity": "sha512-2xqaiY0/uHKFNhC+ZEBINJZM9/fC8gUMFCqP4N6QuXkFbqNZn4RjgbTITkGtRE5Z4m2q9hEfPey4Dc9jep5lzA==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/pixel-art": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/pixel-art/-/pixel-art-9.3.1.tgz",
"integrity": "sha512-yUufylvVqkb9wpG/sYRzNTeSk1YbzVgSq/ZSMyxy1kx/R4BhOkiZBSs6Ra3VjeKWVNDBzUWERaVdylLbFvAQaw==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/pixel-art-neutral": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/pixel-art-neutral/-/pixel-art-neutral-9.3.1.tgz",
"integrity": "sha512-N3mcC4CFTAMk3TqRvZVsZAGY2NONnQwoGpP+MD4E2GF+kVWoQYpvzOybVgFoOz2G0Oe4HAwSO5Qt7KTbAiD7KA==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/rings": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/rings/-/rings-9.3.1.tgz",
"integrity": "sha512-1bQTKJbVzpBPbhSyHS5bzlRjYIRQKO1hR0JGmC/ZWFiE9+ySk/NNwkNghvcDxvDUaz02NLSJXlSp2T8nrsdNHg==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/shapes": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/shapes/-/shapes-9.3.1.tgz",
"integrity": "sha512-xzw/BWSQCznRDFBp8DKQtg1Jxawq+R3upOM2pURwbCPC+9bi8f8CAz1SExA3tlAbbrVx0HQdRKIYS3GW6/GBBA==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/thumbs": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/thumbs/-/thumbs-9.3.1.tgz",
"integrity": "sha512-HS14oyT9HXLT8OPqEz8n0Bdob3oRWoNZ5PSZrxT4nyYXxh0rDSxCCOFwPKanXznk1qCAngtAvuzzID3vo7UG3A==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@dicebear/toon-head": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@dicebear/toon-head/-/toon-head-9.3.1.tgz",
"integrity": "sha512-9a9ydhbrVG57NuscH92yzIMQ0yxEPgJtzOMG1QR6jWctgbeEuzQvJDPvJQTxtfFjx71VlQNsSL40/5rnMtCaTw==",
"license": "(MIT AND CC-BY-4.0)",
"engines": {
"node": ">=16.0.0"
},
"peerDependencies": {
"@dicebear/core": "^9.0.0"
}
},
"node_modules/@emnapi/runtime": {
@@ -713,6 +1147,12 @@
"tslib": "^2.8.0"
}
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.2.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-25.2.1.tgz",

View File

@@ -8,10 +8,15 @@
"start": "next start"
},
"dependencies": {
"@dicebear/collection": "^9.3.1",
"@dicebear/core": "^9.3.1",
"@supabase/supabase-js": "^2.78.0",
"framer-motion": "^12.29.2",
"next": "^16.1.5",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"engines": {
"node": ">=20.9.0"
}
}